[
  {
    "path": ".gitignore",
    "content": ".idea/\n\n.vscode/\n\nsolutions/java/.idea/\nsolutions/java/out/\n\nsolutions/c++/.idea/\n\nsolutions/c#/bin/\nsolutions/c#/obj/\n\n*.py"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img src=\"images/lld-repo-logo.png\" width=\"350\" height=\"200\">\n</p>\n<p align=\"center\">\n  <a href=\"https://blog.algomaster.io/\">Join Free Newsletter</a>\n</p>\n\nThis repository contains resources to learn Low Level Design (LLD) / Object Oriented Design (OOD) and prepare for interviews. It covers OOP fundamentals, design patterns, UML, concurrency and commonly asked interview questions.\n\n👉 For a better and more comprehensive experience, checkout the [LLD page at AlgoMaster.io](https://algomaster.io/learn/lld)\n\n## 🧱 OOP Fundamentals\n- [Classes and Objects](https://algomaster.io/learn/lld/classes-and-objects)\n- [Enums](https://algomaster.io/learn/lld/enums)\n- [Interfaces](https://algomaster.io/learn/lld/interfaces)\n- [Encapsulation](https://algomaster.io/learn/lld/encapsulation)\n- [Abstraction](https://algomaster.io/learn/lld/abstraction)\n- [Inheritance](https://algomaster.io/learn/lld/inheritance)\n- [Polymorphism](https://algomaster.io/learn/lld/polymorphism)\n\n## 🔗 Class Relationships\n- [Association](https://algomaster.io/learn/lld/association)\n- [Aggregation](https://algomaster.io/learn/lld/aggregation)\n- [Composition](https://algomaster.io/learn/lld/composition)\n- [Dependency](https://algomaster.io/learn/lld/dependency)\n\n## 🧭 Design Principles\n- [DRY Principle](https://algomaster.io/learn/lld/dry)\n- [YAGNI Principle](https://algomaster.io/learn/lld/yagni)\n- [KISS Principle](https://algomaster.io/learn/lld/kiss)\n- [SOLID Principles with Pictures](https://medium.com/backticks-tildes/the-s-o-l-i-d-principles-in-pictures-b34ce2f1e898)\n- [SOLID Principles with Code](https://blog.algomaster.io/p/solid-principles-explained-with-code)\n\n## 🧩 Design Patterns\n\n| **Creational Patterns**                                                       | **Structural Patterns**                                         | **Behavioral Patterns**                                                               |\n| ----------------------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------- |\n| [Singleton](https://algomaster.io/learn/lld/singleton)            | [Adapter](https://algomaster.io/learn/lld/adapter)     | [Iterator](https://algomaster.io/learn/lld/iterator)                         |\n| [Factory Method](https://algomaster.io/learn/lld/factory-method)     | [Bridge](https://algomaster.io/learn/lld/bridge)       | [Observer](https://algomaster.io/learn/lld/observer)                         |\n| [Abstract Factory](https://algomaster.io/learn/lld/abstract-factory) | [Composite](https://algomaster.io/learn/lld/composite) | [Strategy](https://algomaster.io/learn/lld/strategy)                         |\n| [Builder](https://algomaster.io/learn/lld/builder)                   | [Decorator](https://algomaster.io/learn/lld/decorator) | [Command](https://algomaster.io/learn/lld/command)                           |\n| [Prototype](https://algomaster.io/learn/lld/prototype)               | [Facade](https://algomaster.io/learn/lld/facade)       | [State](https://algomaster.io/learn/lld/state)                               |\n|                                                                               | [Flyweight](https://algomaster.io/learn/lld/flyweight) | [Template Method](https://algomaster.io/learn/lld/template-method)           |\n|                                                                               | [Proxy](https://algomaster.io/learn/lld/proxy)         | [Visitor](https://algomaster.io/learn/lld/visitor)                           |\n|                                                                               |                                                                 | [Mediator](https://algomaster.io/learn/lld/mediator)                         |\n|                                                                               |                                                                 | [Memento](https://algomaster.io/learn/lld/memento)                           |\n|                                                                               |                                                                 | [Chain of Responsibility](https://algomaster.io/learn/lld/chain-of-responsibility) |\n\n## 🗂️ UML\n- [Class Diagram](https://algomaster.io/learn/lld/class-diagram)\n- [Use Case Diagram](https://algomaster.io/learn/lld/use-case-diagram)\n- [Sequence Diagram](https://algomaster.io/learn/lld/sequence-diagram)\n- [Activity Diagram](https://algomaster.io/learn/lld/activity-diagram)\n- [State Machine Diagram](https://algomaster.io/learn/lld/state-machine-diagram)\n\n## ⏱️ Concurrency and Multi-threading Concepts\n### Concurrency 101\n- [Introduction to Concurrency](https://algomaster.io/learn/concurrency-interview/introduction-to-concurrency)\n- [Concurrency vs Parallelism](https://algomaster.io/learn/concurrency-interview/concurrency-vs-parallelism)\n- [Processes vs Threads](https://algomaster.io/learn/concurrency-interview/processes-vs-threads)\n- [Thread Lifecycle and States](https://algomaster.io/learn/concurrency-interview/thread-lifecycle-and-states)\n- [Race Conditions and Critical Sections](https://algomaster.io/learn/concurrency-interview/race-conditions-and-critical-sections)\n### Synchronization Primitives\n- [Mutex (Mutual Exclusion)](https://algomaster.io/learn/concurrency-interview/mutex)\n- [Semaphores](https://algomaster.io/learn/concurrency-interview/semaphores)\n- [Condition Variables](https://algomaster.io/learn/concurrency-interview/condition-variables)\n- [Coarse-grained vs Fine-grained Locking](https://algomaster.io/learn/concurrency-interview/coarse-vs-fine-grained-locking)\n- [Reentrant Locks](https://algomaster.io/learn/concurrency-interview/reentrant-locks)\n- [Try-Lock and Timed Locking](https://algomaster.io/learn/concurrency-interview/try-lock-and-timed-locking)\n- [Compare-and-Swap (CAS)](https://algomaster.io/learn/concurrency-interview/compare-and-swap)\n### Concurrency Challenges\n- [Deadlock](https://algomaster.io/learn/concurrency-interview/deadlock)\n- [Livelock](https://algomaster.io/learn/concurrency-interview/livelock)\n### Concurrency Patterns\n- [Signaling Pattern](https://algomaster.io/learn/concurrency-interview/signaling-pattern)\n- [Thread Pool Pattern](https://algomaster.io/learn/concurrency-interview/thread-pool-pattern)\n- [Producer-Consumer Pattern](https://algomaster.io/learn/concurrency-interview/producer-consumer-pattern)\n- [Reader-Writer Pattern](https://algomaster.io/learn/concurrency-interview/reader-writer-pattern)\n\n## ✅ [How to Answer a LLD Interview Problem](https://blog.algomaster.io/p/how-to-answer-a-lld-interview-problem)\n<img src=\"images/interview-template.png\" width=\"350\" height=\"250\">\n\n## 💻 Low Level Design Interview Problems\n### Easy Problems\n\n- [Design Parking Lot](problems/parking-lot.md)\n- [Design Stack Overflow](problems/stack-overflow.md)\n- [Design a Vending Machine](problems/vending-machine.md)\n- [Design Logging Framework](problems/logging-framework.md)\n- [Design Traffic Signal Control System](problems/traffic-signal.md)\n- [Design Coffee Vending Machine](problems/coffee-vending-machine.md)\n- [Design a Task Management System](problems/task-management-system.md)\n\n### Medium Problems\n\n- [Design ATM](problems/atm.md)\n- [Design LinkedIn](problems/linkedin.md)\n- [Design LRU Cache](problems/lru-cache.md)\n- [Design Tic Tac Toe Game](problems/tic-tac-toe.md)\n- [Design Pub Sub System](problems/pub-sub-system.md)\n- [Design an Elevator System](problems/elevator-system.md)\n- [Design Car Rental System](problems/car-rental-system.md)\n- [Design an Online Auction System](problems/online-auction-system.md)\n- [Design Hotel Management System](problems/hotel-management-system.md)\n- [Design a Digital Wallet Service](problems/digital-wallet-service.md)\n- [Design Airline Management System](problems/airline-management-system.md)\n- [Design a Library Management System](problems/library-management-system.md)\n- [Design a Social Network like Facebook](problems/social-networking-service.md)\n- [Design Restaurant Management System](problems/restaurant-management-system.md)\n- [Design a Concert Ticket Booking System](problems/concert-ticket-booking-system.md)\n\n### Hard Problems\n\n- [Design CricInfo](problems/cricinfo.md)\n- [Design Splitwise](problems/splitwise.md)\n- [Design Chess Game](problems/chess-game.md)\n- [Design a Snake and Ladder game](problems/snake-and-ladder.md)\n- [Design Ride-Sharing Service like Uber](problems/ride-sharing-service.md)\n- [Design Course Registration System](problems/course-registration-system.md)\n- [Design Movie Ticket Booking System](problems/movie-ticket-booking-system.md)\n- [Design Online Shopping System like Amazon](problems/online-shopping-service.md)\n- [Design Online Stock Brokerage System](problems/online-stock-brokerage-system.md)\n- [Design Music Streaming Service like Spotify](problems/music-streaming-service.md)\n- [Design Online Food Delivery Service like Swiggy](problems/food-delivery-service.md)\n\n## ⏱️ Concurrency and Multi-threading Problems\n\n- [Print FooBar Alternately](https://algomaster.io/learn/concurrency-interview/print-foobar-alternately)\n- [Print Zero Even Odd](https://algomaster.io/learn/concurrency-interview/print-zero-even-odd)\n- [Fizz Buzz Multithreaded](https://algomaster.io/learn/concurrency-interview/fizz-buzz-multithreaded)\n- [Building H2O Molecule](https://algomaster.io/learn/concurrency-interview/building-h2o)\n- [Design Thread-Safe Cache with TTL](https://algomaster.io/learn/concurrency-interview/design-thread-safe-cache-with-ttl)\n- [Design Concurrent HashMap](https://algomaster.io/learn/concurrency-interview/design-concurrent-hashmap)\n- [Design Thread-Safe Blocking Queue](https://algomaster.io/learn/concurrency-interview/design-thread-safe-blocking-queue)\n- [Design Concurrent Bloom Filter](https://algomaster.io/learn/concurrency-interview/design-concurrent-bloom-filter)\n- [Multi-threaded Merge Sort](https://algomaster.io/learn/concurrency-interview/multi-threaded-merge-sort)\n\n## 📇 Courses\n- [Master LLD Interviews - AlgoMaster.io](https://algomaster.io/learn/lld/course-introduction)\n- [Master Concurrency Interviews - AlgoMaster.io](https://algomaster.io/learn/concurrency-interview)\n\n## 📚 Books\n- [Head First Design Patterns](https://www.amazon.in/dp/9385889753)\n- [Clean Code](https://www.amazon.in/dp/B001GSTOAM)\n- [Refactoring: Improving the Design of Existing Code](https://www.amazon.in/dp/0134757599)\n\n## 📩 Newsletter\n- [AlgoMaster Newsletter](https://blog.algomaster.io/)\n\n## Additional resources\n- [Coursera - Object-Oriented Design](https://www.coursera.org/learn/object-oriented-design)\n- [Coursera - Design Patterns](https://www.coursera.org/learn/design-patterns)\n- [Github - Awesome Design Patterns](https://github.com/DovAmir/awesome-design-patterns)\n\n## 🤝 Contributing\nContributions are welcome! If you'd like to add a new problem, improve existing content, or fix errors:\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature/your-feature-name`\n3. Commit your changes: `git commit -m 'Add some feature'`\n4. Push to the branch: `git push origin feature/your-feature-name`\n5. Submit a pull request\n\nPlease make sure to update Readme files and documentation as appropriate.\n\n---\n\n<p align=\"center\">\n  <i>If you find this resource helpful, please give it a star and share it with others!</i>\n</p>\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Chain of Responsibilites/main.js",
    "content": "const {\n  InternetConnectionTeam,\n  InternetSupportTeam,\n  PhoneConnectionTeam,\n  PhoneSupportTeam,\n} = require(\"./supportRequest\");\n\n\nconst phoneSupport = new PhoneSupportTeam(null);\nconst phoneConnection = new PhoneConnectionTeam(phoneSupport);\nconst internetSupport = new InternetSupportTeam(phoneConnection);\nconst internetConnection = new InternetConnectionTeam(internetSupport);\n\n\nconsole.log(\"Problem 1 - internet connection\");\ninternetConnection.handleRequest(\"internet\", \"newConnection\");\n\nconsole.log(\"Problem 2 - phone connection\");\ninternetConnection.handleRequest(\"phone\", \"problem\");\n\nconsole.log(\"Problem 3 - phone support\");\ninternetConnection.handleRequest(\"phone\", \"problem\");\n\n\nconsole.log(\"Problem 4 - Invalid support\");\ninternetConnection.handleRequest(\"Laptop\", \"problem\");\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Chain of Responsibilites/supportRequest.js",
    "content": "// Creating a chain for attaining support team\n\nclass supportHandler {\n  constructor(nextHandler) {\n    this.nextHandler = nextHandler;\n  }\n\n  // Method to handle the request\n  handleRequest(request, type) {\n    if (this.nextHandler) {\n      console.log(\"Passing to the next executive team to resolve your issue\");\n      this.nextHandler.handleRequest(request, type);\n    } else {\n      console.log(\"No further handlers available to process the request.\");\n    }\n  }\n}\n\n// First level internet support team for connection\nclass InternetConnectionTeam extends supportHandler {\n  handleRequest(request, type) {\n    if (request === \"internet\" && type === \"newConnection\") {\n      console.log(\"Your newConnection request is taken. Thank you! 🙂\");\n    } else if (request === \"internet\" && type === \"problem\") {\n      console.log(\n        \"Seems you have an issue; we will redirect to the support team\"\n      );\n      super.handleRequest(request, type); // Transferring to the next team\n    } else {\n      console.log(\n        \"Unknown request type in InternetConnectionTeam. Passing to next team.\"\n      );\n      super.handleRequest(request, type); // Transfer to the next team\n    }\n  }\n}\n\n// Second level internet support team for problem\nclass InternetSupportTeam extends supportHandler {\n  handleRequest(request, type) {\n    if (request === \"internet\" && type === \"problem\") {\n      console.log(\"Your internet request is taken. Thank you! 🙂\");\n    } else {\n      console.log(\n        \"Unknown request type in InternetSupportTeam. Passing to next team.\"\n      );\n      super.handleRequest(request, type); // Transferring to the next team\n    }\n  }\n}\n\n// Third level connection\nclass PhoneConnectionTeam extends supportHandler {\n  handleRequest(request, type) {\n    if (request === \"phone\" && type === \"newConnection\") {\n      console.log(\"Your newConnection request is taken. Thank you! 🙂\");\n    } else if (request === \"phone\" && type === \"problem\") {\n      console.log(\n        \"Seems you have an issue; we will redirect to the support team\"\n      );\n      super.handleRequest(request, type); // Transferring to the next team\n    } else {\n      console.log(\n        \"Unknown request type in PhoneConnectionTeam. Passing to next team.\"\n      );\n      super.handleRequest(request, type); // Transferring to the next team\n    }\n  }\n}\n\n// Last level phone support team for problem\nclass PhoneSupportTeam extends supportHandler {\n  handleRequest(request, type) {\n    if (request === \"phone\" && type === \"problem\") {\n      console.log(\"Your phone request is taken. Thank you! 🙂\");\n    } else {\n      console.log(\n        \"Unknown request type in PhoneSupportTeam. This is the last support level.\"\n      );\n    }\n  }\n}\n\n// Main module export\nmodule.exports = {\n  InternetConnectionTeam,\n  InternetSupportTeam,\n  PhoneConnectionTeam,\n  PhoneSupportTeam,\n};\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Command Design Pattern/command.js",
    "content": "// Abstract Command\nclass Command {\n  execute() {}\n}\n\n// Concrete Command\nclass LightOnCommand extends Command {\n  constructor(light) {\n    super();\n    this.light = light;\n  }\n\n  execute() {\n    this.light.turnOn();\n  }\n}\nclass LightOffCommand extends Command {\n  constructor(light) {\n    super();\n    this.light = light;\n  }\n\n  execute() {\n    this.light.turnOff();\n  }\n}\n\n// Concrete Command to turn on the fan\nclass FanOnCommand extends Command {\n  constructor(fan) {\n    super();\n    this.fan = fan;\n  }\n\n  execute() {\n    this.fan.turnOn();\n  }\n}\n\n// Concrete Command to turn off the fan\nclass FanOffCommand extends Command {\n  constructor(fan) {\n    super();\n    this.fan = fan;\n  }\n\n  execute() {\n    this.fan.turnOff();\n  }\n}\n\nmodule.exports = {\n  LightOnCommand,\n  LightOffCommand,\n  FanOnCommand,\n  FanOffCommand,\n};\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Command Design Pattern/invoker.js",
    "content": "// Invoker class\nclass RemoteControl {\n    setCommand(command) {\n      this.command = command;\n    }\n  \n    pressButton() {\n      this.command.execute();\n    }\n  }\n\n  module.exports = {RemoteControl}\n  "
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Command Design Pattern/main.js",
    "content": "// Client code\n\nconst {\n  LightOnCommand,\n  LightOffCommand,\n  FanOnCommand,\n  FanOffCommand,\n} = require(\"./command\");\n\nconst{Light, Fan} = require('./receiver')\n\nconst {RemoteControl} = require ('./invoker')\n\nconst light = new Light();\nconst fan = new Fan();\n\nconst lightOn = new LightOnCommand(light);\nconst lightOff = new LightOffCommand(light);\n\nconst fanOn = new FanOnCommand(fan);\nconst fanOff = new FanOffCommand(fan);\n\nconst remote = new RemoteControl();\n\n// Turning on the light\nremote.setCommand(lightOn);\nremote.pressButton(); // Output: \"The light is on.\"\n\n// Turning off the light\nremote.setCommand(lightOff);\nremote.pressButton(); // Output: \"The light is off.\"\n\n// Turning on the fan\nremote.setCommand(fanOn);\nremote.pressButton(); // Output: \"The fan is on.\"\n\n// Turning off the fan\nremote.setCommand(fanOff);\nremote.pressButton(); // Output: \"The fan is off.\"\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Command Design Pattern/receiver.js",
    "content": "// Receiver for Light\nclass Light {\n  turnOn() {\n    console.log(\"The light is on.\");\n  }\n\n  turnOff() {\n    console.log(\"The light is off.\");\n  }\n}\n\n// Receiver for Fan\nclass Fan {\n  turnOn() {\n    console.log(\"The fan is on.\");\n  }\n\n  turnOff() {\n    console.log(\"The fan is off.\");\n  }\n}\n\nmodule.exports = { Light, Fan };\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Iterator Design Pattern/aggregate.js",
    "content": "const { LibraryIterator } = require(\"./iterator\");\nconst Book = require(\"./book\");\n\nclass Aggregate {\n  createIterator() {\n    throw new Error(\"Method 'createIterator()' must be implemented.\");\n  }\n}\n\nclass ConcreteAggregate extends Aggregate {\n  constructor() {\n    super();\n    this.books = [];\n  }\n\n  addBook(book) {\n    this.books.push(book);\n  }\n\n  createIterator() {\n    return new LibraryIterator(this.books);\n  }\n}\n\nmodule.exports = ConcreteAggregate;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Iterator Design Pattern/book.js",
    "content": "class Book {\n  constructor(title, author) {\n    this.title = title;\n    this.author = author;\n  }\n\n  getDetails() {\n    return `${this.title} by ${this.author}`;\n  }\n}\n\nmodule.exports = Book;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Iterator Design Pattern/iterator.js",
    "content": "class Iterator {\n  next() {\n    throw new Error(\"Method 'next()' must be implemented.\");\n  }\n\n  hasNext() {\n    throw new Error(\"Method 'hasNext()' must be implemented.\");\n  }\n}\n\n// Concrete Iterator\nclass LibraryIterator extends Iterator {\n  constructor(collection) {\n    super();\n    this.collection = collection;\n    this.index = 0;\n  }\n\n  hasNext() {\n    return this.index < this.collection.length;\n  }\n\n\n  next() {\n    console.log(\"Current index: \" + this.index);\n    return this.collection[this.index++];\n  }\n}\n\nmodule.exports = { Iterator, LibraryIterator };\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Iterator Design Pattern/main.js",
    "content": "const ConcreteAggregate = require(\"./aggregate\");\nconst Book = require(\"./book\");\n\nconst library = new ConcreteAggregate();\n\n// Adding books to the library\nlibrary.addBook(new Book(\"To Kill a Mockingbird\", \"Harper Lee\"));\nlibrary.addBook(new Book(\"1984\", \"George Orwell\"));\nlibrary.addBook(new Book(\"The Great Gatsby\", \"F. Scott Fitzgerald\"));\nlibrary.addBook(new Book(\"Moby Dick\", \"Herman Melville\"));\n\n// Creating an iterator for the library\nconst iterator = library.createIterator();\n\n// Iterating through the collection of books\nwhile (iterator.hasNext()) {\n  const book = iterator.next();\n  console.log(book.getDetails());\n}\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Mediator Design Pattern/main.js",
    "content": "// Client code to handle users registration and messages communication\n\nconst User = require(\"./user\");\nconst ChatRoom = require(\"./mediator\");\n\n// Object for chatRoom (mediator)\nconst chatRoom = new ChatRoom();\n\n// Objects for users\nconst user1 = new User(\"User1\", chatRoom);\nconst user2 = new User(\"User2\", chatRoom);\nconst user3 = new User(\"User3\", chatRoom);\n\n\n// Register users with chatRoom\nchatRoom.register(user1);\nchatRoom.register(user2);\nchatRoom.register(user3);\n\n// Send message\nuser1.send(\"Hello everyone!\");\nuser2.send(\"Hi User1!\");\nuser3.send(\"Hi User2!\");"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Mediator Design Pattern/mediator.js",
    "content": "// Abstract Mediator\nclass Mediator {\n  register(user) {\n    throw new Error(\"Method 'register()' must be implemented\");\n  }\n\n  send(message, user) {\n    throw new Error(\"Method 'send()' must be implemented\");\n  }\n}\n\n// Concrete Mediator\nclass ChatRoom extends Mediator {\n  constructor() {\n    super();\n    this.users = [];\n  }\n\n  register(user) {\n    this.users.push(user);\n  }\n\n  send(message, from) {\n    this.users.forEach((user) => {\n      if (user !== from) {\n        // send senderMessage only to other users\n        user.receive(message, from);\n      }\n    });\n  }\n}\n\nmodule.exports = ChatRoom;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Mediator Design Pattern/user.js",
    "content": "class User {\n  constructor(name, mediator) {\n    this.name = name;\n    this.mediator = mediator;\n  }\n\n  send(message) {\n    console.log(`${this.name} sent: ${message}`);\n    this.mediator.send(message, this);\n  }\n\n  receive(message) { \n    console.log(`${this.name} receives message: ${message}`);\n  }\n}\n\nmodule.exports = User;"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/Example2/canvas.js",
    "content": "// Import CanvasMemento from memento.js\nconst CanvasMemento = require(\"./memento\"); // <-- Add this line\n\nclass DrawingCanvas {\n  constructor() {\n    this.shapes = []; // The current shapes drawn on the canvas\n  }\n\n  // Method to draw a new shape\n  addShape(shape) {\n    this.shapes.push(shape);\n  }\n\n  // Method to remove the last added shape (simulating undo)\n  removeLastShape() {\n    this.shapes.pop();\n  }\n\n  // Create a memento (save the current state)\n  save() {\n    return new CanvasMemento([...this.shapes]); // Copy the current shapes to a new Memento\n  }\n\n  // Restore the canvas state from a memento\n  restore(memento) {\n    this.shapes = memento.getState(); // Replace current shapes with the saved shapes\n  }\n\n  // Print all shapes (to simulate displaying them on the canvas)\n  show() {\n    console.log(\"Current shapes on canvas:\", this.shapes);\n  }\n}\n\nmodule.exports = DrawingCanvas;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/Example2/careTaker.js",
    "content": "// CareTaker -> Manages mementos\n\nclass History {\n  constructor() {\n    this.mementos = []; // List of saved mementos\n  }\n\n  // Save a memento\n  saveMemento(memento) {\n    this.mementos.push(memento);\n  }\n\n  // Get a memento\n  getMemento(index) {\n    return this.mementos[index];\n  }\n\n  // Remove the last memento\n  removeMemento() {\n    return this.mementos.pop();\n  }\n  getLatestMemento() {\n    return this.mementos.length > 0\n      ? this.mementos[this.mementos.length - 1]\n      : null;\n  }\n\n  removeLastMemento() {\n    if (this.mementos.length > 0) {\n      this.mementos.pop();\n    }\n  }\n}\n\nmodule.exports = History;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/Example2/main.js",
    "content": "const DrawingCanvas = require('./canvas');\nconst CanvasMemento = require('./memento');\nconst History = require('./careTaker');\n\n// Create a new drawing canvas (Originator)\nconst canvas = new DrawingCanvas();\n\n// Create a new History (Caretaker)\nconst history = new History();\n\n// Draw some shapes on the canvas\ncanvas.addShape(\"Circle\");\ncanvas.addShape(\"Square\");\n\n// Show current state of canvas\nconsole.log(\"Initial Drawing:\");\ncanvas.show(); // Output: Circle, Square\n\n// Save the current state of the canvas\nhistory.saveMemento(canvas.save()); // Save: Circle, Square\n\n// Draw more shapes\ncanvas.addShape(\"Triangle\");\ncanvas.addShape(\"Hexagon\");\n\n// Show current state of canvas\nconsole.log(\"\\nAfter Drawing More Shapes:\");\ncanvas.show(); // Output: Circle, Square, Triangle, Hexagon\n\n// Save the current state again\nhistory.saveMemento(canvas.save()); // Save: Circle, Square, Triangle, Hexagon\n\n// Draw another shape\ncanvas.addShape(\"Pentagon\");\n\n// Show current state of canvas\nconsole.log(\"\\nAfter Adding Pentagon:\");\ncanvas.show(); // Output: Circle, Square, Triangle, Hexagon, Pentagon\n\n// Undo the last action by restoring the previous memento\ncanvas.restore(history.getLatestMemento());\nhistory.removeLastMemento(); // Remove the latest snapshot\n\nconsole.log(\"\\nAfter Undo (Restoring Previous State):\");\ncanvas.show(); // Output: Circle, Square, Triangle, Hexagon\n\n// Undo another action\ncanvas.restore(history.getLatestMemento());\nhistory.removeLastMemento(); // Remove the latest snapshot\n\nconsole.log(\"\\nAfter Another Undo:\");\ncanvas.show(); // Output: Circle, Square\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/Example2/memento.js",
    "content": "// Memento -> Stores the snapshot of canvas state\nclass CanvasMemento {\n  constructor(state) {\n    this.state = state; // The saved shapes at this point\n  }\n\n  // Returns the saved state\n  getState() {\n    return this.state;\n  }\n}\n\nmodule.exports = CanvasMemento;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/careTaker.js",
    "content": "// careTaker.js\n\nclass CareTaker {\n  constructor() {\n    this.mementos = [];\n  }\n\n  saveMemento(memento) {\n    this.mementos.push(memento);\n  }\n\n  getMemento(index) {\n    return this.mementos[index];\n  }\n}\n\nmodule.exports = CareTaker;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/main.js",
    "content": "const TextEditor = require(\"./orginator\");\nconst Caretaker = require(\"./careTaker\");\n\n// Create a TextEditor instance\nconst textEditor = new TextEditor();\nconst caretaker = new Caretaker();\n\n// Write some content\ntextEditor.write(\"Hello, \");\ncaretaker.saveMemento(textEditor.save()); // Save the current state\n\ntextEditor.write(\"world!\");\nconsole.log(textEditor.getContent()); // Output: \"Hello, world!\"\n\ncaretaker.saveMemento(textEditor.save()); // Save the current state again\n\ntextEditor.write(\" How are you?\");\nconsole.log(textEditor.getContent()); // Output: \"Hello, world! How are you?\"\n\n// Restore to the previous state\ntextEditor.restore(caretaker.getMemento(1));\nconsole.log(textEditor.getContent()); // Output: \"Hello, world!\"\n\n// Restore to the initial state\ntextEditor.restore(caretaker.getMemento(0));\nconsole.log(textEditor.getContent()); // Output: \"Hello, \"\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/memento.js",
    "content": "// Memento\nclass Memento {\n  constructor(state) {\n    this.state = state;\n  }\n\n  getState() {\n    return this.state;\n  }\n}\n\nmodule.exports = Memento;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Memento Design Pattern/orginator.js",
    "content": "// Orginator file\n\nconst Memento = require(\"./memento\");\n\nclass TextEditor {\n  constructor() {\n    this.content = \"\";\n  }\n\n  write(content) {\n    this.content += content;\n  }\n\n  getContent() {\n    return this.content;\n  }\n\n  save() {\n    return new Memento(this.content);\n  }\n\n  restore(memento) {\n    this.content = memento.getState();\n  }\n}\n\nmodule.exports = TextEditor;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Observer Design Pattern/main.js",
    "content": "const { WebUI, MobileUI } = require(\"./observer\");\nconst WeatherStation = require(\"./publisher\");\n\n// Create a WeatherStation instance\nconst weatherStation = new WeatherStation();\n\n// Create observers\nconst webUI = new WebUI();\nconst mobileUI = new MobileUI();\n\n// Register observers with the weather station\nweatherStation.addObserver(webUI);\nweatherStation.addObserver(mobileUI);\n\n// Change the temperature\nweatherStation.setTemperature(25); // Notify the data all observers  \nweatherStation.setTemperature(30); // Notify the updated data all observers\n\n\n// Adding another observer\nconst webUI2 = new WebUI();\nweatherStation.addObserver(webUI2);\nweatherStation.setTemperature(35);\n\n\n// Removing an observer\nweatherStation.removeObserver(webUI);\nweatherStation.setTemperature(40);\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Observer Design Pattern/observer.js",
    "content": "class Observer {\n  update(temperature) {\n    throw new Error(\"Method 'update()' must be implemented\");\n  }\n}\n\nclass WebUI extends Observer {\n  update(temperature) {\n    console.log(`Temperature showing in web UI: ${temperature}`);\n  }\n}\n\nclass MobileUI extends Observer {\n  update(temperature) {\n    console.log(`Temperature showing in mobile UI: ${temperature}`);\n  }\n}\n\nmodule.exports = {\n  WebUI,\n  MobileUI,\n};\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Observer Design Pattern/publisher.js",
    "content": "class WeatherStation {\n  constructor() {\n    this.observers = [];\n    this.temperature = 0;\n  }\n\n  //Method to add Subscribers to the list\n  addObserver(observer) {\n    this.observers.push(observer);\n  }\n\n  // Remove Subscribers from the list\n  removeObserver(observer) {\n    this.observers = this.observers.filter((obs) => obs !== observer);\n  }\n\n  // Notify all subscribers\n  notifyObservers() {\n    this.observers.forEach((observer) => observer.update(this.temperature));\n  }\n\n  //Method to set the temperature\n  setTemperature(temperature) {\n    this.temperature = temperature;\n    this.notifyObservers();\n  }\n}\n\nmodule.exports = WeatherStation;"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/State Design Pattern/context.js",
    "content": "const {Idle} = require(\"./state\");\n\n// Context Class\nclass Phone {\n  constructor() {\n    this.state = new Idle(); // Inital state\n  }\n  setState(state) {\n    this.state = state;\n  }\n  alert() {\n    this.state.alert();\n  }\n  answer() {\n    this.state.answer(this);\n  }\n  hangup() {\n    this.state.hangup(this);\n  }\n}\n\nmodule.exports = Phone;"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/State Design Pattern/main.js",
    "content": "const Phone = require(\"./context\");\n\nconst {Ringing} = require(\"./state\");\n\nconst phone = new Phone();\n\nphone.alert(); // Output: Phone is idle.\n\nphone.answer(); // Output: No incoming call to answer.\nphone.setState(new Ringing());\nphone.alert(); // Output: Phone is ringing...\n\nphone.answer(); // Output: Answering the call.\nphone.alert(); // Output: Phone is in a call.\n\nphone.hangup(); // Output: Hanging up the call.\nphone.alert(); // Output: Phone is idle.\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/State Design Pattern/state.js",
    "content": "// Abstract class for phoneState\nclass PhoneState {\n  alert() {}\n  answer() {}\n  hangup() {}\n}\n\n// Concerte Class for phoneState\n\n// State-1 : Phone is in Ringing State\nclass Ringing extends PhoneState {\n  alert() {\n    console.log(\"Phone is ringing...\");\n  }\n  answer(context) {\n    console.log(\"Phone is answering...\");\n    context.setState(new InCall());\n  }\n  hangup() {\n    console.log(\"Cannot hangup while ringing\");\n  }\n}\n\n// State-2 : Phone is in InCall State\nclass InCall extends PhoneState {\n  alert() {\n    console.log(\"Phone is in call...\");\n  }\n  answer() {\n    console.log(\"Cannot answer while in call\");\n  }\n  hangup(context) {\n    console.log(\"Phone is hanging up...\");\n    context.setState(new Idle());\n  }\n}\n\n// State-3 : Phone is in Idle State\nclass Idle extends PhoneState {\n  alert() {\n    console.log(\"Phone is idle...\");\n  }\n  answer() {\n    console.log(\"Phone is answering...\");\n    this.hangup();\n  }\n  hangup() {\n    console.log(\"Cannot hangup while idle\");\n  }\n}\n\nmodule.exports = { Ringing, InCall, Idle };\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Strategy Design Pattern/main.js",
    "content": "const ShoppinCart = require(\"./shoppingCart_Context\");\nconst { Cash, UPI, Card, InternetBanking } = require(\"./paymentStrategy\");\n\n// Creating a shopping cart Instance\nconst shoppingCart = new ShoppinCart();\n\n// Adding items to the shopping cart\nshoppingCart.addItem({ name: \"Laptop\", price: 500 });\nshoppingCart.addItem({ name: \"Mobile\", price: 200 });\nshoppingCart.addItem({ name: \"TV\", price: 1000 });\n\n// View cart after adding items\nshoppingCart.viewCart();\n\n// Checkout in method - 1\nshoppingCart.setPaymentMethod(new Card(123456789, 123));\nshoppingCart.checkout();\n\n// Checkout in method - 2\nshoppingCart.setPaymentMethod(new Cash(123));\nshoppingCart.checkout();\n\n// Checkout in method - 3\nshoppingCart.setPaymentMethod(new UPI(123456789, 123));\nshoppingCart.checkout();\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Strategy Design Pattern/paymentStrategy.js",
    "content": "// Strategy class\n\n// Abstract class\n\nclass PaymentGateway {\n  pay(amount) {\n    throw new Error(\"Method 'pay()' must be implemented!\");\n  }\n}\n\n// Concrete class for paymentGateway\n\n// Cash payment method\nclass Cash extends PaymentGateway {\n  pay(amount) {\n    console.log(`Payment of ${amount} done using Cash`);\n  }\n}\n\n// UPI payment method\nclass UPI extends PaymentGateway {\n  constructor(UPI_ID, UPI_PIN) {\n    super();\n    this.UPI_ID = UPI_ID;\n    this.UPI_PIN = UPI_PIN;\n  }\n  pay(amount) {\n    console.log(\n      `Payment of ${amount} done using UPI with ID ${this.UPI_ID} and PIN ${this.UPI_PIN}`\n    );\n  }\n}\n\n// Card payment method\nclass Card extends PaymentGateway {\n  constructor(cardNumber, CVV) {\n    super();\n    this.cardNumber = cardNumber;\n    this.CVV = CVV;\n  }\n  pay(amount) {\n    console.log(\n      `Payment of ${amount} done using Card Number ${this.cardNumber} and CVV ${this.CVV}`\n    );\n  }\n}\n\n// Internet Banking payment method\nclass InternetBanking extends PaymentGateway {\n  constructor(accountNumber, IFSC) {\n    super();\n    this.accountNumber = accountNumber;\n    this.IFSC = IFSC;\n  }\n  pay(amount) {\n    console.log(\n      `Payment of ${amount} done using Internet Banking with Account Number ${this.accountNumber} and IFSC ${this.IFSC}`\n    );\n  }\n}\n\nmodule.exports = { Cash, UPI, Card, InternetBanking };\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Strategy Design Pattern/shoppingCart_Context.js",
    "content": "// Context file as shoppingCart class\n\nclass ShoppinCart {\n  constructor() {\n    this.items = [];\n    this.paymentMethod = null;\n  }\n\n  // Adding items to the shopping cart\n  addItem(item) {\n    this.items.push(item);\n  }\n\n  // View cart after adding items\n  viewCart() {\n    console.log(\"Your cart contains: \");\n    this.items.forEach((item, index) => {\n      console.log(`${index + 1}. ${item.name} - $${item.price}`);\n    });\n  }\n\n  // Selecting the payment method\n  setPaymentMethod(paymentMethod) {\n    this.paymentMethod = paymentMethod;\n  }\n\n  // Checkout\n  checkout() {\n    // Adding reduce method to calculate the total bill\n    const Total = this.items.reduce((total, item) => total + item.price, 0);\n\n    // Checks if paymentMethod is choosen to proceed for checkout\n    if (this.paymentMethod) {\n      console.log(`Total Bill: $${Total}`);\n      this.paymentMethod.pay(Total);\n    } else {\n      console.log(\"Please confirm your payment method\");\n    }\n  }\n}\nmodule.exports = ShoppinCart;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Template Design Pattern/beverages.js",
    "content": "// Abstract class in Template Pattern\nclass Food {\n  prepareFood() {\n    this.boilWater();\n    this.brew();\n    this.pourInCup();\n    this.addCondiments();\n    this.noNeedVegetables(); // Setting as optional from template pattern\n  }\n\n  boilWater() {\n    console.log(\"Boiling the water...\");\n  }\n  brew() {\n    throw new error(\"Method 'brew()' must be implemented\");\n  }\n\n  pourInCup() {\n    console.log(\"Pouring into cup...\");\n  }\n  addCondiments() {\n    throw new error(\"Method 'addCondiments()' must be implemented\");\n  }\n\n  // private method\n  noNeedVegetables() {\n    if (this.shouldAddVegetables()) {\n      this.addVegetables();\n    }\n  }\n\n  addVegetables() {\n    console.log(\"No vegetables added here!\");\n  }\n\n  // Default is set to false\n  shouldAddVegetables() {\n    return false;\n  }\n}\n\nmodule.exports = Food;\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Template Design Pattern/beveragesTypes.js",
    "content": "// Concrete classes for Food\n// Make using of superClasses from templatePattern and modifying here (subClasses)\n\nconst Food = require(\"./beverages\");\n\nclass Tea extends Food {\n  brew() {\n    console.log(\"Steeping the tea...\");\n  }\n\n  addCondiments() {\n    console.log(\"Adding lemon...\");\n  }\n\n  addVegetables() {\n    console.log(\"Adding mint leaves to tea...\");\n  }\n\n  shouldAddVegetables() {\n    return true; // Tea includes vegetables\n  }\n}\n\nclass Coffee extends Food {\n  brew() {\n    console.log(\"Dripping coffee through filter...\");\n  }\n\n  addCondiments() {\n    console.log(\"Adding sugar and milk...\");\n  }\n}\n\nmodule.exports = { Tea, Coffee };\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Template Design Pattern/main.js",
    "content": "const { Tea, Coffee } = require(\"./beveragesTypes\");\n\n// Meal 1\nconsole.log(\"Preparing Tea..\");\nconst tea = new Tea();\ntea.prepareFood();\nconsole.log(\"\"); // For spacing\n\n// Meal 2\nconsole.log(\"Preparing Coffee..\");\nconst coffee = new Coffee();\ncoffee.prepareFood();\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Visitor Design Pattern/element.js",
    "content": "// element.js\nclass Shape {\n  accept(visitor) {\n    throw new Error(\"This method should be overridden!\");\n  }\n}\n\nclass Circle extends Shape {\n  constructor(radius) {\n    super();\n    this.radius = radius;\n  }\n\n  accept(visitor) {\n    visitor.visitCircle(this);\n  }\n}\nclass Rectangle extends Shape {\n  constructor(width, height) {\n    super();\n    this.width = width;\n    this.height = height;\n  }\n\n  accept(visitor) {\n    visitor.visitRectangle(this);\n  }\n}\n\nmodule.exports = {Circle,Rectangle};\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Visitor Design Pattern/main.js",
    "content": "const { Circle, Rectangle } = require(\"./element\");\nconst { AreaVisitor, PerimeterVisitor } = require(\"./visitor\");\n\n\nconst shapes = [\n  new Circle(5),\n  new Rectangle(10, 20),\n];\n\n// Create visitors\nconst areaVisitor = new AreaVisitor();\nconst perimeterVisitor = new PerimeterVisitor();\n\n// Calculate areas\nconsole.log(\"Calculating Areas:\");\nshapes.forEach((shape) => {\n  shape.accept(areaVisitor);\n});\n\n// Calculate perimeters\nconsole.log(\"\\nCalculating Perimeters:\");\nshapes.forEach((shape) => {\n  shape.accept(perimeterVisitor);\n});\n"
  },
  {
    "path": "design-patterns/Javascript/Behavioral Pattern/Visitor Design Pattern/visitor.js",
    "content": "// Visitor Interface\nclass ShapeVisitor {\n  visitCircle(circle) {\n    throw new Error(`This circle method should be overridden!`);\n  }\n\n  visitRectangle(rectangle) {\n    throw new Error(`This rectangke method should be overridden!`);\n  }\n}\n\n// Concrete visitor classes\nclass AreaVisitor extends ShapeVisitor {\n  visitCircle(circle) {\n    const area = Math.PI * circle.radius * circle.radius;\n    console.log(`Aread of circle: ${area}`);\n  }\n\n  visitRectangle(rectangle) {\n    const area = rectangle.width * rectangle.height;\n    console.log(`Area of rectangle: ${area}`);\n  }\n}\n\nclass PerimeterVisitor extends ShapeVisitor {\n  visitCircle(circle) {\n    const perimeter = 2 * Math.PI * circle.radius;\n    console.log(`Perimeter of circle: ${perimeter}`);\n  }\n\n  visitRectangle(rectangle) {\n    const perimeter = 2 * (rectangle.width + rectangle.height);\n    console.log(`Perimeter of rectangle: ${perimeter}`);\n  }\n}\n\nmodule.exports = { AreaVisitor, PerimeterVisitor };\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/AbstractFactory Design Pattern/abstract.js",
    "content": "// Abstract product\nclass Chair {\n  sitOn() {\n    throw new error(\"Sitting on chair\");\n  }\n}\n\nclass Sofa {\n  lieOn() {\n    throw new error(\"Lying on sofa\");\n  }\n}\n\n// Concrete product for modernStyle\nclass ModernChair extends Chair {\n  sitOn() {\n    console.log(\"Sitting on modern chair\");\n  }\n}\n\nclass ModernSofa extends Sofa {\n  lieOn() {\n    console.log(\"Lying on modern sofa\");\n  }\n}\n\n// Concrete product for classicStyle\nclass ClassicChair extends Chair {\n  sitOn() {\n    console.log(\"Sitting on classic chair\");\n  }\n}\n\nclass ClassicSofa extends Sofa {\n  lieOn() {\n    console.log(\"Lying on classic sofa\");\n  }\n}\n\n// Abstract factory\nclass FurnitureFactory {\n  createChair() {\n    throw new error(\"Creating chair\");\n  }\n  createSofa() {\n    throw new error(\"Creating sofa\");\n  }\n}\n\n// Concrete factory for modernStyle\nclass ModernFurnitureFactory extends FurnitureFactory {\n  createChair() {\n    return new ModernChair();\n  }\n  createSofa() {\n    return new ModernSofa();\n  }\n}\n\n// Concrete factory for classicStyle\nclass ClassicFurnitureFactory extends FurnitureFactory {\n  createChair() {\n    return new ClassicChair();\n  }\n  createSofa() {\n    return new ClassicSofa();\n  }\n}\n\nmodule.exports = {\n  ModernFurnitureFactory,\n  ClassicFurnitureFactory,\n};\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/AbstractFactory Design Pattern/main.js",
    "content": "const {\n  ModernFurnitureFactory,\n  ClassicFurnitureFactory,\n} = require(\"./abstract\");\n\nfunction createFurniture(factory) {\n  const chair = factory.createChair();\n  const sofa = factory.createSofa();\n\n  chair.sitOn();\n  sofa.lieOn();\n}\n\n// Use the Modern Furniture Factory\nconst modernFactory = new ModernFurnitureFactory();\ncreateFurniture(modernFactory);\n\n// Use the Victorian Furniture Factory\nconst classicFactory = new ClassicFurnitureFactory();\ncreateFurniture(classicFactory);\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Builder Design Pattern/app.js",
    "content": "const ComputerBuilder = require(\"./computerBuilder\");\n\nconst myComputer = new ComputerBuilder(\"Intel\", \"4GB\")\n  .addStorage(\"1TB\")\n  .addMoniter(\"LG\")\n  .build(); // Finally build the computer\n\nconsole.log(myComputer);"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Builder Design Pattern/computerBuilder.js",
    "content": "class Computer {\n  constructor(builder) {\n    this.cpu = builder.cpu;\n    this.ram = builder.ram;\n    this.hardDisk = builder.hardDisk;\n    this.moniter = builder.moniter;\n  }\n}\n\nclass ComputerBuilder {\n  constructor(cpu, ram) {\n    this.cpu = cpu;\n    this.ram = ram;\n  }\n\n  // Methods with chaining\n  addStorage(hardDisk) {\n    this.hardDisk = hardDisk;\n    return this;\n  }\n\n  addMoniter(moniter) {\n    this.moniter = moniter;\n    return this;\n  }\n\n  build() {\n    return new Computer(this); // Pass the builder methods to the computer\n  }\n}\n\nmodule.exports = ComputerBuilder;"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Factory Design Pattern/factory.js",
    "content": "const { cheesePizza, pepperoniPizza } = require(\"./pizza\");\n\nclass pizzaFactory {\n  static createPizza(pizzaType) {\n    if (pizzaType === \"cheese\") {\n      return new cheesePizza();\n    } else if (pizzaType === \"pepperoni\") {\n      return new pepperoniPizza();\n    } else {\n      throw new Error(\"Invalid pizza type\");\n    }\n  }\n}\n\nmodule.exports = pizzaFactory;\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Factory Design Pattern/main.js",
    "content": "const pizzaFactory = require(\"./factory\");\n\nfunction main() {\n  const pizzaType = process.argv[2] || \"cheese\";\n  try {\n    const pizza = pizzaFactory.createPizza(pizzaType);\n    pizza.prepare();\n    pizza.bake();\n    pizza.cut();\n    pizza.box();\n  } catch (error) {\n    console.log(error.message);\n  }\n}\n\nmain();\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Factory Design Pattern/pizza.js",
    "content": "class Pizza {\n  prepare() {\n    throw new error('Method \"prepare()\" must be implemented');\n  }\n  bake() {\n    console.log(\"Baking for 25 minutes\");\n  }\n  cut() {\n    console.log(\"Cutting the pizza\");\n  }\n  box() {\n    console.log(\"boxing the pizza\");\n  }\n}\n\nclass cheesePizza extends Pizza {\n  prepare() {\n    console.log(\"Preparing cheese pizza\");\n  }\n}\n\nclass pepperoniPizza extends Pizza {\n  prepare() {\n    console.log(\"Preparing pepperoni pizza\");\n  }\n}\n\nmodule.exports = {\n  cheesePizza,\n  pepperoniPizza,\n};\n"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Prototype Design Pattern/app.js",
    "content": "class Car{\n    constructor(model, year, color){\n        this.model = model;\n        this.year = year;\n        this.color = color;\n    } \n\n    clone(){ // Clone method to clone the current object\n        return new Car(this.model, this.year, this.color);  // Return the new object with same properties\n    }\n\n    getDetails(){\n        return `Model: ${this.model}, Year: ${this.year}, Color: ${this.color}`\n    }\n}\n\nconst prototypeCar = new Car(\"Mustang\", 2019, \"red\");\n\nconst cloneCar1 = prototypeCar.clone(); // 1st clone\ncloneCar1.color = \"blue\";\n\nconst cloneCar2 = prototypeCar.clone(); // 2nd clone\ncloneCar2.color = \"green\";\n\nconsole.log(prototypeCar.getDetails());\nconsole.log(cloneCar1.getDetails());\nconsole.log(cloneCar2.getDetails());"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Singleton Design  Pattern/app.js",
    "content": "\n// Importing\nconst singleton = require(\"./singleton\");\nconst Singleton1 = require(\"./singleton\");\nconst Singleton2 = require(\"./singleton\");\n\nSingleton1.increment();\n\nconsole.log(Singleton1.getData());\nconsole.log(Singleton2.getData());\n\nconsole.log(Singleton1 === Singleton2); // True"
  },
  {
    "path": "design-patterns/Javascript/Creational Pattern/Singleton Design  Pattern/singleton.js",
    "content": "//Variable to hold the instance\nlet instance = null;\n\nclass Singleton {\n  constructor() {\n    if (instance) {\n      //check if instance already exists\n      return instance; //return existing instance\n    }\n    this.data = 0;\n    instance = this;\n  }\n\n  // Method to modify data\n  increment() {\n    this.data += 1;\n  }\n\n  // Method to get the current data\n  getData() {\n    return this.data;\n  }\n}\n\nmodule.exports = new Singleton();\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Adapter Design Pattern/adapter.js",
    "content": "// usbAdapter.js\n\n// No need to import USB_A_Connector here\n\nclass USB_Adapter {\n  constructor(connector) {\n    this.connector = connector; // Store the USB-A connector instance\n  }\n\n  plugIn() {\n    return this.connector.connect(); // Use the method of the passed instances\n  }\n}\n\nmodule.exports = USB_Adapter;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Adapter Design Pattern/main.js",
    "content": "const USB_A_Connector = require(\"./usbA_connector\");\nconst Adapter = require(\"./adapter\");\n\n// Creating instances for imported classes\n\nconst usbAConnector = new USB_A_Connector();\nconst adapter = new Adapter(usbAConnector);\nconsole.log(adapter.plugIn());\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Adapter Design Pattern/usbA_connector.js",
    "content": "// USB A plug class\n\n// Old system\n\nclass USB_A_Connector {\n  connect() {\n    return \"USB-A connector connected\";\n  }\n}\n\nmodule.exports = USB_A_Connector;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Adapter Design Pattern/usbC_device.js",
    "content": "// Device class to connect USB A cable\n\n// New system\n\nclass USB_C_Device {\n  plugIn() {\n    return \"USB C device connected\";\n  }\n}\n\nmodule.exports = USB_C_Device;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Bridge Design Pattern/device.js",
    "content": "// Device.js\n\n// The Device interface\nclass Device {\n  turnOn() {\n    throw new Error(\"Method 'turnOn()' must be implemented.\");\n  }\n  turnOff() {\n    throw new Error(\"Method 'turnOff()' must be implemented.\");\n  }\n}\n\n// Concrete class for TV\nclass TV extends Device {\n  turnOn() {\n    console.log(\"TV is now ON.\");\n  }\n\n  turnOff() {\n    console.log(\"TV is now OFF.\");\n  }\n}\n\n// Concrete class for Radio\nclass Radio extends Device {\n  turnOn() {\n    console.log(\"Radio is now ON.\");\n  }\n\n  turnOff() {\n    console.log(\"Radio is now OFF.\");\n  }\n}\n\n// Exporting the device classes\nmodule.exports = {\n  TV,\n  Radio,\n};\n    "
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Bridge Design Pattern/main.js",
    "content": "// main.js\nconst { TV, Radio } = require(\"./device\");\nconst RemoteControl = require(\"./remoteControl\");\n\n// Creating instances of devices\nconst tv = new TV();\nconst radio = new Radio();\n\n// Creating a remote control for the TV\nconst tvRemote = new RemoteControl(tv);\ntvRemote.pressOn();\ntvRemote.pressOff();\n\n// Creating a remote control for the Radio\nconst radioRemote = new RemoteControl(radio);\nradioRemote.pressOn();\nradioRemote.pressOff();\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Bridge Design Pattern/remoteControl.js",
    "content": "// RemoteControl.js\n\nclass RemoteControl {\n    constructor(device) {\n      this.device = device; // This is the bridge to the device\n    }\n  \n    pressOn() {\n      this.device.turnOn(); // Call the device's turnOn method\n    }\n  \n    pressOff() {\n      this.device.turnOff(); // Call the device's turnOff method\n    }\n  }\n  \n  module.exports = RemoteControl;\n  "
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Composite Design Pattern/app.js",
    "content": "const File = require(\"./file\");\nconst Folder = require(\"./folder\");\n\n// Let's create some files with random file extensions\nconst file1 = new File(\"File1.js\");\nconst file2 = new File(\"File2.py\");\nconst file3 = new File(\"File3.cpp\");\nconst file4 = new File(\"File4.txt\");\nconst file5 = new File(\"File5.docx\");\nconst file6 = new File(\"File6.xlsx\");\nconst file7 = new File(\"File7.pptx\");\nconst file8 = new File(\"File8.pdf\");\nconst file9 = new File(\"File9.png\");\nconst file10 = new File(\"File10.jpg\");\n\n// Let's create a folder to add files\nconst folder1 = new Folder(\"Folder1\");\nfolder1.add(file1);\nfolder1.add(file2);\nfolder1.add(file4);\n\nconst folder2 = new Folder(\"Folder2\");\nfolder2.add(file3);\nfolder2.add(file8);\n\nconst folder3 = new Folder(\"Folder3\");\nfolder3.add(file5);\nfolder3.add(file9);\nfolder3.add(file10);\n\nconst folder4 = new Folder(\"Folder4\");\nfolder4.add(file6);\nfolder4.add(file7);\n\n// Let's create a root folder\nconst rootFolder = new Folder(\"Root\");\nrootFolder.add(folder1);\nrootFolder.add(folder2);\nrootFolder.add(folder3);\nrootFolder.add(folder4);\n\n\n// Let's show the details from the root folder\nrootFolder.showDetails();\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Composite Design Pattern/component.js",
    "content": "// Abstract Class  or Component class\n\nclass Component {\n  showDetails() {\n    throw new error(\"This method is overriden by subclasses\");\n  }\n}\n\nmodule.exports = Component;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Composite Design Pattern/file.js",
    "content": "const Component = require(\"./component\");\n\nclass File extends Component {\n  constructor(name) {\n    super();\n    this.name = name;\n  }\n\n  showDetails() {\n    console.log(`File: ${this.name}`);\n  }\n}\n\nmodule.exports = File;"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Composite Design Pattern/folder.js",
    "content": "const Component = require(\"./component\");\n\n// Composite: Folder that can hold files or other folders\n\nclass Folder extends Component {\n  constructor(name) {\n    super();\n    this.name = name;\n    this.files = [];\n  }\n\n  add(file) {\n    this.files.push(file);\n  }\n\n  showDetails() {\n    console.log(`Folder: ${this.name}`);\n    this.files.forEach((file) => file.showDetails());\n  }\n}\n\nmodule.exports = Folder;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Decorator Design Pattern/additional.js",
    "content": "// Additional behavior class\n\nclass Cream {\n  constructor(coffee) {\n    this.coffee = coffee;\n  }\n\n  cost() {\n    return this.coffee.cost() + 5; // Add cost of cream to the base coffee class\n  }\n}\n\nclass Sugar {\n  constructor(coffee) {\n    this.coffee = coffee; // Store the coffee instance\n  }\n\n  cost() {\n    return this.coffee.cost() + 2; // Add cost of sugar to the base coffee class\n  }\n}\n\nclass Ice{\n  constructor(coffee) {\n    this.coffee = coffee; // Store the coffee instance\n  }\n\n  cost() {\n    return this.coffee.cost() + 1; // Add cost of ice to the base coffee class\n  }\n}\n\n\nmodule.exports = {Cream, Sugar, Ice};\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Decorator Design Pattern/coffee.js",
    "content": "// Base class component\n\nclass Coffee {\n  cost() {\n    return 10; // Base price of coffee is 10\n  }\n}\n\nmodule.exports = Coffee;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Decorator Design Pattern/main.js",
    "content": "const Coffee = require(\"./coffee\");\nconst {Cream, Sugar, Ice} = require(\"./additional\");\n\n// Create an instance of coffee\nlet myCoffee = new Coffee();\nconsole.log(`Base amount: ${myCoffee.cost()}`); // Get base cost of coffee\n\nmyCoffee = new Sugar(myCoffee);\nconsole.log(`Sugar amount: ${myCoffee.cost()}`); // Add cost of sugar\n\nmyCoffee = new Cream(myCoffee);\nconsole.log(`Cream amount: ${myCoffee.cost()}`); // Add cost of cream\n\nmyCoffee = new Ice(myCoffee);\nconsole.log(`Ice amount: ${myCoffee.cost()}`); // Add cost of ice\n\n\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/dvdPlayer.js",
    "content": "// Class for DVD player functionality\n\nclass DVDPlayer {\n  on() {\n    console.log(\"DVD player is on\");\n  }\n  play(movie) {\n    console.log(`Playing ${movie}`);\n  }\n\n  off() {\n    console.log(\"DVD player is off\");\n  }\n}\n\nmodule.exports = DVDPlayer;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/lights.js",
    "content": "// Class for lights functionality\n\nclass Lights {\n  on() {\n    console.log(\"Lights on, take you're seat!\");\n  }\n\n  off() {\n    console.log(\"Lights off, get ready to see the show!\");\n  }\n}\n\nmodule.exports = Lights;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/main.js",
    "content": "// client code for facade design pattern\n\nconst MovieFacade = require(\"./movieFacade\");\n\nconst movieFacade = new MovieFacade();\n// By getting the required data, we can proceed all the functionality using facade design pattern.\n\nmovieFacade.watchMovie(\"Goat 🍾🎉\");\nmovieFacade.getSnacks(\"Popcorn\");\nmovieFacade.endMovie();"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/movieFacade.js",
    "content": "const SoundSystem = require(\"./soundSystem\");\nconst DVDPlayer = require(\"./dvdPlayer\");\nconst Projector = require(\"./projector\");\nconst Lights = require(\"./lights\");\nconst Snacks = require(\"./snacks\");\n\nclass MovieFacade {\n  constructor() {\n    this.soundSystem = new SoundSystem();\n    this.dvdPlayer = new DVDPlayer();\n    this.projector = new Projector();\n    this.lights = new Lights();\n    this.snacks = new Snacks();\n  }\n\n  watchMovie(movie) {\n    console.log(`Starting to watch a movie ${movie}`);\n    this.lights.on();\n    this.projector.on();\n    this.projector.connect(\"DVD Player\");\n    this.dvdPlayer.on();\n    this.soundSystem.on();\n    this.dvdPlayer.play(movie);\n    this.soundSystem.setVolume(\"High\");\n  }\n\n  getSnacks(snacks) {\n    console.log(\"1st part of the movie is great! Let's order some snacks\");\n    this.snacks.noteOrder(snacks);\n    this.snacks.prepare();\n    this.snacks.serve(snacks);\n  }\n\n  endMovie() {\n    console.log(\"End of the movie, shutting down\");\n    this.lights.off();\n    this.projector.off();\n    this.dvdPlayer.off();\n    this.soundSystem.off();\n  }\n}\n\nmodule.exports = MovieFacade;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/projector.js",
    "content": "// Class for projector functionality\n\nclass Projector {\n  on() {\n    console.log(\"Projector on\");\n  }\n\n  connect(source) {\n    console.log(`Connecting projector to ${source}`);\n  }\n\n  off() {\n    console.log(\"Projector off\");\n  }\n}\n\nmodule.exports = Projector;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/snacks.js",
    "content": "// Class for snacks functionality\n\nclass Snacks {\n  noteOrder(snacks) {\n    console.log(`Ordering ${snacks}`);\n  }\n  prepare() {\n    console.log(\"Preparing snacks 🍿\");\n  }\n\n  serve(snacks) {\n    console.log(`Here is your ${snacks} sir!, enjoy your movie 😊`);\n  }\n}\n\nmodule.exports = Snacks;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Facade Design Pattern/soundSystem.js",
    "content": "// Class for sound system functionality\n\nclass SoundSystem {\n    on() {\n    console.log(\"Sound system is on\");\n  }\n\n  setVolume(volume) {\n    console.log(`Setting volume to ${volume}`);\n  }\n\n  off() {\n    console.log(\"Sound system is off\");\n  }\n}\n\nmodule.exports = SoundSystem;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Flyweight Design Pattern/circle.js",
    "content": "// Intrinsic state\nclass Circle{\n    constructor(color){\n        this.color = color;\n    }\n\n    draw(size, x, y){\n        console.log(`Drawing a circle of size ${size} at position (${x}, ${y})`);\n    }\n}\n\nmodule.exports = Circle;"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Flyweight Design Pattern/circleFactory.js",
    "content": "// circleFactory.js\n\nconst Circle = require(\"./circle\");\n\nclass CircleFactory {\n  constructor() {\n    this.circles = {}; // Store the created circles\n  }\n\n  getCircle(color) {\n    // Check if the circle exists\n    if (!this.circles[color]) {\n      // Create a new circle if it doesn't exist\n      this.circles[color] = new Circle(color);\n    }\n    return this.circles[color];\n  }\n}\n\nmodule.exports = CircleFactory;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Flyweight Design Pattern/main.js",
    "content": "const CircleFactory = require(\"./circleFactory\");\n\nconst circleFactory = new CircleFactory();\n\nconst redCircle = circleFactory.getCircle(\"red\");\nredCircle.draw(\"big\", 20, 30);\n\nconst blueCircle = circleFactory.getCircle(\"blue\");\nblueCircle.draw(\"medium\", 200, 300);\n\nconst greenCircle = circleFactory.getCircle(\"red\");\ngreenCircle.draw(\"medium\", 200, 300); // Here it won't create a new object as it already exists.\n\nconsole.log(\n  `Total unique circle instance created are:  ${\n    Object.keys(circleFactory.circles).length\n  }`\n);\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Proxy Design Pattern/main.js",
    "content": "const proxyImage = require(\"./proxyImage\");\n\nconst image = new proxyImage(\"test.jpg\");\n\nconsole.log('First call to display:');\nimage.display();\n\nconsole.log('Second call to display:');\nimage.display();"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Proxy Design Pattern/proxyImage.js",
    "content": "// Proxy object\n\nconst realImage = require(\"./real_Image\");\n\nclass ProxyImage {\n  constructor(fileName) {\n    this.fileName = fileName;\n    this.realImage = null; // LAZY LOADING (Image not loaded yet)\n  }\n\n  display() {\n    // Loading the image only if requested\n    if (!this.realImage) {\n      this.realImage = new realImage(this.fileName);\n    }\n\n    this.realImage.display();\n  }\n}\n\nmodule.exports = ProxyImage;\n"
  },
  {
    "path": "design-patterns/Javascript/Structural Pattern/Proxy Design Pattern/real_Image.js",
    "content": "class realImage {\n  constructor(fileName) {\n    this.fileName = fileName;\n    this.loadFromDisk();\n  }\n\n  loadFromDisk() {\n    console.log(`Loading image from disk: ${this.fileName}`);\n  }\n\n  display() {\n    console.log(`Displaying image: ${this.fileName}`);\n  }\n}\n\nmodule.exports = realImage;\n"
  },
  {
    "path": "design-patterns/cpp/adapter/in_house_payment_processor.cpp",
    "content": "#include \"in_house_payment_processor.h\"\n#include <iostream>\n#include <chrono>\n#include <sstream>\n\nvoid InHousePaymentProcessor::processPayment(double amount, const std::string& currency) {\n    std::cout << \"InHousePaymentProcessor: Processing payment of \" << amount << \" \" << currency << std::endl;\n    // Process payment logic\n    auto now = std::chrono::system_clock::now();\n    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());\n    transactionId = \"TXN_\" + std::to_string(now_ms.count());\n    isPaymentSuccessful = true;\n    std::cout << \"InHousePaymentProcessor: Payment successful. Txn ID: \" << transactionId << std::endl;\n}\n\nbool InHousePaymentProcessor::isPaymentSuccessful() {\n    return isPaymentSuccessful;\n}\n\nstd::string InHousePaymentProcessor::getTransactionId() {\n    return transactionId;\n} "
  },
  {
    "path": "design-patterns/cpp/adapter/in_house_payment_processor.h",
    "content": "#pragma once\n#include \"payment_processor.h\"\n#include <string>\n\nclass InHousePaymentProcessor : public PaymentProcessor {\npublic:\n    void processPayment(double amount, const std::string& currency) override;\n    bool isPaymentSuccessful() override;\n    std::string getTransactionId() override;\n\nprivate:\n    std::string transactionId;\n    bool isPaymentSuccessful = false;\n}; "
  },
  {
    "path": "design-patterns/cpp/adapter/legacy_gateway.cpp",
    "content": "#include \"legacy_gateway.h\"\n#include <iostream>\n#include <chrono>\n\nvoid LegacyGateway::executeTransaction(double totalAmount, const std::string& currency) {\n    std::cout << \"LegacyGateway: Executing transaction for \" << currency << \" \" << totalAmount << std::endl;\n    auto now = std::chrono::high_resolution_clock::now();\n    transactionReference = now.time_since_epoch().count();\n    isPaymentSuccessful = true;\n    std::cout << \"LegacyGateway: Transaction executed successfully. Txn ID: \" << transactionReference << std::endl;\n}\n\nbool LegacyGateway::checkStatus(long transactionReference) {\n    std::cout << \"LegacyGateway: Checking status for ref: \" << transactionReference << std::endl;\n    return isPaymentSuccessful;\n}\n\nlong LegacyGateway::getReferenceNumber() {\n    return transactionReference;\n} "
  },
  {
    "path": "design-patterns/cpp/adapter/legacy_gateway.h",
    "content": "#pragma once\n#include <string>\n\nclass LegacyGateway {\npublic:\n    void executeTransaction(double totalAmount, const std::string& currency);\n    bool checkStatus(long transactionReference);\n    long getReferenceNumber();\n\nprivate:\n    long transactionReference;\n    bool isPaymentSuccessful = false;\n}; "
  },
  {
    "path": "design-patterns/cpp/adapter/legacy_gateway_adapter.cpp",
    "content": "#include \"legacy_gateway_adapter.h\"\n#include <iostream>\n\nLegacyGatewayAdapter::LegacyGatewayAdapter(LegacyGateway* legacyGateway) \n    : legacyGateway(legacyGateway) {}\n\nvoid LegacyGatewayAdapter::processPayment(double amount, const std::string& currency) {\n    std::cout << \"LegacyGatewayAdapter: Processing payment of \" << amount << \" \" << currency << std::endl;\n    legacyGateway->executeTransaction(amount, currency);\n    std::cout << \"LegacyGatewayAdapter: Payment processed successfully. Txn ID: \" \n              << legacyGateway->getReferenceNumber() << std::endl;\n}\n\nbool LegacyGatewayAdapter::isPaymentSuccessful() {\n    return legacyGateway->checkStatus(legacyGateway->getReferenceNumber());\n}\n\nstd::string LegacyGatewayAdapter::getTransactionId() {\n    return std::to_string(legacyGateway->getReferenceNumber());\n} "
  },
  {
    "path": "design-patterns/cpp/adapter/legacy_gateway_adapter.h",
    "content": "#pragma once\n#include \"payment_processor.h\"\n#include \"legacy_gateway.h\"\n\nclass LegacyGatewayAdapter : public PaymentProcessor {\npublic:\n    explicit LegacyGatewayAdapter(LegacyGateway* legacyGateway);\n    void processPayment(double amount, const std::string& currency) override;\n    bool isPaymentSuccessful() override;\n    std::string getTransactionId() override;\n\nprivate:\n    LegacyGateway* legacyGateway;\n}; "
  },
  {
    "path": "design-patterns/cpp/adapter/main.cpp",
    "content": "#include \"in_house_payment_processor.h\"\n#include \"legacy_gateway.h\"\n#include \"legacy_gateway_adapter.h\"\n#include <iostream>\n\nint main() {\n    std::cout << \"Adapter Pattern Demo\\n\" << std::endl;\n\n    // Using the new payment processor\n    std::cout << \"Using InHousePaymentProcessor:\" << std::endl;\n    PaymentProcessor* processor = new InHousePaymentProcessor();\n    processor->processPayment(100.0, \"USD\");\n    std::cout << \"Payment successful: \" << (processor->isPaymentSuccessful() ? \"Yes\" : \"No\") << std::endl;\n    std::cout << \"Transaction ID: \" << processor->getTransactionId() << std::endl;\n    delete processor;\n\n    std::cout << \"\\nUsing LegacyGateway through adapter:\" << std::endl;\n    LegacyGateway* legacyGateway = new LegacyGateway();\n    PaymentProcessor* adapter = new LegacyGatewayAdapter(legacyGateway);\n    adapter->processPayment(200.0, \"EUR\");\n    std::cout << \"Payment successful: \" << (adapter->isPaymentSuccessful() ? \"Yes\" : \"No\") << std::endl;\n    std::cout << \"Transaction ID: \" << adapter->getTransactionId() << std::endl;\n    \n    delete adapter;\n    delete legacyGateway;\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/adapter/payment_processor.h",
    "content": "#pragma once\n#include <string>\n\nclass PaymentProcessor {\npublic:\n    virtual ~PaymentProcessor() = default;\n    virtual void processPayment(double amount, const std::string& currency) = 0;\n    virtual bool isPaymentSuccessful() = 0;\n    virtual std::string getTransactionId() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/circle.cpp",
    "content": "#include \"circle.h\"\n\nCircle::Circle(Renderer* renderer, float radius)\n    : Shape(renderer), radius(radius) {}\n\nvoid Circle::draw() {\n    renderer->renderCircle(radius);\n} "
  },
  {
    "path": "design-patterns/cpp/bridge/circle.h",
    "content": "#pragma once\n#include \"shape.h\"\n\nclass Circle : public Shape {\npublic:\n    Circle(Renderer* renderer, float radius);\n    void draw() override;\nprivate:\n    float radius;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/main.cpp",
    "content": "#include \"vector_renderer.h\"\n#include \"raster_renderer.h\"\n#include \"circle.h\"\n#include \"rectangle.h\"\n#include <iostream>\n\nint main() {\n    VectorRenderer vectorRenderer;\n    RasterRenderer rasterRenderer;\n\n    Circle vectorCircle(&vectorRenderer, 5.0f);\n    Rectangle vectorRectangle(&vectorRenderer, 4.0f, 3.0f);\n\n    Circle rasterCircle(&rasterRenderer, 7.0f);\n    Rectangle rasterRectangle(&rasterRenderer, 6.0f, 2.0f);\n\n    std::cout << \"Vector Circle: \";\n    vectorCircle.draw();\n    std::cout << \"Vector Rectangle: \";\n    vectorRectangle.draw();\n    std::cout << \"Raster Circle: \";\n    rasterCircle.draw();\n    std::cout << \"Raster Rectangle: \";\n    rasterRectangle.draw();\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/bridge/raster_renderer.cpp",
    "content": "#include \"raster_renderer.h\"\n#include <iostream>\n\nvoid RasterRenderer::renderCircle(float radius) {\n    std::cout << \"Drawing circle as raster with radius: \" << radius << std::endl;\n}\n\nvoid RasterRenderer::renderRectangle(float width, float height) {\n    std::cout << \"Drawing rectangle as raster with width: \" << width << \", height: \" << height << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/bridge/raster_renderer.h",
    "content": "#pragma once\n#include \"renderer.h\"\n\nclass RasterRenderer : public Renderer {\npublic:\n    void renderCircle(float radius) override;\n    void renderRectangle(float width, float height) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/rectangle.cpp",
    "content": "#include \"rectangle.h\"\n\nRectangle::Rectangle(Renderer* renderer, float width, float height)\n    : Shape(renderer), width(width), height(height) {}\n\nvoid Rectangle::draw() {\n    renderer->renderRectangle(width, height);\n} "
  },
  {
    "path": "design-patterns/cpp/bridge/rectangle.h",
    "content": "#pragma once\n#include \"shape.h\"\n\nclass Rectangle : public Shape {\npublic:\n    Rectangle(Renderer* renderer, float width, float height);\n    void draw() override;\nprivate:\n    float width;\n    float height;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/renderer.h",
    "content": "#pragma once\n\nclass Renderer {\npublic:\n    virtual ~Renderer() = default;\n    virtual void renderCircle(float radius) = 0;\n    virtual void renderRectangle(float width, float height) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/shape.cpp",
    "content": "#include \"shape.h\"\n\nShape::Shape(Renderer* renderer) : renderer(renderer) {} "
  },
  {
    "path": "design-patterns/cpp/bridge/shape.h",
    "content": "#pragma once\n#include \"renderer.h\"\n\nclass Shape {\nprotected:\n    Renderer* renderer;\npublic:\n    explicit Shape(Renderer* renderer);\n    virtual ~Shape() = default;\n    virtual void draw() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/bridge/vector_renderer.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/bridge/vector_renderer.h",
    "content": "#pragma once\n#include \"renderer.h\"\n\nclass VectorRenderer : public Renderer {\npublic:\n    void renderCircle(float radius) override;\n    void renderRectangle(float width, float height) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/builder/http_request.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/builder/http_request.h",
    "content": "#pragma once\n#include <string>\n#include <map>\n#include <iostream>\n\nclass HttpRequest {\npublic:\n    class Builder;\n\n    std::string getUrl() const;\n    std::string getMethod() const;\n    const std::map<std::string, std::string>& getHeaders() const;\n    const std::map<std::string, std::string>& getQueryParams() const;\n    std::string getBody() const;\n    int getTimeout() const;\n\n    friend std::ostream& operator<<(std::ostream& os, const HttpRequest& req);\n\nprivate:\n    std::string url;\n    std::string method;\n    std::map<std::string, std::string> headers;\n    std::map<std::string, std::string> queryParams;\n    std::string body;\n    int timeout;\n\n    HttpRequest(const Builder& builder);\n}; "
  },
  {
    "path": "design-patterns/cpp/builder/http_request_builder.cpp",
    "content": "#include \"http_request_builder.h\"\n#include <iostream>\n#include <algorithm>\n\nHttpRequest::Builder::Builder(const std::string& url) : url(url) {\n    if (url.empty()) {\n        throw std::invalid_argument(\"URL cannot be empty.\");\n    }\n}\n\nHttpRequest::Builder& HttpRequest::Builder::method(const std::string& m) {\n    method = m.empty() ? \"GET\" : m;\n    std::transform(method.begin(), method.end(), method.begin(), ::toupper);\n    return *this;\n}\n\nHttpRequest::Builder& HttpRequest::Builder::header(const std::string& key, const std::string& value) {\n    if (!key.empty() && !value.empty()) headers[key] = value;\n    return *this;\n}\n\nHttpRequest::Builder& HttpRequest::Builder::queryParam(const std::string& key, const std::string& value) {\n    if (!key.empty() && !value.empty()) queryParams[key] = value;\n    return *this;\n}\n\nHttpRequest::Builder& HttpRequest::Builder::body(const std::string& b) {\n    body = b;\n    return *this;\n}\n\nHttpRequest::Builder& HttpRequest::Builder::timeout(int timeoutMillis) {\n    if (timeoutMillis > 0) timeout = timeoutMillis;\n    return *this;\n}\n\nHttpRequest HttpRequest::Builder::build() {\n    if ((method == \"POST\" || method == \"PUT\") && body.empty()) {\n        std::cout << \"Warning: Building \" << method << \" request without a body for URL: \" << url << std::endl;\n    }\n    return HttpRequest(*this);\n} "
  },
  {
    "path": "design-patterns/cpp/builder/http_request_builder.h",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/builder/main.cpp",
    "content": "#include \"http_request.h\"\n#include \"http_request_builder.h\"\n#include <iostream>\n\nint main() {\n    // Example 1: Simple GET request\n    HttpRequest getRequest = HttpRequest::Builder(\"https://api.example.com/users\")\n                                .method(\"GET\")\n                                .header(\"Accept\", \"application/json\")\n                                .timeout(5000)\n                                .build();\n    std::cout << \"GET Request: \" << getRequest << std::endl;\n\n    // Example 2: POST request with body and custom headers\n    HttpRequest postRequest = HttpRequest::Builder(\"https://api.example.com/posts\")\n                                 .method(\"POST\")\n                                 .header(\"Content-Type\", \"application/json\")\n                                 .header(\"X-Auth-Token\", \"some_secret_token\")\n                                 .body(\"{\\\"title\\\":\\\"New Post\\\",\\\"content\\\":\\\"Hello Builder!\\\"}\")\n                                 .queryParam(\"userId\", \"123\")\n                                 .build();\n    std::cout << \"POST Request: \" << postRequest << std::endl;\n\n    // Example 3: Request with only required URL (defaults for others)\n    HttpRequest defaultRequest = HttpRequest::Builder(\"https://api.example.com/status\").build();\n    std::cout << \"Default Request: \" << defaultRequest << std::endl;\n\n    // Example 4: Illustrating potential warning from builder\n    HttpRequest putNoBodyRequest = HttpRequest::Builder(\"https://api.example.com/resource/1\")\n                                        .method(\"PUT\")\n                                        // .body(\"updated data\") // Body intentionally omitted\n                                        .build();\n    std::cout << \"PUT Request (no body): \" << putNoBodyRequest << std::endl;\n\n    // Example of trying to build with invalid required parameter\n    try {\n        HttpRequest invalidRequest = HttpRequest::Builder(\"\").build();\n    } catch (const std::invalid_argument& e) {\n        std::cerr << \"Error creating request: \" << e.what() << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/auth_handler.h",
    "content": "#pragma once\n#include \"base_handler.h\"\n#include <iostream>\n\nclass AuthHandler : public BaseHandler {\npublic:\n    void handle(Request& request) override {\n        if (request.user.empty()) {\n            std::cout << \"AuthHandler: ❌ User not authenticated.\" << std::endl;\n            return;\n        }\n        std::cout << \"AuthHandler: ✅ Authenticated.\" << std::endl;\n        forward(request);\n    }\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/authorization_handler.h",
    "content": "#pragma once\n#include \"base_handler.h\"\n#include <iostream>\n\nclass AuthorizationHandler : public BaseHandler {\npublic:\n    void handle(Request& request) override {\n        if (request.userRole != \"ADMIN\") {\n            std::cout << \"AuthorizationHandler: ❌ Access denied.\" << std::endl;\n            return;\n        }\n        std::cout << \"AuthorizationHandler: ✅ Authorized.\" << std::endl;\n        forward(request);\n    }\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/base_handler.cpp",
    "content": "#include \"base_handler.h\"\n\nvoid BaseHandler::setNext(RequestHandler* nextHandler) {\n    next = nextHandler;\n}\n\nvoid BaseHandler::forward(Request& request) {\n    if (next) {\n        next->handle(request);\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/base_handler.h",
    "content": "#pragma once\n#include \"request_handler.h\"\n\nclass BaseHandler : public RequestHandler {\nprotected:\n    RequestHandler* next = nullptr;\npublic:\n    void setNext(RequestHandler* next) override;\n    void forward(Request& request);\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/business_logic_handler.h",
    "content": "#pragma once\n#include \"base_handler.h\"\n#include <iostream>\n\nclass BusinessLogicHandler : public BaseHandler {\npublic:\n    void handle(Request& request) override {\n        std::cout << \"BusinessLogicHandler: 🚀 Processing request...\" << std::endl;\n        // Core application logic goes here\n    }\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/main.cpp",
    "content": "#include \"auth_handler.h\"\n#include \"authorization_handler.h\"\n#include \"rate_limit_handler.h\"\n#include \"validation_handler.h\"\n#include \"business_logic_handler.h\"\n#include \"request.h\"\n#include <iostream>\n\nint main() {\n    // Create handlers\n    AuthHandler auth;\n    AuthorizationHandler authorization;\n    RateLimitHandler rateLimit;\n    ValidationHandler validation;\n    BusinessLogicHandler businessLogic;\n\n    // Build the chain\n    auth.setNext(&authorization);\n    authorization.setNext(&rateLimit);\n    rateLimit.setNext(&validation);\n    validation.setNext(&businessLogic);\n\n    // Send a request through the chain\n    Request request(\"john\", \"ADMIN\", 10, \"{ \\\"data\\\": \\\"valid\\\" }\");\n    auth.handle(request);\n\n    std::cout << \"\\n--- Trying an invalid request ---\" << std::endl;\n    Request badRequest(\"\", \"USER\", 150, \"\");\n    auth.handle(badRequest);\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/rate_limit_handler.h",
    "content": "#pragma once\n#include \"base_handler.h\"\n#include <iostream>\n\nclass RateLimitHandler : public BaseHandler {\npublic:\n    void handle(Request& request) override {\n        if (request.requestCount >= 100) {\n            std::cout << \"RateLimitHandler: ❌ Rate limit exceeded.\" << std::endl;\n            return;\n        }\n        std::cout << \"RateLimitHandler: ✅ Within rate limit.\" << std::endl;\n        forward(request);\n    }\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/request.cpp",
    "content": "#include \"request.h\"\n\nRequest::Request(const std::string& user, const std::string& role, int requestCount, const std::string& payload)\n    : user(user), userRole(role), requestCount(requestCount), payload(payload) {} "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/request.h",
    "content": "#pragma once\n#include <string>\n\nclass Request {\npublic:\n    std::string user;\n    std::string userRole;\n    int requestCount;\n    std::string payload;\n\n    Request(const std::string& user, const std::string& role, int requestCount, const std::string& payload);\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/request_handler.h",
    "content": "#pragma once\n#include \"request.h\"\n\nclass RequestHandler {\npublic:\n    virtual ~RequestHandler() = default;\n    virtual void setNext(RequestHandler* next) = 0;\n    virtual void handle(Request& request) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/chainofresponsibility/validation_handler.h",
    "content": "#pragma once\n#include \"base_handler.h\"\n#include <iostream>\n\nclass ValidationHandler : public BaseHandler {\npublic:\n    void handle(Request& request) override {\n        if (request.payload.empty() || request.payload.find_first_not_of(\" \\t\\n\\r\") == std::string::npos) {\n            std::cout << \"ValidationHandler: ❌ Invalid payload.\" << std::endl;\n            return;\n        }\n        std::cout << \"ValidationHandler: ✅ Payload valid.\" << std::endl;\n        forward(request);\n    }\n}; "
  },
  {
    "path": "design-patterns/cpp/composite/file.cpp",
    "content": "#include \"file.h\"\n#include <iostream>\n\nFile::File(const std::string& name, int size) : name(name), size(size) {}\n\nint File::getSize() const {\n    return size;\n}\n\nvoid File::printStructure(const std::string& indent) const {\n    std::cout << indent << \"- \" << name << \" (\" << size << \" KB)\" << std::endl;\n}\n\nvoid File::delete() {\n    std::cout << \"Deleting file: \" << name << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/composite/file.h",
    "content": "#pragma once\n#include \"file_system_item.h\"\n#include <string>\n\nclass File : public FileSystemItem {\npublic:\n    File(const std::string& name, int size);\n    int getSize() const override;\n    void printStructure(const std::string& indent) const override;\n    void delete() override;\n\nprivate:\n    std::string name;\n    int size;\n}; "
  },
  {
    "path": "design-patterns/cpp/composite/file_system_item.h",
    "content": "#pragma once\n#include <string>\n\nclass FileSystemItem {\npublic:\n    virtual ~FileSystemItem() = default;\n    virtual int getSize() const = 0;\n    virtual void printStructure(const std::string& indent) const = 0;\n    virtual void delete() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/composite/folder.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/composite/folder.h",
    "content": "#pragma once\n#include \"file_system_item.h\"\n#include <string>\n#include <vector>\n#include <memory>\n\nclass Folder : public FileSystemItem {\npublic:\n    explicit Folder(const std::string& name);\n    void addItem(std::shared_ptr<FileSystemItem> item);\n    int getSize() const override;\n    void printStructure(const std::string& indent) const override;\n    void delete() override;\n\nprivate:\n    std::string name;\n    std::vector<std::shared_ptr<FileSystemItem>> children;\n}; "
  },
  {
    "path": "design-patterns/cpp/composite/main.cpp",
    "content": "#include \"file.h\"\n#include \"folder.h\"\n#include <iostream>\n#include <memory>\n\nint main() {\n    auto file1 = std::make_shared<File>(\"readme.txt\", 5);\n    auto file2 = std::make_shared<File>(\"photo.jpg\", 1500);\n    auto file3 = std::make_shared<File>(\"data.csv\", 300);\n\n    auto documents = std::make_shared<Folder>(\"Documents\");\n    documents->addItem(file1);\n    documents->addItem(file3);\n\n    auto pictures = std::make_shared<Folder>(\"Pictures\");\n    pictures->addItem(file2);\n\n    auto home = std::make_shared<Folder>(\"Home\");\n    home->addItem(documents);\n    home->addItem(pictures);\n\n    std::cout << \"---- File Structure ----\" << std::endl;\n    home->printStructure(\"\");\n\n    std::cout << \"\\nTotal Size: \" << home->getSize() << \" KB\" << std::endl;\n\n    std::cout << \"\\n---- Deleting All ----\" << std::endl;\n    home->delete();\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/bold_decorator.cpp",
    "content": "#include \"bold_decorator.h\"\n#include <iostream>\n\nBoldDecorator::BoldDecorator(TextView* inner) : TextDecorator(inner) {}\n\nvoid BoldDecorator::render() {\n    std::cout << \"<b>\";\n    inner->render();\n    std::cout << \"</b>\";\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/bold_decorator.h",
    "content": "#pragma once\n#include \"text_decorator.h\"\n\nclass BoldDecorator : public TextDecorator {\npublic:\n    explicit BoldDecorator(TextView* inner);\n    void render() override;\n}; "
  },
  {
    "path": "design-patterns/cpp/decorator/italic_decorator.cpp",
    "content": "#include \"italic_decorator.h\"\n#include <iostream>\n\nItalicDecorator::ItalicDecorator(TextView* inner) : TextDecorator(inner) {}\n\nvoid ItalicDecorator::render() {\n    std::cout << \"<i>\";\n    inner->render();\n    std::cout << \"</i>\";\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/italic_decorator.h",
    "content": "#pragma once\n#include \"text_decorator.h\"\n\nclass ItalicDecorator : public TextDecorator {\npublic:\n    explicit ItalicDecorator(TextView* inner);\n    void render() override;\n}; "
  },
  {
    "path": "design-patterns/cpp/decorator/main.cpp",
    "content": "#include \"plain_text_view.h\"\n#include \"bold_decorator.h\"\n#include \"italic_decorator.h\"\n#include \"underline_decorator.h\"\n#include <iostream>\n\nint main() {\n    TextView* plain = new PlainTextView(\"Hello, world!\");\n\n    std::cout << \"Plain: \";\n    plain->render();\n    std::cout << std::endl;\n\n    std::cout << \"Bold: \";\n    TextView* bold = new BoldDecorator(plain);\n    bold->render();\n    std::cout << std::endl;\n\n    std::cout << \"Italic + Bold: \";\n    TextView* italicBold = new ItalicDecorator(bold);\n    italicBold->render();\n    std::cout << std::endl;\n\n    std::cout << \"Underline + Italic + Bold: \";\n    TextView* fullStyle = new UnderlineDecorator(italicBold);\n    fullStyle->render();\n    std::cout << std::endl;\n\n    // Clean up\n    delete fullStyle;\n    delete italicBold;\n    delete bold;\n    delete plain;\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/plain_text_view.cpp",
    "content": "#include \"plain_text_view.h\"\n#include <iostream>\n\nPlainTextView::PlainTextView(const std::string& text) : text(text) {}\n\nvoid PlainTextView::render() {\n    std::cout << text;\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/plain_text_view.h",
    "content": "#pragma once\n#include \"text_view.h\"\n#include <string>\n\nclass PlainTextView : public TextView {\npublic:\n    explicit PlainTextView(const std::string& text);\n    void render() override;\nprivate:\n    std::string text;\n}; "
  },
  {
    "path": "design-patterns/cpp/decorator/text_decorator.cpp",
    "content": "#include \"text_decorator.h\"\n\nTextDecorator::TextDecorator(TextView* inner) : inner(inner) {} "
  },
  {
    "path": "design-patterns/cpp/decorator/text_decorator.h",
    "content": "#pragma once\n#include \"text_view.h\"\n\nclass TextDecorator : public TextView {\nprotected:\n    TextView* inner;\npublic:\n    explicit TextDecorator(TextView* inner);\n}; "
  },
  {
    "path": "design-patterns/cpp/decorator/text_view.h",
    "content": "#pragma once\n\nclass TextView {\npublic:\n    virtual ~TextView() = default;\n    virtual void render() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/decorator/underline_decorator.cpp",
    "content": "#include \"underline_decorator.h\"\n#include <iostream>\n\nUnderlineDecorator::UnderlineDecorator(TextView* inner) : TextDecorator(inner) {}\n\nvoid UnderlineDecorator::render() {\n    std::cout << \"<u>\";\n    inner->render();\n    std::cout << \"</u>\";\n} "
  },
  {
    "path": "design-patterns/cpp/decorator/underline_decorator.h",
    "content": "#pragma once\n#include \"text_decorator.h\"\n\nclass UnderlineDecorator : public TextDecorator {\npublic:\n    explicit UnderlineDecorator(TextView* inner);\n    void render() override;\n}; "
  },
  {
    "path": "design-patterns/cpp/facade/build_system.cpp",
    "content": "#include \"build_system.h\"\n\nbool BuildSystem::compileProject() {\n    std::cout << \"BuildSystem: Compiling project...\" << std::endl;\n    simulateDelay(2000);\n    std::cout << \"BuildSystem: Build successful.\" << std::endl;\n    return true;\n}\n\nstd::string BuildSystem::getArtifactPath() {\n    std::string path = \"target/myapplication-1.0.jar\";\n    std::cout << \"BuildSystem: Artifact located at \" << path << std::endl;\n    return path;\n}\n\nvoid BuildSystem::simulateDelay(int ms) {\n    std::this_thread::sleep_for(std::chrono::milliseconds(ms));\n} "
  },
  {
    "path": "design-patterns/cpp/facade/build_system.h",
    "content": "#pragma once\n#include <string>\n#include <chrono>\n#include <thread>\n#include <iostream>\n\nclass BuildSystem {\npublic:\n    bool compileProject();\n    std::string getArtifactPath();\nprivate:\n    void simulateDelay(int ms);\n}; "
  },
  {
    "path": "design-patterns/cpp/facade/deployment_facade.cpp",
    "content": "#include \"deployment_facade.h\"\n#include <iostream>\n\nDeploymentFacade::DeploymentFacade()\n    : vcs(std::make_unique<VersionControlSystem>())\n    , buildSystem(std::make_unique<BuildSystem>())\n    , testingFramework(std::make_unique<TestingFramework>())\n    , deploymentTarget(std::make_unique<DeploymentTarget>()) {}\n\nbool DeploymentFacade::deployApplication(const std::string& branch, const std::string& serverAddress) {\n    std::cout << \"\\nFACADE: --- Initiating FULL DEPLOYMENT for branch: \" << branch << \" to \" << serverAddress << \" ---\" << std::endl;\n    bool success = true;\n\n    try {\n        // Step 1: Pull latest code\n        vcs->pullLatestChanges(branch);\n\n        // Step 2: Build the project\n        if (!buildSystem->compileProject()) {\n            std::cerr << \"FACADE: DEPLOYMENT FAILED - Build compilation failed.\" << std::endl;\n            return false;\n        }\n        std::string artifactPath = buildSystem->getArtifactPath();\n\n        // Step 3: Run tests\n        if (!testingFramework->runUnitTests()) {\n            std::cerr << \"FACADE: DEPLOYMENT FAILED - Unit tests failed.\" << std::endl;\n            return false;\n        }\n        if (!testingFramework->runIntegrationTests()) {\n            std::cerr << \"FACADE: DEPLOYMENT FAILED - Integration tests failed.\" << std::endl;\n            return false;\n        }\n\n        // Step 4: Deploy to production\n        deploymentTarget->transferArtifact(artifactPath, serverAddress);\n        deploymentTarget->activateNewVersion(serverAddress);\n\n        std::cout << \"FACADE: APPLICATION DEPLOYED SUCCESSFULLY TO \" << serverAddress << \"!\" << std::endl;\n    } catch (const std::exception& e) {\n        std::cerr << \"FACADE: DEPLOYMENT FAILED - An unexpected error occurred: \" << e.what() << std::endl;\n        success = false;\n    }\n    return success;\n}\n\nbool DeploymentFacade::deployHotfix(const std::string& branch, const std::string& serverAddress) {\n    std::cout << \"\\nFACADE: --- Initiating HOTFIX DEPLOYMENT for branch: \" << branch << \" to \" << serverAddress << \" ---\" << std::endl;\n    bool success = true;\n\n    try {\n        // Step 1: Pull latest code\n        vcs->pullLatestChanges(branch);\n\n        // Step 2: Build the project\n        if (!buildSystem->compileProject()) {\n            std::cerr << \"FACADE: HOTFIX FAILED - Build compilation failed.\" << std::endl;\n            return false;\n        }\n        std::string artifactPath = buildSystem->getArtifactPath();\n\n        // Step 3: For a hotfix, we skip extensive tests\n        std::cout << \"FACADE: Skipping full test suite for hotfix deployment (or running minimal smoke tests).\" << std::endl;\n\n        // Step 4: Deploy to production\n        deploymentTarget->transferArtifact(artifactPath, serverAddress);\n        deploymentTarget->activateNewVersion(serverAddress);\n\n        std::cout << \"FACADE: HOTFIX DEPLOYED SUCCESSFULLY TO \" << serverAddress << \"!\" << std::endl;\n    } catch (const std::exception& e) {\n        std::cerr << \"FACADE: HOTFIX FAILED - An unexpected error occurred: \" << e.what() << std::endl;\n        success = false;\n    }\n    return success;\n} "
  },
  {
    "path": "design-patterns/cpp/facade/deployment_facade.h",
    "content": "#pragma once\n#include \"version_control_system.h\"\n#include \"build_system.h\"\n#include \"testing_framework.h\"\n#include \"deployment_target.h\"\n#include <string>\n#include <memory>\n\nclass DeploymentFacade {\npublic:\n    DeploymentFacade();\n    bool deployApplication(const std::string& branch, const std::string& serverAddress);\n    bool deployHotfix(const std::string& branch, const std::string& serverAddress);\n\nprivate:\n    std::unique_ptr<VersionControlSystem> vcs;\n    std::unique_ptr<BuildSystem> buildSystem;\n    std::unique_ptr<TestingFramework> testingFramework;\n    std::unique_ptr<DeploymentTarget> deploymentTarget;\n}; "
  },
  {
    "path": "design-patterns/cpp/facade/deployment_target.cpp",
    "content": "#include \"deployment_target.h\"\n\nvoid DeploymentTarget::transferArtifact(const std::string& artifactPath, const std::string& server) {\n    std::cout << \"Deployment: Transferring \" << artifactPath << \" to \" << server << \"...\" << std::endl;\n    simulateDelay(1000);\n    std::cout << \"Deployment: Transfer complete.\" << std::endl;\n}\n\nvoid DeploymentTarget::activateNewVersion(const std::string& server) {\n    std::cout << \"Deployment: Activating new version on \" << server << \"...\" << std::endl;\n    simulateDelay(500);\n    std::cout << \"Deployment: Now live on \" << server << \"!\" << std::endl;\n}\n\nvoid DeploymentTarget::simulateDelay(int ms) {\n    std::this_thread::sleep_for(std::chrono::milliseconds(ms));\n} "
  },
  {
    "path": "design-patterns/cpp/facade/deployment_target.h",
    "content": "#pragma once\n#include <string>\n#include <chrono>\n#include <thread>\n#include <iostream>\n\nclass DeploymentTarget {\npublic:\n    void transferArtifact(const std::string& artifactPath, const std::string& server);\n    void activateNewVersion(const std::string& server);\nprivate:\n    void simulateDelay(int ms);\n}; "
  },
  {
    "path": "design-patterns/cpp/facade/main.cpp",
    "content": "#include \"deployment_facade.h\"\n#include <iostream>\n\nint main() {\n    DeploymentFacade facade;\n\n    // Example 1: Full deployment\n    std::cout << \"=== Full Deployment Example ===\" << std::endl;\n    facade.deployApplication(\"main\", \"production-server\");\n\n    // Example 2: Hotfix deployment\n    std::cout << \"\\n=== Hotfix Deployment Example ===\" << std::endl;\n    facade.deployHotfix(\"hotfix/security-patch\", \"production-server\");\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/facade/testing_framework.cpp",
    "content": "#include \"testing_framework.h\"\n\nbool TestingFramework::runUnitTests() {\n    std::cout << \"Testing: Running unit tests...\" << std::endl;\n    simulateDelay(1500);\n    std::cout << \"Testing: Unit tests passed.\" << std::endl;\n    return true;\n}\n\nbool TestingFramework::runIntegrationTests() {\n    std::cout << \"Testing: Running integration tests...\" << std::endl;\n    simulateDelay(3000);\n    std::cout << \"Testing: Integration tests passed.\" << std::endl;\n    return true;\n}\n\nvoid TestingFramework::simulateDelay(int ms) {\n    std::this_thread::sleep_for(std::chrono::milliseconds(ms));\n} "
  },
  {
    "path": "design-patterns/cpp/facade/testing_framework.h",
    "content": "#pragma once\n#include <chrono>\n#include <thread>\n#include <iostream>\n\nclass TestingFramework {\npublic:\n    bool runUnitTests();\n    bool runIntegrationTests();\nprivate:\n    void simulateDelay(int ms);\n}; "
  },
  {
    "path": "design-patterns/cpp/facade/version_control_system.cpp",
    "content": "#include \"version_control_system.h\"\n\nvoid VersionControlSystem::pullLatestChanges(const std::string& branch) {\n    std::cout << \"VCS: Pulling latest changes from '\" << branch << \"'...\" << std::endl;\n    simulateDelay();\n    std::cout << \"VCS: Pull complete.\" << std::endl;\n}\n\nvoid VersionControlSystem::simulateDelay() {\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n} "
  },
  {
    "path": "design-patterns/cpp/facade/version_control_system.h",
    "content": "#pragma once\n#include <string>\n#include <chrono>\n#include <thread>\n#include <iostream>\n\nclass VersionControlSystem {\npublic:\n    void pullLatestChanges(const std::string& branch);\nprivate:\n    void simulateDelay();\n}; "
  },
  {
    "path": "design-patterns/cpp/factory/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.10)\nproject(factory)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\nadd_executable(factory\n    main.cpp\n    email_notification.cpp\n    sms_notification.cpp\n    push_notification.cpp\n    notification_factory.cpp\n) "
  },
  {
    "path": "design-patterns/cpp/factory/email_notification.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/factory/email_notification.h",
    "content": "#pragma once\n#include \"notification.h\"\n\nclass EmailNotification : public Notification {\npublic:\n    void send(const std::string& message) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/factory/main.cpp",
    "content": "#include \"notification_factory.h\"\n#include <iostream>\n\nint main() {\n    try {\n        // Create different types of notifications using the factory\n        auto emailNotification = NotificationFactory::createNotification(\"EMAIL\");\n        auto smsNotification = NotificationFactory::createNotification(\"SMS\");\n        auto pushNotification = NotificationFactory::createNotification(\"PUSH\");\n\n        // Send messages using the notifications\n        emailNotification->send(\"Hello via Email!\");\n        smsNotification->send(\"Hello via SMS!\");\n        pushNotification->send(\"Hello via Push!\");\n\n        // Try to create an invalid notification type\n        auto invalidNotification = NotificationFactory::createNotification(\"INVALID\");\n    } catch (const std::exception& e) {\n        std::cerr << \"Error: \" << e.what() << std::endl;\n    }\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/factory/notification.h",
    "content": "#pragma once\n#include <string>\n\nclass Notification {\npublic:\n    virtual ~Notification() = default;\n    virtual void send(const std::string& message) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/factory/notification_factory.cpp",
    "content": "#include \"notification_factory.h\"\n#include \"email_notification.h\"\n#include \"sms_notification.h\"\n#include \"push_notification.h\"\n#include <stdexcept>\n\nstd::unique_ptr<Notification> NotificationFactory::createNotification(const std::string& type) {\n    if (type == \"EMAIL\") {\n        return std::make_unique<EmailNotification>();\n    } else if (type == \"SMS\") {\n        return std::make_unique<SMSNotification>();\n    } else if (type == \"PUSH\") {\n        return std::make_unique<PushNotification>();\n    }\n    throw std::invalid_argument(\"Unknown notification type\");\n} "
  },
  {
    "path": "design-patterns/cpp/factory/notification_factory.h",
    "content": "#pragma once\n#include \"notification.h\"\n#include <string>\n#include <memory>\n\nclass NotificationFactory {\npublic:\n    static std::unique_ptr<Notification> createNotification(const std::string& type);\n}; "
  },
  {
    "path": "design-patterns/cpp/factory/push_notification.cpp",
    "content": "#include \"push_notification.h\"\n#include <iostream>\n\nvoid PushNotification::send(const std::string& message) {\n    std::cout << \"Sending push notification: \" << message << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/factory/push_notification.h",
    "content": "#pragma once\n#include \"notification.h\"\n\nclass PushNotification : public Notification {\npublic:\n    void send(const std::string& message) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/factory/sms_notification.cpp",
    "content": "#include \"sms_notification.h\"\n#include <iostream>\n\nvoid SMSNotification::send(const std::string& message) {\n    std::cout << \"Sending SMS: \" << message << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/factory/sms_notification.h",
    "content": "#pragma once\n#include \"notification.h\"\n\nclass SMSNotification : public Notification {\npublic:\n    void send(const std::string& message) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/flyweight/circle.cpp",
    "content": "#include \"circle.h\"\n#include <iostream>\n\nCircle::Circle(const std::string& color) : color(color) {}\n\nvoid Circle::draw() {\n    std::cout << \"Drawing Circle[ color: \" << color \n              << \", x: \" << x \n              << \", y: \" << y \n              << \", radius: \" << radius \n              << \" ]\" << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/flyweight/circle.h",
    "content": "#pragma once\n#include \"shape.h\"\n#include <string>\n\nclass Circle : public Shape {\npublic:\n    Circle(const std::string& color);\n    void draw() override;\n\nprivate:\n    std::string color;\n    int x = 0;\n    int y = 0;\n    int radius = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/flyweight/main.cpp",
    "content": "#include \"shape_factory.h\"\n#include <iostream>\n\nint main() {\n    std::cout << \"Flyweight Pattern Demo\\n\" << std::endl;\n\n    // Get circles of different colors\n    Shape* redCircle = ShapeFactory::getCircle(\"Red\");\n    redCircle->draw();\n\n    Shape* greenCircle = ShapeFactory::getCircle(\"Green\");\n    greenCircle->draw();\n\n    Shape* blueCircle = ShapeFactory::getCircle(\"Blue\");\n    blueCircle->draw();\n\n    // Try to get a red circle again\n    Shape* redCircle2 = ShapeFactory::getCircle(\"Red\");\n    redCircle2->draw();\n\n    std::cout << \"\\nTotal number of circle objects created: \" \n              << ShapeFactory::getCircleCount() << std::endl;\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/flyweight/shape.h",
    "content": "#pragma once\n#include <string>\n\nclass Shape {\npublic:\n    virtual ~Shape() = default;\n    virtual void draw() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/flyweight/shape_factory.cpp",
    "content": "#include \"shape_factory.h\"\n#include \"circle.h\"\n\nstd::unordered_map<std::string, Shape*> ShapeFactory::circleMap;\n\nShape* ShapeFactory::getCircle(const std::string& color) {\n    auto it = circleMap.find(color);\n    if (it == circleMap.end()) {\n        Circle* circle = new Circle(color);\n        circleMap[color] = circle;\n        std::cout << \"Creating circle of color: \" << color << std::endl;\n        return circle;\n    }\n    return it->second;\n}\n\nint ShapeFactory::getCircleCount() {\n    return circleMap.size();\n} "
  },
  {
    "path": "design-patterns/cpp/flyweight/shape_factory.h",
    "content": "#pragma once\n#include \"shape.h\"\n#include <unordered_map>\n#include <string>\n#include <memory>\n\nclass ShapeFactory {\npublic:\n    static Shape* getCircle(const std::string& color);\n    static int getCircleCount();\n\nprivate:\n    static std::unordered_map<std::string, Shape*> circleMap;\n}; "
  },
  {
    "path": "design-patterns/cpp/iterator/container.h",
    "content": "#pragma once\n#include \"iterator.h\"\n\nclass Container {\npublic:\n    virtual ~Container() = default;\n    virtual Iterator* getIterator() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/iterator/iterator.h",
    "content": "#pragma once\n#include <string>\n\nclass Iterator {\npublic:\n    virtual ~Iterator() = default;\n    virtual bool hasNext() = 0;\n    virtual std::string next() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/iterator/main.cpp",
    "content": "#include \"name_repository.h\"\n#include <iostream>\n\nint main() {\n    NameRepository namesRepository;\n    \n    std::cout << \"Names: \";\n    for (Iterator* iter = namesRepository.getIterator(); iter->hasNext();) {\n        std::string name = iter->next();\n        std::cout << name << \" \";\n    }\n    std::cout << std::endl;\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/iterator/name_iterator.cpp",
    "content": "#include \"name_iterator.h\"\n\nNameIterator::NameIterator(const std::vector<std::string>& names) \n    : names(names), index(0) {}\n\nbool NameIterator::hasNext() {\n    return index < names.size();\n}\n\nstd::string NameIterator::next() {\n    if (hasNext()) {\n        return names[index++];\n    }\n    return \"\";\n} "
  },
  {
    "path": "design-patterns/cpp/iterator/name_iterator.h",
    "content": "#pragma once\n#include \"iterator.h\"\n#include <vector>\n#include <string>\n\nclass NameIterator : public Iterator {\npublic:\n    explicit NameIterator(const std::vector<std::string>& names);\n    bool hasNext() override;\n    std::string next() override;\n\nprivate:\n    std::vector<std::string> names;\n    size_t index;\n}; "
  },
  {
    "path": "design-patterns/cpp/iterator/name_repository.cpp",
    "content": "#include \"name_repository.h\"\n#include \"name_iterator.h\"\n\nNameRepository::NameRepository() {\n    names = {\"Robert\", \"John\", \"Julie\", \"Lora\"};\n}\n\nIterator* NameRepository::getIterator() {\n    return new NameIterator(names);\n} "
  },
  {
    "path": "design-patterns/cpp/iterator/name_repository.h",
    "content": "#pragma once\n#include \"container.h\"\n#include <vector>\n#include <string>\n\nclass NameRepository : public Container {\npublic:\n    NameRepository();\n    Iterator* getIterator() override;\n\nprivate:\n    std::vector<std::string> names;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/button.cpp",
    "content": "#include \"button.h\"\n#include <iostream>\n\nButton::Button(UIMediator* mediator) : UIComponent(mediator), enabled(false) {}\n\nvoid Button::click() {\n    if (enabled) {\n        std::cout << \"Login Button clicked!\" << std::endl;\n        notifyMediator(); // Will trigger login attempt\n    } else {\n        std::cout << \"Login Button is disabled.\" << std::endl;\n    }\n}\n\nvoid Button::setEnabled(bool value) {\n    enabled = value;\n    std::cout << \"Login Button is now \" << (enabled ? \"ENABLED\" : \"DISABLED\") << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/button.h",
    "content": "#pragma once\n#include \"ui_component.h\"\n\nclass Button : public UIComponent {\npublic:\n    explicit Button(UIMediator* mediator);\n    void click();\n    void setEnabled(bool value);\n\nprivate:\n    bool enabled;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/form_mediator.cpp",
    "content": "#include \"form_mediator.h\"\n#include <iostream>\n\nvoid FormMediator::setUsernameField(TextField* field) {\n    usernameField = field;\n}\n\nvoid FormMediator::setPasswordField(TextField* field) {\n    passwordField = field;\n}\n\nvoid FormMediator::setLoginButton(Button* button) {\n    loginButton = button;\n}\n\nvoid FormMediator::setStatusLabel(Label* label) {\n    statusLabel = label;\n}\n\nvoid FormMediator::componentChanged(UIComponent* component) {\n    if (component == usernameField || component == passwordField) {\n        bool enableButton = !usernameField->getText().empty() && !passwordField->getText().empty();\n        loginButton->setEnabled(enableButton);\n    } else if (component == loginButton) {\n        const std::string& username = usernameField->getText();\n        const std::string& password = passwordField->getText();\n\n        if (username == \"admin\" && password == \"1234\") {\n            statusLabel->setText(\"✅ Login successful!\");\n        } else {\n            statusLabel->setText(\"❌ Invalid credentials.\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/form_mediator.h",
    "content": "#pragma once\n#include \"ui_mediator.h\"\n#include \"text_field.h\"\n#include \"button.h\"\n#include \"label.h\"\n\nclass FormMediator : public UIMediator {\npublic:\n    void setUsernameField(TextField* field);\n    void setPasswordField(TextField* field);\n    void setLoginButton(Button* button);\n    void setStatusLabel(Label* label);\n    void componentChanged(UIComponent* component) override;\n\nprivate:\n    TextField* usernameField = nullptr;\n    TextField* passwordField = nullptr;\n    Button* loginButton = nullptr;\n    Label* statusLabel = nullptr;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/label.cpp",
    "content": "#include \"label.h\"\n#include <iostream>\n\nLabel::Label(UIMediator* mediator) : UIComponent(mediator) {}\n\nvoid Label::setText(const std::string& message) {\n    text = message;\n    std::cout << \"Status: \" << text << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/label.h",
    "content": "#pragma once\n#include \"ui_component.h\"\n#include <string>\n\nclass Label : public UIComponent {\npublic:\n    explicit Label(UIMediator* mediator);\n    void setText(const std::string& message);\n\nprivate:\n    std::string text;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/main.cpp",
    "content": "#include \"form_mediator.h\"\n#include \"text_field.h\"\n#include \"button.h\"\n#include \"label.h\"\n#include <iostream>\n\nint main() {\n    // Create the mediator\n    FormMediator mediator;\n\n    // Create UI components\n    TextField usernameField(&mediator);\n    TextField passwordField(&mediator);\n    Button loginButton(&mediator);\n    Label statusLabel(&mediator);\n\n    // Register components with the mediator\n    mediator.setUsernameField(&usernameField);\n    mediator.setPasswordField(&passwordField);\n    mediator.setLoginButton(&loginButton);\n    mediator.setStatusLabel(&statusLabel);\n\n    std::cout << \"=== Login Form Demo ===\\n\" << std::endl;\n\n    // Test with empty fields\n    std::cout << \"Test 1: Empty fields\" << std::endl;\n    loginButton.click();\n\n    // Test with username only\n    std::cout << \"\\nTest 2: Username only\" << std::endl;\n    usernameField.setText(\"admin\");\n    loginButton.click();\n\n    // Test with both fields\n    std::cout << \"\\nTest 3: Both fields filled\" << std::endl;\n    passwordField.setText(\"1234\");\n    loginButton.click();\n\n    // Test with wrong credentials\n    std::cout << \"\\nTest 4: Wrong credentials\" << std::endl;\n    usernameField.setText(\"user\");\n    passwordField.setText(\"pass\");\n    loginButton.click();\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/text_field.cpp",
    "content": "#include \"text_field.h\"\n#include <iostream>\n\nTextField::TextField(UIMediator* mediator) : UIComponent(mediator) {}\n\nvoid TextField::setText(const std::string& newText) {\n    text = newText;\n    std::cout << \"TextField updated: \" << newText << std::endl;\n    notifyMediator();\n}\n\nconst std::string& TextField::getText() const {\n    return text;\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/text_field.h",
    "content": "#pragma once\n#include \"ui_component.h\"\n#include <string>\n\nclass TextField : public UIComponent {\npublic:\n    explicit TextField(UIMediator* mediator);\n    void setText(const std::string& newText);\n    const std::string& getText() const;\n\nprivate:\n    std::string text;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/ui_component.cpp",
    "content": "#include \"ui_component.h\"\n\nUIComponent::UIComponent(UIMediator* mediator) : mediator(mediator) {}\n\nvoid UIComponent::notifyMediator() {\n    mediator->componentChanged(this);\n} "
  },
  {
    "path": "design-patterns/cpp/mediator/ui_component.h",
    "content": "#pragma once\n#include \"ui_mediator.h\"\n\nclass UIComponent {\npublic:\n    explicit UIComponent(UIMediator* mediator);\n    virtual ~UIComponent() = default;\n\nprotected:\n    void notifyMediator();\n    UIMediator* mediator;\n}; "
  },
  {
    "path": "design-patterns/cpp/mediator/ui_mediator.h",
    "content": "#pragma once\n\n// Forward declaration\nclass UIComponent;\n\nclass UIMediator {\npublic:\n    virtual ~UIMediator() = default;\n    virtual void componentChanged(UIComponent* component) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/memento/main.cpp",
    "content": "#include \"text_editor.h\"\n#include \"text_editor_undo_manager.h\"\n#include <iostream>\n\nint main() {\n    TextEditor editor;\n    TextEditorUndoManager undoManager;\n\n    std::cout << \"=== Text Editor with Undo Demo ===\\n\" << std::endl;\n\n    // Type some text and save state\n    std::cout << \"Typing and saving initial text:\" << std::endl;\n    editor.type(\"Hello, \");\n    undoManager.save(editor);\n\n    // Type more text and save state\n    std::cout << \"\\nTyping and saving more text:\" << std::endl;\n    editor.type(\"World!\");\n    undoManager.save(editor);\n\n    // Type additional text\n    std::cout << \"\\nTyping additional text:\" << std::endl;\n    editor.type(\" How are you?\");\n\n    // Show current content\n    std::cout << \"\\nCurrent content: \" << editor.getContent() << std::endl;\n\n    // Undo last change\n    std::cout << \"\\nUndoing last change:\" << std::endl;\n    undoManager.undo(editor);\n\n    // Show content after undo\n    std::cout << \"\\nContent after undo: \" << editor.getContent() << std::endl;\n\n    // Undo again\n    std::cout << \"\\nUndoing again:\" << std::endl;\n    undoManager.undo(editor);\n\n    // Show content after second undo\n    std::cout << \"\\nContent after second undo: \" << editor.getContent() << std::endl;\n\n    // Try to undo when nothing is left\n    std::cout << \"\\nTrying to undo when nothing is left:\" << std::endl;\n    undoManager.undo(editor);\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor.cpp",
    "content": "#include \"text_editor.h\"\n#include <iostream>\n\nvoid TextEditor::type(const std::string& newText) {\n    content += newText;\n    std::cout << \"Typed: \" << newText << std::endl;\n}\n\nstd::string TextEditor::getContent() const {\n    return content;\n}\n\nTextEditorMemento TextEditor::save() const {\n    std::cout << \"Saving state: \\\"\" << content << \"\\\"\" << std::endl;\n    return TextEditorMemento(content);\n}\n\nvoid TextEditor::restore(const TextEditorMemento& memento) {\n    content = memento.getState();\n    std::cout << \"Restored state to: \\\"\" << content << \"\\\"\" << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor.h",
    "content": "#pragma once\n#include \"text_editor_memento.h\"\n#include <string>\n\nclass TextEditor {\npublic:\n    void type(const std::string& newText);\n    std::string getContent() const;\n    TextEditorMemento save() const;\n    void restore(const TextEditorMemento& memento);\n\nprivate:\n    std::string content;\n}; "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor_memento.cpp",
    "content": "#include \"text_editor_memento.h\"\n\nTextEditorMemento::TextEditorMemento(const std::string& state) : state(state) {}\n\nstd::string TextEditorMemento::getState() const {\n    return state;\n} "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor_memento.h",
    "content": "#pragma once\n#include <string>\n\nclass TextEditorMemento {\npublic:\n    explicit TextEditorMemento(const std::string& state);\n    std::string getState() const;\n\nprivate:\n    const std::string state;\n}; "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor_undo_manager.cpp",
    "content": "#include \"text_editor_undo_manager.h\"\n#include <iostream>\n\nvoid TextEditorUndoManager::save(TextEditor& editor) {\n    history.push(editor.save());\n}\n\nvoid TextEditorUndoManager::undo(TextEditor& editor) {\n    if (!history.empty()) {\n        editor.restore(history.top());\n        history.pop();\n    } else {\n        std::cout << \"Nothing to undo.\" << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/memento/text_editor_undo_manager.h",
    "content": "#pragma once\n#include \"text_editor.h\"\n#include <stack>\n\nclass TextEditorUndoManager {\npublic:\n    void save(TextEditor& editor);\n    void undo(TextEditor& editor);\n\nprivate:\n    std::stack<TextEditorMemento> history;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/fitness_data.cpp",
    "content": "#include \"fitness_data.h\"\n#include <iostream>\n\nFitnessData::FitnessData() : steps(0), activeMinutes(0), calories(0) {}\n\nvoid FitnessData::registerObserver(FitnessDataObserver* observer) {\n    observers.push_back(observer);\n}\n\nvoid FitnessData::removeObserver(FitnessDataObserver* observer) {\n    auto it = std::find(observers.begin(), observers.end(), observer);\n    if (it != observers.end()) {\n        observers.erase(it);\n    }\n}\n\nvoid FitnessData::notifyObservers() {\n    for (auto observer : observers) {\n        observer->update(*this);\n    }\n}\n\nvoid FitnessData::newFitnessDataPushed(int steps, int activeMinutes, int calories) {\n    this->steps = steps;\n    this->activeMinutes = activeMinutes;\n    this->calories = calories;\n\n    std::cout << \"\\nFitnessData: New data received — Steps: \" << steps\n              << \", Active Minutes: \" << activeMinutes \n              << \", Calories: \" << calories << std::endl;\n    notifyObservers();\n}\n\nvoid FitnessData::dailyReset() {\n    steps = 0;\n    activeMinutes = 0;\n    calories = 0;\n    std::cout << \"\\nFitnessData: Daily reset performed.\" << std::endl;\n    notifyObservers();\n} "
  },
  {
    "path": "design-patterns/cpp/observer/fitness_data.h",
    "content": "#pragma once\n#include \"fitness_data_subject.h\"\n#include <vector>\n#include <memory>\n\nclass FitnessData : public FitnessDataSubject {\npublic:\n    FitnessData();\n\n    // Subject interface implementation\n    void registerObserver(FitnessDataObserver* observer) override;\n    void removeObserver(FitnessDataObserver* observer) override;\n    void notifyObservers() override;\n\n    // Fitness data methods\n    void newFitnessDataPushed(int steps, int activeMinutes, int calories);\n    void dailyReset();\n\n    // Getters\n    int getSteps() const { return steps; }\n    int getActiveMinutes() const { return activeMinutes; }\n    int getCalories() const { return calories; }\n\nprivate:\n    int steps;\n    int activeMinutes;\n    int calories;\n    std::vector<FitnessDataObserver*> observers;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/fitness_data_observer.h",
    "content": "#pragma once\n\n// Forward declaration\nclass FitnessData;\n\nclass FitnessDataObserver {\npublic:\n    virtual ~FitnessDataObserver() = default;\n    virtual void update(const FitnessData& data) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/fitness_data_subject.h",
    "content": "#pragma once\n#include \"fitness_data_observer.h\"\n\nclass FitnessDataSubject {\npublic:\n    virtual ~FitnessDataSubject() = default;\n    virtual void registerObserver(FitnessDataObserver* observer) = 0;\n    virtual void removeObserver(FitnessDataObserver* observer) = 0;\n    virtual void notifyObservers() = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/goal_notifier.cpp",
    "content": "#include \"goal_notifier.h\"\n#include \"fitness_data.h\"\n#include <iostream>\n\nvoid GoalNotifier::update(const FitnessData& data) {\n    if (data.getSteps() >= 10000) {\n        std::cout << \"GoalNotifier: Congratulations! You've reached your daily step goal!\" << std::endl;\n    }\n    if (data.getActiveMinutes() >= 30) {\n        std::cout << \"GoalNotifier: Great job! You've met your active minutes goal!\" << std::endl;\n    }\n    if (data.getCalories() >= 2000) {\n        std::cout << \"GoalNotifier: Amazing! You've burned your target calories!\" << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/observer/goal_notifier.h",
    "content": "#pragma once\n#include \"fitness_data_observer.h\"\n\nclass GoalNotifier : public FitnessDataObserver {\npublic:\n    void update(const FitnessData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/live_activity_display.cpp",
    "content": "#include \"live_activity_display.h\"\n#include \"fitness_data.h\"\n#include <iostream>\n\nvoid LiveActivityDisplay::update(const FitnessData& data) {\n    std::cout << \"LiveActivityDisplay: Current Activity — Steps: \" << data.getSteps()\n              << \", Active Minutes: \" << data.getActiveMinutes()\n              << \", Calories: \" << data.getCalories() << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/observer/live_activity_display.h",
    "content": "#pragma once\n#include \"fitness_data_observer.h\"\n\nclass LiveActivityDisplay : public FitnessDataObserver {\npublic:\n    void update(const FitnessData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/observer/main.cpp",
    "content": "#include \"fitness_data.h\"\n#include \"live_activity_display.h\"\n#include \"progress_logger.h\"\n#include \"goal_notifier.h\"\n#include <iostream>\n\nint main() {\n    // Create the subject\n    FitnessData fitnessData;\n\n    // Create observers\n    LiveActivityDisplay liveDisplay;\n    ProgressLogger logger;\n    GoalNotifier notifier;\n\n    // Register observers\n    fitnessData.registerObserver(&liveDisplay);\n    fitnessData.registerObserver(&logger);\n    fitnessData.registerObserver(&notifier);\n\n    // Simulate fitness data updates\n    std::cout << \"=== Fitness App Observer Demo ===\\n\" << std::endl;\n\n    // First update\n    std::cout << \"Update 1:\" << std::endl;\n    fitnessData.newFitnessDataPushed(5000, 15, 1000);\n\n    // Second update\n    std::cout << \"\\nUpdate 2:\" << std::endl;\n    fitnessData.newFitnessDataPushed(12000, 45, 2500);\n\n    // Daily reset\n    std::cout << \"\\nDaily Reset:\" << std::endl;\n    fitnessData.dailyReset();\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/observer/progress_logger.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/observer/progress_logger.h",
    "content": "#pragma once\n#include \"fitness_data_observer.h\"\n\nclass ProgressLogger : public FitnessDataObserver {\npublic:\n    void update(const FitnessData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/prototype/enemy.cpp",
    "content": "#include \"enemy.h\"\n#include <iostream>\n\nEnemy::Enemy(const std::string& type, int health, double speed, bool armored, const std::string& weapon)\n    : type(type), health(health), speed(speed), armored(armored), weapon(weapon) {}\n\nEnemy* Enemy::clone() const {\n    return new Enemy(type, health, speed, armored, weapon);\n}\n\nvoid Enemy::setHealth(int health) {\n    this->health = health;\n}\n\nvoid Enemy::printStats() const {\n    std::cout << type << \" [Health: \" << health \n              << \", Speed: \" << speed \n              << \", Armored: \" << (armored ? \"true\" : \"false\") \n              << \", Weapon: \" << weapon << \"]\" << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/prototype/enemy.h",
    "content": "#pragma once\n#include \"enemy_prototype.h\"\n#include <string>\n\nclass Enemy : public EnemyPrototype {\npublic:\n    Enemy(const std::string& type, int health, double speed, bool armored, const std::string& weapon);\n    \n    // Clone method implementation\n    Enemy* clone() const override;\n    \n    // Setter for health\n    void setHealth(int health);\n    \n    // Print enemy stats\n    void printStats() const;\n\nprivate:\n    std::string type;\n    int health;\n    double speed;\n    bool armored;\n    std::string weapon;\n}; "
  },
  {
    "path": "design-patterns/cpp/prototype/enemy_prototype.h",
    "content": "#pragma once\n\nclass EnemyPrototype {\npublic:\n    virtual ~EnemyPrototype() = default;\n    virtual EnemyPrototype* clone() const = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/prototype/enemy_registry.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/prototype/enemy_registry.h",
    "content": "#pragma once\n#include \"enemy.h\"\n#include <string>\n#include <unordered_map>\n#include <memory>\n#include <stdexcept>\n\nclass EnemyRegistry {\npublic:\n    void registerPrototype(const std::string& key, std::unique_ptr<Enemy> prototype);\n    std::unique_ptr<Enemy> get(const std::string& key) const;\n\nprivate:\n    std::unordered_map<std::string, std::unique_ptr<Enemy>> prototypes;\n}; "
  },
  {
    "path": "design-patterns/cpp/prototype/main.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/proxy/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.10)\nproject(proxy_pattern)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\n\n# Add executable for version 1\nadd_executable(image_gallery_v1\n    image_gallery_app_v1.cpp\n    high_resolution_image.cpp\n)\n\n# Add executable for version 2\nadd_executable(image_gallery_v2\n    image_gallery_app_v2.cpp\n    high_resolution_image.cpp\n    image_proxy.cpp\n) "
  },
  {
    "path": "design-patterns/cpp/proxy/high_resolution_image.cpp",
    "content": "#include \"high_resolution_image.h\"\n#include <iostream>\n\nHighResolutionImage::HighResolutionImage(const std::string& fileName)\n    : fileName(fileName) {\n    loadImageFromDisk();\n}\n\nvoid HighResolutionImage::loadImageFromDisk() {\n    std::cout << \"Loading image: \" << fileName << \" from disk (Expensive Operation)...\" << std::endl;\n    // Simulate disk read and memory allocation\n    std::this_thread::sleep_for(std::chrono::seconds(2)); // Simulate delay\n    imageData.resize(10 * 1024 * 1024); // 10MB\n    std::cout << \"Image \" << fileName << \" loaded successfully.\" << std::endl;\n}\n\nvoid HighResolutionImage::display() {\n    std::cout << \"Displaying image: \" << fileName << std::endl;\n    // Actual rendering logic would go here\n}\n\nstd::string HighResolutionImage::getFileName() const {\n    return fileName;\n} "
  },
  {
    "path": "design-patterns/cpp/proxy/high_resolution_image.h",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/proxy/image.h",
    "content": "#pragma once\n#include <string>\n\nclass Image {\npublic:\n    virtual ~Image() = default;\n    virtual void display() = 0;\n    virtual std::string getFileName() const = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/proxy/image_gallery_app_v1.cpp",
    "content": "#include \"high_resolution_image.h\"\n#include <iostream>\n\nint main() {\n    // Create high-resolution images directly\n    std::cout << \"Creating high-resolution images...\" << std::endl;\n    HighResolutionImage image1(\"nature.jpg\");\n    HighResolutionImage image2(\"city.jpg\");\n    HighResolutionImage image3(\"people.jpg\");\n\n    // Display images\n    std::cout << \"\\nDisplaying images...\" << std::endl;\n    image1.display();\n    image2.display();\n    image3.display();\n\n    // Note: All images are loaded at creation time, even if not displayed\n    std::cout << \"\\nNote: All images were loaded at creation time, even if not displayed\" << std::endl;\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/proxy/image_gallery_app_v2.cpp",
    "content": "#include \"image_proxy.h\"\n#include <iostream>\n\nint main() {\n    // Create image proxies\n    std::cout << \"Creating image proxies...\" << std::endl;\n    ImageProxy image1(\"nature.jpg\");\n    ImageProxy image2(\"city.jpg\");\n    ImageProxy image3(\"people.jpg\");\n\n    // Note: Images are not loaded yet\n    std::cout << \"\\nNote: Images are not loaded yet, only proxies are created\" << std::endl;\n\n    // Display images (this will trigger loading)\n    std::cout << \"\\nDisplaying images...\" << std::endl;\n    image1.display();  // This will load the image\n    image2.display();  // This will load the image\n    image3.display();  // This will load the image\n\n    // Display again (should use cached images)\n    std::cout << \"\\nDisplaying images again...\" << std::endl;\n    image1.display();  // Should use cached image\n    image2.display();  // Should use cached image\n    image3.display();  // Should use cached image\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/proxy/image_proxy.cpp",
    "content": "#include \"image_proxy.h\"\n#include \"high_resolution_image.h\"\n#include <iostream>\n\nImageProxy::ImageProxy(const std::string& fileName)\n    : fileName(fileName) {\n    std::cout << \"ImageProxy: Created for \" << fileName << \". Real image not loaded yet.\" << std::endl;\n}\n\nvoid ImageProxy::display() {\n    // Lazy initialization: Load only when display() is called\n    if (!realImage) {\n        std::cout << \"ImageProxy: display() requested for \" << fileName << \". Loading high-resolution image...\" << std::endl;\n        realImage = std::make_unique<HighResolutionImage>(fileName);\n    } else {\n        std::cout << \"ImageProxy: Using cached high-resolution image for \" << fileName << std::endl;\n    }\n\n    // Delegate the display call to the real image\n    realImage->display();\n}\n\nstd::string ImageProxy::getFileName() const {\n    // Can safely return without loading the image\n    return fileName;\n} "
  },
  {
    "path": "design-patterns/cpp/proxy/image_proxy.h",
    "content": "#pragma once\n#include \"image.h\"\n#include <memory>\n\nclass HighResolutionImage;\n\nclass ImageProxy : public Image {\npublic:\n    explicit ImageProxy(const std::string& fileName);\n    void display() override;\n    std::string getFileName() const override;\n\nprivate:\n    std::string fileName;\n    std::unique_ptr<HighResolutionImage> realImage;\n}; "
  },
  {
    "path": "design-patterns/cpp/singleton/double_checked_singleton.cpp",
    "content": "#include \"double_checked_singleton.h\"\n\n// Initialize the static instance pointer and mutex\nstd::atomic<DoubleCheckedSingleton*> DoubleCheckedSingleton::instance = nullptr;\nstd::mutex DoubleCheckedSingleton::mutex;\n\nDoubleCheckedSingleton& DoubleCheckedSingleton::getInstance() {\n    // First check (not synchronized)\n    DoubleCheckedSingleton* p = instance.load(std::memory_order_acquire);\n    if (!p) {\n        // Lock the mutex\n        std::lock_guard<std::mutex> lock(mutex);\n        \n        // Second check (synchronized)\n        p = instance.load(std::memory_order_relaxed);\n        if (!p) {\n            // Create the instance\n            p = new DoubleCheckedSingleton();\n            instance.store(p, std::memory_order_release);\n        }\n    }\n    return *p;\n} "
  },
  {
    "path": "design-patterns/cpp/singleton/double_checked_singleton.h",
    "content": "#pragma once\n#include <memory>\n#include <mutex>\n#include <atomic>\n\nclass DoubleCheckedSingleton {\npublic:\n    // Delete copy constructor and assignment operator\n    DoubleCheckedSingleton(const DoubleCheckedSingleton&) = delete;\n    DoubleCheckedSingleton& operator=(const DoubleCheckedSingleton&) = delete;\n\n    // Public method to get the instance\n    static DoubleCheckedSingleton& getInstance();\n\nprivate:\n    // Private constructor to prevent instantiation\n    DoubleCheckedSingleton() = default;\n    \n    // The single instance, initially null\n    static std::atomic<DoubleCheckedSingleton*> instance;\n    \n    // Mutex for thread safety\n    static std::mutex mutex;\n}; "
  },
  {
    "path": "design-patterns/cpp/singleton/eager_singleton.cpp",
    "content": "#include \"eager_singleton.h\"\n\n// Define the static instance\nEagerSingleton EagerSingleton::instance;\n\nEagerSingleton& EagerSingleton::getInstance() {\n    return instance;\n} "
  },
  {
    "path": "design-patterns/cpp/singleton/eager_singleton.h",
    "content": "#pragma once\n\nclass EagerSingleton {\npublic:\n    // Delete copy constructor and assignment operator\n    EagerSingleton(const EagerSingleton&) = delete;\n    EagerSingleton& operator=(const EagerSingleton&) = delete;\n\n    // Public method to get the instance\n    static EagerSingleton& getInstance();\n\nprivate:\n    // Private constructor to prevent instantiation\n    EagerSingleton() = default;\n    \n    // The single instance, created immediately\n    static EagerSingleton instance;\n}; "
  },
  {
    "path": "design-patterns/cpp/singleton/lazy_singleton.cpp",
    "content": "#include \"lazy_singleton.h\"\n\n// Initialize the static instance pointer\nstd::unique_ptr<LazySingleton> LazySingleton::instance = nullptr;\n\nLazySingleton& LazySingleton::getInstance() {\n    // Check if instance is null\n    if (!instance) {\n        // If null, create a new instance\n        instance = std::unique_ptr<LazySingleton>(new LazySingleton());\n    }\n    // Return the instance (either newly created or existing)\n    return *instance;\n} "
  },
  {
    "path": "design-patterns/cpp/singleton/lazy_singleton.h",
    "content": "#pragma once\n#include <memory>\n\nclass LazySingleton {\npublic:\n    // Delete copy constructor and assignment operator\n    LazySingleton(const LazySingleton&) = delete;\n    LazySingleton& operator=(const LazySingleton&) = delete;\n\n    // Public method to get the instance\n    static LazySingleton& getInstance();\n\nprivate:\n    // Private constructor to prevent instantiation\n    LazySingleton() = default;\n    \n    // The single instance, initially null\n    static std::unique_ptr<LazySingleton> instance;\n}; "
  },
  {
    "path": "design-patterns/cpp/singleton/main.cpp",
    "content": "#include \"eager_singleton.h\"\n#include \"lazy_singleton.h\"\n#include \"thread_safe_singleton.h\"\n#include \"double_checked_singleton.h\"\n#include <iostream>\n\nint main() {\n    std::cout << \"=== Singleton Pattern Demo ===\\n\" << std::endl;\n\n    // Test EagerSingleton\n    std::cout << \"Testing EagerSingleton:\" << std::endl;\n    EagerSingleton& eager1 = EagerSingleton::getInstance();\n    EagerSingleton& eager2 = EagerSingleton::getInstance();\n    std::cout << \"EagerSingleton instances are the same: \" \n              << (&eager1 == &eager2) << std::endl;\n\n    // Test LazySingleton\n    std::cout << \"\\nTesting LazySingleton:\" << std::endl;\n    LazySingleton& lazy1 = LazySingleton::getInstance();\n    LazySingleton& lazy2 = LazySingleton::getInstance();\n    std::cout << \"LazySingleton instances are the same: \" \n              << (&lazy1 == &lazy2) << std::endl;\n\n    // Test ThreadSafeSingleton\n    std::cout << \"\\nTesting ThreadSafeSingleton:\" << std::endl;\n    ThreadSafeSingleton& threadSafe1 = ThreadSafeSingleton::getInstance();\n    ThreadSafeSingleton& threadSafe2 = ThreadSafeSingleton::getInstance();\n    std::cout << \"ThreadSafeSingleton instances are the same: \" \n              << (&threadSafe1 == &threadSafe2) << std::endl;\n\n    // Test DoubleCheckedSingleton\n    std::cout << \"\\nTesting DoubleCheckedSingleton:\" << std::endl;\n    DoubleCheckedSingleton& doubleChecked1 = DoubleCheckedSingleton::getInstance();\n    DoubleCheckedSingleton& doubleChecked2 = DoubleCheckedSingleton::getInstance();\n    std::cout << \"DoubleCheckedSingleton instances are the same: \" \n              << (&doubleChecked1 == &doubleChecked2) << std::endl;\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/singleton/thread_safe_singleton.cpp",
    "content": "#include \"thread_safe_singleton.h\"\n\n// Initialize the static instance pointer and mutex\nstd::unique_ptr<ThreadSafeSingleton> ThreadSafeSingleton::instance = nullptr;\nstd::mutex ThreadSafeSingleton::mutex;\n\nThreadSafeSingleton& ThreadSafeSingleton::getInstance() {\n    // Lock the mutex for thread safety\n    std::lock_guard<std::mutex> lock(mutex);\n    \n    // Check if instance is null\n    if (!instance) {\n        // If null, create a new instance\n        instance = std::unique_ptr<ThreadSafeSingleton>(new ThreadSafeSingleton());\n    }\n    // Return the instance (either newly created or existing)\n    return *instance;\n} "
  },
  {
    "path": "design-patterns/cpp/singleton/thread_safe_singleton.h",
    "content": "#pragma once\n#include <memory>\n#include <mutex>\n\nclass ThreadSafeSingleton {\npublic:\n    // Delete copy constructor and assignment operator\n    ThreadSafeSingleton(const ThreadSafeSingleton&) = delete;\n    ThreadSafeSingleton& operator=(const ThreadSafeSingleton&) = delete;\n\n    // Public method to get the instance\n    static ThreadSafeSingleton& getInstance();\n\nprivate:\n    // Private constructor to prevent instantiation\n    ThreadSafeSingleton() = default;\n    \n    // The single instance, initially null\n    static std::unique_ptr<ThreadSafeSingleton> instance;\n    \n    // Mutex for thread safety\n    static std::mutex mutex;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/dispensing_state.cpp",
    "content": "#include \"dispensing_state.h\"\n#include \"vending_machine.h\"\n#include \"idle_state.h\"\n#include <iostream>\n\nvoid DispensingState::selectItem(VendingMachine& context, const std::string& itemCode) {\n    std::cout << \"Please wait, item is being dispensed.\" << std::endl;\n}\n\nvoid DispensingState::insertCoin(VendingMachine& context, double amount) {\n    std::cout << \"Please wait, item is being dispensed.\" << std::endl;\n}\n\nvoid DispensingState::dispenseItem(VendingMachine& context) {\n    std::cout << \"Item dispensed. Thank you for your purchase!\" << std::endl;\n    context.reset();\n    context.setState(std::make_unique<IdleState>());\n} "
  },
  {
    "path": "design-patterns/cpp/state/dispensing_state.h",
    "content": "#pragma once\n#include \"machine_state.h\"\n\nclass DispensingState : public MachineState {\npublic:\n    void selectItem(VendingMachine& context, const std::string& itemCode) override;\n    void insertCoin(VendingMachine& context, double amount) override;\n    void dispenseItem(VendingMachine& context) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/has_money_state.cpp",
    "content": "#include \"has_money_state.h\"\n#include \"vending_machine.h\"\n#include \"dispensing_state.h\"\n#include <iostream>\n\nvoid HasMoneyState::selectItem(VendingMachine& context, const std::string& itemCode) {\n    std::cout << \"Item already selected. Please dispense current item or cancel.\" << std::endl;\n}\n\nvoid HasMoneyState::insertCoin(VendingMachine& context, double amount) {\n    std::cout << \"Additional money inserted: $\" << amount << std::endl;\n    context.setInsertedAmount(context.getInsertedAmount() + amount);\n}\n\nvoid HasMoneyState::dispenseItem(VendingMachine& context) {\n    std::cout << \"Dispensing item: \" << context.getSelectedItem() << std::endl;\n    context.setState(std::make_unique<DispensingState>());\n} "
  },
  {
    "path": "design-patterns/cpp/state/has_money_state.h",
    "content": "#pragma once\n#include \"machine_state.h\"\n\nclass HasMoneyState : public MachineState {\npublic:\n    void selectItem(VendingMachine& context, const std::string& itemCode) override;\n    void insertCoin(VendingMachine& context, double amount) override;\n    void dispenseItem(VendingMachine& context) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/idle_state.cpp",
    "content": "#include \"idle_state.h\"\n#include \"vending_machine.h\"\n#include \"item_selected_state.h\"\n#include <iostream>\n\nvoid IdleState::selectItem(VendingMachine& context, const std::string& itemCode) {\n    std::cout << \"Item selected: \" << itemCode << std::endl;\n    context.setSelectedItem(itemCode);\n    context.setState(std::make_unique<ItemSelectedState>());\n}\n\nvoid IdleState::insertCoin(VendingMachine& context, double amount) {\n    std::cout << \"Please select an item first.\" << std::endl;\n}\n\nvoid IdleState::dispenseItem(VendingMachine& context) {\n    std::cout << \"Please select an item first.\" << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/state/idle_state.h",
    "content": "#pragma once\n#include \"machine_state.h\"\n\nclass IdleState : public MachineState {\npublic:\n    void selectItem(VendingMachine& context, const std::string& itemCode) override;\n    void insertCoin(VendingMachine& context, double amount) override;\n    void dispenseItem(VendingMachine& context) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/item_selected_state.cpp",
    "content": "#include \"item_selected_state.h\"\n#include \"vending_machine.h\"\n#include \"has_money_state.h\"\n#include <iostream>\n\nvoid ItemSelectedState::selectItem(VendingMachine& context, const std::string& itemCode) {\n    std::cout << \"Item already selected. Please insert money or cancel.\" << std::endl;\n}\n\nvoid ItemSelectedState::insertCoin(VendingMachine& context, double amount) {\n    std::cout << \"Money inserted: $\" << amount << std::endl;\n    context.setInsertedAmount(amount);\n    context.setState(std::make_unique<HasMoneyState>());\n}\n\nvoid ItemSelectedState::dispenseItem(VendingMachine& context) {\n    std::cout << \"Please insert money first.\" << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/state/item_selected_state.h",
    "content": "#pragma once\n#include \"machine_state.h\"\n\nclass ItemSelectedState : public MachineState {\npublic:\n    void selectItem(VendingMachine& context, const std::string& itemCode) override;\n    void insertCoin(VendingMachine& context, double amount) override;\n    void dispenseItem(VendingMachine& context) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/machine_state.h",
    "content": "#pragma once\n#include <string>\n\nclass VendingMachine;  // Forward declaration\n\nclass MachineState {\npublic:\n    virtual ~MachineState() = default;\n    virtual void selectItem(VendingMachine& context, const std::string& itemCode) = 0;\n    virtual void insertCoin(VendingMachine& context, double amount) = 0;\n    virtual void dispenseItem(VendingMachine& context) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/state/main.cpp",
    "content": "#include \"vending_machine.h\"\n#include <iostream>\n\nint main() {\n    VendingMachine machine;\n\n    // Test the vending machine workflow\n    std::cout << \"=== Vending Machine Demo ===\\n\" << std::endl;\n\n    // Try to insert coin before selecting item\n    std::cout << \"Attempting to insert coin before selecting item:\" << std::endl;\n    machine.insertCoin(1.0);\n\n    // Select an item\n    std::cout << \"\\nSelecting item A1:\" << std::endl;\n    machine.selectItem(\"A1\");\n\n    // Insert coin\n    std::cout << \"\\nInserting coin:\" << std::endl;\n    machine.insertCoin(1.0);\n\n    // Try to select another item\n    std::cout << \"\\nAttempting to select another item:\" << std::endl;\n    machine.selectItem(\"B2\");\n\n    // Insert more money\n    std::cout << \"\\nInserting more money:\" << std::endl;\n    machine.insertCoin(0.5);\n\n    // Dispense item\n    std::cout << \"\\nDispensing item:\" << std::endl;\n    machine.dispenseItem();\n\n    // Try to interact after dispensing\n    std::cout << \"\\nAttempting to interact after dispensing:\" << std::endl;\n    machine.selectItem(\"C3\");\n    machine.insertCoin(1.0);\n    machine.dispenseItem();\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/state/vending_machine.cpp",
    "content": "#include \"vending_machine.h\"\n#include \"idle_state.h\"\n\nVendingMachine::VendingMachine()\n    : currentState(std::make_unique<IdleState>())\n    , selectedItem(\"\")\n    , insertedAmount(0.0) {}\n\nvoid VendingMachine::setState(std::unique_ptr<MachineState> newState) {\n    currentState = std::move(newState);\n}\n\nvoid VendingMachine::setSelectedItem(const std::string& itemCode) {\n    selectedItem = itemCode;\n}\n\nvoid VendingMachine::setInsertedAmount(double amount) {\n    insertedAmount = amount;\n}\n\nconst std::string& VendingMachine::getSelectedItem() const {\n    return selectedItem;\n}\n\ndouble VendingMachine::getInsertedAmount() const {\n    return insertedAmount;\n}\n\nvoid VendingMachine::selectItem(const std::string& itemCode) {\n    currentState->selectItem(*this, itemCode);\n}\n\nvoid VendingMachine::insertCoin(double amount) {\n    currentState->insertCoin(*this, amount);\n}\n\nvoid VendingMachine::dispenseItem() {\n    currentState->dispenseItem(*this);\n}\n\nvoid VendingMachine::reset() {\n    selectedItem = \"\";\n    insertedAmount = 0.0;\n    currentState = std::make_unique<IdleState>();\n} "
  },
  {
    "path": "design-patterns/cpp/state/vending_machine.h",
    "content": "#pragma once\n#include \"machine_state.h\"\n#include <memory>\n#include <string>\n\nclass VendingMachine {\npublic:\n    VendingMachine();\n    \n    void setState(std::unique_ptr<MachineState> newState);\n    void setSelectedItem(const std::string& itemCode);\n    void setInsertedAmount(double amount);\n    \n    const std::string& getSelectedItem() const;\n    double getInsertedAmount() const;\n    \n    void selectItem(const std::string& itemCode);\n    void insertCoin(double amount);\n    void dispenseItem();\n    void reset();\n\nprivate:\n    std::unique_ptr<MachineState> currentState;\n    std::string selectedItem;\n    double insertedAmount;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/distance_based_shipping.cpp",
    "content": "#include \"distance_based_shipping.h\"\n#include <iostream>\n#include <map>\n\ndouble DistanceBasedShipping::calculateCost(const Order& order) {\n    std::cout << \"Calculating distance-based shipping cost...\" << std::endl;\n    \n    // Zone-based rates\n    std::map<std::string, double> zoneRates = {\n        {\"ZoneA\", 5.0},\n        {\"ZoneB\", 10.0},\n        {\"ZoneC\", 15.0}\n    };\n\n    auto it = zoneRates.find(order.getDestinationZone());\n    if (it != zoneRates.end()) {\n        return it->second;\n    }\n    return 20.0; // Default rate for unknown zones\n} "
  },
  {
    "path": "design-patterns/cpp/strategy/distance_based_shipping.h",
    "content": "#pragma once\n#include \"shipping_strategy.h\"\n\nclass DistanceBasedShipping : public ShippingStrategy {\npublic:\n    double calculateCost(const Order& order) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/ecommerce_app.cpp",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/strategy/flat_rate_shipping.cpp",
    "content": "#include \"flat_rate_shipping.h\"\n#include <iostream>\n\ndouble FlatRateShipping::calculateCost(const Order& order) {\n    std::cout << \"Calculating flat rate shipping cost...\" << std::endl;\n    return 10.0; // Fixed rate of $10\n} "
  },
  {
    "path": "design-patterns/cpp/strategy/flat_rate_shipping.h",
    "content": "#pragma once\n#include \"shipping_strategy.h\"\n\nclass FlatRateShipping : public ShippingStrategy {\npublic:\n    double calculateCost(const Order& order) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/order.h",
    "content": "#pragma once\n#include <string>\n\nclass Order {\npublic:\n    double getTotalWeight() const { return 5.0; } // kg\n    std::string getDestinationZone() const { return \"ZoneA\"; }\n    double getOrderValue() const { return 150.0; }\n    // ... other order details\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/shipping_cost_service.cpp",
    "content": "#include \"shipping_cost_service.h\"\n\nShippingCostService::ShippingCostService(std::unique_ptr<ShippingStrategy> strategy)\n    : strategy(std::move(strategy)) {}\n\nvoid ShippingCostService::setStrategy(std::unique_ptr<ShippingStrategy> newStrategy) {\n    strategy = std::move(newStrategy);\n}\n\ndouble ShippingCostService::calculateShippingCost(const Order& order) {\n    return strategy->calculateCost(order);\n} "
  },
  {
    "path": "design-patterns/cpp/strategy/shipping_cost_service.h",
    "content": "#pragma once\n#include \"shipping_strategy.h\"\n#include <memory>\n\nclass ShippingCostService {\npublic:\n    explicit ShippingCostService(std::unique_ptr<ShippingStrategy> strategy);\n    void setStrategy(std::unique_ptr<ShippingStrategy> strategy);\n    double calculateShippingCost(const Order& order);\n\nprivate:\n    std::unique_ptr<ShippingStrategy> strategy;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/shipping_strategy.h",
    "content": "#pragma once\n#include \"order.h\"\n\nclass ShippingStrategy {\npublic:\n    virtual ~ShippingStrategy() = default;\n    virtual double calculateCost(const Order& order) = 0;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/third_party_api_shipping.cpp",
    "content": "#include \"third_party_api_shipping.h\"\n#include <iostream>\n\ndouble ThirdPartyApiShipping::calculateCost(const Order& order) {\n    std::cout << \"Calculating shipping cost using third-party API...\" << std::endl;\n    // Simulate API call\n    return order.getOrderValue() * 0.1; // 10% of order value\n} "
  },
  {
    "path": "design-patterns/cpp/strategy/third_party_api_shipping.h",
    "content": "#pragma once\n#include \"shipping_strategy.h\"\n\nclass ThirdPartyApiShipping : public ShippingStrategy {\npublic:\n    double calculateCost(const Order& order) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/strategy/weight_based_shipping.cpp",
    "content": "#include \"weight_based_shipping.h\"\n#include <iostream>\n\ndouble WeightBasedShipping::calculateCost(const Order& order) {\n    std::cout << \"Calculating weight-based shipping cost...\" << std::endl;\n    return order.getTotalWeight() * 2.0; // $2 per kg\n} "
  },
  {
    "path": "design-patterns/cpp/strategy/weight_based_shipping.h",
    "content": "#pragma once\n#include \"shipping_strategy.h\"\n\nclass WeightBasedShipping : public ShippingStrategy {\npublic:\n    double calculateCost(const Order& order) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/templatemethod/CMakeLists.txt",
    "content": " "
  },
  {
    "path": "design-patterns/cpp/templatemethod/abstract_report_exporter.cpp",
    "content": "#include \"abstract_report_exporter.h\"\n#include <iostream>\n\nvoid AbstractReportExporter::exportReport(const ReportData& data, const std::string& filePath) {\n    prepareData(data);\n    openFile(filePath);\n    writeHeader(data);\n    writeDataRows(data);\n    writeFooter(data);\n    closeFile(filePath);\n    std::cout << \"Report exported to \" << filePath << std::endl;\n}\n\nvoid AbstractReportExporter::prepareData(const ReportData& data) {\n    std::cout << \"Preparing report data...\" << std::endl;\n}\n\nvoid AbstractReportExporter::openFile(const std::string& filePath) {\n    std::cout << \"Opening file: \" << filePath << std::endl;\n}\n\nvoid AbstractReportExporter::writeFooter(const ReportData& data) {\n    std::cout << \"Writing footer...\" << std::endl;\n}\n\nvoid AbstractReportExporter::closeFile(const std::string& filePath) {\n    std::cout << \"Closing file: \" << filePath << std::endl;\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/abstract_report_exporter.h",
    "content": "#pragma once\n#include \"report_data.h\"\n#include <string>\n\nclass AbstractReportExporter {\npublic:\n    virtual ~AbstractReportExporter() = default;\n    \n    // Template method\n    void exportReport(const ReportData& data, const std::string& filePath);\n\nprotected:\n    // Hook methods - optional for subclasses to override\n    virtual void prepareData(const ReportData& data);\n    virtual void openFile(const std::string& filePath);\n    virtual void writeHeader(const ReportData& data) = 0;\n    virtual void writeDataRows(const ReportData& data) = 0;\n    virtual void writeFooter(const ReportData& data);\n    virtual void closeFile(const std::string& filePath);\n}; "
  },
  {
    "path": "design-patterns/cpp/templatemethod/csv_report_exporter.cpp",
    "content": "#include \"csv_report_exporter.h\"\n#include <iostream>\n#include <sstream>\n\nvoid CsvReportExporter::writeHeader(const ReportData& data) {\n    std::cout << \"Writing CSV header...\" << std::endl;\n    const auto& headers = data.getHeaders();\n    for (size_t i = 0; i < headers.size(); ++i) {\n        std::cout << headers[i];\n        if (i < headers.size() - 1) {\n            std::cout << \",\";\n        }\n    }\n    std::cout << std::endl;\n}\n\nvoid CsvReportExporter::writeDataRows(const ReportData& data) {\n    std::cout << \"Writing CSV data rows...\" << std::endl;\n    for (const auto& row : data.getRows()) {\n        for (const auto& header : data.getHeaders()) {\n            const auto& value = row.at(header);\n            std::visit([](const auto& v) { std::cout << v; }, value);\n            if (&header != &data.getHeaders().back()) {\n                std::cout << \",\";\n            }\n        }\n        std::cout << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/csv_report_exporter.h",
    "content": "#pragma once\n#include \"abstract_report_exporter.h\"\n\nclass CsvReportExporter : public AbstractReportExporter {\nprotected:\n    void writeHeader(const ReportData& data) override;\n    void writeDataRows(const ReportData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/templatemethod/excel_report_exporter.cpp",
    "content": "#include \"excel_report_exporter.h\"\n#include <iostream>\n\nvoid ExcelReportExporter::writeHeader(const ReportData& data) {\n    std::cout << \"Writing Excel header...\" << std::endl;\n    std::cout << \"| \";\n    for (const auto& header : data.getHeaders()) {\n        std::cout << header << \" | \";\n    }\n    std::cout << std::endl;\n    std::cout << \"|\";\n    for (size_t i = 0; i < data.getHeaders().size(); ++i) {\n        std::cout << \"---|\";\n    }\n    std::cout << std::endl;\n}\n\nvoid ExcelReportExporter::writeDataRows(const ReportData& data) {\n    std::cout << \"Writing Excel data rows...\" << std::endl;\n    for (const auto& row : data.getRows()) {\n        std::cout << \"| \";\n        for (const auto& header : data.getHeaders()) {\n            const auto& value = row.at(header);\n            std::visit([](const auto& v) { std::cout << v; }, value);\n            std::cout << \" | \";\n        }\n        std::cout << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/excel_report_exporter.h",
    "content": "#pragma once\n#include \"abstract_report_exporter.h\"\n\nclass ExcelReportExporter : public AbstractReportExporter {\nprotected:\n    void writeHeader(const ReportData& data) override;\n    void writeDataRows(const ReportData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/templatemethod/pdf_report_exporter.cpp",
    "content": "#include \"pdf_report_exporter.h\"\n#include <iostream>\n\nvoid PdfReportExporter::writeHeader(const ReportData& data) {\n    std::cout << \"Writing PDF header...\" << std::endl;\n    std::cout << \"=== Report Header ===\" << std::endl;\n    for (const auto& header : data.getHeaders()) {\n        std::cout << header << \"\\t\";\n    }\n    std::cout << std::endl;\n    std::cout << \"===================\" << std::endl;\n}\n\nvoid PdfReportExporter::writeDataRows(const ReportData& data) {\n    std::cout << \"Writing PDF data rows...\" << std::endl;\n    for (const auto& row : data.getRows()) {\n        for (const auto& header : data.getHeaders()) {\n            const auto& value = row.at(header);\n            std::visit([](const auto& v) { std::cout << v; }, value);\n            std::cout << \"\\t\";\n        }\n        std::cout << std::endl;\n    }\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/pdf_report_exporter.h",
    "content": "#pragma once\n#include \"abstract_report_exporter.h\"\n\nclass PdfReportExporter : public AbstractReportExporter {\nprotected:\n    void writeHeader(const ReportData& data) override;\n    void writeDataRows(const ReportData& data) override;\n}; "
  },
  {
    "path": "design-patterns/cpp/templatemethod/report_app.cpp",
    "content": "#include \"report_data.h\"\n#include \"csv_report_exporter.h\"\n#include \"pdf_report_exporter.h\"\n#include \"excel_report_exporter.h\"\n#include <iostream>\n\nint main() {\n    ReportData data;\n\n    // Export to CSV\n    std::cout << \"\\nExporting to CSV...\" << std::endl;\n    CsvReportExporter csvExporter;\n    csvExporter.exportReport(data, \"report.csv\");\n\n    // Export to PDF\n    std::cout << \"\\nExporting to PDF...\" << std::endl;\n    PdfReportExporter pdfExporter;\n    pdfExporter.exportReport(data, \"report.pdf\");\n\n    // Export to Excel\n    std::cout << \"\\nExporting to Excel...\" << std::endl;\n    ExcelReportExporter excelExporter;\n    excelExporter.exportReport(data, \"report.xlsx\");\n\n    return 0;\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/report_data.cpp",
    "content": "#include \"report_data.h\"\n\nstd::vector<std::string> ReportData::getHeaders() const {\n    return {\"ID\", \"Name\", \"Value\"};\n}\n\nstd::vector<std::map<std::string, std::variant<int, double, std::string>>> ReportData::getRows() const {\n    return {\n        {\n            {\"ID\", 1},\n            {\"Name\", \"Item A\"},\n            {\"Value\", 100.0}\n        },\n        {\n            {\"ID\", 2},\n            {\"Name\", \"Item B\"},\n            {\"Value\", 150.5}\n        },\n        {\n            {\"ID\", 3},\n            {\"Name\", \"Item C\"},\n            {\"Value\", 75.25}\n        }\n    };\n} "
  },
  {
    "path": "design-patterns/cpp/templatemethod/report_data.h",
    "content": "#pragma once\n#include <string>\n#include <vector>\n#include <map>\n#include <variant>\n\nclass ReportData {\npublic:\n    std::vector<std::string> getHeaders() const;\n    std::vector<std::map<std::string, std::variant<int, double, std::string>>> getRows() const;\n}; "
  },
  {
    "path": "design-patterns/csharp/adapter/CheckoutService.cs",
    "content": "using System;\n\nnamespace Adapter\n{\n    public class CheckoutService\n    {\n        private readonly IPaymentProcessor paymentProcessor;\n\n        public CheckoutService(IPaymentProcessor paymentProcessor)\n        {\n            this.paymentProcessor = paymentProcessor;\n        }\n\n        public bool Checkout(double amount, string currency)\n        {\n            Console.WriteLine($\"CheckoutService: Initiating checkout for {currency} {amount}\");\n            \n            paymentProcessor.ProcessPayment(amount, currency);\n            \n            if (paymentProcessor.IsPaymentSuccessful())\n            {\n                Console.WriteLine($\"CheckoutService: Payment successful. Transaction ID: {paymentProcessor.GetTransactionId()}\");\n                return true;\n            }\n            \n            Console.WriteLine(\"CheckoutService: Payment failed.\");\n            return false;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/adapter/IPaymentProcessor.cs",
    "content": "namespace Adapter\n{\n    public interface IPaymentProcessor\n    {\n        void ProcessPayment(double amount, string currency);\n        bool IsPaymentSuccessful();\n        string GetTransactionId();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/adapter/InHousePaymentProcessor.cs",
    "content": "using System;\n\nnamespace Adapter\n{\n    public class InHousePaymentProcessor : IPaymentProcessor\n    {\n        private string transactionId;\n        private bool isPaymentSuccessful;\n\n        public void ProcessPayment(double amount, string currency)\n        {\n            try\n            {\n                Console.WriteLine($\"InHousePaymentProcessor: Processing payment of {currency} {amount}\");\n                transactionId = Guid.NewGuid().ToString();\n                isPaymentSuccessful = true;\n                Console.WriteLine($\"InHousePaymentProcessor: Payment processed successfully. Txn ID: {transactionId}\");\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine($\"Error processing payment: {ex.Message}\");\n                isPaymentSuccessful = false;\n            }\n        }\n\n        public bool IsPaymentSuccessful()\n        {\n            return isPaymentSuccessful;\n        }\n\n        public string GetTransactionId()\n        {\n            return transactionId;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/adapter/LegacyGateway.cs",
    "content": "using System;\n\nnamespace Adapter\n{\n    public class LegacyGateway\n    {\n        private long transactionReference;\n        private bool isPaymentSuccessful;\n\n        public void ExecuteTransaction(double totalAmount, string currency)\n        {\n            Console.WriteLine($\"LegacyGateway: Executing transaction for {currency} {totalAmount}\");\n            transactionReference = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n            isPaymentSuccessful = true;\n            Console.WriteLine($\"LegacyGateway: Transaction executed successfully. Txn ID: {transactionReference}\");\n        }\n\n        public bool CheckStatus(long transactionReference)\n        {\n            Console.WriteLine($\"LegacyGateway: Checking status for ref: {transactionReference}\");\n            return isPaymentSuccessful;\n        }\n\n        public long GetReferenceNumber()\n        {\n            return transactionReference;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/adapter/LegacyGatewayAdapter.cs",
    "content": "using System;\n\nnamespace Adapter\n{\n    public class LegacyGatewayAdapter : IPaymentProcessor\n    {\n        private readonly LegacyGateway legacyGateway;\n        private bool isPaymentSuccessful;\n\n        public LegacyGatewayAdapter()\n        {\n            legacyGateway = new LegacyGateway();\n        }\n\n        public void ProcessPayment(double amount, string currency)\n        {\n            try\n            {\n                legacyGateway.ExecuteTransaction(amount, currency);\n                isPaymentSuccessful = true;\n            }\n            catch (Exception ex)\n            {\n                Console.WriteLine($\"Error processing payment: {ex.Message}\");\n                isPaymentSuccessful = false;\n            }\n        }\n\n        public bool IsPaymentSuccessful()\n        {\n            return isPaymentSuccessful && \n                   legacyGateway.CheckStatus(legacyGateway.GetReferenceNumber());\n        }\n\n        public string GetTransactionId()\n        {\n            return legacyGateway.GetReferenceNumber().ToString();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/adapter/Program.cs",
    "content": "using System;\n\nnamespace Adapter\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Example 1: Using the in-house payment processor\n            Console.WriteLine(\"=== Using In-House Payment Processor ===\");\n            var inHouseProcessor = new InHousePaymentProcessor();\n            var checkoutService1 = new CheckoutService(inHouseProcessor);\n            checkoutService1.Checkout(100.00, \"USD\");\n\n            Console.WriteLine(\"\\n=== Using Legacy Gateway Adapter ===\");\n            var legacyAdapter = new LegacyGatewayAdapter();\n            var checkoutService2 = new CheckoutService(legacyAdapter);\n            checkoutService2.Checkout(200.00, \"EUR\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/Circle.cs",
    "content": "namespace Bridge\n{\n    public class Circle : Shape\n    {\n        private readonly float radius;\n\n        public Circle(IRenderer renderer, float radius) : base(renderer)\n        {\n            this.radius = radius;\n        }\n\n        public override void Draw()\n        {\n            renderer.RenderCircle(radius);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/IRenderer.cs",
    "content": "namespace Bridge\n{\n    public interface IRenderer\n    {\n        void RenderCircle(float radius);\n        void RenderRectangle(float width, float height);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/Program.cs",
    "content": "using System;\n\nnamespace Bridge\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Create renderers\n            var vectorRenderer = new VectorRenderer();\n            var rasterRenderer = new RasterRenderer();\n\n            // Create shapes with vector renderer\n            Console.WriteLine(\"=== Drawing with Vector Renderer ===\");\n            var vectorCircle = new Circle(vectorRenderer, 5);\n            var vectorRectangle = new Rectangle(vectorRenderer, 10, 5);\n\n            vectorCircle.Draw();\n            vectorRectangle.Draw();\n\n            // Create shapes with raster renderer\n            Console.WriteLine(\"\\n=== Drawing with Raster Renderer ===\");\n            var rasterCircle = new Circle(rasterRenderer, 5);\n            var rasterRectangle = new Rectangle(rasterRenderer, 10, 5);\n\n            rasterCircle.Draw();\n            rasterRectangle.Draw();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/RasterRenderer.cs",
    "content": "using System;\n\nnamespace Bridge\n{\n    public class RasterRenderer : IRenderer\n    {\n        public void RenderCircle(float radius)\n        {\n            Console.WriteLine($\"Drawing a circle of radius {radius} using raster graphics\");\n        }\n\n        public void RenderRectangle(float width, float height)\n        {\n            Console.WriteLine($\"Drawing a rectangle of width {width} and height {height} using raster graphics\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/Rectangle.cs",
    "content": "namespace Bridge\n{\n    public class Rectangle : Shape\n    {\n        private readonly float width;\n        private readonly float height;\n\n        public Rectangle(IRenderer renderer, float width, float height) : base(renderer)\n        {\n            this.width = width;\n            this.height = height;\n        }\n\n        public override void Draw()\n        {\n            renderer.RenderRectangle(width, height);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/Shape.cs",
    "content": "namespace Bridge\n{\n    public abstract class Shape\n    {\n        protected readonly IRenderer renderer;\n\n        protected Shape(IRenderer renderer)\n        {\n            this.renderer = renderer;\n        }\n\n        public abstract void Draw();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/bridge/VectorRenderer.cs",
    "content": "using System;\n\nnamespace Bridge\n{\n    public class VectorRenderer : IRenderer\n    {\n        public void RenderCircle(float radius)\n        {\n            Console.WriteLine($\"Drawing a circle of radius {radius} using vector graphics\");\n        }\n\n        public void RenderRectangle(float width, float height)\n        {\n            Console.WriteLine($\"Drawing a rectangle of width {width} and height {height} using vector graphics\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/builder/HttpRequest.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Builder\n{\n    public class HttpRequest\n    {\n        public string Url { get; }         // Required\n        public string Method { get; }      // Optional, default GET\n        public IReadOnlyDictionary<string, string> Headers { get; } // Optional\n        public IReadOnlyDictionary<string, string> QueryParams { get; } // Optional\n        public string Body { get; }        // Optional\n        public int Timeout { get; }        // Optional, default 30s\n\n        // Private constructor, only accessible by the Builder\n        private HttpRequest(Builder builder)\n        {\n            Url = builder.Url;\n            Method = builder.Method;\n            Headers = new Dictionary<string, string>(builder.Headers); // Defensive copy\n            QueryParams = new Dictionary<string, string>(builder.QueryParams); // Defensive copy\n            Body = builder.Body;\n            Timeout = builder.Timeout;\n        }\n\n        public override string ToString()\n        {\n            return $\"HttpRequest{{\" +\n                   $\"url='{Url}', \" +\n                   $\"method='{Method}', \" +\n                   $\"headers={{{string.Join(\", \", Headers.Select(kv => $\"{kv.Key}={kv.Value}\"))}}}, \" +\n                   $\"queryParams={{{string.Join(\", \", QueryParams.Select(kv => $\"{kv.Key}={kv.Value}\"))}}}, \" +\n                   $\"body='{(Body != null ? (Body.Length > 10 ? Body.Substring(0, 10) + \"...\" : Body) : \"null\")}', \" +\n                   $\"timeout={Timeout}}}\";\n        }\n\n        // --- Builder Class ---\n        public class Builder\n        {\n            // Required parameter\n            public string Url { get; }\n\n            // Optional parameters - initialized to default values\n            public string Method { get; private set; } = \"GET\";\n            public Dictionary<string, string> Headers { get; } = new Dictionary<string, string>();\n            public Dictionary<string, string> QueryParams { get; } = new Dictionary<string, string>();\n            public string Body { get; private set; }\n            public int Timeout { get; private set; } = 30000; // 30 seconds default\n\n            // Builder constructor for required fields\n            public Builder(string url)\n            {\n                if (string.IsNullOrWhiteSpace(url))\n                {\n                    throw new ArgumentException(\"URL cannot be null or empty.\", nameof(url));\n                }\n                Url = url;\n            }\n\n            // Setter-like methods for optional fields, returning the Builder for fluency\n            public Builder WithMethod(string method)\n            {\n                Method = string.IsNullOrWhiteSpace(method) ? \"GET\" : method.ToUpper();\n                return this;\n            }\n\n            public Builder WithHeader(string key, string value)\n            {\n                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))\n                {\n                    Headers[key] = value;\n                }\n                return this;\n            }\n\n            public Builder WithQueryParam(string key, string value)\n            {\n                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))\n                {\n                    QueryParams[key] = value;\n                }\n                return this;\n            }\n\n            public Builder WithBody(string body)\n            {\n                Body = body;\n                return this;\n            }\n\n            public Builder WithTimeout(int timeoutMillis)\n            {\n                if (timeoutMillis > 0)\n                {\n                    Timeout = timeoutMillis;\n                }\n                return this;\n            }\n\n            // The final build method that creates the HttpRequest object\n            public HttpRequest Build()\n            {\n                // Optionally, add validation logic here before creating the object\n                if ((Method == \"POST\" || Method == \"PUT\") && string.IsNullOrEmpty(Body))\n                {\n                    Console.WriteLine($\"Warning: Building {Method} request without a body for URL: {Url}\");\n                }\n                return new HttpRequest(this);\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/builder/Program.cs",
    "content": "using System;\n\nnamespace Builder\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Example 1: Simple GET request\n            var getRequest = new HttpRequest.Builder(\"https://api.example.com/users\")\n                .WithHeader(\"Accept\", \"application/json\")\n                .WithQueryParam(\"page\", \"1\")\n                .WithQueryParam(\"limit\", \"10\")\n                .Build();\n\n            Console.WriteLine(\"=== GET Request ===\");\n            Console.WriteLine(getRequest);\n\n            // Example 2: POST request with body\n            var postRequest = new HttpRequest.Builder(\"https://api.example.com/users\")\n                .WithMethod(\"POST\")\n                .WithHeader(\"Content-Type\", \"application/json\")\n                .WithHeader(\"Authorization\", \"Bearer token123\")\n                .WithBody(\"{\\\"name\\\":\\\"John Doe\\\",\\\"email\\\":\\\"john@example.com\\\"}\")\n                .WithTimeout(5000)\n                .Build();\n\n            Console.WriteLine(\"\\n=== POST Request ===\");\n            Console.WriteLine(postRequest);\n\n            // Example 3: PUT request with validation warning\n            var putRequest = new HttpRequest.Builder(\"https://api.example.com/users/123\")\n                .WithMethod(\"PUT\")\n                .WithHeader(\"Content-Type\", \"application/json\")\n                .WithHeader(\"Authorization\", \"Bearer token123\")\n                .WithTimeout(10000)\n                .Build();\n\n            Console.WriteLine(\"\\n=== PUT Request (with warning) ===\");\n            Console.WriteLine(putRequest);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/AuthHandler.cs",
    "content": "using System;\n\nnamespace ChainOfResponsibility\n{\n    public class AuthHandler : BaseHandler\n    {\n        public override void Handle(Request request)\n        {\n            if (string.IsNullOrEmpty(request.User))\n            {\n                Console.WriteLine(\"AuthHandler: User is not authenticated\");\n                return;\n            }\n\n            Console.WriteLine($\"AuthHandler: User {request.User} is authenticated\");\n            HandleNext(request);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/AuthorizationHandler.cs",
    "content": "using System;\n\nnamespace ChainOfResponsibility\n{\n    public class AuthorizationHandler : BaseHandler\n    {\n        public override void Handle(Request request)\n        {\n            if (string.IsNullOrEmpty(request.UserRole) || request.UserRole != \"ADMIN\")\n            {\n                Console.WriteLine($\"AuthorizationHandler: User {request.User} is not authorized\");\n                return;\n            }\n\n            Console.WriteLine($\"AuthorizationHandler: User {request.User} is authorized\");\n            HandleNext(request);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/BaseHandler.cs",
    "content": "namespace ChainOfResponsibility\n{\n    public abstract class BaseHandler : IRequestHandler\n    {\n        protected IRequestHandler Next { get; private set; }\n\n        public void SetNext(IRequestHandler next)\n        {\n            Next = next;\n        }\n\n        public abstract void Handle(Request request);\n\n        protected void HandleNext(Request request)\n        {\n            if (Next != null)\n            {\n                Next.Handle(request);\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/BusinessLogicHandler.cs",
    "content": "using System;\n\nnamespace ChainOfResponsibility\n{\n    public class BusinessLogicHandler : BaseHandler\n    {\n        public override void Handle(Request request)\n        {\n            Console.WriteLine($\"BusinessLogicHandler: Processing request for user {request.User}\");\n            HandleNext(request);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/IRequestHandler.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/Program.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/RateLimitHandler.cs",
    "content": "using System;\n\nnamespace ChainOfResponsibility\n{\n    public class RateLimitHandler : BaseHandler\n    {\n        private const int MAX_REQUESTS = 5;\n\n        public override void Handle(Request request)\n        {\n            if (request.RequestCount > MAX_REQUESTS)\n            {\n                Console.WriteLine($\"RateLimitHandler: User {request.User} has exceeded the rate limit\");\n                return;\n            }\n\n            Console.WriteLine($\"RateLimitHandler: User {request.User} is within rate limit\");\n            HandleNext(request);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/Request.cs",
    "content": "namespace ChainOfResponsibility\n{\n    public class Request\n    {\n        public string User { get; }\n        public string UserRole { get; }\n        public int RequestCount { get; }\n        public string Payload { get; }\n\n        public Request(string user, string role, int requestCount, string payload)\n        {\n            User = user;\n            UserRole = role;\n            RequestCount = requestCount;\n            Payload = payload;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/chainofresponsibility/ValidationHandler.cs",
    "content": "using System;\n\nnamespace ChainOfResponsibility\n{\n    public class ValidationHandler : BaseHandler\n    {\n        public override void Handle(Request request)\n        {\n            if (string.IsNullOrEmpty(request.Payload))\n            {\n                Console.WriteLine(\"ValidationHandler: Request payload is empty\");\n                return;\n            }\n\n            Console.WriteLine(\"ValidationHandler: Request payload is valid\");\n            HandleNext(request);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/composite/File.cs",
    "content": "using System;\n\nnamespace Composite\n{\n    public class File : IFileSystemItem\n    {\n        private readonly string name;\n        private readonly int size;\n\n        public File(string name, int size)\n        {\n            this.name = name;\n            this.size = size;\n        }\n\n        public int GetSize()\n        {\n            return size;\n        }\n\n        public void PrintStructure(string indent)\n        {\n            Console.WriteLine($\"{indent}File: {name} ({size} bytes)\");\n        }\n\n        public void Delete()\n        {\n            Console.WriteLine($\"Deleting file: {name}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/composite/Folder.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Composite\n{\n    public class Folder : IFileSystemItem\n    {\n        private readonly string name;\n        private readonly List<IFileSystemItem> children;\n\n        public Folder(string name)\n        {\n            this.name = name;\n            this.children = new List<IFileSystemItem>();\n        }\n\n        public void Add(IFileSystemItem item)\n        {\n            children.Add(item);\n        }\n\n        public void Remove(IFileSystemItem item)\n        {\n            children.Remove(item);\n        }\n\n        public int GetSize()\n        {\n            int totalSize = 0;\n            foreach (var child in children)\n            {\n                totalSize += child.GetSize();\n            }\n            return totalSize;\n        }\n\n        public void PrintStructure(string indent)\n        {\n            Console.WriteLine($\"{indent}Folder: {name}\");\n            foreach (var child in children)\n            {\n                child.PrintStructure(indent + \"  \");\n            }\n        }\n\n        public void Delete()\n        {\n            Console.WriteLine($\"Deleting folder: {name}\");\n            foreach (var child in children)\n            {\n                child.Delete();\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/composite/IFileSystemItem.cs",
    "content": "namespace Composite\n{\n    public interface IFileSystemItem\n    {\n        int GetSize();\n        void PrintStructure(string indent);\n        void Delete();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/composite/Program.cs",
    "content": "using System;\n\nnamespace Composite\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Create a file system structure\n            var root = new Folder(\"Root\");\n            \n            var documents = new Folder(\"Documents\");\n            var downloads = new Folder(\"Downloads\");\n            var pictures = new Folder(\"Pictures\");\n\n            var file1 = new File(\"readme.txt\", 1024);\n            var file2 = new File(\"document.pdf\", 2048);\n            var file3 = new File(\"image.jpg\", 4096);\n            var file4 = new File(\"video.mp4\", 8192);\n\n            // Build the structure\n            root.Add(documents);\n            root.Add(downloads);\n            root.Add(pictures);\n\n            documents.Add(file1);\n            documents.Add(file2);\n            downloads.Add(file3);\n            pictures.Add(file4);\n\n            // Print the structure\n            Console.WriteLine(\"=== File System Structure ===\");\n            root.PrintStructure(\"\");\n\n            // Get total size\n            Console.WriteLine($\"\\nTotal size: {root.GetSize()} bytes\");\n\n            // Delete a folder\n            Console.WriteLine(\"\\n=== Deleting Documents Folder ===\");\n            documents.Delete();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/BoldDecorator.cs",
    "content": "using System;\n\nnamespace Decorator\n{\n    public class BoldDecorator : TextDecorator\n    {\n        public BoldDecorator(ITextView inner) : base(inner)\n        {\n        }\n\n        public override void Render()\n        {\n            Console.Write(\"<b>\");\n            inner.Render();\n            Console.Write(\"</b>\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/ITextView.cs",
    "content": "namespace Decorator\n{\n    public interface ITextView\n    {\n        void Render();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/ItalicDecorator.cs",
    "content": "using System;\n\nnamespace Decorator\n{\n    public class ItalicDecorator : TextDecorator\n    {\n        public ItalicDecorator(ITextView inner) : base(inner)\n        {\n        }\n\n        public override void Render()\n        {\n            Console.Write(\"<i>\");\n            inner.Render();\n            Console.Write(\"</i>\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/PlainTextView.cs",
    "content": "using System;\n\nnamespace Decorator\n{\n    public class PlainTextView : ITextView\n    {\n        private readonly string text;\n\n        public PlainTextView(string text)\n        {\n            this.text = text;\n        }\n\n        public void Render()\n        {\n            Console.Write(text);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/Program.cs",
    "content": "using System;\n\nnamespace Decorator\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            ITextView plain = new PlainTextView(\"Hello, world!\");\n\n            Console.Write(\"Plain: \");\n            plain.Render();\n            Console.WriteLine();\n\n            Console.Write(\"Bold: \");\n            ITextView bold = new BoldDecorator(plain);\n            bold.Render();\n            Console.WriteLine();\n\n            Console.Write(\"Italic + Bold: \");\n            ITextView italicBold = new ItalicDecorator(bold);\n            italicBold.Render();\n            Console.WriteLine();\n\n            Console.Write(\"Underline + Italic + Bold: \");\n            ITextView fullStyle = new UnderlineDecorator(italicBold);\n            fullStyle.Render();\n            Console.WriteLine();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/TextDecorator.cs",
    "content": "namespace Decorator\n{\n    public abstract class TextDecorator : ITextView\n    {\n        protected readonly ITextView inner;\n\n        public TextDecorator(ITextView inner)\n        {\n            this.inner = inner;\n        }\n\n        public abstract void Render();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/decorator/UnderlineDecorator.cs",
    "content": "using System;\n\nnamespace Decorator\n{\n    public class UnderlineDecorator : TextDecorator\n    {\n        public UnderlineDecorator(ITextView inner) : base(inner)\n        {\n        }\n\n        public override void Render()\n        {\n            Console.Write(\"<u>\");\n            inner.Render();\n            Console.Write(\"</u>\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/BuildSystem.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace Facade\n{\n    public class BuildSystem\n    {\n        public bool CompileProject()\n        {\n            Console.WriteLine(\"BuildSystem: Compiling project...\");\n            SimulateDelay(2000);\n            Console.WriteLine(\"BuildSystem: Build successful.\");\n            return true;\n        }\n\n        public string GetArtifactPath()\n        {\n            string path = \"target/myapplication-1.0.jar\";\n            Console.WriteLine($\"BuildSystem: Artifact located at {path}\");\n            return path;\n        }\n        \n        private void SimulateDelay(int ms)\n        {\n            Thread.Sleep(ms);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/DeploymentFacade.cs",
    "content": "using System;\n\nnamespace Facade\n{\n    public class DeploymentFacade\n    {\n        private readonly VersionControlSystem vcs;\n        private readonly BuildSystem buildSystem;\n        private readonly TestingFramework testingFramework;\n        private readonly DeploymentTarget deploymentTarget;\n\n        public DeploymentFacade()\n        {\n            vcs = new VersionControlSystem();\n            buildSystem = new BuildSystem();\n            testingFramework = new TestingFramework();\n            deploymentTarget = new DeploymentTarget();\n        }\n\n        public bool DeployApplication(string branch, string serverAddress)\n        {\n            Console.WriteLine($\"\\nFACADE: --- Initiating FULL DEPLOYMENT for branch: {branch} to {serverAddress} ---\");\n            bool success = true;\n\n            try\n            {\n                // Step 1: Pull latest code\n                vcs.PullLatestChanges(branch);\n\n                // Step 2: Build the project\n                if (!buildSystem.CompileProject())\n                {\n                    Console.Error.WriteLine(\"FACADE: DEPLOYMENT FAILED - Build compilation failed.\");\n                    return false;\n                }\n                string artifactPath = buildSystem.GetArtifactPath();\n\n                // Step 3: Run tests\n                if (!testingFramework.RunUnitTests())\n                {\n                    Console.Error.WriteLine(\"FACADE: DEPLOYMENT FAILED - Unit tests failed.\");\n                    return false;\n                }\n                if (!testingFramework.RunIntegrationTests())\n                {\n                    Console.Error.WriteLine(\"FACADE: DEPLOYMENT FAILED - Integration tests failed.\");\n                    return false;\n                }\n\n                // Step 4: Deploy to production\n                deploymentTarget.TransferArtifact(artifactPath, serverAddress);\n                deploymentTarget.ActivateNewVersion(serverAddress);\n\n                Console.WriteLine($\"FACADE: APPLICATION DEPLOYED SUCCESSFULLY TO {serverAddress}!\");\n            }\n            catch (Exception e)\n            {\n                Console.Error.WriteLine($\"FACADE: DEPLOYMENT FAILED - An unexpected error occurred: {e.Message}\");\n                success = false;\n            }\n            return success;\n        }\n\n        public bool DeployHotfix(string branch, string serverAddress)\n        {\n            Console.WriteLine($\"\\nFACADE: --- Initiating HOTFIX DEPLOYMENT for branch: {branch} to {serverAddress} ---\");\n            bool success = true;\n\n            try\n            {\n                // Step 1: Pull latest code\n                vcs.PullLatestChanges(branch);\n\n                // Step 2: Build the project\n                if (!buildSystem.CompileProject())\n                {\n                    Console.Error.WriteLine(\"FACADE: HOTFIX FAILED - Build compilation failed.\");\n                    return false;\n                }\n                string artifactPath = buildSystem.GetArtifactPath();\n\n                // Step 3: For a hotfix, we might skip extensive tests or run a specific \"smoke test\" suite.\n                Console.WriteLine(\"FACADE: Skipping full test suite for hotfix deployment (or running minimal smoke tests).\");\n\n                // Step 4: Deploy to production\n                deploymentTarget.TransferArtifact(artifactPath, serverAddress);\n                deploymentTarget.ActivateNewVersion(serverAddress);\n\n                Console.WriteLine($\"FACADE: HOTFIX DEPLOYED SUCCESSFULLY TO {serverAddress}!\");\n            }\n            catch (Exception e)\n            {\n                Console.Error.WriteLine($\"FACADE: HOTFIX FAILED - An unexpected error occurred: {e.Message}\");\n                success = false;\n            }\n            return success;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/DeploymentTarget.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace Facade\n{\n    public class DeploymentTarget\n    {\n        public void TransferArtifact(string artifactPath, string server)\n        {\n            Console.WriteLine($\"Deployment: Transferring {artifactPath} to {server}...\");\n            SimulateDelay(1000);\n            Console.WriteLine(\"Deployment: Transfer complete.\");\n        }\n\n        public void ActivateNewVersion(string server)\n        {\n            Console.WriteLine($\"Deployment: Activating new version on {server}...\");\n            SimulateDelay(500);\n            Console.WriteLine($\"Deployment: Now live on {server}!\");\n        }\n\n        private void SimulateDelay(int ms)\n        {\n            Thread.Sleep(ms);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/Program.cs",
    "content": "using System;\n\nnamespace Facade\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var deploymentFacade = new DeploymentFacade();\n\n            // Demonstrate full deployment\n            Console.WriteLine(\"=== Full Deployment Example ===\");\n            deploymentFacade.DeployApplication(\"main\", \"production-server\");\n\n            // Demonstrate hotfix deployment\n            Console.WriteLine(\"\\n=== Hotfix Deployment Example ===\");\n            deploymentFacade.DeployHotfix(\"hotfix/security-patch\", \"production-server\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/TestingFramework.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace Facade\n{\n    public class TestingFramework\n    {\n        public bool RunUnitTests()\n        {\n            Console.WriteLine(\"Testing: Running unit tests...\");\n            SimulateDelay(1500);\n            Console.WriteLine(\"Testing: Unit tests passed.\");\n            return true;\n        }\n\n        public bool RunIntegrationTests()\n        {\n            Console.WriteLine(\"Testing: Running integration tests...\");\n            SimulateDelay(3000);\n            Console.WriteLine(\"Testing: Integration tests passed.\");\n            return true;\n        }\n\n        private void SimulateDelay(int ms)\n        {\n            Thread.Sleep(ms);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/facade/VersionControlSystem.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/factory/EmailNotification.cs",
    "content": "using System;\n\nnamespace Factory\n{\n    public class EmailNotification : INotification\n    {\n        public void Send(string message)\n        {\n            Console.WriteLine($\"Sending email: {message}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/INotification.cs",
    "content": "namespace Factory\n{\n    public interface INotification\n    {\n        void Send(string message);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/NotificationServiceNaive.cs",
    "content": "using System;\n\nnamespace Factory\n{\n    public class NotificationServiceNaive\n    {\n        public void SendNotification(string type, string message)\n        {\n            if (type == \"EMAIL\")\n            {\n                var email = new EmailNotification();\n                email.Send(message);\n            }\n            else if (type == \"SMS\")\n            {\n                var sms = new SMSNotification();\n                sms.Send(message);\n            }\n            else if (type == \"PUSH\")\n            {\n                var push = new PushNotification();\n                push.Send(message);\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/Program.cs",
    "content": "using System;\n\nnamespace Factory\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            // Using the factory\n            Console.WriteLine(\"=== Using Factory Pattern ===\");\n            var emailNotification = SimpleNotificationFactory.CreateNotification(\"EMAIL\");\n            emailNotification.Send(\"Hello via Email!\");\n\n            var smsNotification = SimpleNotificationFactory.CreateNotification(\"SMS\");\n            smsNotification.Send(\"Hello via SMS!\");\n\n            var pushNotification = SimpleNotificationFactory.CreateNotification(\"PUSH\");\n            pushNotification.Send(\"Hello via Push!\");\n\n            // Using the naive approach\n            Console.WriteLine(\"\\n=== Using Naive Approach ===\");\n            var notificationService = new NotificationServiceNaive();\n            notificationService.SendNotification(\"EMAIL\", \"Hello via Email!\");\n            notificationService.SendNotification(\"SMS\", \"Hello via SMS!\");\n            notificationService.SendNotification(\"PUSH\", \"Hello via Push!\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/PushNotification.cs",
    "content": "using System;\n\nnamespace Factory\n{\n    public class PushNotification : INotification\n    {\n        public void Send(string message)\n        {\n            Console.WriteLine($\"Sending push notification: {message}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/SMSNotification.cs",
    "content": "using System;\n\nnamespace Factory\n{\n    public class SMSNotification : INotification\n    {\n        public void Send(string message)\n        {\n            Console.WriteLine($\"Sending SMS: {message}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/factory/SimpleNotificationFactory.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/flyweight/CharacterFlyweightFactory.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Flyweight\n{\n    public class CharacterFlyweightFactory\n    {\n        private static readonly Dictionary<string, ICharacterFlyweight> flyweightCache = new();\n\n        public static ICharacterFlyweight GetFlyweight(char symbol, string fontFamily, int fontSize, string color)\n        {\n            string key = $\"{symbol}-{fontSize}-{color}\";\n            if (!flyweightCache.ContainsKey(key))\n            {\n                flyweightCache[key] = new CharacterGlyph(symbol, fontFamily, fontSize, color);\n            }\n            return flyweightCache[key];\n        }\n\n        public int GetFlyweightCount()\n        {\n            return flyweightCache.Count;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/flyweight/CharacterGlyph.cs",
    "content": "using System;\n\nnamespace Flyweight\n{\n    public class CharacterGlyph : ICharacterFlyweight\n    {\n        private readonly char symbol;\n        private readonly string fontFamily;\n        private readonly int fontSize;\n        private readonly string color;\n\n        public CharacterGlyph(char symbol, string fontFamily, int fontSize, string color)\n        {\n            this.symbol = symbol;\n            this.fontFamily = fontFamily;\n            this.fontSize = fontSize;\n            this.color = color;\n        }\n\n        public void Draw(int x, int y)\n        {\n            Console.WriteLine($\"Rendering {symbol} at ({x}, {y}) with font {fontFamily}, size {fontSize}, color {color}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/flyweight/ICharacterFlyweight.cs",
    "content": "namespace Flyweight\n{\n    public interface ICharacterFlyweight\n    {\n        void Draw(int x, int y);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/flyweight/Program.cs",
    "content": "using System;\n\nnamespace Flyweight\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var editor = new TextEditorClient();\n\n            // Render 'Hello' with the same style\n            string word = \"Hello\";\n            for (int i = 0; i < word.Length; i++)\n            {\n                editor.AddCharacter(word[i], 10 + i * 15, 50, \"Arial\", 14, \"#000000\");\n            }\n\n            // Render 'World' with a different font and color\n            string word2 = \"World\";\n            for (int i = 0; i < word2.Length; i++)\n            {\n                editor.AddCharacter(word2[i], 10 + i * 15, 100, \"Times New Roman\", 14, \"#3333FF\");\n            }\n\n            editor.RenderDocument();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/flyweight/TextEditorClient.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Flyweight\n{\n    public class TextEditorClient\n    {\n        private readonly CharacterFlyweightFactory factory = new();\n        private readonly List<RenderedCharacter> document = new();\n\n        public void AddCharacter(char c, int x, int y, string font, int size, string color)\n        {\n            ICharacterFlyweight glyph = CharacterFlyweightFactory.GetFlyweight(c, font, size, color);\n            document.Add(new RenderedCharacter(glyph, x, y));\n        }\n\n        public void RenderDocument()\n        {\n            foreach (var rc in document)\n            {\n                rc.Draw();\n            }\n            Console.WriteLine($\"Total flyweight objects used: {factory.GetFlyweightCount()}\");\n        }\n\n        private class RenderedCharacter\n        {\n            private readonly ICharacterFlyweight glyph;\n            private readonly int x, y;\n\n            public RenderedCharacter(ICharacterFlyweight glyph, int x, int y)\n            {\n                this.glyph = glyph;\n                this.x = x;\n                this.y = y;\n            }\n\n            public void Draw()\n            {\n                glyph.Draw(x, y);\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/iterator/IIterableCollection.cs",
    "content": "namespace Iterator\n{\n    public interface IIterableCollection<T>\n    {\n        IIterator<T> CreateIterator();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/iterator/IIterator.cs",
    "content": "namespace Iterator\n{\n    public interface IIterator<T>\n    {\n        bool HasNext();\n        T Next();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/iterator/Playlist.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/iterator/PlaylistIterator.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/iterator/Program.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/mediator/Button.cs",
    "content": "using System;\n\nnamespace Mediator\n{\n    public class Button : UIComponent\n    {\n        private bool enabled = false;\n\n        public Button(IUIMediator mediator) : base(mediator)\n        {\n        }\n\n        public void Click()\n        {\n            if (enabled)\n            {\n                Console.WriteLine(\"Login Button clicked!\");\n                NotifyMediator(); // Will trigger login attempt\n            }\n            else\n            {\n                Console.WriteLine(\"Login Button is disabled.\");\n            }\n        }\n\n        public void SetEnabled(bool value)\n        {\n            this.enabled = value;\n            Console.WriteLine($\"Login Button is now {(enabled ? \"ENABLED\" : \"DISABLED\")}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/FormMediator.cs",
    "content": "namespace Mediator\n{\n    public class FormMediator : IUIMediator\n    {\n        private TextField usernameField;\n        private TextField passwordField;\n        private Button loginButton;\n        private Label statusLabel;\n\n        public void SetUsernameField(TextField usernameField)\n        {\n            this.usernameField = usernameField;\n        }\n\n        public void SetPasswordField(TextField passwordField)\n        {\n            this.passwordField = passwordField;\n        }\n\n        public void SetLoginButton(Button loginButton)\n        {\n            this.loginButton = loginButton;\n        }\n\n        public void SetStatusLabel(Label statusLabel)\n        {\n            this.statusLabel = statusLabel;\n        }\n\n        public void ComponentChanged(UIComponent component)\n        {\n            if (component == usernameField || component == passwordField)\n            {\n                bool enableButton = !string.IsNullOrEmpty(usernameField.GetText()) && \n                                  !string.IsNullOrEmpty(passwordField.GetText());\n                loginButton.SetEnabled(enableButton);\n            }\n            else if (component == loginButton)\n            {\n                string username = usernameField.GetText();\n                string password = passwordField.GetText();\n\n                if (username == \"admin\" && password == \"1234\")\n                {\n                    statusLabel.SetText(\"✅ Login successful!\");\n                }\n                else\n                {\n                    statusLabel.SetText(\"❌ Invalid credentials.\");\n                }\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/IUIMediator.cs",
    "content": "namespace Mediator\n{\n    public interface IUIMediator\n    {\n        void ComponentChanged(UIComponent component);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/Label.cs",
    "content": "using System;\n\nnamespace Mediator\n{\n    public class Label : UIComponent\n    {\n        private string text;\n\n        public Label(IUIMediator mediator) : base(mediator)\n        {\n        }\n\n        public void SetText(string message)\n        {\n            this.text = message;\n            Console.WriteLine($\"Status: {text}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/Program.cs",
    "content": "using System;\n\nnamespace Mediator\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var mediator = new FormMediator();\n\n            var usernameField = new TextField(mediator);\n            var passwordField = new TextField(mediator);\n            var loginButton = new Button(mediator);\n            var statusLabel = new Label(mediator);\n\n            mediator.SetUsernameField(usernameField);\n            mediator.SetPasswordField(passwordField);\n            mediator.SetLoginButton(loginButton);\n            mediator.SetStatusLabel(statusLabel);\n\n            // Simulate user interaction\n            usernameField.SetText(\"admin\");\n            passwordField.SetText(\"1234\");\n            loginButton.Click();  // Should succeed\n\n            Console.WriteLine(\"\\n--- New Attempt with Wrong Password ---\");\n            passwordField.SetText(\"wrong\");\n            loginButton.Click();  // Should fail\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/TextField.cs",
    "content": "using System;\n\nnamespace Mediator\n{\n    public class TextField : UIComponent\n    {\n        private string text = \"\";\n\n        public TextField(IUIMediator mediator) : base(mediator)\n        {\n        }\n\n        public void SetText(string newText)\n        {\n            this.text = newText;\n            Console.WriteLine($\"TextField updated: {newText}\");\n            NotifyMediator();\n        }\n\n        public string GetText()\n        {\n            return text;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/mediator/UIComponent.cs",
    "content": "namespace Mediator\n{\n    public abstract class UIComponent\n    {\n        protected readonly IUIMediator mediator;\n\n        public UIComponent(IUIMediator mediator)\n        {\n            this.mediator = mediator;\n        }\n\n        public void NotifyMediator()\n        {\n            mediator.ComponentChanged(this);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/memento/Program.cs",
    "content": "using System;\n\nnamespace Memento\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var editor = new TextEditor();\n            var undoManager = new TextEditorUndoManager();\n\n            // Type some text and save state\n            editor.Type(\"Hello\");\n            undoManager.Save(editor);\n\n            editor.Type(\" World\");\n            undoManager.Save(editor);\n\n            editor.Type(\"!\");\n            Console.WriteLine($\"Current content: {editor.GetContent()}\");\n\n            // Undo twice\n            Console.WriteLine(\"\\nUndoing last change:\");\n            undoManager.Undo(editor);\n            Console.WriteLine($\"Content after undo: {editor.GetContent()}\");\n\n            Console.WriteLine(\"\\nUndoing another change:\");\n            undoManager.Undo(editor);\n            Console.WriteLine($\"Content after second undo: {editor.GetContent()}\");\n\n            // Try to undo when nothing is left\n            Console.WriteLine(\"\\nTrying to undo when nothing is left:\");\n            undoManager.Undo(editor);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/memento/TextEditor.cs",
    "content": "using System;\n\nnamespace Memento\n{\n    public class TextEditor\n    {\n        private string content = \"\";\n\n        public void Type(string newText)\n        {\n            content += newText;\n            Console.WriteLine($\"Typed: {newText}\");\n        }\n\n        public string GetContent()\n        {\n            return content;\n        }\n\n        public TextEditorMemento Save()\n        {\n            Console.WriteLine($\"Saving state: \\\"{content}\\\"\");\n            return new TextEditorMemento(content);\n        }\n\n        public void Restore(TextEditorMemento memento)\n        {\n            content = memento.GetState();\n            Console.WriteLine($\"Restored state to: \\\"{content}\\\"\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/memento/TextEditorMemento.cs",
    "content": "namespace Memento\n{\n    public class TextEditorMemento\n    {\n        private readonly string state;\n\n        public TextEditorMemento(string state)\n        {\n            this.state = state;\n        }\n\n        public string GetState()\n        {\n            return state;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/memento/TextEditorUndoManager.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Memento\n{\n    public class TextEditorUndoManager\n    {\n        private readonly Stack<TextEditorMemento> history = new Stack<TextEditorMemento>();\n\n        public void Save(TextEditor editor)\n        {\n            history.Push(editor.Save());\n        }\n\n        public void Undo(TextEditor editor)\n        {\n            if (history.Count > 0)\n            {\n                editor.Restore(history.Pop());\n            }\n            else\n            {\n                Console.WriteLine(\"Nothing to undo.\");\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/FitnessData.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Observer\n{\n    public class FitnessData : IFitnessDataSubject\n    {\n        private int steps;\n        private int activeMinutes;\n        private int calories;\n\n        private readonly List<IFitnessDataObserver> observers = new List<IFitnessDataObserver>();\n\n        public void RegisterObserver(IFitnessDataObserver observer)\n        {\n            observers.Add(observer);\n        }\n\n        public void RemoveObserver(IFitnessDataObserver observer)\n        {\n            observers.Remove(observer);\n        }\n\n        public void NotifyObservers()\n        {\n            foreach (var observer in observers)\n            {\n                observer.Update(this);\n            }\n        }\n\n        public void NewFitnessDataPushed(int steps, int activeMinutes, int calories)\n        {\n            this.steps = steps;\n            this.activeMinutes = activeMinutes;\n            this.calories = calories;\n\n            Console.WriteLine($\"\\nFitnessData: New data received — Steps: {steps}, \" +\n                            $\"Active Minutes: {activeMinutes}, Calories: {calories}\");\n            NotifyObservers();\n        }\n\n        public void DailyReset()\n        {\n            this.steps = 0;\n            this.activeMinutes = 0;\n            this.calories = 0;\n            Console.WriteLine(\"\\nFitnessData: Daily reset performed.\");\n            NotifyObservers();\n        }\n\n        // Properties\n        public int Steps => steps;\n        public int ActiveMinutes => activeMinutes;\n        public int Calories => calories;\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/GoalNotifier.cs",
    "content": "using System;\n\nnamespace Observer\n{\n    public class GoalNotifier : IFitnessDataObserver\n    {\n        private const int STEPS_GOAL = 10000;\n        private const int ACTIVE_MINUTES_GOAL = 30;\n        private const int CALORIES_GOAL = 500;\n\n        public void Update(FitnessData data)\n        {\n            if (data.Steps >= STEPS_GOAL)\n            {\n                Console.WriteLine($\"GoalNotifier: Congratulations! You've reached your daily steps goal of {STEPS_GOAL} steps!\");\n            }\n\n            if (data.ActiveMinutes >= ACTIVE_MINUTES_GOAL)\n            {\n                Console.WriteLine($\"GoalNotifier: Great job! You've achieved your active minutes goal of {ACTIVE_MINUTES_GOAL} minutes!\");\n            }\n\n            if (data.Calories >= CALORIES_GOAL)\n            {\n                Console.WriteLine($\"GoalNotifier: Amazing! You've burned {CALORIES_GOAL} calories today!\");\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/IFitnessDataObserver.cs",
    "content": "namespace Observer\n{\n    public interface IFitnessDataObserver\n    {\n        void Update(FitnessData data);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/IFitnessDataSubject.cs",
    "content": "namespace Observer\n{\n    public interface IFitnessDataSubject\n    {\n        void RegisterObserver(IFitnessDataObserver observer);\n        void RemoveObserver(IFitnessDataObserver observer);\n        void NotifyObservers();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/LiveActivityDisplay.cs",
    "content": "using System;\n\nnamespace Observer\n{\n    public class LiveActivityDisplay : IFitnessDataObserver\n    {\n        public void Update(FitnessData data)\n        {\n            Console.WriteLine($\"LiveActivityDisplay: Steps: {data.Steps}, \" +\n                            $\"Active Minutes: {data.ActiveMinutes}, \" +\n                            $\"Calories: {data.Calories}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/observer/Program.cs",
    "content": " "
  },
  {
    "path": "design-patterns/csharp/observer/ProgressLogger.cs",
    "content": "using System;\n\nnamespace Observer\n{\n    public class ProgressLogger : IFitnessDataObserver\n    {\n        public void Update(FitnessData data)\n        {\n            Console.WriteLine($\"ProgressLogger: Logging progress — \" +\n                            $\"Steps: {data.Steps}, \" +\n                            $\"Active Minutes: {data.ActiveMinutes}, \" +\n                            $\"Calories: {data.Calories}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/prototype/Enemy.cs",
    "content": "using System;\n\nnamespace Prototype\n{\n    public class Enemy : IEnemyPrototype\n    {\n        private string type;\n        private int health;\n        private double speed;\n        private bool armored;\n        private string weapon;\n\n        public Enemy(string type, int health, double speed, bool armored, string weapon)\n        {\n            this.type = type;\n            this.health = health;\n            this.speed = speed;\n            this.armored = armored;\n            this.weapon = weapon;\n        }\n\n        public IEnemyPrototype Clone()\n        {\n            return new Enemy(type, health, speed, armored, weapon);\n        }\n\n        public void SetHealth(int health)\n        {\n            this.health = health;\n        }\n\n        public void PrintStats()\n        {\n            Console.WriteLine($\"{type} [Health: {health}, Speed: {speed}, Armored: {armored}, Weapon: {weapon}]\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/prototype/EnemyRegistry.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace Prototype\n{\n    public class EnemyRegistry\n    {\n        private readonly Dictionary<string, Enemy> prototypes = new Dictionary<string, Enemy>();\n\n        public void Register(string key, Enemy prototype)\n        {\n            prototypes[key] = prototype;\n        }\n\n        public Enemy Get(string key)\n        {\n            if (prototypes.TryGetValue(key, out var prototype))\n            {\n                return (Enemy)prototype.Clone();\n            }\n            throw new ArgumentException($\"No prototype registered for: {key}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/prototype/Game.cs",
    "content": "using System;\n\nnamespace Prototype\n{\n    class Game\n    {\n        static void Main(string[] args)\n        {\n            var registry = new EnemyRegistry();\n\n            // Register prototype enemies\n            registry.Register(\"flying\", new Enemy(\"FlyingEnemy\", 100, 12.0, false, \"Laser\"));\n            registry.Register(\"armored\", new Enemy(\"ArmoredEnemy\", 300, 6.0, true, \"Cannon\"));\n\n            // Clone from registry\n            Enemy e1 = registry.Get(\"flying\");\n            Enemy e2 = registry.Get(\"flying\");\n            e2.SetHealth(80); // this one is damaged\n\n            Enemy e3 = registry.Get(\"armored\");\n\n            // Print enemy stats\n            e1.PrintStats();\n            e2.PrintStats();\n            e3.PrintStats();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/prototype/IEnemyPrototype.cs",
    "content": "namespace Prototype\n{\n    public interface IEnemyPrototype\n    {\n        IEnemyPrototype Clone();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/proxy/HighResolutionImage.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace Proxy\n{\n    public class HighResolutionImage : IImage\n    {\n        private string fileName;\n        private byte[] imageData; // Simulate large data\n\n        public HighResolutionImage(string fileName)\n        {\n            this.fileName = fileName;\n            LoadImageFromDisk(); // Expensive operation!\n        }\n\n        private void LoadImageFromDisk()\n        {\n            Console.WriteLine($\"Loading image: {fileName} from disk (Expensive Operation)...\");\n            // Simulate disk read and memory allocation\n            Thread.Sleep(2000); // Simulate delay\n            this.imageData = new byte[10 * 1024 * 1024]; // 10MB\n            Console.WriteLine($\"Image {fileName} loaded successfully.\");\n        }\n\n        public void Display()\n        {\n            Console.WriteLine($\"Displaying image: {fileName}\");\n            // Actual rendering logic would go here\n        }\n\n        public string GetFileName()\n        {\n            return fileName;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/proxy/IImage.cs",
    "content": "namespace Proxy\n{\n    public interface IImage\n    {\n        void Display();\n        string GetFileName();\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/proxy/ImageGalleryApp.cs",
    "content": "using System;\n\nnamespace Proxy\n{\n    class ImageGalleryApp\n    {\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"Application Started. Initializing image proxies for gallery...\");\n\n            // Create lightweight proxies instead of full image objects\n            IImage image1 = new ImageProxy(\"photo1.jpg\");\n            IImage image2 = new ImageProxy(\"photo2.png\"); // Never displayed\n            IImage image3 = new ImageProxy(\"photo3.gif\");\n\n            Console.WriteLine(\"\\nGallery initialized. No images actually loaded yet.\");\n            Console.WriteLine($\"Image 1 Filename: {image1.GetFileName()}\"); // Does not trigger image load\n\n            // User clicks on image1\n            Console.WriteLine($\"\\nUser requests to display {image1.GetFileName()}\");\n            image1.Display(); // Lazy loading happens here\n\n            // User clicks on image1 again\n            Console.WriteLine($\"\\nUser requests to display {image1.GetFileName()} again.\");\n            image1.Display(); // Already loaded; no loading delay\n\n            // User clicks on image3\n            Console.WriteLine($\"\\nUser requests to display {image3.GetFileName()}\");\n            image3.Display(); // Triggers loading for image3\n\n            Console.WriteLine(\"\\nApplication finished. Note: photo2.png was never loaded.\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/proxy/ImageProxy.cs",
    "content": "using System;\n\nnamespace Proxy\n{\n    public class ImageProxy : IImage\n    {\n        private string fileName;\n        private HighResolutionImage realImage; // RealSubject\n\n        public ImageProxy(string fileName)\n        {\n            this.fileName = fileName;\n            Console.WriteLine($\"ImageProxy: Created for {fileName}. Real image not loaded yet.\");\n        }\n\n        public string GetFileName()\n        {\n            // Can safely return without loading the image\n            return fileName;\n        }\n\n        public void Display()\n        {\n            // Lazy initialization: Load only when Display() is called\n            if (realImage == null)\n            {\n                Console.WriteLine($\"ImageProxy: Display() requested for {fileName}. Loading high-resolution image...\");\n                realImage = new HighResolutionImage(fileName);\n            }\n            else\n            {\n                Console.WriteLine($\"ImageProxy: Using cached high-resolution image for {fileName}\");\n            }\n\n            // Delegate the display call to the real image\n            realImage.Display();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/BillPughSingleton.cs",
    "content": "namespace Singleton\n{\n    public class BillPughSingleton\n    {\n        private BillPughSingleton() { }\n        public static BillPughSingleton GetInstance()\n        {\n            return Nested.instance;\n        }\n        private class Nested\n        {\n            internal static readonly BillPughSingleton instance = new BillPughSingleton();\n            static Nested() { }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/DoubleCheckedLockingSingleton.cs",
    "content": "namespace Singleton\n{\n    public class DoubleCheckedLockingSingleton\n    {\n        private static volatile DoubleCheckedLockingSingleton instance;\n        private static readonly object lockObj = new object();\n        private DoubleCheckedLockingSingleton() { }\n        public static DoubleCheckedLockingSingleton GetInstance()\n        {\n            if (instance == null)\n            {\n                lock (lockObj)\n                {\n                    if (instance == null)\n                    {\n                        instance = new DoubleCheckedLockingSingleton();\n                    }\n                }\n            }\n            return instance;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/EagerSingleton.cs",
    "content": "namespace Singleton\n{\n    public class EagerSingleton\n    {\n        private static readonly EagerSingleton instance = new EagerSingleton();\n        private EagerSingleton() { }\n        public static EagerSingleton GetInstance()\n        {\n            return instance;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/LazySingleton.cs",
    "content": "namespace Singleton\n{\n    public class LazySingleton\n    {\n        private static LazySingleton instance;\n        private LazySingleton() { }\n        public static LazySingleton GetInstance()\n        {\n            if (instance == null)\n            {\n                instance = new LazySingleton();\n            }\n            return instance;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/SingletonDemo.cs",
    "content": "using System;\n\nnamespace Singleton\n{\n    class SingletonDemo\n    {\n        static void Main(string[] args)\n        {\n            Console.WriteLine(\"LazySingleton: \" + (LazySingleton.GetInstance() == LazySingleton.GetInstance()));\n            Console.WriteLine(\"ThreadSafeSingleton: \" + (ThreadSafeSingleton.GetInstance() == ThreadSafeSingleton.GetInstance()));\n            Console.WriteLine(\"DoubleCheckedLockingSingleton: \" + (DoubleCheckedLockingSingleton.GetInstance() == DoubleCheckedLockingSingleton.GetInstance()));\n            Console.WriteLine(\"EagerSingleton: \" + (EagerSingleton.GetInstance() == EagerSingleton.GetInstance()));\n            Console.WriteLine(\"StaticBlockSingleton: \" + (StaticBlockSingleton.GetInstance() == StaticBlockSingleton.GetInstance()));\n            Console.WriteLine(\"BillPughSingleton: \" + (BillPughSingleton.GetInstance() == BillPughSingleton.GetInstance()));\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/StaticBlockSingleton.cs",
    "content": "using System;\n\nnamespace Singleton\n{\n    public class StaticBlockSingleton\n    {\n        private static readonly StaticBlockSingleton instance;\n        static StaticBlockSingleton()\n        {\n            try\n            {\n                instance = new StaticBlockSingleton();\n            }\n            catch (Exception ex)\n            {\n                throw new Exception(\"Exception occurred in creating singleton instance\", ex);\n            }\n        }\n        private StaticBlockSingleton() { }\n        public static StaticBlockSingleton GetInstance()\n        {\n            return instance;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/singleton/ThreadSafeSingleton.cs",
    "content": "namespace Singleton\n{\n    public class ThreadSafeSingleton\n    {\n        private static ThreadSafeSingleton instance;\n        private static readonly object lockObj = new object();\n        private ThreadSafeSingleton() { }\n        public static ThreadSafeSingleton GetInstance()\n        {\n            lock (lockObj)\n            {\n                if (instance == null)\n                {\n                    instance = new ThreadSafeSingleton();\n                }\n                return instance;\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/DispensingState.cs",
    "content": "using System;\n\nnamespace State\n{\n    public class DispensingState : IMachineState\n    {\n        public void SelectItem(VendingMachine context, string itemCode)\n        {\n            Console.WriteLine(\"Please wait, dispensing in progress.\");\n        }\n\n        public void InsertCoin(VendingMachine context, double amount)\n        {\n            Console.WriteLine(\"Please wait, dispensing in progress.\");\n        }\n\n        public void DispenseItem(VendingMachine context)\n        {\n            Console.WriteLine(\"Already dispensing. Please wait.\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/HasMoneyState.cs",
    "content": "using System;\nusing System.Threading;\n\nnamespace State\n{\n    public class HasMoneyState : IMachineState\n    {\n        public void SelectItem(VendingMachine context, string itemCode)\n        {\n            Console.WriteLine(\"Cannot change item after inserting money.\");\n        }\n\n        public void InsertCoin(VendingMachine context, double amount)\n        {\n            Console.WriteLine(\"Money already inserted.\");\n        }\n\n        public void DispenseItem(VendingMachine context)\n        {\n            Console.WriteLine($\"Dispensing item: {context.GetSelectedItem()}\");\n            context.SetState(new DispensingState());\n\n            // Simulate dispensing\n            Thread.Sleep(1000);\n\n            Console.WriteLine(\"Item dispensed successfully.\");\n            context.Reset();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/IMachineState.cs",
    "content": "namespace State\n{\n    public interface IMachineState\n    {\n        void SelectItem(VendingMachine context, string itemCode);\n        void InsertCoin(VendingMachine context, double amount);\n        void DispenseItem(VendingMachine context);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/IdleState.cs",
    "content": "using System;\n\nnamespace State\n{\n    public class IdleState : IMachineState\n    {\n        public void SelectItem(VendingMachine context, string itemCode)\n        {\n            Console.WriteLine($\"Item selected: {itemCode}\");\n            context.SetSelectedItem(itemCode);\n            context.SetState(new ItemSelectedState());\n        }\n\n        public void InsertCoin(VendingMachine context, double amount)\n        {\n            Console.WriteLine(\"Please select an item before inserting coins.\");\n        }\n\n        public void DispenseItem(VendingMachine context)\n        {\n            Console.WriteLine(\"No item selected. Nothing to dispense.\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/ItemSelectedState.cs",
    "content": "using System;\n\nnamespace State\n{\n    public class ItemSelectedState : IMachineState\n    {\n        public void SelectItem(VendingMachine context, string itemCode)\n        {\n            Console.WriteLine($\"Item already selected: {context.GetSelectedItem()}\");\n        }\n\n        public void InsertCoin(VendingMachine context, double amount)\n        {\n            Console.WriteLine($\"Inserted ${amount} for item: {context.GetSelectedItem()}\");\n            context.SetInsertedAmount(amount);\n            context.SetState(new HasMoneyState());\n        }\n\n        public void DispenseItem(VendingMachine context)\n        {\n            Console.WriteLine(\"Insert coin before dispensing.\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/Program.cs",
    "content": "using System;\n\nnamespace State\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var vm = new VendingMachine();\n\n            vm.InsertCoin(1.0); // Invalid in IdleState\n            vm.SelectItem(\"A1\");\n            vm.InsertCoin(1.5);\n            vm.DispenseItem();\n\n            Console.WriteLine(\"\\n--- Second Transaction ---\");\n            vm.SelectItem(\"B2\");\n            vm.InsertCoin(2.0);\n            vm.DispenseItem();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/state/VendingMachine.cs",
    "content": "namespace State\n{\n    public class VendingMachine\n    {\n        private IMachineState currentState;\n        private string selectedItem;\n        private double insertedAmount;\n\n        public VendingMachine()\n        {\n            this.currentState = new IdleState(); // Initial state\n        }\n\n        public void SetState(IMachineState newState)\n        {\n            this.currentState = newState;\n        }\n\n        public void SetSelectedItem(string itemCode)\n        {\n            this.selectedItem = itemCode;\n        }\n\n        public void SetInsertedAmount(double amount)\n        {\n            this.insertedAmount = amount;\n        }\n\n        public string GetSelectedItem()\n        {\n            return selectedItem;\n        }\n\n        public double GetInsertedAmount()\n        {\n            return insertedAmount;\n        }\n\n        public void SelectItem(string itemCode)\n        {\n            currentState.SelectItem(this, itemCode);\n        }\n\n        public void InsertCoin(double amount)\n        {\n            currentState.InsertCoin(this, amount);\n        }\n\n        public void DispenseItem()\n        {\n            currentState.DispenseItem(this);\n        }\n\n        public void Reset()\n        {\n            this.selectedItem = \"\";\n            this.insertedAmount = 0.0;\n            this.currentState = new IdleState();\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/DistanceBasedShipping.cs",
    "content": "namespace Strategy\n{\n    public class DistanceBasedShipping : IShippingStrategy\n    {\n        private const double BASE_RATE = 5.0;\n        private const double ZONE_A_MULTIPLIER = 1.0;\n        private const double ZONE_B_MULTIPLIER = 1.5;\n        private const double ZONE_C_MULTIPLIER = 2.0;\n\n        public double CalculateCost(Order order)\n        {\n            double multiplier = order.GetDestinationZone() switch\n            {\n                \"ZoneA\" => ZONE_A_MULTIPLIER,\n                \"ZoneB\" => ZONE_B_MULTIPLIER,\n                \"ZoneC\" => ZONE_C_MULTIPLIER,\n                _ => ZONE_A_MULTIPLIER\n            };\n\n            return BASE_RATE * multiplier;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/FlatRateShipping.cs",
    "content": "namespace Strategy\n{\n    public class FlatRateShipping : IShippingStrategy\n    {\n        private const double FLAT_RATE = 10.0;\n\n        public double CalculateCost(Order order)\n        {\n            return FLAT_RATE;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/IShippingStrategy.cs",
    "content": "namespace Strategy\n{\n    public interface IShippingStrategy\n    {\n        double CalculateCost(Order order);\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/Order.cs",
    "content": "namespace Strategy\n{\n    public class Order\n    {\n        public double GetTotalWeight() => 5.0; // kg\n        public string GetDestinationZone() => \"ZoneA\";\n        public double GetOrderValue() => 150.0;\n        // ... other order details\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/Program.cs",
    "content": "using System;\n\nnamespace Strategy\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var order = new Order();\n\n            // Using different shipping strategies\n            var flatRateService = new ShippingCostService(new FlatRateShipping());\n            var weightBasedService = new ShippingCostService(new WeightBasedShipping());\n            var distanceBasedService = new ShippingCostService(new DistanceBasedShipping());\n            var thirdPartyService = new ShippingCostService(new ThirdPartyApiShipping());\n\n            Console.WriteLine(\"Shipping costs using different strategies:\");\n            Console.WriteLine($\"Flat Rate Shipping: ${flatRateService.CalculateShippingCost(order):F2}\");\n            Console.WriteLine($\"Weight Based Shipping: ${weightBasedService.CalculateShippingCost(order):F2}\");\n            Console.WriteLine($\"Distance Based Shipping: ${distanceBasedService.CalculateShippingCost(order):F2}\");\n            Console.WriteLine($\"Third Party API Shipping: ${thirdPartyService.CalculateShippingCost(order):F2}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/ShippingCostService.cs",
    "content": "namespace Strategy\n{\n    public class ShippingCostService\n    {\n        private readonly IShippingStrategy shippingStrategy;\n\n        public ShippingCostService(IShippingStrategy shippingStrategy)\n        {\n            this.shippingStrategy = shippingStrategy;\n        }\n\n        public double CalculateShippingCost(Order order)\n        {\n            return shippingStrategy.CalculateCost(order);\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/ThirdPartyApiShipping.cs",
    "content": "namespace Strategy\n{\n    public class ThirdPartyApiShipping : IShippingStrategy\n    {\n        public double CalculateCost(Order order)\n        {\n            // Simulate API call to third-party shipping service\n            double baseRate = 15.0;\n            double weightFactor = order.GetTotalWeight() * 1.5;\n            double distanceFactor = order.GetDestinationZone() == \"ZoneC\" ? 2.0 : 1.0;\n\n            return baseRate + weightFactor * distanceFactor;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/strategy/WeightBasedShipping.cs",
    "content": "namespace Strategy\n{\n    public class WeightBasedShipping : IShippingStrategy\n    {\n        private const double RATE_PER_KG = 2.0;\n\n        public double CalculateCost(Order order)\n        {\n            return order.GetTotalWeight() * RATE_PER_KG;\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/AbstractReportExporter.cs",
    "content": "using System;\n\nnamespace TemplateMethod\n{\n    public abstract class AbstractReportExporter\n    {\n        public void ExportReport(ReportData data, string filePath)\n        {\n            PrepareData(data);\n            OpenFile(filePath);\n            WriteHeader(data);\n            WriteDataRows(data);\n            WriteFooter(data);\n            CloseFile(filePath);\n            Console.WriteLine($\"Report exported to {filePath}\");\n        }\n\n        // Hook method – optional for subclasses to override\n        protected virtual void PrepareData(ReportData data)\n        {\n            Console.WriteLine(\"Preparing report data...\");\n        }\n\n        // Hook method – optional for subclasses to override\n        protected virtual void OpenFile(string filePath)\n        {\n            Console.WriteLine($\"Opening file: {filePath}\");\n        }\n\n        protected abstract void WriteHeader(ReportData data);\n\n        protected abstract void WriteDataRows(ReportData data);\n\n        // Hook method – optional for subclasses to override\n        protected virtual void WriteFooter(ReportData data)\n        {\n            Console.WriteLine(\"Writing footer...\");\n        }\n\n        // Hook method – optional for subclasses to override\n        protected virtual void CloseFile(string filePath)\n        {\n            Console.WriteLine($\"Closing file: {filePath}\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/CsvReportExporter.cs",
    "content": "using System;\nusing System.Linq;\n\nnamespace TemplateMethod\n{\n    public class CsvReportExporter : AbstractReportExporter\n    {\n        protected override void WriteHeader(ReportData data)\n        {\n            var headers = data.GetHeaders();\n            Console.WriteLine(string.Join(\",\", headers));\n        }\n\n        protected override void WriteDataRows(ReportData data)\n        {\n            foreach (var row in data.GetRows())\n            {\n                var values = data.GetHeaders()\n                    .Select(header => row[header].ToString())\n                    .ToList();\n                Console.WriteLine(string.Join(\",\", values));\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/ExcelReportExporter.cs",
    "content": "using System;\n\nnamespace TemplateMethod\n{\n    public class ExcelReportExporter : AbstractReportExporter\n    {\n        protected override void WriteHeader(ReportData data)\n        {\n            Console.WriteLine(\"Excel Header:\");\n            foreach (var header in data.GetHeaders())\n            {\n                Console.WriteLine($\"\\t{header}\");\n            }\n        }\n\n        protected override void WriteDataRows(ReportData data)\n        {\n            Console.WriteLine(\"Excel Data:\");\n            foreach (var row in data.GetRows())\n            {\n                Console.WriteLine(\"\\tRow:\");\n                foreach (var header in data.GetHeaders())\n                {\n                    Console.WriteLine($\"\\t\\t{header}: {row[header]}\");\n                }\n            }\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/PdfReportExporter.cs",
    "content": "using System;\n\nnamespace TemplateMethod\n{\n    public class PdfReportExporter : AbstractReportExporter\n    {\n        protected override void WriteHeader(ReportData data)\n        {\n            Console.WriteLine(\"PDF Header:\");\n            Console.WriteLine(\"----------------------------------------\");\n            foreach (var header in data.GetHeaders())\n            {\n                Console.Write($\"{header,-15}\");\n            }\n            Console.WriteLine(\"\\n----------------------------------------\");\n        }\n\n        protected override void WriteDataRows(ReportData data)\n        {\n            Console.WriteLine(\"PDF Data:\");\n            foreach (var row in data.GetRows())\n            {\n                foreach (var header in data.GetHeaders())\n                {\n                    Console.Write($\"{row[header],-15}\");\n                }\n                Console.WriteLine();\n            }\n            Console.WriteLine(\"----------------------------------------\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/Program.cs",
    "content": "using System;\n\nnamespace TemplateMethod\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n            var data = new ReportData();\n\n            // Export to different formats\n            var csvExporter = new CsvReportExporter();\n            var excelExporter = new ExcelReportExporter();\n            var pdfExporter = new PdfReportExporter();\n\n            Console.WriteLine(\"Exporting to CSV:\");\n            csvExporter.ExportReport(data, \"report.csv\");\n\n            Console.WriteLine(\"\\nExporting to Excel:\");\n            excelExporter.ExportReport(data, \"report.xlsx\");\n\n            Console.WriteLine(\"\\nExporting to PDF:\");\n            pdfExporter.ExportReport(data, \"report.pdf\");\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/csharp/templatemethod/ReportData.cs",
    "content": "using System.Collections.Generic;\n\nnamespace TemplateMethod\n{\n    public class ReportData\n    {\n        public List<string> GetHeaders()\n        {\n            return new List<string> { \"ID\", \"Name\", \"Value\" };\n        }\n\n        public List<Dictionary<string, object>> GetRows()\n        {\n            return new List<Dictionary<string, object>>\n            {\n                new Dictionary<string, object> { { \"ID\", 1 }, { \"Name\", \"Item A\" }, { \"Value\", 100.0 } },\n                new Dictionary<string, object> { { \"ID\", 2 }, { \"Name\", \"Item B\" }, { \"Value\", 150.5 } },\n                new Dictionary<string, object> { { \"ID\", 3 }, { \"Name\", \"Item C\" }, { \"Value\", 75.25 } }\n            };\n        }\n    }\n} "
  },
  {
    "path": "design-patterns/golang/adapter/checkout_service.go",
    "content": "package adapter\n\nimport \"fmt\"\n\n// CheckoutService handles the checkout process\ntype CheckoutService struct {\n\tpaymentProcessor PaymentProcessor\n}\n\n// NewCheckoutService creates a new CheckoutService\nfunc NewCheckoutService(paymentProcessor PaymentProcessor) *CheckoutService {\n\treturn &CheckoutService{\n\t\tpaymentProcessor: paymentProcessor,\n\t}\n}\n\n// ProcessCheckout processes a checkout with the given amount and currency\nfunc (cs *CheckoutService) ProcessCheckout(amount float64, currency string) {\n\tcs.paymentProcessor.ProcessPayment(amount, currency)\n\n\tif cs.paymentProcessor.IsPaymentSuccessful() {\n\t\tfmt.Printf(\"Checkout successful! Transaction ID: %s\\n\", cs.paymentProcessor.GetTransactionID())\n\t} else {\n\t\tfmt.Println(\"Checkout failed!\")\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/adapter/go.mod",
    "content": "module design-patterns/golang/adapter\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/adapter/in_house_payment_processor.go",
    "content": "package adapter\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// InHousePaymentProcessor represents our in-house payment processing system\ntype InHousePaymentProcessor struct {\n\ttransactionID string\n\tisSuccessful  bool\n}\n\n// ProcessPayment implements the PaymentProcessor interface\nfunc (p *InHousePaymentProcessor) ProcessPayment(amount float64, currency string) {\n\tfmt.Printf(\"InHousePaymentProcessor: Processing payment of %s %.2f\\n\", currency, amount)\n\tp.transactionID = fmt.Sprintf(\"INH-%d\", time.Now().UnixNano())\n\tp.isSuccessful = true\n\tfmt.Printf(\"InHousePaymentProcessor: Payment processed successfully. Txn ID: %s\\n\", p.transactionID)\n}\n\n// IsPaymentSuccessful implements the PaymentProcessor interface\nfunc (p *InHousePaymentProcessor) IsPaymentSuccessful() bool {\n\treturn p.isSuccessful\n}\n\n// GetTransactionID implements the PaymentProcessor interface\nfunc (p *InHousePaymentProcessor) GetTransactionID() string {\n\treturn p.transactionID\n}\n"
  },
  {
    "path": "design-patterns/golang/adapter/legacy_gateway.go",
    "content": "package adapter\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// LegacyGateway represents the legacy payment gateway\ntype LegacyGateway struct {\n\ttransactionReference int64\n\tisPaymentSuccessful  bool\n}\n\n// ExecuteTransaction processes a payment using the legacy gateway\nfunc (lg *LegacyGateway) ExecuteTransaction(totalAmount float64, currency string) {\n\tfmt.Printf(\"LegacyGateway: Executing transaction for %s %.2f\\n\", currency, totalAmount)\n\tlg.transactionReference = time.Now().UnixNano()\n\tlg.isPaymentSuccessful = true\n\tfmt.Printf(\"LegacyGateway: Transaction executed successfully. Txn ID: %d\\n\", lg.transactionReference)\n}\n\n// CheckStatus checks the status of a transaction\nfunc (lg *LegacyGateway) CheckStatus(transactionReference int64) bool {\n\tfmt.Printf(\"LegacyGateway: Checking status for ref: %d\\n\", transactionReference)\n\treturn lg.isPaymentSuccessful\n}\n\n// GetReferenceNumber returns the transaction reference number\nfunc (lg *LegacyGateway) GetReferenceNumber() int64 {\n\treturn lg.transactionReference\n}\n"
  },
  {
    "path": "design-patterns/golang/adapter/legacy_gateway_adapter.go",
    "content": "package adapter\n\nimport \"fmt\"\n\n// LegacyGatewayAdapter adapts the LegacyGateway to the PaymentProcessor interface\ntype LegacyGatewayAdapter struct {\n\tlegacyGateway *LegacyGateway\n}\n\n// NewLegacyGatewayAdapter creates a new LegacyGatewayAdapter\nfunc NewLegacyGatewayAdapter(legacyGateway *LegacyGateway) *LegacyGatewayAdapter {\n\treturn &LegacyGatewayAdapter{\n\t\tlegacyGateway: legacyGateway,\n\t}\n}\n\n// ProcessPayment implements the PaymentProcessor interface\nfunc (adapter *LegacyGatewayAdapter) ProcessPayment(amount float64, currency string) {\n\tadapter.legacyGateway.ExecuteTransaction(amount, currency)\n}\n\n// IsPaymentSuccessful implements the PaymentProcessor interface\nfunc (adapter *LegacyGatewayAdapter) IsPaymentSuccessful() bool {\n\treturn adapter.legacyGateway.CheckStatus(adapter.legacyGateway.GetReferenceNumber())\n}\n\n// GetTransactionID implements the PaymentProcessor interface\nfunc (adapter *LegacyGatewayAdapter) GetTransactionID() string {\n\treturn fmt.Sprintf(\"LEG-%d\", adapter.legacyGateway.GetReferenceNumber())\n}\n"
  },
  {
    "path": "design-patterns/golang/adapter/main.go",
    "content": "package main\n\nimport (\n\t\"design-patterns/golang/adapter\"\n\t\"fmt\"\n)\n\nfunc main() {\n\t// Using the in-house payment processor\n\tfmt.Println(\"Using In-House Payment Processor:\")\n\tinHouseProcessor := &adapter.InHousePaymentProcessor{}\n\tcheckoutService := adapter.NewCheckoutService(inHouseProcessor)\n\tcheckoutService.ProcessCheckout(100.0, \"USD\")\n\n\tfmt.Println(\"\\nUsing Legacy Gateway (via Adapter):\")\n\t// Using the legacy gateway through the adapter\n\tlegacyGateway := &adapter.LegacyGateway{}\n\tlegacyAdapter := adapter.NewLegacyGatewayAdapter(legacyGateway)\n\tcheckoutService = adapter.NewCheckoutService(legacyAdapter)\n\tcheckoutService.ProcessCheckout(150.0, \"EUR\")\n}\n"
  },
  {
    "path": "design-patterns/golang/adapter/payment_processor.go",
    "content": "package adapter\n\n// PaymentProcessor defines the interface for processing payments\ntype PaymentProcessor interface {\n\tProcessPayment(amount float64, currency string)\n\tIsPaymentSuccessful() bool\n\tGetTransactionID() string\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/circle.go",
    "content": "package bridge\n\n// Circle represents a circle shape\ntype Circle struct {\n\t*BaseShape\n\tradius float64\n}\n\n// NewCircle creates a new Circle\nfunc NewCircle(renderer Renderer, radius float64) *Circle {\n\treturn &Circle{\n\t\tBaseShape: NewBaseShape(renderer),\n\t\tradius:    radius,\n\t}\n}\n\n// Draw implements the Shape interface\nfunc (c *Circle) Draw() {\n\tc.renderer.RenderCircle(c.radius)\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/go.mod",
    "content": "module design-patterns/golang/bridge\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/bridge/main.go",
    "content": "package main\n\nimport (\n\t\"design-patterns/golang/bridge\"\n\t\"fmt\"\n)\n\nfunc main() {\n\t// Create renderers\n\tvectorRenderer := bridge.NewVectorRenderer()\n\trasterRenderer := bridge.NewRasterRenderer()\n\n\t// Create shapes with vector renderer\n\tcircle := bridge.NewCircle(vectorRenderer, 5.0)\n\trectangle := bridge.NewRectangle(vectorRenderer, 10.0, 5.0)\n\n\tfmt.Println(\"Drawing shapes with vector renderer:\")\n\tcircle.Draw()\n\trectangle.Draw()\n\n\t// Create shapes with raster renderer\n\tcircle = bridge.NewCircle(rasterRenderer, 5.0)\n\trectangle = bridge.NewRectangle(rasterRenderer, 10.0, 5.0)\n\n\tfmt.Println(\"\\nDrawing shapes with raster renderer:\")\n\tcircle.Draw()\n\trectangle.Draw()\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/raster_renderer.go",
    "content": "package bridge\n\nimport \"fmt\"\n\n// RasterRenderer renders shapes as raster graphics\ntype RasterRenderer struct{}\n\n// NewRasterRenderer creates a new RasterRenderer\nfunc NewRasterRenderer() *RasterRenderer {\n\treturn &RasterRenderer{}\n}\n\n// RenderCircle implements the Renderer interface\nfunc (r *RasterRenderer) RenderCircle(radius float64) {\n\tfmt.Printf(\"Drawing a circle of radius %.2f using raster graphics\\n\", radius)\n}\n\n// RenderRectangle implements the Renderer interface\nfunc (r *RasterRenderer) RenderRectangle(width, height float64) {\n\tfmt.Printf(\"Drawing a rectangle of width %.2f and height %.2f using raster graphics\\n\", width, height)\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/rectangle.go",
    "content": "package bridge\n\n// Rectangle represents a rectangle shape\ntype Rectangle struct {\n\t*BaseShape\n\twidth  float64\n\theight float64\n}\n\n// NewRectangle creates a new Rectangle\nfunc NewRectangle(renderer Renderer, width, height float64) *Rectangle {\n\treturn &Rectangle{\n\t\tBaseShape: NewBaseShape(renderer),\n\t\twidth:     width,\n\t\theight:    height,\n\t}\n}\n\n// Draw implements the Shape interface\nfunc (r *Rectangle) Draw() {\n\tr.renderer.RenderRectangle(r.width, r.height)\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/renderer.go",
    "content": "package bridge\n\n// Renderer defines the interface for rendering shapes\ntype Renderer interface {\n\tRenderCircle(radius float64)\n\tRenderRectangle(width, height float64)\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/shape.go",
    "content": "package bridge\n\n// Shape defines the interface for shapes\ntype Shape interface {\n\tDraw()\n}\n\n// BaseShape provides common functionality for shapes\ntype BaseShape struct {\n\trenderer Renderer\n}\n\n// NewBaseShape creates a new BaseShape\nfunc NewBaseShape(renderer Renderer) *BaseShape {\n\treturn &BaseShape{\n\t\trenderer: renderer,\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/bridge/vector_renderer.go",
    "content": "package bridge\n\nimport \"fmt\"\n\n// VectorRenderer renders shapes as vector graphics\ntype VectorRenderer struct{}\n\n// NewVectorRenderer creates a new VectorRenderer\nfunc NewVectorRenderer() *VectorRenderer {\n\treturn &VectorRenderer{}\n}\n\n// RenderCircle implements the Renderer interface\nfunc (v *VectorRenderer) RenderCircle(radius float64) {\n\tfmt.Printf(\"Drawing a circle of radius %.2f using vector graphics\\n\", radius)\n}\n\n// RenderRectangle implements the Renderer interface\nfunc (v *VectorRenderer) RenderRectangle(width, height float64) {\n\tfmt.Printf(\"Drawing a rectangle of width %.2f and height %.2f using vector graphics\\n\", width, height)\n}\n"
  },
  {
    "path": "design-patterns/golang/builder/go.mod",
    "content": "module design-patterns/golang/builder\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/builder/http_request.go",
    "content": "package builder\n\nimport (\n\t\"fmt\"\n)\n\n// HttpRequest represents an HTTP request with all its components\ntype HttpRequest struct {\n\turl         string            // Required\n\tmethod      string            // Optional, default GET\n\theaders     map[string]string // Optional\n\tqueryParams map[string]string // Optional\n\tbody        string            // Optional\n\ttimeout     int               // Optional, default 30s\n}\n\n// NewHttpRequest creates a new HttpRequest using the builder pattern\nfunc NewHttpRequest(builder *HttpRequestBuilder) *HttpRequest {\n\treturn &HttpRequest{\n\t\turl:         builder.url,\n\t\tmethod:      builder.method,\n\t\theaders:     builder.headers,\n\t\tqueryParams: builder.queryParams,\n\t\tbody:        builder.body,\n\t\ttimeout:     builder.timeout,\n\t}\n}\n\n// GetURL returns the request URL\nfunc (r *HttpRequest) GetURL() string {\n\treturn r.url\n}\n\n// GetMethod returns the request method\nfunc (r *HttpRequest) GetMethod() string {\n\treturn r.method\n}\n\n// GetHeaders returns the request headers\nfunc (r *HttpRequest) GetHeaders() map[string]string {\n\treturn r.headers\n}\n\n// GetQueryParams returns the request query parameters\nfunc (r *HttpRequest) GetQueryParams() map[string]string {\n\treturn r.queryParams\n}\n\n// GetBody returns the request body\nfunc (r *HttpRequest) GetBody() string {\n\treturn r.body\n}\n\n// GetTimeout returns the request timeout\nfunc (r *HttpRequest) GetTimeout() int {\n\treturn r.timeout\n}\n\n// String returns a string representation of the HttpRequest\nfunc (r *HttpRequest) String() string {\n\tbodyPreview := r.body\n\tif len(bodyPreview) > 10 {\n\t\tbodyPreview = bodyPreview[:10] + \"...\"\n\t}\n\treturn fmt.Sprintf(\"HttpRequest{url='%s', method='%s', headers=%v, queryParams=%v, body='%s', timeout=%d}\",\n\t\tr.url, r.method, r.headers, r.queryParams, bodyPreview, r.timeout)\n}\n"
  },
  {
    "path": "design-patterns/golang/builder/http_request_builder.go",
    "content": "package builder\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// HttpRequestBuilder is responsible for building HttpRequest objects\ntype HttpRequestBuilder struct {\n\turl         string            // Required\n\tmethod      string            // Optional, default GET\n\theaders     map[string]string // Optional\n\tqueryParams map[string]string // Optional\n\tbody        string            // Optional\n\ttimeout     int               // Optional, default 30s\n}\n\n// NewHttpRequestBuilder creates a new HttpRequestBuilder with the required URL\nfunc NewHttpRequestBuilder(url string) (*HttpRequestBuilder, error) {\n\tif strings.TrimSpace(url) == \"\" {\n\t\treturn nil, fmt.Errorf(\"URL cannot be null or empty\")\n\t}\n\n\treturn &HttpRequestBuilder{\n\t\turl:         url,\n\t\tmethod:      \"GET\",\n\t\theaders:     make(map[string]string),\n\t\tqueryParams: make(map[string]string),\n\t\ttimeout:     30000, // 30 seconds default\n\t}, nil\n}\n\n// Method sets the HTTP method\nfunc (b *HttpRequestBuilder) Method(method string) *HttpRequestBuilder {\n\tif strings.TrimSpace(method) == \"\" {\n\t\tb.method = \"GET\"\n\t} else {\n\t\tb.method = strings.ToUpper(method)\n\t}\n\treturn b\n}\n\n// Header adds a header to the request\nfunc (b *HttpRequestBuilder) Header(key, value string) *HttpRequestBuilder {\n\tif key != \"\" && value != \"\" {\n\t\tb.headers[key] = value\n\t}\n\treturn b\n}\n\n// QueryParam adds a query parameter to the request\nfunc (b *HttpRequestBuilder) QueryParam(key, value string) *HttpRequestBuilder {\n\tif key != \"\" && value != \"\" {\n\t\tb.queryParams[key] = value\n\t}\n\treturn b\n}\n\n// Body sets the request body\nfunc (b *HttpRequestBuilder) Body(body string) *HttpRequestBuilder {\n\tb.body = body\n\treturn b\n}\n\n// Timeout sets the request timeout in milliseconds\nfunc (b *HttpRequestBuilder) Timeout(timeoutMillis int) *HttpRequestBuilder {\n\tif timeoutMillis > 0 {\n\t\tb.timeout = timeoutMillis\n\t}\n\treturn b\n}\n\n// Build creates and returns a new HttpRequest\nfunc (b *HttpRequestBuilder) Build() *HttpRequest {\n\t// Validate the request\n\tif (b.method == \"POST\" || b.method == \"PUT\") && b.body == \"\" {\n\t\tfmt.Printf(\"Warning: Building %s request without a body for URL: %s\\n\", b.method, b.url)\n\t}\n\n\treturn NewHttpRequest(b)\n}\n"
  },
  {
    "path": "design-patterns/golang/builder/main.go",
    "content": "package main\n\nimport (\n\t\"design-patterns/golang/builder\"\n\t\"fmt\"\n)\n\nfunc main() {\n\t// Create a GET request\n\tgetRequest, err := builder.NewHttpRequestBuilder(\"https://api.example.com/users\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error creating request: %v\\n\", err)\n\t\treturn\n\t}\n\n\tgetRequest.\n\t\tMethod(\"GET\").\n\t\tHeader(\"Accept\", \"application/json\").\n\t\tQueryParam(\"page\", \"1\").\n\t\tQueryParam(\"limit\", \"10\").\n\t\tTimeout(5000)\n\n\trequest := getRequest.Build()\n\tfmt.Println(\"GET Request:\", request)\n\n\t// Create a POST request\n\tpostRequest, err := builder.NewHttpRequestBuilder(\"https://api.example.com/users\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error creating request: %v\\n\", err)\n\t\treturn\n\t}\n\n\tpostRequest.\n\t\tMethod(\"POST\").\n\t\tHeader(\"Content-Type\", \"application/json\").\n\t\tHeader(\"Authorization\", \"Bearer token123\").\n\t\tBody(`{\"name\": \"John Doe\", \"email\": \"john@example.com\"}`).\n\t\tTimeout(10000)\n\n\trequest = postRequest.Build()\n\tfmt.Println(\"\\nPOST Request:\", request)\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/authentication_handler.go",
    "content": "package chainofresponsibility\n\nimport \"fmt\"\n\n// AuthenticationHandler handles authentication requests\ntype AuthenticationHandler struct {\n\tBaseHandler\n}\n\n// Handle processes authentication requests\nfunc (h *AuthenticationHandler) Handle(request *Request) {\n\tif request.Type == \"auth\" {\n\t\tfmt.Printf(\"AuthenticationHandler: Processing authentication request for user %s\\n\", request.Data)\n\t\t// Simulate authentication logic\n\t\tif request.Data == \"valid_user\" {\n\t\t\tfmt.Println(\"AuthenticationHandler: Authentication successful\")\n\t\t} else {\n\t\t\tfmt.Println(\"AuthenticationHandler: Authentication failed\")\n\t\t}\n\t} else {\n\t\th.HandleNext(request)\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/authorization_handler.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/base_handler.go",
    "content": "package chainofresponsibility\n\n// BaseHandler provides common functionality for request handlers\ntype BaseHandler struct {\n\tnext RequestHandler\n}\n\n// SetNext sets the next handler in the chain\nfunc (h *BaseHandler) SetNext(handler RequestHandler) {\n\th.next = handler\n}\n\n// HandleNext passes the request to the next handler if one exists\nfunc (h *BaseHandler) HandleNext(request *Request) {\n\tif h.next != nil {\n\t\th.next.Handle(request)\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/go.mod",
    "content": "module chainofresponsibility\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/main.go",
    "content": "package chainofresponsibility\n\nimport (\n\t\"fmt\"\n)\n\nfunc main() {\n\t// Create handlers\n\tauth := &AuthenticationHandler{}\n\tauthz := &AuthorizationHandler{}\n\tvalidate := &ValidationHandler{}\n\n\t// Set up the chain\n\tauth.SetNext(authz)\n\tauthz.SetNext(validate)\n\n\t// Create requests\n\tauthRequest := &Request{\n\t\tType: \"auth\",\n\t\tData: \"valid_user\",\n\t}\n\n\tauthzRequest := &Request{\n\t\tType: \"authz\",\n\t\tData: \"admin_resource\",\n\t}\n\n\tvalidateRequest := &Request{\n\t\tType: \"validate\",\n\t\tData: \"test_data\",\n\t}\n\n\tinvalidRequest := &Request{\n\t\tType: \"unknown\",\n\t\tData: \"invalid_data\",\n\t}\n\n\t// Process requests\n\tfmt.Println(\"Processing authentication request:\")\n\tauth.Handle(authRequest)\n\n\tfmt.Println(\"\\nProcessing authorization request:\")\n\tauth.Handle(authzRequest)\n\n\tfmt.Println(\"\\nProcessing validation request:\")\n\tauth.Handle(validateRequest)\n\n\tfmt.Println(\"\\nProcessing invalid request:\")\n\tauth.Handle(invalidRequest)\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/request.go",
    "content": "package chainofresponsibility\n\n// Request represents a request in the chain\ntype Request struct {\n\tType string\n\tData string\n}\n\n// NewRequest creates a new Request\nfunc NewRequest(user, role string, requestCount int, payload string) *Request {\n\treturn &Request{\n\t\tUser:         user,\n\t\tUserRole:     role,\n\t\tRequestCount: requestCount,\n\t\tPayload:      payload,\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/request_handler.go",
    "content": "package chainofresponsibility\n\n// RequestHandler defines the interface for request handlers in the chain\ntype RequestHandler interface {\n\tSetNext(handler RequestHandler)\n\tHandle(request *Request)\n}\n"
  },
  {
    "path": "design-patterns/golang/chainofresponsibility/validation_handler.go",
    "content": "package chainofresponsibility\n\nimport \"fmt\"\n\n// ValidationHandler handles validation requests\ntype ValidationHandler struct {\n\tBaseHandler\n}\n\n// Handle processes validation requests\nfunc (h *ValidationHandler) Handle(request *Request) {\n\tif request.Type == \"validate\" {\n\t\tfmt.Printf(\"ValidationHandler: Processing validation request for data %s\\n\", request.Data)\n\t\t// Simulate validation logic\n\t\tif len(request.Data) > 0 {\n\t\t\tfmt.Println(\"ValidationHandler: Validation successful\")\n\t\t} else {\n\t\t\tfmt.Println(\"ValidationHandler: Validation failed\")\n\t\t}\n\t} else {\n\t\th.HandleNext(request)\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/composite/file.go",
    "content": "package composite\n\nimport \"fmt\"\n\n// File represents a file in the file system\ntype File struct {\n\tname string\n\tsize int64\n}\n\n// NewFile creates a new File instance\nfunc NewFile(name string, size int64) *File {\n\treturn &File{\n\t\tname: name,\n\t\tsize: size,\n\t}\n}\n\n// GetName returns the name of the file\nfunc (f *File) GetName() string {\n\treturn f.name\n}\n\n// GetSize returns the size of the file\nfunc (f *File) GetSize() int64 {\n\treturn f.size\n}\n\n// Print prints the file information with the given indentation\nfunc (f *File) Print(indent string) {\n\tfmt.Printf(\"%sFile: %s (%d bytes)\\n\", indent, f.name, f.size)\n}\n\n// Delete deletes the file\nfunc (f *File) Delete() {\n\tfmt.Printf(\"Deleting file: %s\\n\", f.name)\n}\n"
  },
  {
    "path": "design-patterns/golang/composite/file_system_item.go",
    "content": "package composite\n\n// FileSystemItem defines the interface for both files and folders\ntype FileSystemItem interface {\n\tGetName() string\n\tGetSize() int64\n\tPrint(indent string)\n\tDelete()\n}\n"
  },
  {
    "path": "design-patterns/golang/composite/folder.go",
    "content": "package composite\n\nimport \"fmt\"\n\n// Folder represents a folder in the file system\ntype Folder struct {\n\tname     string\n\tchildren []FileSystemItem\n}\n\n// NewFolder creates a new Folder instance\nfunc NewFolder(name string) *Folder {\n\treturn &Folder{\n\t\tname:     name,\n\t\tchildren: make([]FileSystemItem, 0),\n\t}\n}\n\n// GetName returns the name of the folder\nfunc (f *Folder) GetName() string {\n\treturn f.name\n}\n\n// GetSize returns the total size of the folder and its contents\nfunc (f *Folder) GetSize() int64 {\n\tvar totalSize int64\n\tfor _, item := range f.children {\n\t\ttotalSize += item.GetSize()\n\t}\n\treturn totalSize\n}\n\n// Add adds a new item to the folder\nfunc (f *Folder) Add(item FileSystemItem) {\n\tf.children = append(f.children, item)\n}\n\n// Remove removes an item from the folder\nfunc (f *Folder) Remove(item FileSystemItem) {\n\tfor i, child := range f.children {\n\t\tif child.GetName() == item.GetName() {\n\t\t\tf.children = append(f.children[:i], f.children[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Print prints the folder structure with the given indentation\nfunc (f *Folder) Print(indent string) {\n\tfmt.Printf(\"%sFolder: %s\\n\", indent, f.name)\n\tfor _, item := range f.children {\n\t\titem.Print(indent + \"  \")\n\t}\n}\n\n// Delete deletes the folder and its contents\nfunc (f *Folder) Delete() {\n\tfmt.Printf(\"Deleting folder: %s\\n\", f.name)\n\tfor _, item := range f.children {\n\t\titem.Delete()\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/composite/go.mod",
    "content": "module composite\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/composite/main.go",
    "content": "package composite\n\nimport \"fmt\"\n\nfunc main() {\n\t// Create root folder\n\troot := NewFolder(\"Root\")\n\n\t// Create subfolders\n\tdocuments := NewFolder(\"Documents\")\n\tdownloads := NewFolder(\"Downloads\")\n\tpictures := NewFolder(\"Pictures\")\n\n\t// Create files\n\treport := NewFile(\"report.txt\", 1024)\n\timage := NewFile(\"image.jpg\", 2048)\n\tvideo := NewFile(\"video.mp4\", 4096)\n\n\t// Build the structure\n\troot.Add(documents)\n\troot.Add(downloads)\n\troot.Add(pictures)\n\n\tdocuments.Add(report)\n\tdownloads.Add(video)\n\tpictures.Add(image)\n\n\t// Print the structure\n\tfmt.Println(\"File System Structure:\")\n\troot.Print(\"\")\n\n\t// Print total size\n\tfmt.Printf(\"\\nTotal size: %d bytes\\n\", root.GetSize())\n\n\t// Delete a folder\n\tfmt.Println(\"\\nDeleting Documents folder:\")\n\troot.Remove(documents)\n\tdocuments.Delete()\n\n\t// Print the structure again\n\tfmt.Println(\"\\nUpdated File System Structure:\")\n\troot.Print(\"\")\n}\n"
  },
  {
    "path": "design-patterns/golang/decorator/beverage.go",
    "content": "package decorator\n\n// Beverage defines the interface for all beverages\ntype Beverage interface {\n\tGetDescription() string\n\tCost() float64\n}\n"
  },
  {
    "path": "design-patterns/golang/decorator/beverage_decorator.go",
    "content": "package decorator\n\n// BeverageDecorator is the base decorator that wraps a Beverage\ntype BeverageDecorator struct {\n\tbeverage Beverage\n}\n\n// NewBeverageDecorator creates a new BeverageDecorator\nfunc NewBeverageDecorator(beverage Beverage) *BeverageDecorator {\n\treturn &BeverageDecorator{\n\t\tbeverage: beverage,\n\t}\n}\n\n// GetDescription returns the description of the decorated beverage\nfunc (d *BeverageDecorator) GetDescription() string {\n\treturn d.beverage.GetDescription()\n}\n\n// Cost returns the cost of the decorated beverage\nfunc (d *BeverageDecorator) Cost() float64 {\n\treturn d.beverage.Cost()\n}\n"
  },
  {
    "path": "design-patterns/golang/decorator/go.mod",
    "content": " "
  },
  {
    "path": "design-patterns/golang/decorator/main.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/decorator/milk_decorator.go",
    "content": "package decorator\n\n// MilkDecorator adds milk to a beverage\ntype MilkDecorator struct {\n\t*BeverageDecorator\n}\n\n// NewMilkDecorator creates a new MilkDecorator\nfunc NewMilkDecorator(beverage Beverage) *MilkDecorator {\n\treturn &MilkDecorator{\n\t\tBeverageDecorator: NewBeverageDecorator(beverage),\n\t}\n}\n\n// GetDescription returns the description of the beverage with milk\nfunc (d *MilkDecorator) GetDescription() string {\n\treturn d.beverage.GetDescription() + \" with Milk\"\n}\n\n// Cost returns the cost of the beverage with milk\nfunc (d *MilkDecorator) Cost() float64 {\n\treturn d.beverage.Cost() + 0.5\n}\n"
  },
  {
    "path": "design-patterns/golang/decorator/simple_coffee.go",
    "content": "package decorator\n\n// SimpleCoffee represents a basic coffee without any additions\ntype SimpleCoffee struct{}\n\n// NewSimpleCoffee creates a new SimpleCoffee instance\nfunc NewSimpleCoffee() *SimpleCoffee {\n\treturn &SimpleCoffee{}\n}\n\n// GetDescription returns the description of the coffee\nfunc (c *SimpleCoffee) GetDescription() string {\n\treturn \"Simple Coffee\"\n}\n\n// Cost returns the cost of the coffee\nfunc (c *SimpleCoffee) Cost() float64 {\n\treturn 1.0\n}\n"
  },
  {
    "path": "design-patterns/golang/decorator/sugar_decorator.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/facade/build_system.go",
    "content": "package facade\n\nimport (\n\t\"fmt\"\n)\n\n// BuildSystem handles project compilation\ntype BuildSystem struct{}\n\n// NewBuildSystem creates a new BuildSystem instance\nfunc NewBuildSystem() *BuildSystem {\n\treturn &BuildSystem{}\n}\n\n// CompileProject compiles the project\nfunc (b *BuildSystem) CompileProject() bool {\n\tfmt.Println(\"Build: Compiling project...\")\n\tsimulateDelay()\n\tfmt.Println(\"Build: Compilation complete.\")\n\treturn true\n}\n\n// GetArtifactPath returns the path to the compiled artifact\nfunc (b *BuildSystem) GetArtifactPath() string {\n\treturn \"/path/to/artifact\"\n}\n"
  },
  {
    "path": "design-patterns/golang/facade/deployment_facade.go",
    "content": "package facade\n\nimport \"fmt\"\n\n// DeploymentFacade provides a simplified interface to the deployment system\ntype DeploymentFacade struct {\n\tvcs              *VersionControlSystem\n\tbuildSystem      *BuildSystem\n\ttestingFramework *TestingFramework\n\tdeploymentTarget *DeploymentTarget\n}\n\n// NewDeploymentFacade creates a new DeploymentFacade instance\nfunc NewDeploymentFacade() *DeploymentFacade {\n\treturn &DeploymentFacade{\n\t\tvcs:              NewVersionControlSystem(),\n\t\tbuildSystem:      NewBuildSystem(),\n\t\ttestingFramework: NewTestingFramework(),\n\t\tdeploymentTarget: NewDeploymentTarget(),\n\t}\n}\n\n// DeployApplication performs a full standard deployment\nfunc (f *DeploymentFacade) DeployApplication(branch, serverAddress string) bool {\n\tfmt.Printf(\"\\nFACADE: --- Initiating FULL DEPLOYMENT for branch: %s to %s ---\\n\", branch, serverAddress)\n\tsuccess := true\n\n\t// Step 1: Pull latest code\n\tf.vcs.PullLatestChanges(branch)\n\n\t// Step 2: Build the project\n\tif !f.buildSystem.CompileProject() {\n\t\tfmt.Println(\"FACADE: DEPLOYMENT FAILED - Build compilation failed.\")\n\t\treturn false\n\t}\n\tartifactPath := f.buildSystem.GetArtifactPath()\n\n\t// Step 3: Run tests\n\tif !f.testingFramework.RunUnitTests() {\n\t\tfmt.Println(\"FACADE: DEPLOYMENT FAILED - Unit tests failed.\")\n\t\treturn false\n\t}\n\tif !f.testingFramework.RunIntegrationTests() {\n\t\tfmt.Println(\"FACADE: DEPLOYMENT FAILED - Integration tests failed.\")\n\t\treturn false\n\t}\n\n\t// Step 4: Deploy to production\n\tf.deploymentTarget.TransferArtifact(artifactPath, serverAddress)\n\tf.deploymentTarget.ActivateNewVersion(serverAddress)\n\n\tfmt.Printf(\"FACADE: APPLICATION DEPLOYED SUCCESSFULLY TO %s!\\n\", serverAddress)\n\treturn success\n}\n\n// DeployHotfix performs a hotfix deployment\nfunc (f *DeploymentFacade) DeployHotfix(branch, serverAddress string) bool {\n\tfmt.Printf(\"\\nFACADE: --- Initiating HOTFIX DEPLOYMENT for branch: %s to %s ---\\n\", branch, serverAddress)\n\tsuccess := true\n\n\t// Step 1: Pull latest code\n\tf.vcs.PullLatestChanges(branch)\n\n\t// Step 2: Build the project\n\tif !f.buildSystem.CompileProject() {\n\t\tfmt.Println(\"FACADE: HOTFIX FAILED - Build compilation failed.\")\n\t\treturn false\n\t}\n\tartifactPath := f.buildSystem.GetArtifactPath()\n\n\t// Step 3: Skip extensive tests for hotfix\n\tfmt.Println(\"FACADE: Skipping full test suite for hotfix deployment (or running minimal smoke tests).\")\n\n\t// Step 4: Deploy to production\n\tf.deploymentTarget.TransferArtifact(artifactPath, serverAddress)\n\tf.deploymentTarget.ActivateNewVersion(serverAddress)\n\n\tfmt.Printf(\"FACADE: HOTFIX DEPLOYED SUCCESSFULLY TO %s!\\n\", serverAddress)\n\treturn success\n}\n"
  },
  {
    "path": "design-patterns/golang/facade/deployment_target.go",
    "content": "package facade\n\nimport (\n\t\"fmt\"\n)\n\n// DeploymentTarget handles artifact deployment\ntype DeploymentTarget struct{}\n\n// NewDeploymentTarget creates a new DeploymentTarget instance\nfunc NewDeploymentTarget() *DeploymentTarget {\n\treturn &DeploymentTarget{}\n}\n\n// TransferArtifact transfers the artifact to the target server\nfunc (d *DeploymentTarget) TransferArtifact(artifactPath, serverAddress string) {\n\tfmt.Printf(\"Deployment: Transferring artifact from %s to %s...\\n\", artifactPath, serverAddress)\n\tsimulateDelay()\n\tfmt.Println(\"Deployment: Transfer complete.\")\n}\n\n// ActivateNewVersion activates the new version on the target server\nfunc (d *DeploymentTarget) ActivateNewVersion(serverAddress string) {\n\tfmt.Printf(\"Deployment: Activating new version on %s...\\n\", serverAddress)\n\tsimulateDelay()\n\tfmt.Println(\"Deployment: Activation complete.\")\n}\n"
  },
  {
    "path": "design-patterns/golang/facade/go.mod",
    "content": "module facade\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/facade/main.go",
    "content": "package facade\n\nimport \"fmt\"\n\nfunc main() {\n\t// Create the deployment facade\n\tdeploymentFacade := NewDeploymentFacade()\n\n\t// Perform a full deployment\n\tfmt.Println(\"=== Performing Full Deployment ===\")\n\tsuccess := deploymentFacade.DeployApplication(\"main\", \"production-server\")\n\tif !success {\n\t\tfmt.Println(\"Full deployment failed!\")\n\t}\n\n\t// Perform a hotfix deployment\n\tfmt.Println(\"\\n=== Performing Hotfix Deployment ===\")\n\tsuccess = deploymentFacade.DeployHotfix(\"hotfix-123\", \"production-server\")\n\tif !success {\n\t\tfmt.Println(\"Hotfix deployment failed!\")\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/facade/testing_framework.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/facade/version_control_system.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/factory/email_notification.go",
    "content": "package factory\n\nimport \"fmt\"\n\n// EmailNotification represents an email notification\ntype EmailNotification struct{}\n\n// NewEmailNotification creates a new EmailNotification instance\nfunc NewEmailNotification() *EmailNotification {\n\treturn &EmailNotification{}\n}\n\n// Send sends an email notification\nfunc (e *EmailNotification) Send(message string) {\n\tfmt.Printf(\"Sending email: %s\\n\", message)\n}\n"
  },
  {
    "path": "design-patterns/golang/factory/go.mod",
    "content": "module factory\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/factory/main.go",
    "content": "package factory\n\nimport \"fmt\"\n\nfunc main() {\n\t// Create the factory\n\tfactory := NewSimpleNotificationFactory()\n\n\t// Create and send different types of notifications\n\tnotifications := []string{\"EMAIL\", \"SMS\", \"PUSH\"}\n\tmessages := []string{\n\t\t\"Welcome to our platform!\",\n\t\t\"Your OTP is 123456\",\n\t\t\"You have a new follower!\",\n\t}\n\n\tfor i, notificationType := range notifications {\n\t\tnotification, err := factory.CreateNotification(notificationType)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error creating notification: %v\\n\", err)\n\t\t\tcontinue\n\t\t}\n\t\tnotification.Send(messages[i])\n\t}\n} "
  },
  {
    "path": "design-patterns/golang/factory/notification.go",
    "content": "package factory\n\n// Notification defines the interface for all notification types\ntype Notification interface {\n\tSend(message string)\n}\n"
  },
  {
    "path": "design-patterns/golang/factory/push_notification.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/factory/simple_notification_factory.go",
    "content": "package factory\n\n// SimpleNotificationFactory creates different types of notifications\ntype SimpleNotificationFactory struct{}\n\n// NewSimpleNotificationFactory creates a new SimpleNotificationFactory instance\nfunc NewSimpleNotificationFactory() *SimpleNotificationFactory {\n\treturn &SimpleNotificationFactory{}\n}\n\n// CreateNotification creates a notification based on the type\nfunc (f *SimpleNotificationFactory) CreateNotification(notificationType string) (Notification, error) {\n\tswitch notificationType {\n\tcase \"EMAIL\":\n\t\treturn NewEmailNotification(), nil\n\tcase \"SMS\":\n\t\treturn NewSMSNotification(), nil\n\tcase \"PUSH\":\n\t\treturn NewPushNotification(), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown notification type: %s\", notificationType)\n\t}\n} "
  },
  {
    "path": "design-patterns/golang/factory/sms_notification.go",
    "content": "package factory\n\nimport \"fmt\"\n\n// SMSNotification represents an SMS notification\ntype SMSNotification struct{}\n\n// NewSMSNotification creates a new SMSNotification instance\nfunc NewSMSNotification() *SMSNotification {\n\treturn &SMSNotification{}\n}\n\n// Send sends an SMS notification\nfunc (s *SMSNotification) Send(message string) {\n\tfmt.Printf(\"Sending SMS: %s\\n\", message)\n}\n"
  },
  {
    "path": "design-patterns/golang/flyweight/character_flyweight.go",
    "content": "package flyweight\n\n// CharacterFlyweight defines the interface for character glyphs\ntype CharacterFlyweight interface {\n\tDraw(x, y int)\n}\n"
  },
  {
    "path": "design-patterns/golang/flyweight/character_flyweight_factory.go",
    "content": "package flyweight\n\nimport \"fmt\"\n\n// CharacterFlyweightFactory manages the flyweight objects\ntype CharacterFlyweightFactory struct {\n\tflyweightCache map[string]CharacterFlyweight\n}\n\n// NewCharacterFlyweightFactory creates a new CharacterFlyweightFactory instance\nfunc NewCharacterFlyweightFactory() *CharacterFlyweightFactory {\n\treturn &CharacterFlyweightFactory{\n\t\tflyweightCache: make(map[string]CharacterFlyweight),\n\t}\n}\n\n// GetFlyweight returns a flyweight object for the given character properties\nfunc (f *CharacterFlyweightFactory) GetFlyweight(symbol rune, fontFamily string, fontSize int, color string) CharacterFlyweight {\n\tkey := fmt.Sprintf(\"%c-%d-%s\", symbol, fontSize, color)\n\tif _, exists := f.flyweightCache[key]; !exists {\n\t\tf.flyweightCache[key] = NewCharacterGlyph(symbol, fontFamily, fontSize, color)\n\t}\n\treturn f.flyweightCache[key]\n}\n\n// GetFlyweightCount returns the number of unique flyweight objects\nfunc (f *CharacterFlyweightFactory) GetFlyweightCount() int {\n\treturn len(f.flyweightCache)\n}\n"
  },
  {
    "path": "design-patterns/golang/flyweight/character_glyph.go",
    "content": "package flyweight\n\nimport \"fmt\"\n\n// CharacterGlyph represents a character with its intrinsic properties\ntype CharacterGlyph struct {\n\tsymbol     rune\n\tfontFamily string\n\tfontSize   int\n\tcolor      string\n}\n\n// NewCharacterGlyph creates a new CharacterGlyph instance\nfunc NewCharacterGlyph(symbol rune, fontFamily string, fontSize int, color string) *CharacterGlyph {\n\treturn &CharacterGlyph{\n\t\tsymbol:     symbol,\n\t\tfontFamily: fontFamily,\n\t\tfontSize:   fontSize,\n\t\tcolor:      color,\n\t}\n}\n\n// Draw renders the character at the specified position\nfunc (g *CharacterGlyph) Draw(x, y int) {\n\tfmt.Printf(\"Rendering %c at (%d, %d) with font %s, size %d, color %s\\n\",\n\t\tg.symbol, x, y, g.fontFamily, g.fontSize, g.color)\n}\n"
  },
  {
    "path": "design-patterns/golang/flyweight/go.mod",
    "content": "module flyweight\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/flyweight/main.go",
    "content": "package flyweight\n\nimport \"fmt\"\n\nfunc main() {\n\t// Create a text editor client\n\teditor := NewTextEditorClient()\n\n\t// Render some text with the same properties\n\tfmt.Println(\"Rendering text with same properties:\")\n\teditor.RenderText(\"Hello\", 0, 0, \"Arial\", 12, \"black\")\n\tfmt.Printf(\"Number of unique characters: %d\\n\\n\", editor.GetUniqueCharacterCount())\n\n\t// Render the same text with different properties\n\tfmt.Println(\"Rendering text with different properties:\")\n\teditor.RenderText(\"Hello\", 0, 20, \"Times New Roman\", 14, \"blue\")\n\tfmt.Printf(\"Number of unique characters: %d\\n\\n\", editor.GetUniqueCharacterCount())\n\n\t// Render text with mixed properties\n\tfmt.Println(\"Rendering text with mixed properties:\")\n\teditor.RenderText(\"World\", 0, 40, \"Arial\", 12, \"red\")\n\tfmt.Printf(\"Number of unique characters: %d\\n\", editor.GetUniqueCharacterCount())\n}\n"
  },
  {
    "path": "design-patterns/golang/flyweight/text_editor_client.go",
    "content": "package flyweight\n\n// TextEditorClient represents a client that uses the flyweight objects\ntype TextEditorClient struct {\n\tfactory *CharacterFlyweightFactory\n}\n\n// NewTextEditorClient creates a new TextEditorClient instance\nfunc NewTextEditorClient() *TextEditorClient {\n\treturn &TextEditorClient{\n\t\tfactory: NewCharacterFlyweightFactory(),\n\t}\n}\n\n// RenderText renders a text string using flyweight objects\nfunc (c *TextEditorClient) RenderText(text string, x, y int, fontFamily string, fontSize int, color string) {\n\tfor i, char := range text {\n\t\tflyweight := c.factory.GetFlyweight(char, fontFamily, fontSize, color)\n\t\tflyweight.Draw(x+i*fontSize, y)\n\t}\n}\n\n// GetUniqueCharacterCount returns the number of unique character flyweights\nfunc (c *TextEditorClient) GetUniqueCharacterCount() int {\n\treturn c.factory.GetFlyweightCount()\n}\n"
  },
  {
    "path": "design-patterns/golang/iterator/book.go",
    "content": "package iterator\n\n// Book represents a book with title and author\ntype Book struct {\n\tTitle  string\n\tAuthor string\n}\n\n// NewBook creates a new Book instance\nfunc NewBook(title, author string) *Book {\n\treturn &Book{\n\t\tTitle:  title,\n\t\tAuthor: author,\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/iterator/book_collection.go",
    "content": "package iterator\n\n// BookCollection represents a collection of books\ntype BookCollection struct {\n\tbooks []*Book\n}\n\n// NewBookCollection creates a new BookCollection instance\nfunc NewBookCollection() *BookCollection {\n\treturn &BookCollection{\n\t\tbooks: make([]*Book, 0),\n\t}\n}\n\n// AddBook adds a book to the collection\nfunc (bc *BookCollection) AddBook(book *Book) {\n\tbc.books = append(bc.books, book)\n}\n\n// CreateIterator creates a new iterator for the book collection\nfunc (bc *BookCollection) CreateIterator() Iterator {\n\treturn NewBookIterator(bc)\n}\n\n// BookIterator represents an iterator for the book collection\ntype BookIterator struct {\n\tcollection *BookCollection\n\tindex      int\n}\n\n// NewBookIterator creates a new BookIterator instance\nfunc NewBookIterator(collection *BookCollection) *BookIterator {\n\treturn &BookIterator{\n\t\tcollection: collection,\n\t\tindex:      0,\n\t}\n}\n\n// HasNext checks if there are more books to iterate\nfunc (bi *BookIterator) HasNext() bool {\n\treturn bi.index < len(bi.collection.books)\n}\n\n// Next returns the next book in the collection\nfunc (bi *BookIterator) Next() interface{} {\n\tif bi.HasNext() {\n\t\tbook := bi.collection.books[bi.index]\n\t\tbi.index++\n\t\treturn book\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "design-patterns/golang/iterator/collection.go",
    "content": "package iterator\n\n// Collection defines the interface for creating an iterator\ntype Collection interface {\n\tCreateIterator() Iterator\n}\n"
  },
  {
    "path": "design-patterns/golang/iterator/go.mod",
    "content": "module iterator\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/iterator/iterator.go",
    "content": "package iterator\n\n// Iterator defines the interface for traversing a collection\ntype Iterator interface {\n\tHasNext() bool\n\tNext() interface{}\n}\n"
  },
  {
    "path": "design-patterns/golang/iterator/main.go",
    "content": "package iterator\n\nimport \"fmt\"\n\nfunc main() {\n\t// Create a book collection\n\tcollection := NewBookCollection()\n\n\t// Add some books to the collection\n\tcollection.AddBook(NewBook(\"The Great Gatsby\", \"F. Scott Fitzgerald\"))\n\tcollection.AddBook(NewBook(\"To Kill a Mockingbird\", \"Harper Lee\"))\n\tcollection.AddBook(NewBook(\"1984\", \"George Orwell\"))\n\n\t// Create an iterator for the collection\n\titerator := collection.CreateIterator()\n\n\t// Iterate through the books\n\tfmt.Println(\"Iterating through the book collection:\")\n\tfor iterator.HasNext() {\n\t\tbook := iterator.Next().(*Book)\n\t\tfmt.Printf(\"Book: %s by %s\\n\", book.Title, book.Author)\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/mediator/chat_mediator.go",
    "content": "package mediator\n\n// ChatMediator is a concrete mediator that manages users\ntype ChatMediator struct {\n\tusers []Colleague\n}\n\n// NewChatMediator creates a new ChatMediator\nfunc NewChatMediator() *ChatMediator {\n\treturn &ChatMediator{users: make([]Colleague, 0)}\n}\n\n// AddUser adds a user to the chat\nfunc (m *ChatMediator) AddUser(user Colleague) {\n\tm.users = append(m.users, user)\n\tuser.SetMediator(m)\n}\n\n// SendMessage sends a message from one user to all others\nfunc (m *ChatMediator) SendMessage(message string, sender Colleague) {\n\tfor _, user := range m.users {\n\t\tif user != sender {\n\t\t\tuser.ReceiveMessage(sender.GetName() + \": \" + message)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/mediator/colleague.go",
    "content": "package mediator\n\n// Colleague defines the interface for participants in the communication\ntype Colleague interface {\n\tSetMediator(mediator Mediator)\n\tGetName() string\n\tReceiveMessage(message string)\n}\n"
  },
  {
    "path": "design-patterns/golang/mediator/main.go",
    "content": "package mediator\n\nfunc main() {\n\tmediator := NewChatMediator()\n\n\talice := NewUser(\"Alice\")\n\tbob := NewUser(\"Bob\")\n\tcarol := NewUser(\"Carol\")\n\n\tmediator.AddUser(alice)\n\tmediator.AddUser(bob)\n\tmediator.AddUser(carol)\n\n\talice.SendMessage(\"Hello, everyone!\")\n\tbob.SendMessage(\"Hi Alice!\")\n\tcarol.SendMessage(\"Hey folks!\")\n}\n"
  },
  {
    "path": "design-patterns/golang/mediator/mediator.go",
    "content": "package mediator\n\n// Mediator defines the interface for communication between colleagues\ntype Mediator interface {\n\tSendMessage(message string, colleague Colleague)\n}\n"
  },
  {
    "path": "design-patterns/golang/mediator/user.go",
    "content": "package mediator\n\nimport \"fmt\"\n\n// User represents a concrete colleague\ntype User struct {\n\tname     string\n\tmediator Mediator\n}\n\n// NewUser creates a new User\nfunc NewUser(name string) *User {\n\treturn &User{name: name}\n}\n\nfunc (u *User) SetMediator(mediator Mediator) {\n\tu.mediator = mediator\n}\n\nfunc (u *User) GetName() string {\n\treturn u.name\n}\n\nfunc (u *User) ReceiveMessage(message string) {\n\tfmt.Printf(\"%s received: %s\\n\", u.name, message)\n}\n\n// SendMessage allows the user to send a message via the mediator\nfunc (u *User) SendMessage(message string) {\n\tif u.mediator != nil {\n\t\tu.mediator.SendMessage(message, u)\n\t}\n}\n"
  },
  {
    "path": "design-patterns/golang/memento/go.mod",
    "content": "module memento\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/memento/main.go",
    "content": "package memento\n\nimport \"fmt\"\n\nfunc main() {\n\teditor := NewTextEditor()\n\tundoManager := NewTextEditorUndoManager()\n\n\teditor.Type(\"Hello, \")\n\tundoManager.Save(editor)\n\n\teditor.Type(\"world!\")\n\tundoManager.Save(editor)\n\n\teditor.Type(\" This is a test.\")\n\tfmt.Println(\"Current content:\", editor.GetContent())\n\n\tundoManager.Undo(editor)\n\tfmt.Println(\"After undo:\", editor.GetContent())\n\n\tundoManager.Undo(editor)\n\tfmt.Println(\"After second undo:\", editor.GetContent())\n\n\tundoManager.Undo(editor)\n}\n"
  },
  {
    "path": "design-patterns/golang/memento/text_editor.go",
    "content": "package memento\n\nimport \"fmt\"\n\n// TextEditor is the originator that can save and restore its state\ntype TextEditor struct {\n\tcontent string\n}\n\n// NewTextEditor creates a new TextEditor\nfunc NewTextEditor() *TextEditor {\n\treturn &TextEditor{}\n}\n\n// Type appends text to the editor\nfunc (e *TextEditor) Type(words string) {\n\te.content += words\n\tfmt.Printf(\"Typed: %s\\n\", words)\n}\n\n// GetContent returns the current content\nfunc (e *TextEditor) GetContent() string {\n\treturn e.content\n}\n\n// Save creates a memento of the current state\nfunc (e *TextEditor) Save() *TextEditorMemento {\n\tfmt.Printf(\"Saved state: %s\\n\", e.content)\n\treturn NewTextEditorMemento(e.content)\n}\n\n// Restore restores the state from a memento\nfunc (e *TextEditor) Restore(memento *TextEditorMemento) {\n\te.content = memento.State\n\tfmt.Printf(\"Restored state: %s\\n\", e.content)\n}\n"
  },
  {
    "path": "design-patterns/golang/memento/text_editor_memento.go",
    "content": "package memento\n\n// TextEditorMemento stores the state of the TextEditor\ntype TextEditorMemento struct {\n\tState string\n}\n\n// NewTextEditorMemento creates a new memento with the given state\nfunc NewTextEditorMemento(state string) *TextEditorMemento {\n\treturn &TextEditorMemento{State: state}\n}\n"
  },
  {
    "path": "design-patterns/golang/memento/text_editor_undo_manager.go",
    "content": "package memento\n\nimport \"fmt\"\n\n// TextEditorUndoManager manages the undo stack for the TextEditor\ntype TextEditorUndoManager struct {\n\thistory []*TextEditorMemento\n}\n\n// NewTextEditorUndoManager creates a new undo manager\nfunc NewTextEditorUndoManager() *TextEditorUndoManager {\n\treturn &TextEditorUndoManager{history: make([]*TextEditorMemento, 0)}\n}\n\n// Save saves the current state of the editor\nfunc (m *TextEditorUndoManager) Save(editor *TextEditor) {\n\tm.history = append(m.history, editor.Save())\n}\n\n// Undo restores the last saved state\nfunc (m *TextEditorUndoManager) Undo(editor *TextEditor) {\n\tn := len(m.history)\n\tif n == 0 {\n\t\tfmt.Println(\"Nothing to undo.\")\n\t\treturn\n\t}\n\tlast := m.history[n-1]\n\tm.history = m.history[:n-1]\n\teditor.Restore(last)\n}\n"
  },
  {
    "path": "design-patterns/golang/observer/fitness_data.go",
    "content": "package observer\n\n// FitnessData is the concrete subject that manages observers and fitness data\ntype FitnessData struct {\n\tobservers []FitnessDataObserver\n\tsteps     int\n\tcalories  int\n\tdistance  float64\n}\n\n// NewFitnessData creates a new FitnessData instance\nfunc NewFitnessData() *FitnessData {\n\treturn &FitnessData{\n\t\tobservers: make([]FitnessDataObserver, 0),\n\t}\n}\n\nfunc (f *FitnessData) RegisterObserver(observer FitnessDataObserver) {\n\tf.observers = append(f.observers, observer)\n}\n\nfunc (f *FitnessData) RemoveObserver(observer FitnessDataObserver) {\n\tfor i, obs := range f.observers {\n\t\tif obs == observer {\n\t\t\tf.observers = append(f.observers[:i], f.observers[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (f *FitnessData) NotifyObservers() {\n\tfor _, observer := range f.observers {\n\t\tobserver.Update(f.steps, f.calories, f.distance)\n\t}\n}\n\n// SetMeasurements updates the fitness data and notifies observers\nfunc (f *FitnessData) SetMeasurements(steps int, calories int, distance float64) {\n\tf.steps = steps\n\tf.calories = calories\n\tf.distance = distance\n\tf.NotifyObservers()\n}\n"
  },
  {
    "path": "design-patterns/golang/observer/fitness_data_observer.go",
    "content": "package observer\n\n// FitnessDataObserver defines the interface for observers\ntype FitnessDataObserver interface {\n\tUpdate(steps int, calories int, distance float64)\n}\n"
  },
  {
    "path": "design-patterns/golang/observer/fitness_data_subject.go",
    "content": "package observer\n\n// FitnessDataSubject defines the interface for the subject\ntype FitnessDataSubject interface {\n\tRegisterObserver(observer FitnessDataObserver)\n\tRemoveObserver(observer FitnessDataObserver)\n\tNotifyObservers()\n}\n"
  },
  {
    "path": "design-patterns/golang/observer/go.mod",
    "content": "module observer\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/observer/goal_notifier.go",
    "content": "package observer\n\nimport \"fmt\"\n\n// GoalNotifier notifies when a goal is reached\ntype GoalNotifier struct {\n\tgoalSteps int\n}\n\nfunc NewGoalNotifier(goalSteps int) *GoalNotifier {\n\treturn &GoalNotifier{goalSteps: goalSteps}\n}\n\nfunc (g *GoalNotifier) Update(steps int, calories int, distance float64) {\n\tif steps >= g.goalSteps {\n\t\tfmt.Printf(\"[GoalNotifier] Congratulations! Goal of %d steps reached!\\n\", g.goalSteps)\n\t} else {\n\t\tfmt.Printf(\"[GoalNotifier] %d steps to go to reach your goal of %d steps.\\n\", g.goalSteps-steps, g.goalSteps)\n\t}\n} "
  },
  {
    "path": "design-patterns/golang/observer/live_activity_display.go",
    "content": "package observer\n\nimport \"fmt\"\n\n// LiveActivityDisplay displays live activity updates\ntype LiveActivityDisplay struct{}\n\nfunc NewLiveActivityDisplay() *LiveActivityDisplay {\n\treturn &LiveActivityDisplay{}\n}\n\nfunc (l *LiveActivityDisplay) Update(steps int, calories int, distance float64) {\n\tfmt.Printf(\"[LiveActivityDisplay] Steps: %d, Calories: %d, Distance: %.2f km\\n\", steps, calories, distance)\n}\n"
  },
  {
    "path": "design-patterns/golang/observer/main.go",
    "content": "package observer\n\nfunc main() {\n\tfitnessData := NewFitnessData()\n\n\tliveDisplay := NewLiveActivityDisplay()\n\tlogger := NewProgressLogger()\n\tgoalNotifier := NewGoalNotifier(10000)\n\n\tfitnessData.RegisterObserver(liveDisplay)\n\tfitnessData.RegisterObserver(logger)\n\tfitnessData.RegisterObserver(goalNotifier)\n\n\tfitnessData.SetMeasurements(3000, 120, 2.5)\n\tfitnessData.SetMeasurements(7000, 250, 5.0)\n\tfitnessData.SetMeasurements(10000, 400, 8.0)\n\n\tfitnessData.RemoveObserver(logger)\n\tfitnessData.SetMeasurements(12000, 500, 10.0)\n} "
  },
  {
    "path": "design-patterns/golang/observer/progress_logger.go",
    "content": "package observer\n\nimport \"fmt\"\n\n// ProgressLogger logs progress updates\ntype ProgressLogger struct{}\n\nfunc NewProgressLogger() *ProgressLogger {\n\treturn &ProgressLogger{}\n}\n\nfunc (p *ProgressLogger) Update(steps int, calories int, distance float64) {\n\tfmt.Printf(\"[ProgressLogger] Progress logged: %d steps, %d calories, %.2f km\\n\", steps, calories, distance)\n}\n"
  },
  {
    "path": "design-patterns/golang/prototype/enemy.go",
    "content": "package prototype\n\nimport \"fmt\"\n\n// Enemy represents a game enemy\ntype Enemy struct {\n\tType    string\n\tHealth  int\n\tSpeed   float64\n\tArmored bool\n\tWeapon  string\n}\n\n// NewEnemy creates a new Enemy instance\nfunc NewEnemy(type_ string, health int, speed float64, armored bool, weapon string) *Enemy {\n\treturn &Enemy{\n\t\tType:    type_,\n\t\tHealth:  health,\n\t\tSpeed:   speed,\n\t\tArmored: armored,\n\t\tWeapon:  weapon,\n\t}\n}\n\n// Clone creates a copy of the enemy\nfunc (e *Enemy) Clone() EnemyPrototype {\n\treturn NewEnemy(e.Type, e.Health, e.Speed, e.Armored, e.Weapon)\n}\n\n// SetHealth updates the enemy's health\nfunc (e *Enemy) SetHealth(health int) {\n\te.Health = health\n}\n\n// PrintStats displays the enemy's statistics\nfunc (e *Enemy) PrintStats() {\n\tfmt.Printf(\"%s [Health: %d, Speed: %.1f, Armored: %v, Weapon: %s]\\n\",\n\t\te.Type, e.Health, e.Speed, e.Armored, e.Weapon)\n} "
  },
  {
    "path": "design-patterns/golang/prototype/enemy_prototype.go",
    "content": "package prototype\n\n// EnemyPrototype defines the interface for cloneable enemies\ntype EnemyPrototype interface {\n\tClone() EnemyPrototype\n}\n"
  },
  {
    "path": "design-patterns/golang/prototype/enemy_registry.go",
    "content": "package prototype\n\n// EnemyRegistry manages enemy prototypes\ntype EnemyRegistry struct {\n\tprototypes map[string]*Enemy\n}\n\n// NewEnemyRegistry creates a new EnemyRegistry\nfunc NewEnemyRegistry() *EnemyRegistry {\n\treturn &EnemyRegistry{\n\t\tprototypes: make(map[string]*Enemy),\n\t}\n}\n\n// Register adds a prototype to the registry\nfunc (r *EnemyRegistry) Register(key string, prototype *Enemy) {\n\tr.prototypes[key] = prototype\n}\n\n// Get retrieves and clones a prototype from the registry\nfunc (r *EnemyRegistry) Get(key string) *Enemy {\n\tif prototype, exists := r.prototypes[key]; exists {\n\t\treturn prototype.Clone().(*Enemy)\n\t}\n\tpanic(\"No prototype registered for: \" + key)\n}\n"
  },
  {
    "path": "design-patterns/golang/prototype/go.mod",
    "content": "module prototype\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/prototype/main.go",
    "content": "package prototype\n\nfunc main() {\n\tregistry := NewEnemyRegistry()\n\n\t// Register prototype enemies\n\tregistry.Register(\"flying\", NewEnemy(\"FlyingEnemy\", 100, 12.0, false, \"Laser\"))\n\tregistry.Register(\"armored\", NewEnemy(\"ArmoredEnemy\", 300, 6.0, true, \"Cannon\"))\n\n\t// Clone from registry\n\te1 := registry.Get(\"flying\")\n\te2 := registry.Get(\"flying\")\n\te2.SetHealth(80) // this one is damaged\n\n\te3 := registry.Get(\"armored\")\n\n\t// Print enemy stats\n\te1.PrintStats()\n\te2.PrintStats()\n\te3.PrintStats()\n}\n"
  },
  {
    "path": "design-patterns/golang/proxy/go.mod",
    "content": "module proxy\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/proxy/high_resolution_image.go",
    "content": "package proxy\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// HighResolutionImage represents a high-resolution image\ntype HighResolutionImage struct {\n\tfileName  string\n\timageData []byte // Simulate large data\n}\n\n// NewHighResolutionImage creates a new HighResolutionImage\nfunc NewHighResolutionImage(fileName string) *HighResolutionImage {\n\timage := &HighResolutionImage{fileName: fileName}\n\timage.loadImageFromDisk() // Expensive operation!\n\treturn image\n}\n\nfunc (i *HighResolutionImage) loadImageFromDisk() {\n\tfmt.Printf(\"Loading image: %s from disk (Expensive Operation)...\\n\", i.fileName)\n\t// Simulate disk read and memory allocation\n\ttime.Sleep(2 * time.Second)              // Simulate delay\n\ti.imageData = make([]byte, 10*1024*1024) // 10MB\n\tfmt.Printf(\"Image %s loaded successfully.\\n\", i.fileName)\n}\n\nfunc (i *HighResolutionImage) Display() {\n\tfmt.Printf(\"Displaying image: %s\\n\", i.fileName)\n\t// Actual rendering logic would go here\n}\n\nfunc (i *HighResolutionImage) GetFileName() string {\n\treturn i.fileName\n}\n"
  },
  {
    "path": "design-patterns/golang/proxy/image.go",
    "content": "package proxy\n\n// Image defines the interface for image operations\ntype Image interface {\n\tDisplay()\n\tGetFileName() string\n}\n"
  },
  {
    "path": "design-patterns/golang/proxy/image_proxy.go",
    "content": "package proxy\n\nimport \"fmt\"\n\n// ImageProxy represents a proxy for high-resolution images\ntype ImageProxy struct {\n\tfileName  string\n\trealImage *HighResolutionImage // RealSubject\n}\n\n// NewImageProxy creates a new ImageProxy\nfunc NewImageProxy(fileName string) *ImageProxy {\n\tfmt.Printf(\"ImageProxy: Created for %s. Real image not loaded yet.\\n\", fileName)\n\treturn &ImageProxy{fileName: fileName}\n}\n\nfunc (p *ImageProxy) GetFileName() string {\n\t// Can safely return without loading the image\n\treturn p.fileName\n}\n\nfunc (p *ImageProxy) Display() {\n\t// Lazy initialization: Load only when Display() is called\n\tif p.realImage == nil {\n\t\tfmt.Printf(\"ImageProxy: Display() requested for %s. Loading high-resolution image...\\n\", p.fileName)\n\t\tp.realImage = NewHighResolutionImage(p.fileName)\n\t} else {\n\t\tfmt.Printf(\"ImageProxy: Using cached high-resolution image for %s\\n\", p.fileName)\n\t}\n\n\t// Delegate the display call to the real image\n\tp.realImage.Display()\n}\n"
  },
  {
    "path": "design-patterns/golang/proxy/main.go",
    "content": "package proxy\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Println(\"Application Started. Initializing image proxies for gallery...\")\n\n\t// Create lightweight proxies instead of full image objects\n\timage1 := NewImageProxy(\"photo1.jpg\")\n\timage2 := NewImageProxy(\"photo2.png\") // Never displayed\n\timage3 := NewImageProxy(\"photo3.gif\")\n\n\tfmt.Println(\"\\nGallery initialized. No images actually loaded yet.\")\n\tfmt.Printf(\"Image 1 Filename: %s\\n\", image1.GetFileName()) // Does not trigger image load\n\n\t// User clicks on image1\n\tfmt.Printf(\"\\nUser requests to display %s\\n\", image1.GetFileName())\n\timage1.Display() // Lazy loading happens here\n\n\t// User clicks on image1 again\n\tfmt.Printf(\"\\nUser requests to display %s again.\\n\", image1.GetFileName())\n\timage1.Display() // Already loaded; no loading delay\n\n\t// User clicks on image3\n\tfmt.Printf(\"\\nUser requests to display %s\\n\", image3.GetFileName())\n\timage3.Display() // Triggers loading for image3\n\n\tfmt.Println(\"\\nApplication finished. Note: photo2.png was never loaded.\")\n}\n"
  },
  {
    "path": "design-patterns/golang/singleton/double_checked_singleton.go",
    "content": "package singleton\n\nimport \"sync\"\n\n// DoubleCheckedSingleton implements double-checked locking singleton pattern\ntype DoubleCheckedSingleton struct{}\n\nvar (\n\tdoubleCheckedInstance *DoubleCheckedSingleton\n\tdcMu                  sync.Mutex\n)\n\n// GetDoubleCheckedInstance returns the singleton instance\nfunc GetDoubleCheckedInstance() *DoubleCheckedSingleton {\n\tif doubleCheckedInstance == nil {\n\t\tdcMu.Lock()\n\t\tdefer dcMu.Unlock()\n\n\t\tif doubleCheckedInstance == nil {\n\t\t\tdoubleCheckedInstance = &DoubleCheckedSingleton{}\n\t\t}\n\t}\n\treturn doubleCheckedInstance\n}\n"
  },
  {
    "path": "design-patterns/golang/singleton/eager_singleton.go",
    "content": "package singleton\n\n// EagerSingleton implements eager initialization singleton pattern\ntype EagerSingleton struct{}\n\n// The single instance, created immediately\nvar instance = &EagerSingleton{}\n\n// GetInstance returns the singleton instance\nfunc GetInstance() *EagerSingleton {\n\treturn instance\n}\n"
  },
  {
    "path": "design-patterns/golang/singleton/go.mod",
    "content": "module singleton\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/singleton/lazy_singleton.go",
    "content": "package singleton\n\nimport \"sync\"\n\n// LazySingleton implements lazy initialization singleton pattern\ntype LazySingleton struct{}\n\nvar (\n\tinstance *LazySingleton\n\tonce     sync.Once\n)\n\n// GetInstance returns the singleton instance\nfunc GetInstance() *LazySingleton {\n\tonce.Do(func() {\n\t\tinstance = &LazySingleton{}\n\t})\n\treturn instance\n}\n"
  },
  {
    "path": "design-patterns/golang/singleton/main.go",
    "content": " "
  },
  {
    "path": "design-patterns/golang/singleton/thread_safe_singleton.go",
    "content": "package singleton\n\nimport \"sync\"\n\n// ThreadSafeSingleton implements thread-safe singleton pattern\ntype ThreadSafeSingleton struct{}\n\nvar (\n\tthreadSafeInstance *ThreadSafeSingleton\n\tmu                 sync.Mutex\n)\n\n// GetThreadSafeInstance returns the singleton instance\nfunc GetThreadSafeInstance() *ThreadSafeSingleton {\n\tmu.Lock()\n\tdefer mu.Unlock()\n\n\tif threadSafeInstance == nil {\n\t\tthreadSafeInstance = &ThreadSafeSingleton{}\n\t}\n\treturn threadSafeInstance\n}\n"
  },
  {
    "path": "design-patterns/golang/state/go.mod",
    "content": "module state\n\ngo 1.21 "
  },
  {
    "path": "design-patterns/golang/state/has_money_state.go",
    "content": "package state\n\nimport \"fmt\"\n\n// HasMoneyState represents the state after money is inserted\ntype HasMoneyState struct{}\n\nfunc (s *HasMoneyState) SelectItem(context *VendingMachine, item string) {\n\tfmt.Println(\"Transaction in progress. Please wait.\")\n}\n\nfunc (s *HasMoneyState) InsertCoin(context *VendingMachine, amount float64) {\n\tfmt.Println(\"Already received money. Dispensing item...\")\n}\n\nfunc (s *HasMoneyState) DispenseItem(context *VendingMachine) {\n\titem := context.GetSelectedItem()\n\tamt := context.GetInsertedAmount()\n\tfmt.Printf(\"Dispensing '%s' for $%.2f. Thank you!\\n\", item, amt)\n\tcontext.Reset()\n}\n"
  },
  {
    "path": "design-patterns/golang/state/idle_state.go",
    "content": "package state\n\nimport \"fmt\"\n\n// IdleState represents the state when the machine is waiting for item selection\ntype IdleState struct{}\n\nfunc (s *IdleState) SelectItem(context *VendingMachine, item string) {\n\tfmt.Printf(\"Item '%s' selected. Please insert coins.\\n\", item)\n\tcontext.SetSelectedItem(item)\n\tcontext.SetState(&ItemSelectedState{})\n}\n\nfunc (s *IdleState) InsertCoin(context *VendingMachine, amount float64) {\n\tfmt.Println(\"Please select an item first.\")\n}\n\nfunc (s *IdleState) DispenseItem(context *VendingMachine) {\n\tfmt.Println(\"Please select an item and insert coins first.\")\n}\n"
  },
  {
    "path": "design-patterns/golang/state/item_selected_state.go",
    "content": "package state\n\nimport \"fmt\"\n\n// ItemSelectedState represents the state after an item is selected\ntype ItemSelectedState struct{}\n\nfunc (s *ItemSelectedState) SelectItem(context *VendingMachine, item string) {\n\tfmt.Println(\"Item already selected. Please insert coins.\")\n}\n\nfunc (s *ItemSelectedState) InsertCoin(context *VendingMachine, amount float64) {\n\tfmt.Printf(\"Inserted $%.2f.\\n\", amount)\n\tcontext.SetInsertedAmount(amount)\n\tcontext.SetState(&HasMoneyState{})\n}\n\nfunc (s *ItemSelectedState) DispenseItem(context *VendingMachine) {\n\tfmt.Println(\"Please insert coins before dispensing the item.\")\n}\n"
  },
  {
    "path": "design-patterns/golang/state/machine_state.go",
    "content": "package state\n\n// MachineState defines the interface for vending machine states\ntype MachineState interface {\n\tSelectItem(context *VendingMachine, item string)\n\tInsertCoin(context *VendingMachine, amount float64)\n\tDispenseItem(context *VendingMachine)\n}\n"
  },
  {
    "path": "design-patterns/golang/state/main.go",
    "content": "package state\n\nfunc main() {\n\tvm := NewVendingMachine()\n\n\t// Try to insert coin before selecting item\n\tvm.InsertCoin(1.0)\n\n\t// Select an item\n\tvm.SelectItem(\"Soda\")\n\n\t// Insert coin\n\tvm.InsertCoin(1.5)\n\n\t// Dispense item\n\tvm.DispenseItem()\n\n\t// Try another transaction\n\tvm.SelectItem(\"Chips\")\n\tvm.InsertCoin(2.0)\n\tvm.DispenseItem()\n}\n"
  },
  {
    "path": "design-patterns/golang/state/vending_machine.go",
    "content": "package state\n\nimport \"fmt\"\n\n// VendingMachine is the context that maintains the current state\ntype VendingMachine struct {\n\tstate        MachineState\n\tselectedItem string\n\tinsertedAmt  float64\n}\n\nfunc NewVendingMachine() *VendingMachine {\n\treturn &VendingMachine{\n\t\tstate: &IdleState{},\n\t}\n}\n\nfunc (vm *VendingMachine) SetState(state MachineState) {\n\tvm.state = state\n}\n\nfunc (vm *VendingMachine) SetSelectedItem(item string) {\n\tvm.selectedItem = item\n}\n\nfunc (vm *VendingMachine) SetInsertedAmount(amount float64) {\n\tvm.insertedAmt = amount\n}\n\nfunc (vm *VendingMachine) GetSelectedItem() string {\n\treturn vm.selectedItem\n}\n\nfunc (vm *VendingMachine) GetInsertedAmount() float64 {\n\treturn vm.insertedAmt\n}\n\nfunc (vm *VendingMachine) SelectItem(item string) {\n\tvm.state.SelectItem(vm, item)\n}\n\nfunc (vm *VendingMachine) InsertCoin(amount float64) {\n\tvm.state.InsertCoin(vm, amount)\n}\n\nfunc (vm *VendingMachine) DispenseItem() {\n\tvm.state.DispenseItem(vm)\n}\n\nfunc (vm *VendingMachine) Reset() {\n\tfmt.Println(\"Resetting vending machine...\")\n\tvm.selectedItem = \"\"\n\tvm.insertedAmt = 0\n\tvm.state = &IdleState{}\n}\n"
  },
  {
    "path": "design-patterns/golang/strategy/credit_card_payment.go",
    "content": "package strategy\n\nimport \"fmt\"\n\n// CreditCardPayment represents the credit card payment strategy\ntype CreditCardPayment struct {\n\tcardNumber string\n\tname       string\n\tcvv        string\n\tdateOfExp  string\n}\n\n// NewCreditCardPayment creates a new credit card payment strategy\nfunc NewCreditCardPayment(cardNumber, name, cvv, dateOfExp string) *CreditCardPayment {\n\treturn &CreditCardPayment{\n\t\tcardNumber: cardNumber,\n\t\tname:       name,\n\t\tcvv:        cvv,\n\t\tdateOfExp:  dateOfExp,\n\t}\n}\n\n// Pay implements the payment strategy for credit card\nfunc (c *CreditCardPayment) Pay(amount float64) string {\n\treturn fmt.Sprintf(\"%.2f paid with credit/debit card\", amount)\n}\n"
  },
  {
    "path": "design-patterns/golang/strategy/main.go",
    "content": "package strategy\n\nfunc main() {\n\tcart := NewShoppingCart(100.0)\n\n\t// Use credit card payment\n\tcreditCard := NewCreditCardPayment(\"1234-5678-9012-3456\", \"John Doe\", \"123\", \"12/25\")\n\tcart.SetPaymentStrategy(creditCard)\n\tcart.Checkout()\n\n\t// Use PayPal payment\n\tpaypal := NewPayPalPayment(\"john@example.com\")\n\tcart.SetPaymentStrategy(paypal)\n\tcart.Checkout()\n} "
  },
  {
    "path": "design-patterns/golang/strategy/payment_strategy.go",
    "content": "package strategy\n\n// PaymentStrategy defines the interface for payment strategies\ntype PaymentStrategy interface {\n\tPay(amount float64) string\n}\n"
  },
  {
    "path": "design-patterns/golang/strategy/paypal_payment.go",
    "content": "package strategy\n\nimport \"fmt\"\n\n// PayPalPayment represents the PayPal payment strategy\ntype PayPalPayment struct {\n\temail string\n}\n\n// NewPayPalPayment creates a new PayPal payment strategy\nfunc NewPayPalPayment(email string) *PayPalPayment {\n\treturn &PayPalPayment{email: email}\n}\n\n// Pay implements the payment strategy for PayPal\nfunc (p *PayPalPayment) Pay(amount float64) string {\n\treturn fmt.Sprintf(\"%.2f paid using PayPal\", amount)\n}\n"
  },
  {
    "path": "design-patterns/golang/strategy/shopping_cart.go",
    "content": "package strategy\n\nimport \"fmt\"\n\n// ShoppingCart is the context that uses a payment strategy\ntype ShoppingCart struct {\n\tamount   float64\n\tstrategy PaymentStrategy\n}\n\nfunc NewShoppingCart(amount float64) *ShoppingCart {\n\treturn &ShoppingCart{amount: amount}\n}\n\nfunc (c *ShoppingCart) SetPaymentStrategy(strategy PaymentStrategy) {\n\tc.strategy = strategy\n}\n\nfunc (c *ShoppingCart) Checkout() {\n\tif c.strategy == nil {\n\t\tfmt.Println(\"No payment strategy selected.\")\n\t\treturn\n\t}\n\tresult := c.strategy.Pay(c.amount)\n\tfmt.Println(result)\n}\n"
  },
  {
    "path": "design-patterns/golang/templatemethod/csv_data_processor.go",
    "content": "package templatemethod\n\nimport \"fmt\"\n\ntype CSVDataProcessor struct{}\n\nfunc (c *CSVDataProcessor) ReadData() {\n\tfmt.Println(\"Reading data from CSV file...\")\n}\n\nfunc (c *CSVDataProcessor) ProcessData() {\n\tfmt.Println(\"Processing CSV data...\")\n}\n\nfunc (c *CSVDataProcessor) SaveData() {\n\tfmt.Println(\"Saving processed data to CSV file...\")\n}\n"
  },
  {
    "path": "design-patterns/golang/templatemethod/data_processor.go",
    "content": "package templatemethod\n\nimport \"fmt\"\n\n// DataProcessor defines the interface for steps\n// and provides the template method Process\n// (Go doesn't have abstract classes, so we use interface + embedding)\ntype DataProcessor interface {\n\tReadData()\n\tProcessData()\n\tSaveData()\n}\n\ntype BaseDataProcessor struct {\n\tProcessor DataProcessor\n}\n\nfunc (b *BaseDataProcessor) Process() {\n\tb.Processor.ReadData()\n\tb.Processor.ProcessData()\n\tb.Processor.SaveData()\n\tfmt.Println(\"Data processing completed.\")\n}\n"
  },
  {
    "path": "design-patterns/golang/templatemethod/main.go",
    "content": "package templatemethod\n\nfunc main() {\n\tcsvProcessor := &CSVDataProcessor{}\n\tbaseCSV := &BaseDataProcessor{Processor: csvProcessor}\n\tbaseCSV.Process()\n\n\txmlProcessor := &XMLDataProcessor{}\n\tbaseXML := &BaseDataProcessor{Processor: xmlProcessor}\n\tbaseXML.Process()\n}\n"
  },
  {
    "path": "design-patterns/golang/templatemethod/xml_data_processor.go",
    "content": "package templatemethod\n\nimport \"fmt\"\n\ntype XMLDataProcessor struct{}\n\nfunc (x *XMLDataProcessor) ReadData() {\n\tfmt.Println(\"Reading data from XML file...\")\n}\n\nfunc (x *XMLDataProcessor) ProcessData() {\n\tfmt.Println(\"Processing XML data...\")\n}\n\nfunc (x *XMLDataProcessor) SaveData() {\n\tfmt.Println(\"Saving processed data to XML file...\")\n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/AppLauncher.java",
    "content": "public class AppLauncher {\n    public static void main(String[] args) {\n        // Simulate platform detection\n        String os = System.getProperty(\"os.name\").toLowerCase();\n        GUIFactory factory;\n\n        if (os.contains(\"mac\")) {\n            factory = new MacOSFactory();\n        } else {\n            factory = new WindowsFactory();\n        }\n\n        Application app = new Application(factory);\n        app.renderUI();\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/Application.java",
    "content": "public class Application {\n    private final Button button;\n    private final Checkbox checkbox;\n\n    public Application(GUIFactory factory) {\n        this.button = factory.createButton();\n        this.checkbox = factory.createCheckbox();\n    }\n\n    public void renderUI() {\n        button.paint();\n        checkbox.paint();\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/Button.java",
    "content": "public interface Button {\n    void paint();\n    void onClick();\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/Checkbox.java",
    "content": "public interface Checkbox {\n    void paint();\n    void onSelect();\n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/GUIFactory.java",
    "content": "public interface GUIFactory {\n    Button createButton();\n    Checkbox createCheckbox();\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/MacOSButton.java",
    "content": "public class MacOSButton implements Button {\n    @Override\n    public void paint() {\n        System.out.println(\"Painting a macOS-style button.\");\n    }\n\n    @Override\n    public void onClick() {\n        System.out.println(\"MacOS button clicked.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/MacOSCheckbox.java",
    "content": "public class MacOSCheckbox implements Checkbox {\n    @Override\n    public void paint() {\n        System.out.println(\"Painting a macOS-style checkbox.\");\n    }\n\n    @Override\n    public void onSelect() {\n        System.out.println(\"MacOS checkbox selected.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/MacOSFactory.java",
    "content": "public class MacOSFactory implements GUIFactory {\n    @Override\n    public Button createButton() {\n        return new MacOSButton();\n    }\n\n    @Override\n    public Checkbox createCheckbox() {\n        return new MacOSCheckbox();\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/WindowsButton.java",
    "content": "public class WindowsButton implements Button {\n    @Override\n    public void paint() {\n        System.out.println(\"Painting a Windows-style button.\");\n    }\n\n    @Override\n    public void onClick() {\n        System.out.println(\"Windows button clicked.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/WindowsCheckbox.java",
    "content": "public class WindowsCheckbox implements Checkbox {\n    @Override\n    public void paint() {\n        System.out.println(\"Painting a Windows-style checkbox.\");\n    }\n\n    @Override\n    public void onSelect() {\n        System.out.println(\"Windows checkbox selected.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/WindowsFactory.java",
    "content": "public class WindowsFactory implements GUIFactory {\n    @Override\n    public Button createButton() {\n        return new WindowsButton();\n    }\n\n    @Override\n    public Checkbox createCheckbox() {\n        return new WindowsCheckbox();\n    }\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/BumpySole.java",
    "content": "public class BumpySole implements Sole {\n\n    @Override\n    public String soleBuild() {\n        return \"Bummpy\";\n    }\n\n    @Override\n    public String soleMaterial() {\n        return \"Plastic Rubber\";\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/CasualShoeFactory.java",
    "content": "public class CasualShoeFactory implements ShoeFactory {\n\n    @Override\n    public Sole createShoeSole() {\n        return new ThinSole();\n    }\n\n    @Override\n    public ShoeLace createShoeLace() {\n        return new TapeShoeLace();\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/FlatSole.java",
    "content": "public class FlatSole implements Sole {\n\n    @Override\n    public String soleBuild() {\n        return \"Flat\";\n    }\n\n    @Override\n    public String soleMaterial() {\n        return \"Synthetic Rubber\";\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/FormalShoeFactory.java",
    "content": "public class FormalShoeFactory implements ShoeFactory {\n\n    @Override\n    public Sole createShoeSole() {\n        return new FlatSole();\n     }\n\n    @Override\n    public ShoeLace createShoeLace() {\n        return new RoundShoeLace();\n     }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/RoundShoeLace.java",
    "content": "public class RoundShoeLace implements ShoeLace {\n\n    @Override\n    public String shoeLaceBuild() {\n        return \"Round\";\n    }\n\n    @Override\n    public String shoeLaceMaterial() {\n        return \"Synthetic Polyster\";\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/Shoe.java",
    "content": "public class Shoe {\n    private Sole sole;\n    private ShoeLace shoeLace;\n\n    public Shoe(Sole sole, ShoeLace shoeLace){\n        this.sole = sole;\n        this.shoeLace = shoeLace;        \n    }\n\n    public void displayBuildShoe()\n    {\n        System.out.println(\"Sole Type is: \"+ this.sole.soleBuild());\n        System.out.println(\"Sole Material is: \"+ this.sole.soleMaterial());\n        System.out.println(\"ShoeLace Type is: \"+ this.shoeLace.shoeLaceBuild());\n        System.out.println(\"ShoeLace Material is: \"+ this.shoeLace.shoeLaceMaterial());\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/ShoeFactory.java",
    "content": "public interface ShoeFactory {\n    public Sole createShoeSole();\n    public ShoeLace createShoeLace();\n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/ShoeLace.java",
    "content": "public interface ShoeLace {\n\n    public String shoeLaceBuild();\n    public String shoeLaceMaterial();\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/ShoeManufacture.java",
    "content": "public class ShoeManufacture {\n\n    static ShoeFactory shoeFactory;\n    public static Shoe produceShoe(String shoeType)\n    {\n        if(shoeType == \"Formal\")\n        {\n            shoeFactory = new FormalShoeFactory();\n        }\n        if(shoeType == \"Sports\")\n        {\n            shoeFactory = new SportsShoeFactory();\n        }\n        if(shoeType == \"Casual\")\n        {\n            shoeFactory = new CasualShoeFactory();\n        }\n        return new Shoe(shoeFactory.createShoeSole(), shoeFactory.createShoeLace());\n    }\n    public static void main(String[] args) {\n        Shoe formalShoe = produceShoe(\"Formal\");\n        Shoe sportaShoe = produceShoe(\"Sports\");\n        Shoe casualShoe = produceShoe(\"Casual\");\n\n        formalShoe.displayBuildShoe();\n        sportaShoe.displayBuildShoe();\n        casualShoe.displayBuildShoe();\n\n\n\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/Sole.java",
    "content": "public interface Sole {\n\n    public String soleBuild();\n    public String soleMaterial();\n}"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/SportsShoeFactory.java",
    "content": "public class SportsShoeFactory implements ShoeFactory {\n\n    @Override\n    public Sole createShoeSole() {\n        return new BumpySole();\n    }\n\n    @Override\n    public ShoeLace createShoeLace() {\n        return new RoundShoeLace();\n     }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/TapeShoeLace.java",
    "content": "public class TapeShoeLace implements ShoeLace{\n\n    @Override\n    public String shoeLaceBuild() {\n        return \"Tape Flat\";\n    }\n\n    @Override\n    public String shoeLaceMaterial() {\n        return \"Synthetic Cotton\";\n    }\n    \n}\n"
  },
  {
    "path": "design-patterns/java/abstractfactory/shoefactory/ThinSole.java",
    "content": "public class ThinSole implements Sole {\n\n    @Override\n    public String soleBuild() {\n        return \"Thin Plated\";\n     }\n\n    @Override\n    public String soleMaterial() {\n        return \"Rubber\";\n    }\n    \n    \n}\n"
  },
  {
    "path": "design-patterns/java/adapter/CheckoutService.java",
    "content": "public class CheckoutService {\n    private PaymentProcessor paymentProcessor;\n\n    public CheckoutService(PaymentProcessor paymentProcessor) {\n        this.paymentProcessor = paymentProcessor;\n    }\n\n    public void checkout(double amount, String currency) {\n        System.out.println(\"CheckoutService: Attempting to process order for $\" + amount + \" \" + currency);\n        paymentProcessor.processPayment(amount, currency);\n        if (paymentProcessor.isPaymentSuccessful()) {\n            System.out.println(\"CheckoutService: Order successful! Transaction ID: \" + paymentProcessor.getTransactionId());\n        } else {\n            System.out.println(\"CheckoutService: Order failed. Payment was not successful.\");\n        }\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/adapter/ECommerceAppV1.java",
    "content": "public class ECommerceAppV1 {\n    public static void main(String[] args) {\n        PaymentProcessor processor = new InHousePaymentProcessor();\n        CheckoutService checkout = new CheckoutService(processor);\n        checkout.checkout(199.99, \"USD\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/adapter/ECommerceAppV2.java",
    "content": "public class ECommerceAppV2 {\n    public static void main(String[] args) {\n        PaymentProcessor inHouseProcessor = new InHousePaymentProcessor();\n        PaymentProcessor legacyProcessor = new LegacyGatewayAdapter(new LegacyGateway());\n\n        CheckoutService checkoutService = new CheckoutService(inHouseProcessor);\n        checkoutService.checkout(100, \"USD\");\n\n        System.out.println(\"--------------------------------\");\n\n        checkoutService = new CheckoutService(legacyProcessor);\n        checkoutService.checkout(100, \"USD\");\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/adapter/InHousePaymentProcessor.java",
    "content": "public class InHousePaymentProcessor implements PaymentProcessor {\n    private String transactionId;\n    private boolean isPaymentSuccessful;\n\n    @Override\n    public void processPayment(double amount, String currency) {\n        System.out.println(\"InHousePaymentProcessor: Processing payment of \" + amount + \" \" + currency);\n        // Process payment logic\n        transactionId = \"TXN_\" + System.currentTimeMillis();\n        isPaymentSuccessful = true;\n        System.out.println(\"InHousePaymentProcessor: Payment successful. Txn ID: \" + this.transactionId);\n    }\n\n    @Override\n    public boolean isPaymentSuccessful() {\n        return isPaymentSuccessful;\n    }\n\n    @Override\n    public String getTransactionId() {\n        return transactionId;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/adapter/LegacyGateway.java",
    "content": "public class LegacyGateway {\n    private long transactionReference;\n    private boolean isPaymentSuccessful;\n\n    public void executeTransaction(double totalAmount, String currency) {\n        System.out.println(\"LegacyGateway: Executing transaction for \" + currency + \" \" + totalAmount);\n        transactionReference = System.nanoTime();\n        isPaymentSuccessful = true;\n        System.out.println(\"LegacyGateway: Transaction executed successfully. Txn ID: \" + transactionReference);\n    }\n\n    public boolean checkStatus(long transactionReference) {\n        System.out.println(\"LegacyGateway: Checking status for ref: \" + transactionReference);\n        return isPaymentSuccessful;\n    }\n\n    public long getReferenceNumber() {\n        return transactionReference;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/adapter/LegacyGatewayAdapter.java",
    "content": "public class LegacyGatewayAdapter implements PaymentProcessor {\n    private LegacyGateway legacyGateway;\n\n    public LegacyGatewayAdapter(LegacyGateway legacyGateway) {\n        this.legacyGateway = legacyGateway;\n    }\n\n    @Override\n    public void processPayment(double amount, String currency) {\n        System.out.println(\"LegacyGatewayAdapter: Processing payment of \" + amount + \" \" + currency);\n        legacyGateway.executeTransaction(amount, currency);\n        System.out.println(\"LegacyGatewayAdapter: Payment processed successfully. Txn ID: \" + legacyGateway.getReferenceNumber());\n    }\n\n    @Override\n    public boolean isPaymentSuccessful() {\n        return legacyGateway.checkStatus(legacyGateway.getReferenceNumber());\n    }\n\n    @Override\n    public String getTransactionId() {\n        return String.valueOf(legacyGateway.getReferenceNumber());\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/adapter/PaymentProcessor.java",
    "content": "public interface PaymentProcessor {\n    void processPayment(double amount, String currency);\n    boolean isPaymentSuccessful();\n    String getTransactionId();\n}"
  },
  {
    "path": "design-patterns/java/bridge/BridgeDemo.java",
    "content": "public class BridgeDemo {\n    public static void main(String[] args) {\n        Renderer vector = new VectorRenderer();\n        Renderer raster = new RasterRenderer();\n\n        Shape circle1 = new Circle(vector, 5);\n        Shape circle2 = new Circle(raster, 5);\n\n        Shape rectangle1 = new Rectangle(vector, 10, 4);\n        Shape rectangle2 = new Rectangle(raster, 10, 4);\n\n        circle1.draw();     // Vector\n        circle2.draw();     // Raster\n        rectangle1.draw();  // Vector\n        rectangle2.draw();  // Raster\n    }\n}"
  },
  {
    "path": "design-patterns/java/bridge/Circle.java",
    "content": "public class Circle extends Shape {\n    private final float radius;\n\n    public Circle(Renderer renderer, float radius) {\n        super(renderer);\n        this.radius = radius;\n    }\n\n    @Override\n    public void draw() {\n        renderer.renderCircle(radius);\n    }\n}"
  },
  {
    "path": "design-patterns/java/bridge/RasterRenderer.java",
    "content": "public class RasterRenderer implements Renderer {\n    @Override\n    public void renderCircle(float radius) {\n        System.out.println(\"Drawing pixels for a circle of radius \" + radius + \" (RASTER).\");\n    }\n\n    @Override\n    public void renderRectangle(float width, float height) {\n        System.out.println(\"Drawing pixels for a rectangle \" + width + \"x\" + height + \" (RASTER).\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/bridge/Rectangle.java",
    "content": "public class Rectangle extends Shape {\n    private final float width;\n    private final float height;\n\n    public Rectangle(Renderer renderer, float width, float height) {\n        super(renderer);\n        this.width = width;\n        this.height = height;\n    }\n\n    @Override\n    public void draw() {\n        renderer.renderRectangle(width, height);\n    }\n}"
  },
  {
    "path": "design-patterns/java/bridge/Renderer.java",
    "content": "public interface Renderer {\n    void renderCircle(float radius);\n    void renderRectangle(float width, float height);\n}"
  },
  {
    "path": "design-patterns/java/bridge/Shape.java",
    "content": "public abstract class Shape {\n    protected Renderer renderer;\n\n    public Shape(Renderer renderer) {\n        this.renderer = renderer;\n    }\n\n    public abstract void draw();\n}"
  },
  {
    "path": "design-patterns/java/bridge/VectorRenderer.java",
    "content": "public class VectorRenderer implements Renderer {\n    @Override\n    public void renderCircle(float radius) {\n        System.out.println(\"Drawing a circle of radius \" + radius + \" using VECTOR rendering.\");\n    }\n\n    @Override\n    public void renderRectangle(float width, float height) {\n        System.out.println(\"Drawing a rectangle \" + width + \"x\" + height + \" using VECTOR rendering.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/builder/HttpAppBuilder.java",
    "content": "public class HttpAppBuilder {\n    public static void main(String[] args) {\n        // Example 1: Simple GET request\n        HttpRequest getRequest = new HttpRequest.Builder(\"https://api.example.com/users\")\n                                        .method(\"GET\")\n                                        .header(\"Accept\", \"application/json\")\n                                        .timeout(5000)\n                                        .build();\n        System.out.println(\"GET Request: \" + getRequest);\n\n        // Example 2: POST request with body and custom headers\n        HttpRequest postRequest = new HttpRequest.Builder(\"https://api.example.com/posts\")\n                                         .method(\"POST\")\n                                         .header(\"Content-Type\", \"application/json\")\n                                         .header(\"X-Auth-Token\", \"some_secret_token\")\n                                         .body(\"{\\\"title\\\":\\\"New Post\\\",\\\"content\\\":\\\"Hello Builder!\\\"}\")\n                                         .queryParam(\"userId\", \"123\")\n                                         .build();\n        System.out.println(\"POST Request: \" + postRequest);\n\n        // Example 3: Request with only required URL (defaults for others)\n        HttpRequest defaultRequest = new HttpRequest.Builder(\"https://api.example.com/status\").build();\n        System.out.println(\"Default Request: \" + defaultRequest);\n\n        // Example 4: Illustrating potential warning from builder\n        HttpRequest putNoBodyRequest = new HttpRequest.Builder(\"https://api.example.com/resource/1\")\n                                            .method(\"PUT\")\n                                            // .body(\"updated data\") // Body intentionally omitted\n                                            .build();\n        System.out.println(\"PUT Request (no body): \" + putNoBodyRequest);\n\n        // Example of trying to build with invalid required parameter\n        try {\n            HttpRequest invalidRequest = new HttpRequest.Builder(null).build();\n        } catch (IllegalArgumentException e) {\n            System.err.println(\"Error creating request: \" + e.getMessage());\n        }\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/builder/HttpAppTelescoping.java",
    "content": "public class HttpAppTelescoping {\n    public static void main(String[] args) {\n        HttpRequestTelescoping req1 = new HttpRequestTelescoping(\"https://api.example.com/data\"); // GET, defaults\n        HttpRequestTelescoping req2 = new HttpRequestTelescoping(\"https://api.example.com/submit\", \"POST\", null, null, \"{\\\"key\\\":\\\"value\\\"}\"); // POST with body\n        HttpRequestTelescoping req3 = new HttpRequestTelescoping(\"https://api.example.com/config\", \"PUT\", Map.of(\"X-API-Key\", \"secret\"), null, \"config_data\", 5000);\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/builder/HttpRequest.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\nimport java.util.Collections;\n\npublic class HttpRequest {\n    private final String url;         // Required\n    private final String method;      // Optional, default GET\n    private final Map<String, String> headers; // Optional\n    private final Map<String, String> queryParams; // Optional\n    private final String body;        // Optional\n    private final int timeout;        // Optional, default 30s\n\n    // Private constructor, only accessible by the Builder\n    private HttpRequest(Builder builder) {\n        this.url = builder.url;\n        this.method = builder.method;\n        this.headers = Collections.unmodifiableMap(new HashMap<>(builder.headers)); // Defensive copy\n        this.queryParams = Collections.unmodifiableMap(new HashMap<>(builder.queryParams)); // Defensive copy\n        this.body = builder.body;\n        this.timeout = builder.timeout;\n    }\n\n    // Getters (no setters to ensure immutability)\n    public String getUrl() { return url; }\n    public String getMethod() { return method; }\n    public Map<String, String> getHeaders() { return headers; }\n    public Map<String, String> getQueryParams() { return queryParams; }\n    public String getBody() { return body; }\n    public int getTimeout() { return timeout; }\n\n    @Override\n    public String toString() {\n        return \"HttpRequest{\" +\n               \"url='\" + url + '\\'' +\n               \", method='\" + method + '\\'' +\n               \", headers=\" + headers +\n               \", queryParams=\" + queryParams +\n               \", body='\" + (body != null ? body.substring(0, Math.min(10, body.length()))+\"...\" : \"null\") + '\\'' +\n               \", timeout=\" + timeout +\n               '}';\n    }\n\n    // --- Static Nested Builder Class ---\n    public static class Builder {\n        // Required parameter\n        private final String url;\n\n        // Optional parameters - initialized to default values\n        private String method = \"GET\";\n        private Map<String, String> headers = new HashMap<>();\n        private Map<String, String> queryParams = new HashMap<>();\n        private String body = null;\n        private int timeout = 30000; // 30 seconds default\n\n        // Builder constructor for required fields\n        public Builder(String url) {\n            if (url == null || url.trim().isEmpty()) {\n                throw new IllegalArgumentException(\"URL cannot be null or empty.\");\n            }\n            this.url = url;\n        }\n\n        // Setter-like methods for optional fields, returning the Builder for fluency\n        public Builder method(String method) {\n            this.method = (method == null || method.trim().isEmpty()) ? \"GET\" : method.toUpperCase();\n            return this;\n        }\n\n        public Builder header(String key, String value) {\n            if (key != null && value != null) {\n                this.headers.put(key, value);\n            }\n            return this;\n        }\n\n        public Builder queryParam(String key, String value) {\n            if (key != null && value != null) {\n                this.queryParams.put(key, value);\n            }\n            return this;\n        }\n\n        public Builder body(String body) {\n            this.body = body;\n            return this;\n        }\n\n        public Builder timeout(int timeoutMillis) {\n            if (timeoutMillis > 0) {\n                this.timeout = timeoutMillis;\n            }\n            return this;\n        }\n\n        // The final build method that creates the HttpRequest object\n        public HttpRequest build() {\n            // Optionally, add validation logic here before creating the object\n            // For example, ensure body is present for POST/PUT if required by your design\n            if ((\"POST\".equals(method) || \"PUT\".equals(method)) && (body == null || body.isEmpty())) {\n                 System.out.println(\"Warning: Building \" + method + \" request without a body for URL: \" + url);\n            }\n            return new HttpRequest(this);\n        }\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/builder/HttpRequestTelescoping.java",
    "content": "\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class HttpRequestTelescoping {\n    private String url;         // Required\n    private String method;      // Optional, default GET\n    private Map<String, String> headers; // Optional\n    private Map<String, String> queryParams; // Optional\n    private String body;        // Optional\n    private int timeout;        // Optional, default 30s\n\n    public HttpRequestTelescoping(String url) {\n        this(url, \"GET\");\n    }\n    public HttpRequestTelescoping(String url, String method) {\n        this(url, method, null);\n    }\n    public HttpRequestTelescoping(String url, String method, Map<String, String> headers) {\n        this(url, method, headers, null);\n    }\n    public HttpRequestTelescoping(String url, String method, Map<String, String> headers, Map<String, String> queryParams) {\n        this(url, method, headers, queryParams, null);\n    }\n    public HttpRequestTelescoping(String url, String method, Map<String, String> headers, Map<String, String> queryParams, String body) {\n        this(url, method, headers, queryParams, body, 30000);\n    }\n    public HttpRequestTelescoping(String url, String method, Map<String, String> headers,\n                                  Map<String, String> queryParams, String body, int timeout) {\n        this.url = url;\n        this.method = method;\n        this.headers = headers == null ? new HashMap<>() : headers;\n        this.queryParams = queryParams == null ? new HashMap<>() : queryParams;\n        this.body = body;\n        this.timeout = timeout;\n        System.out.println(\"HttpRequest Created: URL=\" + url + \", Method=\" + method +\n                           \", Headers=\" + this.headers.size() + \", Params=\" + this.queryParams.size() +\n                           \", Body=\" + (body != null) + \", Timeout=\" + timeout);\n    }\n    // ... getters ...    \n}\n"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/AuthHandler.java",
    "content": "public class AuthHandler extends BaseHandler {\n    @Override\n    public void handle(Request request) {\n        if (request.user == null) {\n            System.out.println(\"AuthHandler: ❌ User not authenticated.\");\n            return; // Stop the chain\n        }\n        System.out.println(\"AuthHandler: ✅ Authenticated.\");\n        forward(request);\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/AuthorizationHandler.java",
    "content": "public class AuthorizationHandler extends BaseHandler {\n    @Override\n    public void handle(Request request) {\n        if (!\"ADMIN\".equals(request.userRole)) {\n            System.out.println(\"AuthorizationHandler: ❌ Access denied.\");\n            return;\n        }\n        System.out.println(\"AuthorizationHandler: ✅ Authorized.\");\n        forward(request);\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/BaseHandler.java",
    "content": "public abstract class BaseHandler implements RequestHandler {\n    protected RequestHandler next;\n\n    @Override\n    public void setNext(RequestHandler next) {\n        this.next = next;\n    }\n\n    protected void forward(Request request) {\n        if (next != null) {\n            next.handle(request);\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/BusinessLogicHandler.java",
    "content": "public class BusinessLogicHandler extends BaseHandler {\n    @Override\n    public void handle(Request request) {\n        System.out.println(\"BusinessLogicHandler: 🚀 Processing request...\");\n        // Core application logic goes here\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/RateLimitHandler.java",
    "content": "public class RateLimitHandler extends BaseHandler {\n    @Override\n    public void handle(Request request) {\n        if (request.requestCount >= 100) {\n            System.out.println(\"RateLimitHandler: ❌ Rate limit exceeded.\");\n            return;\n        }\n        System.out.println(\"RateLimitHandler: ✅ Within rate limit.\");\n        forward(request);\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/Request.java",
    "content": "public class Request {\n    public String user;\n    public String userRole;\n    public int requestCount;\n    public String payload;\n\n    public Request(String user, String role, int requestCount, String payload) {\n        this.user = user;\n        this.userRole = role;\n        this.requestCount = requestCount;\n        this.payload = payload;\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/RequestHandler.java",
    "content": "public interface RequestHandler {\n    void setNext(RequestHandler next);\n    void handle(Request request);\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/RequestHandlerV1.java",
    "content": "public class RequestHandlerV1 {\n    public void handle(Request request) {\n        if (!authenticate(request)) {\n            System.out.println(\"Request Rejected: Authentication failed.\");\n            return;\n        }\n\n        if (!authorize(request)) {\n            System.out.println(\"Request Rejected: Authorization failed.\");\n            return;\n        }\n\n        if (!rateLimit(request)) {\n            System.out.println(\"Request Rejected: Rate limit exceeded.\");\n            return;\n        }\n\n        if (!validate(request)) {\n            System.out.println(\"Request Rejected: Invalid payload.\");\n            return;\n        }\n\n        System.out.println(\"Request passed all checks. Executing business logic...\");\n        // Proceed to business logic\n    }\n\n    private boolean authenticate(Request req) {\n        return req.user != null;\n    }\n\n    private boolean authorize(Request req) {\n        return \"ADMIN\".equals(req.userRole);\n    }\n\n    private boolean rateLimit(Request req) {\n        return req.requestCount < 100;\n    }\n\n    private boolean validate(Request req) {\n        return req.payload != null && !req.payload.isEmpty();\n    }\n}"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/RequestHandlerV2.java",
    "content": "public class RequestHandlerV2 {\n    public static void main(String[] args) {\n        // Create handlers\n        RequestHandler auth = new AuthHandler();\n        RequestHandler authorization = new AuthorizationHandler();\n        RequestHandler rateLimit = new RateLimitHandler();\n        RequestHandler validation = new ValidationHandler();\n        RequestHandler businessLogic = new BusinessLogicHandler();\n\n        // Build the chain\n        auth.setNext(authorization);\n        authorization.setNext(rateLimit);\n        rateLimit.setNext(validation);\n        validation.setNext(businessLogic);\n\n        // Send a request through the chain\n        Request request = new Request(\"john\", \"ADMIN\", 10, \"{ \\\"data\\\": \\\"valid\\\" }\");\n        auth.handle(request);\n\n        System.out.println(\"\\n--- Trying an invalid request ---\");\n        Request badRequest = new Request(null, \"USER\", 150, \"\");\n        auth.handle(badRequest);\n    } \n}\n"
  },
  {
    "path": "design-patterns/java/chainofresponsibility/ValidationHandler.java",
    "content": "public class ValidationHandler extends BaseHandler {\n    @Override\n    public void handle(Request request) {\n        if (request.payload == null || request.payload.trim().isEmpty()) {\n            System.out.println(\"ValidationHandler: ❌ Invalid payload.\");\n            return;\n        }\n        System.out.println(\"ValidationHandler: ✅ Payload valid.\");\n        forward(request);\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/Command.java",
    "content": "interface Command {\n    void execute();\n    void undo();\n}"
  },
  {
    "path": "design-patterns/java/command/CommandPatternDemo.java",
    "content": "public class CommandPatternDemo {\n    public static void main(String[] args) {\n        // Receivers\n        Light light = new Light();\n        Thermostat thermostat = new Thermostat();\n\n        // Commands\n        Command lightOn = new LightOnCommand(light);\n        Command lightOff = new LightOffCommand(light);\n        Command setTemp22 = new SetTemperatureCommand(thermostat, 22);\n\n        // Invoker\n        SmartButton button = new SmartButton();\n\n        // Simulate usage\n        System.out.println(\"→ Pressing Light ON\");\n        button.setCommand(lightOn);\n        button.press();\n\n        System.out.println(\"→ Pressing Set Temp to 22°C\");\n        button.setCommand(setTemp22);\n        button.press();\n\n        System.out.println(\"→ Pressing Light OFF\");\n        button.setCommand(lightOff);\n        button.press();\n\n        System.out.println(\"\\n🔁 Undo Last Action\");\n        button.undoLast(); // Undo Light OFF\n\n        System.out.println(\"🔁 Undo Previous Action\");\n        button.undoLast(); // Undo Set Temp\n\n        System.out.println(\"🔁 Undo Again\");\n        button.undoLast(); // Undo Light ON\n\n        System.out.println(\"🔁 Undo Once More\");\n        button.undoLast(); // No more actions\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/Light.java",
    "content": "public class Light {\n    public void on() {\n        System.out.println(\"Light turned ON\");\n    }\n\n    public void off() {\n        System.out.println(\"Light turned OFF\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/LightOffCommand.java",
    "content": "public class LightOffCommand implements Command {\n    private final Light light;\n\n    public LightOffCommand(Light light) {\n        this.light = light;\n    }\n\n    @Override\n    public void execute() {\n        light.off();\n    }\n\n    @Override\n    public void undo() {\n        light.on();\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/LightOnCommand.java",
    "content": "public class LightOnCommand implements Command {\n    private final Light light;\n\n    public LightOnCommand(Light light) {\n        this.light = light;\n    }\n\n    @Override\n    public void execute() {\n        light.on();\n    }\n\n    @Override\n    public void undo() {\n        light.off();\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/SetTemperatureCommand.java",
    "content": "public class SetTemperatureCommand implements Command {\n    private final Thermostat thermostat;\n    private final int newTemperature;\n    private int previousTemperature;\n\n    public SetTemperatureCommand(Thermostat thermostat, int temperature) {\n        this.thermostat = thermostat;\n        this.newTemperature = temperature;\n    }\n\n    @Override\n    public void execute() {\n        previousTemperature = thermostat.getCurrentTemperature();\n        thermostat.setTemperature(newTemperature);\n    }\n\n    @Override\n    public void undo() {\n        thermostat.setTemperature(previousTemperature);\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/SmartButton.java",
    "content": "import java.util.Stack;\n\npublic class SmartButton {\n    private Command currentCommand;\n    private final Stack<Command> history = new Stack<>();\n\n    public void setCommand(Command command) {\n        this.currentCommand = command;\n    }\n\n    public void press() {\n        if (currentCommand != null) {\n            currentCommand.execute();\n            history.push(currentCommand);\n        } else {\n            System.out.println(\"No command assigned.\");\n        }\n    }\n\n    public void undoLast() {\n        if (!history.isEmpty()) {\n            Command lastCommand = history.pop();\n            lastCommand.undo();\n        } else {\n            System.out.println(\"Nothing to undo.\");\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/command/Thermostat.java",
    "content": "public class Thermostat {\n    private int currentTemperature = 20; // default\n\n    public void setTemperature(int temp) {\n        System.out.println(\"Thermostat set to \" + temp + \"°C\");\n        currentTemperature = temp;\n    }\n\n    public int getCurrentTemperature() {\n        return currentTemperature;\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/filesystem/File.java",
    "content": "public class File implements FileSystemItem {\n    private final String name;\n    private final int size;\n\n    public File(String name, int size) {\n        this.name = name;\n        this.size = size;\n    }\n\n    @Override\n    public int getSize() {\n        return size;\n    }\n\n    @Override\n    public void printStructure(String indent) {\n        System.out.println(indent + \"- \" + name + \" (\" + size + \" KB)\");\n    }\n\n    @Override\n    public void delete() {\n        System.out.println(\"Deleting file: \" + name);\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/filesystem/FileExplorerApp.java",
    "content": "public class FileExplorerApp {\n    public static void main(String[] args) {\n        FileSystemItem file1 = new File(\"readme.txt\", 5);\n        FileSystemItem file2 = new File(\"photo.jpg\", 1500);\n        FileSystemItem file3 = new File(\"data.csv\", 300);\n\n        Folder documents = new Folder(\"Documents\");\n        documents.addItem(file1);\n        documents.addItem(file3);\n\n        Folder pictures = new Folder(\"Pictures\");\n        pictures.addItem(file2);\n\n        Folder home = new Folder(\"Home\");\n        home.addItem(documents);\n        home.addItem(pictures);\n\n        System.out.println(\"---- File Structure ----\");\n        home.printStructure(\"\");\n\n        System.out.println(\"\\nTotal Size: \" + home.getSize() + \" KB\");\n\n        System.out.println(\"\\n---- Deleting All ----\");\n        home.delete();\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/filesystem/FileSystemItem.java",
    "content": "public interface FileSystemItem {\n    int getSize();\n    void printStructure(String indent);\n    void delete();\n}"
  },
  {
    "path": "design-patterns/java/composite/filesystem/Folder.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\npublic class Folder implements FileSystemItem {\n    private final String name;\n    private final List<FileSystemItem> children = new ArrayList<>();\n\n    public Folder(String name) {\n        this.name = name;\n    }\n\n    public void addItem(FileSystemItem item) {\n        children.add(item);\n    }\n\n    @Override\n    public int getSize() {\n        int total = 0;\n        for (FileSystemItem item : children) {\n            total += item.getSize();\n        }\n        return total;\n    }\n\n    @Override\n    public void printStructure(String indent) {\n        System.out.println(indent + \"+ \" + name + \"/\");\n        for (FileSystemItem item : children) {\n            item.printStructure(indent + \"  \");\n        }\n    }\n\n    @Override\n    public void delete() {\n        for (FileSystemItem item : children) {\n            item.delete();\n        }\n        System.out.println(\"Deleting folder: \" + name);\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/organization/CompositeDemo.java",
    "content": "public class CompositeDemo {\n    public static void main(String[] args) {\n        Developer dev1 = new Developer(\"John Doe\", 100000);\n        Developer dev2 = new Developer(\"Jane Smith\", 120000);\n        Designer designer = new Designer(\"Mike Johnson\", 90000);\n\n        Manager engManager = new Manager(\"Emily Brown\", 200000);\n        engManager.addEmployee(dev1);\n        engManager.addEmployee(dev2);\n        engManager.addEmployee(designer);\n\n        Manager generalManager = new Manager(\"David Wilson\", 300000);\n        generalManager.addEmployee(engManager);\n\n        System.out.println(\"Company Structure:\");\n        generalManager.showDetails();\n\n        System.out.println(\"\\nTotal Salary Budget: $\" + generalManager.getSalary());\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/organization/Designer.java",
    "content": "class Designer implements Employee {\n    private String name;\n    private double salary;\n\n    public Designer(String name, double salary) {\n        this.name = name;\n        this.salary = salary;\n    }\n\n    @Override\n    public void showDetails() {\n        System.out.println(\"Designer: \" + name + \", Salary: $\" + salary);\n    }\n\n    @Override\n    public double getSalary() {\n        return salary;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/composite/organization/Developer.java",
    "content": "class Developer implements Employee {\n    private String name;\n    private double salary;\n\n    public Developer(String name, double salary) {\n        this.name = name;\n        this.salary = salary;\n    }\n\n    @Override\n    public void showDetails() {\n        System.out.println(\"Developer: \" + name + \", Salary: $\" + salary);\n    }\n\n    @Override\n    public double getSalary() {\n        return salary;\n    }\n}"
  },
  {
    "path": "design-patterns/java/composite/organization/Employee.java",
    "content": "interface Employee {\n    void showDetails();\n    double getSalary();\n}"
  },
  {
    "path": "design-patterns/java/composite/organization/Manager.java",
    "content": "import java.util.ArrayList;\nimport java.util.List;\n\nclass Manager implements Employee {\n    private String name;\n    private double salary;\n    private List<Employee> subordinates = new ArrayList<>();\n\n    public Manager(String name, double salary) {\n        this.name = name;\n        this.salary = salary;\n    }\n\n    public void addEmployee(Employee employee) {\n        subordinates.add(employee);\n    }\n\n    public void removeEmployee(Employee employee) {\n        subordinates.remove(employee);\n    }\n\n    @Override\n    public void showDetails() {\n        System.out.println(\"Manager: \" + name + \", Salary: $\" + salary);\n        System.out.println(\"Subordinates:\");\n        for (Employee employee : subordinates) {\n            employee.showDetails();\n        }\n    }\n\n    @Override\n    public double getSalary() {\n        double totalSalary = salary;\n        for (Employee employee : subordinates) {\n            totalSalary += employee.getSalary();\n        }\n        return totalSalary;\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/BoldDecorator.java",
    "content": "public class BoldDecorator extends TextDecorator {\n    public BoldDecorator(TextView inner) {\n        super(inner);\n    }\n\n    @Override\n    public void render() {\n        System.out.print(\"<b>\");\n        inner.render();\n        System.out.print(\"</b>\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/DecoratorDemo.java",
    "content": "public class DecoratorDemo {\n    public static void main(String[] args) {\n        TextView plain = new PlainTextView(\"Hello, world!\");\n\n        System.out.print(\"Plain: \");\n        plain.render();\n        System.out.println();\n\n        System.out.print(\"Bold: \");\n        TextView bold = new BoldDecorator(plain);\n        bold.render();\n        System.out.println();\n\n        System.out.print(\"Italic + Bold: \");\n        TextView italicBold = new ItalicDecorator(bold);\n        italicBold.render();\n        System.out.println();\n\n        System.out.print(\"Underline + Italic + Bold: \");\n        TextView fullStyle = new UnderlineDecorator(italicBold);\n        fullStyle.render();\n        System.out.println();\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/ItalicDecorator.java",
    "content": "public class ItalicDecorator extends TextDecorator {\n    public ItalicDecorator(TextView inner) {\n        super(inner);\n    }\n\n    @Override\n    public void render() {\n        System.out.print(\"<i>\");\n        inner.render();\n        System.out.print(\"</i>\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/PlainTextView.java",
    "content": "public class PlainTextView implements TextView {\n    private final String text;\n\n    public PlainTextView(String text) {\n        this.text = text;\n    }\n\n    @Override\n    public void render() {\n        System.out.print(text);\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/TextDecorator.java",
    "content": "public abstract class TextDecorator implements TextView {\n    protected final TextView inner;\n\n    public TextDecorator(TextView inner) {\n        this.inner = inner;\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/TextView.java",
    "content": "public interface TextView {\n    void render();\n}"
  },
  {
    "path": "design-patterns/java/decorator/UnderlineDecorator.java",
    "content": "public class UnderlineDecorator extends TextDecorator {\n    public UnderlineDecorator(TextView inner) {\n        super(inner);\n    }\n\n    @Override\n    public void render() {\n        System.out.print(\"<u>\");\n        inner.render();\n        System.out.print(\"</u>\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/Coffee.java",
    "content": "interface Coffee {\n    double getCost();\n    String getDescription();\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/CoffeeDecorator.java",
    "content": "abstract class CoffeeDecorator implements Coffee {\n    protected Coffee decoratedCoffee;\n\n    public CoffeeDecorator(Coffee coffee) {\n        this.decoratedCoffee = coffee;\n    }\n\n    public double getCost() {\n        return decoratedCoffee.getCost();\n    }\n\n    public String getDescription() {\n        return decoratedCoffee.getDescription();\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/DecoratorDemo.java",
    "content": "public class DecoratorDemo {\n    public static void main(String[] args) {\n        // Order a simple coffee\n        Coffee coffee = new SimpleCoffee();\n        System.out.println(\"Cost: $\" + coffee.getCost() + \"; Description: \" + coffee.getDescription());\n\n        // Decorate it with milk\n        coffee = new Milk(coffee);\n        System.out.println(\"Cost: $\" + coffee.getCost() + \"; Description: \" + coffee.getDescription());\n\n        // Decorate it with sugar\n        coffee = new Sugar(coffee);\n        System.out.println(\"Cost: $\" + coffee.getCost() + \"; Description: \" + coffee.getDescription());\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/Milk.java",
    "content": "class Milk extends CoffeeDecorator {\n    public Milk(Coffee coffee) {\n        super(coffee);\n    }\n\n    @Override\n    public double getCost() {\n        return super.getCost() + 0.5;\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \", milk\";\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/SimpleCoffee.java",
    "content": "class SimpleCoffee implements Coffee {\n    @Override\n    public double getCost() {\n        return 1.0;\n    }\n\n    @Override\n    public String getDescription() {\n        return \"Simple coffee\";\n    }\n}"
  },
  {
    "path": "design-patterns/java/decorator/coffee/Sugar.java",
    "content": "class Sugar extends CoffeeDecorator {\n    public Sugar(Coffee coffee) {\n        super(coffee);\n    }\n\n    @Override\n    public double getCost() {\n        return super.getCost() + 0.2;\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \", sugar\";\n    }\n}"
  },
  {
    "path": "design-patterns/java/facade/BuildSystem.java",
    "content": "public class BuildSystem {\n    public boolean compileProject() {\n        System.out.println(\"BuildSystem: Compiling project...\");\n        simulateDelay(2000);\n        System.out.println(\"BuildSystem: Build successful.\");\n        return true;\n    }\n\n    public String getArtifactPath() {\n        String path = \"target/myapplication-1.0.jar\";\n        System.out.println(\"BuildSystem: Artifact located at \" + path);\n        return path;\n    }\n    \n    private void simulateDelay(int ms) {\n        try {\n            Thread.sleep(ms);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/facade/DeploymentAppDirect.java",
    "content": "public class DeploymentAppDirect {\n    public static void main(String[] args) {\n        DeploymentOrchestrator orchestrator = new DeploymentOrchestrator();\n        orchestrator.deployApplication(\"main\", \"prod.server.example.com\");\n\n        System.out.println(\"\\n--- Attempting another deployment ---\");\n        orchestrator.deployApplication(\"feature/new-ui\", \"staging.server.example.com\");\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/facade/DeploymentAppFacade.java",
    "content": "public class DeploymentAppFacade {\n    public static void main(String[] args) {\n        DeploymentFacade deploymentFacade = new DeploymentFacade();\n\n        // Deploy to production\n        deploymentFacade.deployApplication(\"main\", \"prod.server.example.com\");\n\n        // Deploy a feature branch to staging\n        System.out.println(\"\\n--- Deploying feature branch to staging ---\");\n        deploymentFacade.deployApplication(\"feature/new-ui\", \"staging.server.example.com\");\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/facade/DeploymentFacade.java",
    "content": "public class DeploymentFacade {\n    // Instances of all the subsystem components\n    // or they can be injected (e.g., via constructor for better testability).\n    private VersionControlSystem vcs = new VersionControlSystem();\n    private BuildSystem buildSystem = new BuildSystem();\n    private TestingFramework testingFramework = new TestingFramework();\n    private DeploymentTarget deploymentTarget = new DeploymentTarget();\n\n    // Perform a full standard deployment: pull, build, test, deploy.\n    public boolean deployApplication(String branch, String serverAddress) {\n        System.out.println(\"\\nFACADE: --- Initiating FULL DEPLOYMENT for branch: \" + branch + \" to \" + serverAddress + \" ---\");\n        boolean success = true;\n\n        try {\n            // Step 1: Pull latest code\n            vcs.pullLatestChanges(branch);\n\n            // Step 2: Build the project\n            if (!buildSystem.compileProject()) {\n                System.err.println(\"FACADE: DEPLOYMENT FAILED - Build compilation failed.\");\n                return false; // Exit early on critical failure\n            }\n            String artifactPath = buildSystem.getArtifactPath();\n\n            // Step 3: Run tests\n            if (!testingFramework.runUnitTests()) {\n                System.err.println(\"FACADE: DEPLOYMENT FAILED - Unit tests failed.\");\n                return false;\n            }\n            if (!testingFramework.runIntegrationTests()) {\n                System.err.println(\"FACADE: DEPLOYMENT FAILED - Integration tests failed.\");\n                return false;\n            }\n\n            // Step 4: Deploy to production\n            deploymentTarget.transferArtifact(artifactPath, serverAddress);\n            deploymentTarget.activateNewVersion(serverAddress);\n\n            System.out.println(\"FACADE: APPLICATION DEPLOYED SUCCESSFULLY TO \" + serverAddress + \"!\");\n        } catch (Exception e) {\n            System.err.println(\"FACADE: DEPLOYMENT FAILED - An unexpected error occurred: \" + e.getMessage());\n            e.printStackTrace(); // Log the full stack trace\n            success = false;\n        }\n        return success;\n    }\n\n\n    public boolean deployHotfix(String branch, String serverAddress) {\n        System.out.println(\"\\nFACADE: --- Initiating HOTFIX DEPLOYMENT for branch: \" + branch + \" to \" + serverAddress + \" ---\");\n        boolean success = true;\n        try {\n            // Step 1: Pull latest code\n            vcs.pullLatestChanges(branch);\n\n            // Step 2: Build the project\n            if (!buildSystem.compileProject()) {\n                System.err.println(\"FACADE: HOTFIX FAILED - Build compilation failed.\");\n                return false;\n            }\n            String artifactPath = buildSystem.getArtifactPath();\n\n            // Step 3: For a hotfix, we might skip extensive tests or run a specific \"smoke test\" suite.\n            System.out.println(\"FACADE: Skipping full test suite for hotfix deployment (or running minimal smoke tests).\");\n            // if (!testingFramework.runSmokeTests()) { return false; } // Example\n\n            // Step 4: Deploy to production\n            deploymentTarget.transferArtifact(artifactPath, serverAddress);\n            deploymentTarget.activateNewVersion(serverAddress);\n\n            System.out.println(\"FACADE: HOTFIX DEPLOYED SUCCESSFULLY TO \" + serverAddress + \"!\");\n        } catch (Exception e) {\n            System.err.println(\"FACADE: HOTFIX FAILED - An unexpected error occurred: \" + e.getMessage());\n            success = false;\n        }\n        return success;\n    }\n    // We could add other simplified methods: rollbackLastDeployment(), checkDeploymentStatus(), etc.\n}\n"
  },
  {
    "path": "design-patterns/java/facade/DeploymentOrchestrator.java",
    "content": "public class DeploymentOrchestrator {\n    private VersionControlSystem vcs = new VersionControlSystem();\n    private BuildSystem buildSystem = new BuildSystem();\n    private TestingFramework testFramework = new TestingFramework();\n    private DeploymentTarget deployTarget = new DeploymentTarget();\n\n    public boolean deployApplication(String branch, String prodServer) {\n        System.out.println(\"\\n[Orchestrator] Starting deployment for branch: \" + branch);\n\n        vcs.pullLatestChanges(branch);\n\n        if (!buildSystem.compileProject()) {\n            System.err.println(\"Build failed. Deployment aborted.\");\n            return false;\n        }\n\n        String artifact = buildSystem.getArtifactPath();\n\n        if (!testFramework.runUnitTests() || !testFramework.runIntegrationTests()) {\n            System.err.println(\"Tests failed. Deployment aborted.\");\n            return false;\n        }\n\n        deployTarget.transferArtifact(artifact, prodServer);\n        deployTarget.activateNewVersion(prodServer);\n\n        System.out.println(\"[Orchestrator] Deployment successful!\");\n        return true;\n    }    \n}"
  },
  {
    "path": "design-patterns/java/facade/DeploymentTarget.java",
    "content": "public class DeploymentTarget {\n    public void transferArtifact(String artifactPath, String server) {\n        System.out.println(\"Deployment: Transferring \" + artifactPath + \" to \" + server + \"...\");\n        simulateDelay(1000);\n        System.out.println(\"Deployment: Transfer complete.\");\n    }\n\n    public void activateNewVersion(String server) {\n        System.out.println(\"Deployment: Activating new version on \" + server + \"...\");\n        simulateDelay(500);\n        System.out.println(\"Deployment: Now live on \" + server + \"!\");\n    }\n\n    private void simulateDelay(int ms) {\n        try {\n            Thread.sleep(ms);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/facade/TestingFramework.java",
    "content": "public class TestingFramework {\n    public boolean runUnitTests() {\n        System.out.println(\"Testing: Running unit tests...\");\n        simulateDelay(1500);\n        System.out.println(\"Testing: Unit tests passed.\");\n        return true;\n    }\n\n    public boolean runIntegrationTests() {\n        System.out.println(\"Testing: Running integration tests...\");\n        simulateDelay(3000);\n        System.out.println(\"Testing: Integration tests passed.\");\n        return true;\n    }\n\n    private void simulateDelay(int ms) {\n        try {\n            Thread.sleep(ms);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/facade/VersionControlSystem.java",
    "content": "public class VersionControlSystem {\n    public void pullLatestChanges(String branch) {\n        System.out.println(\"VCS: Pulling latest changes from '\" + branch + \"'...\");\n        simulateDelay();\n        System.out.println(\"VCS: Pull complete.\");\n    }\n    \n    private void simulateDelay() {\n        try {\n            Thread.sleep(1000);\n        } catch (InterruptedException e) {\n            e.printStackTrace();\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/factory/notification/EmailNotification.java",
    "content": "public class EmailNotification implements Notification {\n    @Override\n    public void send(String message) {\n        System.out.println(\"Sending email: \" + message);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/EmailNotificationCreator.java",
    "content": "public class EmailNotificationCreator extends NotificationCreator {\n    @Override\n    public Notification createNotification() {\n        return new EmailNotification();\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/FactoryMethodDemo.java",
    "content": "public class FactoryMethodDemo {\n    public static void main(String[] args) {\n        NotificationCreator creator;\n\n        // Send Email\n        creator = new EmailNotificationCreator();\n        creator.send(\"Welcome to our platform!\");\n\n        // Send SMS\n        creator = new SMSNotificationCreator();\n        creator.send(\"Your OTP is 123456\");\n\n        // Send Push Notification\n        creator = new PushNotificationCreator();\n        creator.send(\"You have a new follower!\");\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/Notification.java",
    "content": "public interface Notification {\n    public void send(String message);\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/NotificationCreator.java",
    "content": "public abstract class NotificationCreator {\n    // Factory Method\n    public abstract Notification createNotification();\n    \n    // Common logic using the factory method\n    public void send(String message) {\n        Notification notification = createNotification();\n        notification.send(message);\n    }\n}"
  },
  {
    "path": "design-patterns/java/factory/notification/NotificationServiceNaive.java",
    "content": "public class NotificationServiceNaive {\n    public void sendNotification(String type, String message) {\n        if (type.equals(\"EMAIL\")) {\n            EmailNotification email = new EmailNotification();\n            email.send(message);\n        } else if (type.equals(\"SMS\")) {\n            SMSNotification sms = new SMSNotification();\n            sms.send(message);\n        } else if (type.equals(\"Push\")) {\n            PushNotification push = new PushNotification();\n            push.send(message);\n        }\n    }    \n}"
  },
  {
    "path": "design-patterns/java/factory/notification/PushNotification.java",
    "content": "public class PushNotification implements Notification {\n    @Override\n    public void send(String message) {\n        System.out.println(\"Sending push notification: \" + message);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/PushNotificationCreator.java",
    "content": "public class PushNotificationCreator extends NotificationCreator {\n    @Override\n    public Notification createNotification() {\n        return new PushNotification();\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/SMSNotification.java",
    "content": "public class SMSNotification implements Notification {\n    @Override\n    public void send(String message) {\n        System.out.println(\"Sending SMS: \" + message);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/SMSNotificationCreator.java",
    "content": "public class SMSNotificationCreator extends NotificationCreator {\n    @Override\n    public Notification createNotification() {\n        return new SMSNotification();\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/notification/SimpleNotificationFactory.java",
    "content": "public class SimpleNotificationFactory {\n    public static Notification createNotification(String type) {\n        return switch (type) {\n            case \"EMAIL\" -> new EmailNotification();\n            case \"SMS\" -> new SMSNotification();\n            case \"PUSH\" -> new PushNotification();\n            default -> throw new IllegalArgumentException(\"Unknown type\");\n        };\n    }    \n}"
  },
  {
    "path": "design-patterns/java/factory/subscription/Customer.java",
    "content": "public class Customer {\n    public String customerId;\n    public Subscription subscription = null;\n\n    public Customer(String customerId) {\n        this.customerId = customerId;\n    }\n\n    public void SubscribePlan(Subscription subscription) {\n        this.subscription = subscription;\n        this.subscription.addSubscription(this);\n    }\n\n    public void unSubscribePlan() {\n        subscription.removeSubscription(this);\n    }\n    \n    public void updateSubcribePlan(Subscription newSubscription) {\n        subscription.removeSubscription(this);\n        this.subscription = newSubscription;\n        this.subscription.addSubscription(this);\n    }\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/DataBase.java",
    "content": "import java.util.HashMap;\n\npublic class DataBase {\n    private HashMap<String, String> customerList;\n\n    public DataBase() {\n        customerList = new HashMap<>();\n    }\n\n    public void addToDataBase(String customerId, String subscriptionType) {\n        if(!customerList.containsKey(customerId))\n            customerList.put(customerId, subscriptionType);\n        System.out.println(\"Successfull Added to the DB\");\n    }\n\n    public void removeFromDataBase(String customerId) {\n        if(customerList.containsKey(customerId))\n            customerList.remove(customerId);\n        System.out.println(\"Successfully removed from the DB\");\n    }\n\n    public void updateDataBase(String customerId, String subscriptionType) {\n        if(!customerList.containsKey(customerId))\n            System.out.println(\"Record not found\");\n        else {\n            customerList.put(customerId, subscriptionType);\n            System.out.println(\"Sucessfully update the DB\");\n        }    \n            \n    }\n    \n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/FactoryApplication.java",
    "content": "public class FactoryApplication {\n    static public DataBase dataBase;\n\n    public static void main(String[] arg) {\n        dataBase = new DataBase();\n        SubscriptionFactory factory = new SubscriptionFactory(dataBase);\n        Customer customer1 = new Customer(\"1\");\n        Customer customer2 = new Customer(\"2\");\n        Customer customer3 = new Customer(\"3\");\n\n\n        customer1.SubscribePlan(factory.getSubscription(\"gold\"));\n        customer2.SubscribePlan(factory.getSubscription(\"silver\"));\n        customer1.updateSubcribePlan(factory.getSubscription(\"royalGold\"));\n        customer2.unSubscribePlan();\n        customer3.SubscribePlan(factory.getSubscription(\"platinum\"));\n\n\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/Gold.java",
    "content": "public class Gold implements Subscription {\n\n    DataBase dataBase;\n\n    public Gold(DataBase dataBase) {\n        this.dataBase = dataBase;\n    }\n\n    @Override\n    public String subscriptionType() {\n        return this.getClass().getName();\n    }\n\n    @Override\n    public boolean addSubscription(Customer customer) {\n        System.out.println(\"Customer\"+ customer.customerId+ \"Added to the Gold List\" );\n        dataBase.addToDataBase(customer.customerId, \"Gold\");\n        return true;\n    }\n\n    @Override\n    public boolean removeSubscription(Customer customer) {\n        dataBase.removeFromDataBase(customer.customerId);\n        System.out.println(\"Customer \"+ customer.customerId +\" removed to the Gold List\" );\n        return true;\n    }\n\n    @Override\n    public boolean updateSubscription(Customer customer) {\n        dataBase.updateDataBase(customer.customerId, \"Gold\");\n        System.out.println(\"Customer \"+ customer.customerId+\" Updated to the Gold List\" );\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/Platinum.java",
    "content": "public class Platinum implements Subscription {\n\n    DataBase dataBase;\n\n    public Platinum(DataBase dataBase) {\n        this.dataBase = dataBase;\n    }\n\n    @Override\n    public String subscriptionType() {\n        return this.getClass().getName();\n    }\n\n    @Override\n    public boolean addSubscription(Customer customer) {\n        System.out.println(\"Customer Added to the Platinum List\" );\n        dataBase.addToDataBase(customer.customerId, \"Platinum\");\n        return true;\n    }\n\n    @Override\n    public boolean removeSubscription(Customer customer) {\n        dataBase.removeFromDataBase(customer.customerId);\n        System.out.println(\"Customer removed to the Platinum List\" );\n        return true;\n    }\n\n    @Override\n    public boolean updateSubscription(Customer customer) {\n        dataBase.updateDataBase(customer.customerId, \"Platinum\");\n        System.out.println(\"Customer Updated to the Platinum List\" );\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/RoyalGold.java",
    "content": "public class RoyalGold implements Subscription {\n\n    DataBase dataBase;\n\n    public RoyalGold(DataBase dataBase) {\n        this.dataBase = dataBase;\n    }\n\n    @Override\n    public String subscriptionType() {\n        return this.getClass().getName();\n    }\n\n    @Override\n    public boolean addSubscription(Customer customer) {\n        System.out.println(\"Customer Added to the RoyalGold List\" );\n        dataBase.addToDataBase(customer.customerId, \"RoyalGold\");\n        return true;\n    }\n\n    @Override\n    public boolean removeSubscription(Customer customer) {\n        dataBase.removeFromDataBase(customer.customerId);\n        System.out.println(\"Customer removed to the RoyalGold List\" );\n        return true;\n    }\n\n    @Override\n    public boolean updateSubscription(Customer customer) {\n        dataBase.updateDataBase(customer.customerId, \"RoyalGold\");\n        System.out.println(\"Customer Updated to the RoyalGold List\" );\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/Silver.java",
    "content": "public class Silver implements Subscription {\n\n    DataBase dataBase;\n\n    public Silver(DataBase dataBase) {\n        this.dataBase = dataBase;\n    }\n\n    @Override\n    public String subscriptionType() {\n        return this.getClass().getName();\n    }\n\n    @Override\n    public boolean addSubscription(Customer customer) {\n        System.out.println(\"Customer Added to the Silver List\" );\n        dataBase.addToDataBase(customer.customerId, \"Silver\");\n        return true;\n    }\n\n    @Override\n    public boolean removeSubscription(Customer customer) {\n        dataBase.removeFromDataBase(customer.customerId);\n        System.out.println(\"Customer removed to the Silver List\" );\n        return true;\n    }\n\n    @Override\n    public boolean updateSubscription(Customer customer) {\n        dataBase.updateDataBase(customer.customerId, \"Silver\");\n        System.out.println(\"Customer Updated to the Silver List\" );\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/Subscription.java",
    "content": "public interface Subscription {\n     public String subscriptionType();\n     public boolean addSubscription(Customer customer);\n     public boolean removeSubscription(Customer customer);\n     public boolean updateSubscription(Customer customer);\n\n}\n"
  },
  {
    "path": "design-patterns/java/factory/subscription/SubscriptionFactory.java",
    "content": "public class SubscriptionFactory {\n    private final DataBase dataBase;\n\n    public SubscriptionFactory(DataBase dataBase){\n        this.dataBase = dataBase;\n    }\n    public Subscription getSubscription(String subscriptionType){\n\n        return switch (subscriptionType) {\n            case \"gold\" -> new Gold(dataBase);\n            case \"silver\" -> new Silver(dataBase);\n            case \"platinum\" -> new Platinum(dataBase);\n            case \"royalGold\" -> new RoyalGold(dataBase);\n            default -> throw new IllegalArgumentException(\"Unknown subcription type\");\n        };\n\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/flyweight/CharacterFlyweight.java",
    "content": "public interface CharacterFlyweight {\n    void draw(int x, int y);\n}\n"
  },
  {
    "path": "design-patterns/java/flyweight/CharacterFlyweightFactory.java",
    "content": "import java.util.Map;\nimport java.util.HashMap;\n\npublic class CharacterFlyweightFactory {\n    private static final Map<String, CharacterFlyweight> flyweightCache = new HashMap<>();\n\n    public static CharacterFlyweight getFlyweight(char symbol, String fontFamily, int fontSize, String color) {\n        String key = String.format(\"%s-%d-%s\", symbol, fontSize, color);\n        if (!flyweightCache.containsKey(key)) {\n            flyweightCache.put(key, new CharacterGlyph(symbol, fontFamily, fontSize, color));\n        }\n        return flyweightCache.get(key);\n    }\n\n    public int getFlyweightCount() {\n        return flyweightCache.size();\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/flyweight/CharacterGlyph.java",
    "content": "public class CharacterGlyph implements CharacterFlyweight {\n    private final char symbol;\n    private final String fontFamily;\n    private final int fontSize;\n    private final String color;\n\n    public CharacterGlyph(char symbol, String fontFamily, int fontSize, String color) {\n        this.symbol = symbol;\n        this.fontFamily = fontFamily;\n        this.fontSize = fontSize;\n        this.color = color;\n    }\n\n    @Override\n    public void draw(int x, int y) {\n        System.out.println(String.format(\"Rendering %s at (%d, %d) with font %s, size %d, color %s\", symbol, x, y, fontFamily, fontSize, color));\n    }\n}"
  },
  {
    "path": "design-patterns/java/flyweight/FlyweightDemo.java",
    "content": "public class FlyweightDemo {\n    public static void main(String[] args) {\n        TextEditorClient editor = new TextEditorClient();\n\n        // Render 'Hello' with the same style\n        String word = \"Hello\";\n        for (int i = 0; i < word.length(); i++) {\n            editor.addCharacter(word.charAt(i), 10 + i * 15, 50, \"Arial\", 14, \"#000000\");\n        }\n\n        // Render 'World' with a different font and color\n        String word2 = \"World\";\n        for (int i = 0; i < word2.length(); i++) {\n            editor.addCharacter(word2.charAt(i), 10 + i * 15, 100, \"Times New Roman\", 14, \"#3333FF\");\n        }\n\n        editor.renderDocument();\n    }\n}"
  },
  {
    "path": "design-patterns/java/flyweight/TextEditorClient.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\n\npublic class TextEditorClient {\n    private final CharacterFlyweightFactory factory = new CharacterFlyweightFactory();\n    private final List<RenderedCharacter> document = new ArrayList<>();\n\n    public void addCharacter(char c, int x, int y, String font, int size, String color) {\n        CharacterFlyweight glyph = factory.getFlyweight(c, font, size, color);\n        document.add(new RenderedCharacter(glyph, x, y));\n    }\n\n    public void renderDocument() {\n        for (RenderedCharacter rc : document) {\n            rc.draw();\n        }\n        System.out.println(\"Total flyweight objects used: \" + factory.getFlyweightCount());\n    }\n\n    private static class RenderedCharacter {\n        private final CharacterFlyweight glyph;\n        private final int x, y;\n\n        public RenderedCharacter(CharacterFlyweight glyph, int x, int y) {\n            this.glyph = glyph;\n            this.x = x;\n            this.y = y;\n        }\n\n        public void draw() {\n            glyph.draw(x, y);\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/iterator/IterableCollection.java",
    "content": "public interface IterableCollection<T> {\n    Iterator<T> createIterator();\n}\n"
  },
  {
    "path": "design-patterns/java/iterator/Iterator.java",
    "content": "public interface Iterator<T> {\n    boolean hasNext();\n    T next();\n}\n"
  },
  {
    "path": "design-patterns/java/iterator/MusicPlayer.java",
    "content": "public class MusicPlayer {\n    public static void main(String[] args) {\n        Playlist playlist = new Playlist();\n        playlist.addSong(\"Shape of You\");\n        playlist.addSong(\"Bohemian Rhapsody\");\n        playlist.addSong(\"Blinding Lights\");\n\n        Iterator<String> iterator = playlist.createIterator();\n\n        System.out.println(\"Now Playing:\");\n        while (iterator.hasNext()) {\n            System.out.println(\"🎵 \" + iterator.next());\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/iterator/Playlist.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\n\npublic class Playlist implements IterableCollection<String> {\n    private final List<String> songs = new ArrayList<>();\n\n    public void addSong(String song) {\n        songs.add(song);\n    }\n\n    public String getSongAt(int index) {\n        return songs.get(index);\n    }\n\n    public int getSize() {\n        return songs.size();\n    }\n\n    @Override\n    public Iterator<String> createIterator() {\n        return new PlaylistIterator(this);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/iterator/PlaylistIterator.java",
    "content": "public class PlaylistIterator implements Iterator<String> {\n    private final Playlist playlist;\n    private int index = 0;\n\n    public PlaylistIterator(Playlist playlist) {\n        this.playlist = playlist;\n    }\n\n    @Override\n    public boolean hasNext() {\n        return index < playlist.getSize();\n    }\n\n    @Override\n    public String next() {\n        return playlist.getSongAt(index++);\n    }\n}"
  },
  {
    "path": "design-patterns/java/iterator/books/Book.java",
    "content": "class Book {\n    private String title;\n\n    public Book(String title) {\n        this.title = title;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n}"
  },
  {
    "path": "design-patterns/java/iterator/books/BookShelf.java",
    "content": "import java.util.List;\nimport java.util.ArrayList;\nimport java.util.Iterator;\n\nclass BookShelf implements Container<Book> {\n    private List<Book> books;\n\n    public BookShelf() {\n        books = new ArrayList<>();\n    }\n\n    public void addBook(Book book) {\n        books.add(book);\n    }\n\n    @Override\n    public Iterator<Book> getIterator() {\n        return new BookShelfIterator();\n    }\n\n    // ConcreteIterator\n    private class BookShelfIterator implements Iterator<Book> {\n        private int index;\n\n        @Override\n        public boolean hasNext() {\n            return index < books.size();\n        }\n\n        @Override\n        public Book next() {\n            if (this.hasNext()) {\n                return books.get(index++);\n            }\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/iterator/books/Container.java",
    "content": "interface Container<T> {\n    Iterator<T> getIterator();\n}\n"
  },
  {
    "path": "design-patterns/java/iterator/books/Iterator.java",
    "content": "interface Iterator<T> {\n    boolean hasNext();\n    T next();\n}"
  },
  {
    "path": "design-patterns/java/iterator/books/IteratorDemo.java",
    "content": "public class IteratorDemo {\n    public static void main(String[] args) {\n        BookShelf bookShelf = new BookShelf();\n        bookShelf.addBook(new Book(\"Design Patterns\"));\n        bookShelf.addBook(new Book(\"Clean Code\"));\n        bookShelf.addBook(new Book(\"Refactoring\"));\n\n        Iterator<Book> iterator = bookShelf.getIterator();\n        System.out.println(\"Books in the shelf:\");\n        while (iterator.hasNext()) {\n            Book book = iterator.next();\n            System.out.println(\"- \" + book.getTitle());\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/Button.java",
    "content": "public class Button extends UIComponent {\n    private boolean enabled = false;\n\n    public Button(UIMediator mediator) {\n        super(mediator);\n    }\n\n    public void click() {\n        if (enabled) {\n            System.out.println(\"Login Button clicked!\");\n            notifyMediator(); // Will trigger login attempt\n        } else {\n            System.out.println(\"Login Button is disabled.\");\n        }\n    }\n\n    public void setEnabled(boolean value) {\n        this.enabled = value;\n        System.out.println(\"Login Button is now \" + (enabled ? \"ENABLED\" : \"DISABLED\"));\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/FormMediator.java",
    "content": "public class FormMediator implements UIMediator {\n    private TextField usernameField;\n    private TextField passwordField;\n    private Button loginButton;\n    private Label statusLabel;\n\n    public void setUsernameField(TextField usernameField) {\n        this.usernameField = usernameField;\n    }\n\n    public void setPasswordField(TextField passwordField) {\n        this.passwordField = passwordField;\n    }\n\n    public void setLoginButton(Button loginButton) {\n        this.loginButton = loginButton;\n    }\n\n    public void setStatusLabel(Label statusLabel) {\n        this.statusLabel = statusLabel;\n    }\n\n    @Override\n    public void componentChanged(UIComponent component) {\n        if (component == usernameField || component == passwordField) {\n            boolean enableButton = !usernameField.getText().isEmpty() && !passwordField.getText().isEmpty();\n            loginButton.setEnabled(enableButton);\n        } else if (component == loginButton) {\n            String username = usernameField.getText();\n            String password = passwordField.getText();\n\n            if (\"admin\".equals(username) && \"1234\".equals(password)) {\n                statusLabel.setText(\"✅ Login successful!\");\n            } else {\n                statusLabel.setText(\"❌ Invalid credentials.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/Label.java",
    "content": "public class Label extends UIComponent {\n    private String text;\n\n    public Label(UIMediator mediator) {\n        super(mediator);\n    }\n\n    public void setText(String message) {\n        this.text = message;\n        System.out.println(\"Status: \" + text);\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/MediatorApp.java",
    "content": "public class MediatorApp {\n    public static void main(String[] args) {\n        FormMediator mediator = new FormMediator();\n\n        TextField usernameField = new TextField(mediator);\n        TextField passwordField = new TextField(mediator);\n        Button loginButton = new Button(mediator);\n        Label statusLabel = new Label(mediator);\n\n        mediator.setUsernameField(usernameField);\n        mediator.setPasswordField(passwordField);\n        mediator.setLoginButton(loginButton);\n        mediator.setStatusLabel(statusLabel);\n\n        // Simulate user interaction\n        usernameField.setText(\"admin\");\n        passwordField.setText(\"1234\");\n        loginButton.click();  // Should succeed\n\n        System.out.println(\"\\n--- New Attempt with Wrong Password ---\");\n        passwordField.setText(\"wrong\");\n        loginButton.click();  // Should fail\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/TextField.java",
    "content": "public class TextField extends UIComponent {\n    private String text = \"\";\n\n    public TextField(UIMediator mediator) {\n        super(mediator);\n    }\n\n    public void setText(String newText) {\n        this.text = newText;\n        System.out.println(\"TextField updated: \" + newText);\n        notifyMediator();\n    }\n\n    public String getText() {\n        return text;\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/UIComponent.java",
    "content": "public abstract class UIComponent {\n    protected UIMediator mediator;\n\n    public UIComponent(UIMediator mediator) {\n        this.mediator = mediator;\n    }\n\n    public void notifyMediator() {\n        mediator.componentChanged(this);\n    }\n}"
  },
  {
    "path": "design-patterns/java/mediator/UIMediator.java",
    "content": "public interface UIMediator {\n    void componentChanged(UIComponent component);\n}"
  },
  {
    "path": "design-patterns/java/memento/TextEditor.java",
    "content": "public class TextEditor {\n    private String content = \"\";\n\n    public void type(String newText) {\n        content += newText;\n        System.out.println(\"Typed: \" + newText);\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public TextEditorMemento save() {\n        System.out.println(\"Saving state: \\\"\" + content + \"\\\"\");\n        return new TextEditorMemento(content);\n    }\n\n    public void restore(TextEditorMemento memento) {\n        content = memento.getState();\n        System.out.println(\"Restored state to: \\\"\" + content + \"\\\"\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/memento/TextEditorMemento.java",
    "content": "public class TextEditorMemento {\n    private final String state;\n\n    public TextEditorMemento(String state) {\n        this.state = state;\n    }\n\n    public String getState() {\n        return state;\n    }    \n}"
  },
  {
    "path": "design-patterns/java/memento/TextEditorNaive.java",
    "content": "public class TextEditorNaive {\n    private String content = \"\";\n\n    public void type(String newText) {\n        content += newText;\n    }\n\n    public void undo(String previousContent) {\n        content = previousContent;\n    }\n\n    public String getContent() {\n        return content;\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/memento/TextEditorUndoManager.java",
    "content": "import java.util.Stack;\n\npublic class TextEditorUndoManager {\n    private final Stack<TextEditorMemento> history = new Stack<>();\n\n    public void save(TextEditor editor) {\n        history.push(editor.save());\n    }\n\n    public void undo(TextEditor editor) {\n        if (!history.isEmpty()) {\n            editor.restore(history.pop());\n        } else {\n            System.out.println(\"Nothing to undo.\");\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/java/memento/TextEditorUndoV1.java",
    "content": "public class TextEditorUndoV1 {\n    public static void main(String[] args) {\n        TextEditorNaive editor = new TextEditorNaive();\n\n        editor.type(\"Hello\");\n        String snapshot1 = editor.getContent(); // manual snapshot\n\n        editor.type(\" World\");\n        String snapshot2 = editor.getContent();\n\n        System.out.println(\"Current Content: \" + editor.getContent()); // Hello World\n\n        // Undo 1 step\n        editor.undo(snapshot1);\n        System.out.println(\"After Undo: \" + editor.getContent()); // Hello\n    }\n}"
  },
  {
    "path": "design-patterns/java/memento/TextEditorUndoV2.java",
    "content": "public class TextEditorUndoV2 {\n    public static void main(String[] args) {\n        TextEditor editor = new TextEditor();\n        TextEditorUndoManager undoManager = new TextEditorUndoManager();\n\n        editor.type(\"Hello\");\n        undoManager.save(editor);  // save state: Hello\n\n        editor.type(\" World\");\n        undoManager.save(editor);  // save state: Hello World\n\n        editor.type(\"!\");\n        System.out.println(\"Current Content: \" + editor.getContent()); // Hello World!\n\n        System.out.println(\"\\n--- Undo 1 ---\");\n        undoManager.undo(editor); // Back to: Hello World\n\n        System.out.println(\"\\n--- Undo 2 ---\");\n        undoManager.undo(editor); // Back to: Hello\n\n        System.out.println(\"\\n--- Undo 3 ---\");\n        undoManager.undo(editor); // Nothing left to undo\n    }\n}"
  },
  {
    "path": "design-patterns/java/observer/FitnessAppNaiveClient.java",
    "content": "public class FitnessAppNaiveClient {\n    public static void main(String[] args) {\n        LiveActivityDisplayNaive display = new LiveActivityDisplayNaive();\n        ProgressLoggerNaive logger = new ProgressLoggerNaive();\n        NotificationServiceNaive notifier = new NotificationServiceNaive();\n\n        FitnessDataNaive fitnessData = new FitnessDataNaive(display, logger, notifier);\n\n        fitnessData.newFitnessDataPushed(500, 5, 20);\n        fitnessData.newFitnessDataPushed(9800, 85, 350);\n        fitnessData.newFitnessDataPushed(10100, 90, 380); // Goal should be hit\n        fitnessData.dailyReset();\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/observer/FitnessAppObserverDemo.java",
    "content": "public class FitnessAppObserverDemo {\n    public static void main(String[] args) {\n        FitnessData fitnessData = new FitnessData();\n\n        LiveActivityDisplay display = new LiveActivityDisplay();\n        ProgressLogger logger = new ProgressLogger();\n        GoalNotifier notifier = new GoalNotifier();\n\n        // Register observers\n        fitnessData.registerObserver(display);\n        fitnessData.registerObserver(logger);\n        fitnessData.registerObserver(notifier);\n\n        // Simulate updates\n        fitnessData.newFitnessDataPushed(500, 5, 20);\n        fitnessData.newFitnessDataPushed(9800, 85, 350);\n        fitnessData.newFitnessDataPushed(10100, 90, 380); // Goal should trigger\n\n        // Daily reset\n        notifier.reset();\n        fitnessData.dailyReset();\n    }\n}"
  },
  {
    "path": "design-patterns/java/observer/FitnessData.java",
    "content": "import java.util.*;\n\npublic class FitnessData implements FitnessDataSubject {\n    private int steps;\n    private int activeMinutes;\n    private int calories;\n\n    private final List<FitnessDataObserver> observers = new ArrayList<>();\n\n    @Override\n    public void registerObserver(FitnessDataObserver observer) {\n        observers.add(observer);\n    }\n\n    @Override\n    public void removeObserver(FitnessDataObserver observer) {\n        observers.remove(observer);\n    }\n\n    @Override\n    public void notifyObservers() {\n        for (FitnessDataObserver observer : observers) {\n            observer.update(this);\n        }\n    }\n\n    public void newFitnessDataPushed(int steps, int activeMinutes, int calories) {\n        this.steps = steps;\n        this.activeMinutes = activeMinutes;\n        this.calories = calories;\n\n        System.out.println(\"\\nFitnessData: New data received — Steps: \" + steps +\n                           \", Active Minutes: \" + activeMinutes + \", Calories: \" + calories);\n        notifyObservers();\n    }\n\n    public void dailyReset() {\n        this.steps = 0;\n        this.activeMinutes = 0;\n        this.calories = 0;\n        System.out.println(\"\\nFitnessData: Daily reset performed.\");\n        notifyObservers();\n    }\n\n    // Getters\n    public int getSteps() { return steps; }\n    public int getActiveMinutes() { return activeMinutes; }\n    public int getCalories() { return calories; }\n}"
  },
  {
    "path": "design-patterns/java/observer/FitnessDataNaive.java",
    "content": "public class FitnessDataNaive {\n    private int steps;\n    private int activeMinutes;\n    private int calories;\n\n    // Direct, hardcoded references to all dependent modules!\n    private LiveActivityDisplayNaive liveDisplay;\n    private ProgressLoggerNaive progressLogger;\n    private NotificationServiceNaive notificationService;\n\n    public FitnessDataNaive(LiveActivityDisplayNaive ld, ProgressLoggerNaive pl, NotificationServiceNaive ns) {\n        this.liveDisplay = ld;\n        this.progressLogger = pl;\n        this.notificationService = ns;\n    }\n\n    // This method gets called when new data arrives from the wearable\n    public void newFitnessDataPushed(int newSteps, int newActiveMinutes, int newCalories) {\n        this.steps = newSteps;\n        this.activeMinutes = newActiveMinutes;\n        this.calories = newCalories;\n\n        System.out.println(\"\\nFitnessDataNaive: New data received - Steps:\" + steps +\n                           \", ActiveMins:\" + activeMinutes + \", Calories:\" + calories);\n\n        // Manually notify each dependent module\n        liveDisplay.showStats(steps, activeMinutes, calories);\n        progressLogger.logDataPoint(steps, activeMinutes, calories);\n        notificationService.checkAndNotify(steps);\n    }\n\n    public void dailyReset() {\n        // ... reset steps, etc. ...\n        notificationService.resetDailyNotifications();\n        System.out.println(\"FitnessDataNaive: Daily data reset.\");\n        newFitnessDataPushed(0,0,0); // Notify of reset state\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/observer/FitnessDataObserver.java",
    "content": "public interface FitnessDataObserver {\n    void update(FitnessData data);\n}"
  },
  {
    "path": "design-patterns/java/observer/FitnessDataSubject.java",
    "content": "public interface FitnessDataSubject {\n    void registerObserver(FitnessDataObserver o);\n    void removeObserver(FitnessDataObserver o);\n    void notifyObservers();\n}"
  },
  {
    "path": "design-patterns/java/observer/GoalNotifier.java",
    "content": "public class GoalNotifier implements FitnessDataObserver {\n    private final int stepGoal = 10000;\n    private boolean goalReached = false;\n\n    @Override\n    public void update(FitnessData data) {\n        if (data.getSteps() >= stepGoal && !goalReached) {\n            System.out.println(\"Notifier → 🎉 Goal Reached! You've hit \" + stepGoal + \" steps!\");\n            goalReached = true;\n        }\n    }\n\n    public void reset() {\n        goalReached = false;\n    }\n}"
  },
  {
    "path": "design-patterns/java/observer/LiveActivityDisplay.java",
    "content": "public class LiveActivityDisplay implements FitnessDataObserver {\n    @Override\n    public void update(FitnessData data) {\n        System.out.println(\"Live Display → Steps: \" + data.getSteps() +\n                           \" | Active Minutes: \" + data.getActiveMinutes() +\n                           \" | Calories: \" + data.getCalories());\n    }\n}"
  },
  {
    "path": "design-patterns/java/observer/LiveActivityDisplayNaive.java",
    "content": "public class LiveActivityDisplayNaive {\n    public void showStats(int steps, int activeMinutes, int calories) {\n        System.out.println(\"NAIVE Live Display: Steps: \" + steps +\n                           \" | Active Mins: \" + activeMinutes +\n                           \" | Calories: \" + calories);\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/observer/NotificationServiceNaive.java",
    "content": "public class NotificationServiceNaive {\n    private int stepGoal = 10000;\n    private boolean dailyStepGoalNotified = false;\n\n    public void checkAndNotify(int currentSteps) {\n        if (currentSteps >= stepGoal && !dailyStepGoalNotified) {\n            System.out.println(\"NAIVE Notifier: ALERT! You've reached your \" + stepGoal + \" step goal!\");\n            dailyStepGoalNotified = true;\n        }\n        // ... other notification logic, e.g., inactivity alerts ...\n    }\n    public void resetDailyNotifications() {\n        dailyStepGoalNotified = false;\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/observer/ProgressLogger.java",
    "content": "public class ProgressLogger implements FitnessDataObserver {\n    @Override\n    public void update(FitnessData data) {\n        System.out.println(\"Logger → Saving to DB: Steps=\" + data.getSteps() +\n                           \", ActiveMinutes=\" + data.getActiveMinutes() +\n                           \", Calories=\" + data.getCalories());\n        // Simulated DB/file write...\n    }\n}"
  },
  {
    "path": "design-patterns/java/observer/ProgressLoggerNaive.java",
    "content": "public class ProgressLoggerNaive {\n    public void logDataPoint(int steps, int activeMinutes, int calories) {\n        System.out.println(\"NAIVE Logger: Saving data - Steps: \" + steps +\n                           \", Active Mins: \" + activeMinutes +\n                           \", Calories: \" + calories);\n        // ... actual database/file logging logic ...\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/prototype/Enemy.java",
    "content": "public class Enemy implements EnemyPrototype {\n    private String type;\n    private int health;\n    private double speed;\n    private boolean armored;\n    private String weapon;\n\n    public Enemy(String type, int health, double speed, boolean armored, String weapon) {\n        this.type = type;\n        this.health = health;\n        this.speed = speed;\n        this.armored = armored;\n        this.weapon = weapon;\n    }\n\n    @Override\n    public Enemy clone() {\n        return new Enemy(type, health, speed, armored, weapon);\n    }\n\n    public void setHealth(int health) {\n        this.health = health;\n    }\n\n    public void printStats() {\n        System.out.println(type + \" [Health: \" + health + \", Speed: \" + speed + \", Armored: \" + armored + \", Weapon: \" + weapon + \"]\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/prototype/EnemyPrototype.java",
    "content": "public interface EnemyPrototype {\n    EnemyPrototype clone();\n}"
  },
  {
    "path": "design-patterns/java/prototype/EnemyRegistry.java",
    "content": "import java.util.HashMap;\nimport java.util.Map;\n\npublic class EnemyRegistry {\n    private Map<String, Enemy> prototypes = new HashMap<>();\n\n    public void register(String key, Enemy prototype) {\n        prototypes.put(key, prototype);\n    }\n\n    public Enemy get(String key) {\n        Enemy prototype = prototypes.get(key);\n        if (prototype != null) {\n            return prototype.clone();\n        }\n        throw new IllegalArgumentException(\"No prototype registered for: \" + key);\n    }\n}"
  },
  {
    "path": "design-patterns/java/prototype/Game.java",
    "content": "public class Game {\n    public static void main(String[] args) {\n        EnemyRegistry registry = new EnemyRegistry();\n\n        // Register prototype enemies\n        registry.register(\"flying\", new Enemy(\"FlyingEnemy\", 100, 12.0, false, \"Laser\"));\n        registry.register(\"armored\", new Enemy(\"ArmoredEnemy\", 300, 6.0, true, \"Cannon\"));\n\n        // Clone from registry\n        Enemy e1 = registry.get(\"flying\");\n        Enemy e2 = registry.get(\"flying\");\n        e2.setHealth(80); // this one is damaged\n\n        Enemy e3 = registry.get(\"armored\");\n\n        // Print enemy stats\n        e1.printStats();\n        e2.printStats();\n        e3.printStats();\n    }\n}"
  },
  {
    "path": "design-patterns/java/proxy/HighResolutionImage.java",
    "content": "public class HighResolutionImage implements Image {\n    private String fileName;\n    private byte[] imageData; // Simulate large data\n\n    public HighResolutionImage(String fileName) {\n        this.fileName = fileName;\n        loadImageFromDisk(); // Expensive operation!\n    }\n\n    private void loadImageFromDisk() {\n        System.out.println(\"Loading image: \" + fileName + \" from disk (Expensive Operation)...\");\n        // Simulate disk read and memory allocation\n        try {\n            Thread.sleep(2000); // Simulate delay\n            this.imageData = new byte[10 * 1024 * 1024]; // 10MB\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n        }\n        System.out.println(\"Image \" + fileName + \" loaded successfully.\");\n    }\n\n    @Override\n    public void display() {\n        System.out.println(\"Displaying image: \" + fileName);\n        // Actual rendering logic would go here\n    }\n\n    @Override\n    public String getFileName() {\n        return fileName;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/proxy/Image.java",
    "content": "public interface Image {\n    void display();\n    String getFileName();\n}\n"
  },
  {
    "path": "design-patterns/java/proxy/ImageGalleryAppV1.java",
    "content": "public class ImageGalleryAppV1 {\n    public static void main(String[] args) {\n        System.out.println(\"Application Started. Initializing images for gallery...\");\n\n        // Imagine we need to create image objects for a list of thumbnails\n        // Even if the user never clicks them, they get loaded!\n        Image image1 = new HighResolutionImage(\"photo1.jpg\");\n        Image image2 = new HighResolutionImage(\"photo2.png\");\n        Image image3 = new HighResolutionImage(\"photo3.gif\");\n\n        System.out.println(\"\\nGallery initialized. User might view an image now.\");\n\n        // User clicks on image1\n        System.out.println(\"User requests to display \" + image1.getFileName());\n        image1.display();\n\n        // User clicks on image3\n        System.out.println(\"\\nUser requests to display \" + image3.getFileName());\n        image3.display();\n\n        // image2 was loaded but never displayed by the user in this session. Waste of resources!\n        System.out.println(\"\\nApplication finished.\");\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/proxy/ImageGalleryAppV2.java",
    "content": "public class ImageGalleryAppV2 {\n    public static void main(String[] args) {\n        System.out.println(\"Application Started. Initializing image proxies for gallery...\");\n\n        // Create lightweight proxies instead of full image objects\n        Image image1 = new ImageProxy(\"photo1.jpg\");\n        Image image2 = new ImageProxy(\"photo2.png\"); // Never displayed\n        Image image3 = new ImageProxy(\"photo3.gif\");\n\n        System.out.println(\"\\nGallery initialized. No images actually loaded yet.\");\n        System.out.println(\"Image 1 Filename: \" + image1.getFileName()); // Does not trigger image load\n\n        // User clicks on image1\n        System.out.println(\"\\nUser requests to display \" + image1.getFileName());\n        image1.display(); // Lazy loading happens here\n\n        // User clicks on image1 again\n        System.out.println(\"\\nUser requests to display \" + image1.getFileName() + \" again.\");\n        image1.display(); // Already loaded; no loading delay\n\n        // User clicks on image3\n        System.out.println(\"\\nUser requests to display \" + image3.getFileName());\n        image3.display(); // Triggers loading for image3\n\n        System.out.println(\"\\nApplication finished. Note: photo2.png was never loaded.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/proxy/ImageProxy.java",
    "content": "public class ImageProxy implements Image {\n    private String fileName;\n    private HighResolutionImage realImage; // RealSubject\n\n    public ImageProxy(String fileName) {\n        this.fileName = fileName;\n        System.out.println(\"ImageProxy: Created for \" + fileName + \". Real image not loaded yet.\");\n    }\n\n    @Override\n    public String getFileName() {\n        // Can safely return without loading the image\n        return fileName;\n    }\n\n    @Override\n    public void display() {\n        // Lazy initialization: Load only when display() is called\n        if (realImage == null) {\n            System.out.println(\"ImageProxy: display() requested for \" + fileName + \". Loading high-resolution image...\");\n            realImage = new HighResolutionImage(fileName);\n        } else {\n            System.out.println(\"ImageProxy: Using cached high-resolution image for \" + fileName);\n        }\n\n        // Delegate the display call to the real image\n        realImage.display();\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/BillPughSingleton.java",
    "content": "class BillPughSingleton {\n    // Private constructor to prevent instantiation\n    private BillPughSingleton() {}\n    \n    // Static inner class that holds the instance\n    private static class SingletonHelper {\n        private static final BillPughSingleton INSTANCE = new BillPughSingleton();\n    }\n    \n    // Public method to get the instance\n    public static BillPughSingleton getInstance() {\n        return SingletonHelper.INSTANCE;\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/DoubleCheckedLockingSingleton.java",
    "content": "class DoubleCheckedSingleton {\n    // The single instance, initially null, marked as volatile\n    private static volatile DoubleCheckedSingleton instance;\n    \n    // Private constructor to prevent instantiation\n    private DoubleCheckedSingleton() {}\n    \n    // Public method to get the instance\n    public static DoubleCheckedSingleton getInstance() {\n        // First check (not synchronized)\n        if (instance == null) {\n            // Synchronize on the class object\n            synchronized (DoubleCheckedSingleton.class) {\n                // Second check (synchronized)\n                if (instance == null) {\n                    // Create the instance\n                    instance = new DoubleCheckedSingleton();\n                }\n            }\n        }\n        // Return the instance (either newly created or existing)\n        return instance;\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/EagerSingleton.java",
    "content": "class EagerSingleton {\n    // The single instance, created immediately\n    private static final EagerSingleton instance = new EagerSingleton();\n    \n    // Private constructor to prevent instantiation\n    private EagerSingleton() {}\n    \n    // Public method to get the instance\n    public static EagerSingleton getInstance() {\n        return instance;\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/EnumSingleton.java",
    "content": "public enum EnumSingleton {\n    INSTANCE;\n\n    public void doSomething() {\n        // Add any singleton logic here\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/singleton/LazySingleton.java",
    "content": "class LazySingleton {\n    // The single instance, initially null\n    private static LazySingleton instance;\n    \n    // Private constructor to prevent instantiation\n    private LazySingleton() {}\n    \n    // Public method to get the instance\n    public static LazySingleton getInstance() {\n        // Check if instance is null\n        if (instance == null) {\n            // If null, create a new instance\n            instance = new LazySingleton();\n        }\n        // Return the instance (either newly created or existing)\n        return instance;\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/StaticBlockSingleton.java",
    "content": "class StaticBlockSingleton {\n    // The single instance\n    private static StaticBlockSingleton instance;\n    \n    // Private constructor to prevent instantiation\n    private StaticBlockSingleton() {}\n    \n    // Static block for initialization\n    static {\n        try {\n            instance = new StaticBlockSingleton();\n        } catch (Exception e) {\n            throw new RuntimeException(\"Exception occurred in creating singleton instance\");\n        }\n    }\n    \n    // Public method to get the instance\n    public static StaticBlockSingleton getInstance() {\n        return instance;\n    }\n}"
  },
  {
    "path": "design-patterns/java/singleton/ThreadSafeSingleton.java",
    "content": "class ThreadSafeSingleton {\n    // The single instance, initially null\n    private static ThreadSafeSingleton instance;\n    \n    // Private constructor to prevent instantiation\n    private ThreadSafeSingleton() {}\n    \n    // Public method to get the instance, with synchronized keyword\n    public static synchronized ThreadSafeSingleton getInstance() {\n        // Check if instance is null\n        if (instance == null) {\n            // If null, create a new instance\n            instance = new ThreadSafeSingleton();\n        }\n        // Return the instance (either newly created or existing)\n        return instance;\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/DispensingState.java",
    "content": "public class DispensingState implements MachineState {\n    @Override\n    public void selectItem(VendingMachine context, String itemCode) {\n        System.out.println(\"Please wait, dispensing in progress.\");\n    }\n\n    @Override\n    public void insertCoin(VendingMachine context, double amount) {\n        System.out.println(\"Please wait, dispensing in progress.\");\n    }\n\n    @Override\n    public void dispenseItem(VendingMachine context) {\n        System.out.println(\"Already dispensing. Please wait.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/HasMoneyState.java",
    "content": "public class HasMoneyState implements MachineState {\n    @Override\n    public void selectItem(VendingMachine context, String itemCode) {\n        System.out.println(\"Cannot change item after inserting money.\");\n    }\n\n    @Override\n    public void insertCoin(VendingMachine context, double amount) {\n        System.out.println(\"Money already inserted.\");\n    }\n\n    @Override\n    public void dispenseItem(VendingMachine context) {\n        System.out.println(\"Dispensing item: \" + context.getSelectedItem());\n        context.setState(new DispensingState());\n\n        // Simulate dispensing\n        try { Thread.sleep(1000); } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n        }\n\n        System.out.println(\"Item dispensed successfully.\");\n        context.reset();\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/IdleState.java",
    "content": "public class IdleState implements MachineState {\n    @Override\n    public void selectItem(VendingMachine context, String itemCode) {\n        System.out.println(\"Item selected: \" + itemCode);\n        context.setSelectedItem(itemCode);\n        context.setState(new ItemSelectedState());\n    }\n\n    @Override\n    public void insertCoin(VendingMachine context, double amount) {\n        System.out.println(\"Please select an item before inserting coins.\");\n    }\n\n    @Override\n    public void dispenseItem(VendingMachine context) {\n        System.out.println(\"No item selected. Nothing to dispense.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/ItemSelectedState.java",
    "content": "public class ItemSelectedState implements MachineState {\n    @Override\n    public void selectItem(VendingMachine context, String itemCode) {\n        System.out.println(\"Item already selected: \" + context.getSelectedItem());\n    }\n\n    @Override\n    public void insertCoin(VendingMachine context, double amount) {\n        System.out.println(\"Inserted $\" + amount + \" for item: \" + context.getSelectedItem());\n        context.setInsertedAmount(amount);\n        context.setState(new HasMoneyState());\n    }\n\n    @Override\n    public void dispenseItem(VendingMachine context) {\n        System.out.println(\"Insert coin before dispensing.\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/MachineState.java",
    "content": "public interface MachineState {\n    void selectItem(VendingMachine context, String itemCode);\n    void insertCoin(VendingMachine context, double amount);\n    void dispenseItem(VendingMachine context);\n}"
  },
  {
    "path": "design-patterns/java/state/VendingMachine.java",
    "content": "public class VendingMachine {\n    private MachineState currentState;\n    private String selectedItem;\n    private double insertedAmount;\n\n    public VendingMachine() {\n        this.currentState = new IdleState(); // Initial state\n    }\n\n    public void setState(MachineState newState) {\n        this.currentState = newState;\n    }\n\n    public void setSelectedItem(String itemCode) {\n        this.selectedItem = itemCode;\n    }\n\n    public void setInsertedAmount(double amount) {\n        this.insertedAmount = amount;\n    }\n\n    public String getSelectedItem() {\n        return selectedItem;\n    }\n\n    public double getInsertedAmount() {\n        return insertedAmount;\n    }\n\n    public void selectItem(String itemCode) {\n        currentState.selectItem(this, itemCode);\n    }\n\n    public void insertCoin(double amount) {\n        currentState.insertCoin(this, amount);\n    }\n\n    public void dispenseItem() {\n        currentState.dispenseItem(this);\n    }\n\n    public void reset() {\n        this.selectedItem = \"\";\n        this.insertedAmount = 0.0;\n        this.currentState = new IdleState();\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/VendingMachineApp.java",
    "content": "public class VendingMachineApp {\n    public static void main(String[] args) {\n        VendingMachine vm = new VendingMachine();\n\n        vm.insertCoin(1.0); // Invalid in IdleState\n        vm.selectItem(\"A1\");\n        vm.insertCoin(1.5);\n        vm.dispenseItem();\n\n        System.out.println(\"\\n--- Second Transaction ---\");\n        vm.selectItem(\"B2\");\n        vm.insertCoin(2.0);\n        vm.dispenseItem();\n    }\n}"
  },
  {
    "path": "design-patterns/java/state/VendingMachineNaive.java",
    "content": "public class VendingMachineNaive {\n    private enum State {\n        IDLE,\n        ITEM_SELECTED,\n        HAS_MONEY,\n        DISPENSING\n    }\n\n    private State currentState = State.IDLE;\n    private String selectedItem = \"\";\n    private double insertedAmount = 0.0;\n\n    public void selectItem(String itemCode) {\n        switch (currentState) {\n            case IDLE:\n                selectedItem = itemCode;\n                System.out.println(\"Item '\" + itemCode + \"' selected. Please insert coin.\");\n                currentState = State.ITEM_SELECTED;\n                break;\n            case ITEM_SELECTED:\n                System.out.println(\"Item already selected: '\" + selectedItem + \"'. Insert coin or cancel.\");\n                break;\n            case HAS_MONEY:\n                System.out.println(\"Payment already received for item '\" + selectedItem + \"'. Dispense in progress.\");\n                break;\n            case DISPENSING:\n                System.out.println(\"Cannot select new item. Currently dispensing.\");\n                break;\n        }\n    }\n\n    public void insertCoin(double amount) {\n        switch (currentState) {\n            case IDLE:\n                System.out.println(\"No item selected. Please select an item before inserting coins.\");\n                break;\n            case ITEM_SELECTED:\n                insertedAmount = amount;\n                System.out.println(\"Inserted $\" + amount + \" for item '\" + selectedItem + \"'. Ready to dispense.\");\n                currentState = State.HAS_MONEY;\n                break;\n            case HAS_MONEY:\n                System.out.println(\"Money already inserted. Please wait or press dispense.\");\n                break;\n            case DISPENSING:\n                System.out.println(\"Currently dispensing. Please wait.\");\n                break;\n        }\n    }\n\n    public void dispenseItem() {\n        switch (currentState) {\n            case IDLE:\n                System.out.println(\"No item selected. Nothing to dispense.\");\n                break;\n            case ITEM_SELECTED:\n                System.out.println(\"Please insert coin before dispensing.\");\n                break;\n            case HAS_MONEY:\n                System.out.println(\"Dispensing item '\" + selectedItem + \"'...\");\n                currentState = State.DISPENSING;\n\n                // Simulate delay and completion\n                try {\n                    Thread.sleep(1000);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                }\n\n                System.out.println(\"Item dispensed successfully.\");\n                resetMachine();\n                break;\n            case DISPENSING:\n                System.out.println(\"Already dispensing. Please wait.\");\n                break;\n        }\n    }\n\n    public void cancelTransaction() {\n        switch (currentState) {\n            case IDLE:\n                System.out.println(\"Nothing to cancel.\");\n                break;\n            case ITEM_SELECTED:\n                System.out.println(\"Transaction cancelled. Returning to IDLE.\");\n                resetMachine();\n                break;\n            case HAS_MONEY:\n                System.out.println(\"Transaction cancelled. Refunding $\" + insertedAmount + \".\");\n                resetMachine();\n                break;\n            case DISPENSING:\n                System.out.println(\"Cannot cancel. Item is being dispensed.\");\n                break;\n        }\n    }\n\n    private void resetMachine() {\n        selectedItem = \"\";\n        insertedAmount = 0.0;\n        currentState = State.IDLE;\n    }\n}"
  },
  {
    "path": "design-patterns/java/strategy/DistanceBasedShipping.java",
    "content": "public class DistanceBasedShipping implements ShippingStrategy {\n    private double ratePerKm;\n\n    public DistanceBasedShipping(double ratePerKm) {\n        this.ratePerKm = ratePerKm;\n    }\n\n    @Override\n    public double calculateCost(Order order) {\n        System.out.println(\"Calculating with Distance-Based strategy for zone: \" + order.getDestinationZone());\n        \n        return switch (order.getDestinationZone()) {\n            case \"ZoneA\" -> ratePerKm * 5.0;\n            case \"ZoneB\" -> ratePerKm * 7.0;\n            default -> ratePerKm * 10.0;\n        };        \n    }\n}\n"
  },
  {
    "path": "design-patterns/java/strategy/ECommerceAppV1.java",
    "content": "public class ECommerceAppV1 {\n    public static void main(String[] args) {\n        ShippingCostCalculatorNaive calculator = new ShippingCostCalculatorNaive();\n        Order order1 = new Order();\n\n        System.out.println(\"--- Order 1 ---\");\n        calculator.calculateShippingCost(order1, \"FLAT_RATE\");\n        calculator.calculateShippingCost(order1, \"WEIGHT_BASED\");\n        calculator.calculateShippingCost(order1, \"DISTANCE_BASED\");\n        calculator.calculateShippingCost(order1, \"THIRD_PARTY_API\");\n\n        // What if we want to try a new \"PremiumZone\" strategy?\n        // We have to modify the ShippingCostCalculatorNaive class!\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/strategy/ECommerceAppV2.java",
    "content": "public class ECommerceAppV2 {\n    public static void main(String[] args) {\n        Order order1 = new Order();\n\n        // Create different strategy instances\n        ShippingStrategy flatRate = new FlatRateShipping(10.0);\n        ShippingStrategy weightBased = new WeightBasedShipping(2.5);\n        ShippingStrategy distanceBased = new DistanceBasedShipping(5.0);\n        ShippingStrategy thirdParty = new ThirdPartyApiShipping(7.5, 0.02);\n\n        // Create context with an initial strategy\n        ShippingCostService shippingService = new ShippingCostService(flatRate);\n\n        System.out.println(\"--- Order 1: Using Flat Rate (initial) ---\");\n        shippingService.calculateShippingCost(order1);\n\n        System.out.println(\"\\n--- Order 1: Changing to Weight-Based ---\");\n        shippingService.setStrategy(weightBased);\n        shippingService.calculateShippingCost(order1);\n\n        System.out.println(\"\\n--- Order 1: Changing to Distance-Based ---\");\n        shippingService.setStrategy(distanceBased);\n        shippingService.calculateShippingCost(order1);\n\n        System.out.println(\"\\n--- Order 1: Changing to Third-Party API ---\");\n        shippingService.setStrategy(thirdParty);\n        shippingService.calculateShippingCost(order1);\n\n        // Adding a NEW strategy is easy:\n        // 1. Create a new class implementing ShippingStrategy (e.g., FreeShippingStrategy)\n        // 2. Client can then instantiate and use it:\n        //    ShippingStrategy freeShipping = new FreeShippingStrategy();\n        //    shippingService.setStrategy(freeShipping);\n        //    shippingService.calculateShippingCost(primeMemberOrder);\n        // No modification to ShippingCostService is needed!\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/strategy/FlatRateShipping.java",
    "content": "public class FlatRateShipping implements ShippingStrategy {\n    private double rate;\n\n    public FlatRateShipping(double rate) {\n        this.rate = rate;\n    }\n\n    @Override\n    public double calculateCost(Order order) {\n        System.out.println(\"Calculating with Flat Rate strategy ($\" + rate + \")\");\n        return rate;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/strategy/Order.java",
    "content": "public class Order {\n    public double getTotalWeight() { return 5.0; /* kg */ }\n    public String getDestinationZone() { return \"ZoneA\"; }\n    public double getOrderValue() { return 150.0; }\n    // ... other order details    \n}"
  },
  {
    "path": "design-patterns/java/strategy/ShippingCostCalculatorNaive.java",
    "content": "public class ShippingCostCalculatorNaive {\n    public double calculateShippingCost(Order order, String strategyType) {\n        double cost = 0.0;\n\n        if (\"FLAT_RATE\".equalsIgnoreCase(strategyType)) {\n            System.out.println(\"Calculating with Flat Rate strategy.\");\n            cost = 10.0; // Fixed $10\n        } else if (\"WEIGHT_BASED\".equalsIgnoreCase(strategyType)) {\n            System.out.println(\"Calculating with Weight-Based strategy.\");\n            cost = order.getTotalWeight() * 2.5; // $2.5 per kg\n        } else if (\"DISTANCE_BASED\".equalsIgnoreCase(strategyType)) {\n            System.out.println(\"Calculating with Distance-Based strategy.\");\n            if (\"ZoneA\".equals(order.getDestinationZone())) {\n                cost = 5.0;\n            } else if (\"ZoneB\".equals(order.getDestinationZone())) {\n                cost = 12.0;\n            } else {\n                cost = 20.0; // Default for other zones\n            }\n        } else if (\"THIRD_PARTY_API\".equalsIgnoreCase(strategyType)) {\n            System.out.println(\"Calculating with Third-Party API strategy.\");\n            // Simulate API call\n            cost = 7.5 + (order.getOrderValue() * 0.02); // Example: base fee + % of order value\n        } else {\n            throw new IllegalArgumentException(\"Unknown shipping strategy type: \" + strategyType);\n        }\n        System.out.println(\"Calculated Shipping Cost: $\" + cost);\n        return cost;\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/strategy/ShippingCostService.java",
    "content": "public class ShippingCostService {\n    private ShippingStrategy strategy;\n\n    // Constructor to set initial strategy\n    public ShippingCostService(ShippingStrategy strategy) {\n        this.strategy = strategy;\n    }\n\n    // Method to change strategy at runtime\n    public void setStrategy(ShippingStrategy strategy) {\n        System.out.println(\"ShippingCostService: Strategy changed to \" + strategy.getClass().getSimpleName());\n        this.strategy = strategy;\n    }\n\n    public double calculateShippingCost(Order order) {\n        if (strategy == null) {\n            throw new IllegalStateException(\"Shipping strategy not set.\");\n        }\n        double cost = strategy.calculateCost(order); // Delegate to the strategy\n        System.out.println(\"ShippingCostService: Final Calculated Shipping Cost: $\" + cost +\n                           \" (using \" + strategy.getClass().getSimpleName() + \")\");\n        return cost;\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/strategy/ShippingStrategy.java",
    "content": "public interface ShippingStrategy {\n    double calculateCost(Order order);\n}\n"
  },
  {
    "path": "design-patterns/java/strategy/ThirdPartyApiShipping.java",
    "content": "public class ThirdPartyApiShipping implements ShippingStrategy {\n    private final double baseFee;\n    private final double percentageFee;\n\n    public ThirdPartyApiShipping(double baseFee, double percentageFee) {\n        this.baseFee = baseFee;\n        this.percentageFee = percentageFee;\n    }\n\n    @Override\n    public double calculateCost(Order order) {\n        System.out.println(\"Calculating with Third-Party API strategy.\");\n        // Simulate API call\n        return baseFee + (order.getOrderValue() * percentageFee);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/strategy/WeightBasedShipping.java",
    "content": "public class WeightBasedShipping implements ShippingStrategy {\n    private final double ratePerKg;\n\n    public WeightBasedShipping(double ratePerKg) {\n        this.ratePerKg = ratePerKg;\n    }\n\n    @Override\n    public double calculateCost(Order order) {\n        System.out.println(\"Calculating with Weight-Based strategy ($\" + ratePerKg + \"/kg)\");\n        return order.getTotalWeight() * ratePerKg;\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/AbstractReportExporter.java",
    "content": "public abstract class AbstractReportExporter {\n    public final void exportReport(ReportData data, String filePath) {\n        prepareData(data);\n        openFile(filePath);\n        writeHeader(data);\n        writeDataRows(data);\n        writeFooter(data);\n        closeFile(filePath);\n        System.out.println(\"Report exported to \" + filePath);\n    }\n\n    // Hook method – optional for subclasses to override\n    protected void prepareData(ReportData data) {\n        System.out.println(\"Preparing report data...\");\n    }\n\n    // Hook method – optional for subclasses to override\n    protected void openFile(String filePath) {\n        System.out.println(\"Opening file: \" + filePath);\n    }\n\n    protected abstract void writeHeader(ReportData data);\n\n    protected abstract void writeDataRows(ReportData data);\n    \n    // Hook method – optional for subclasses to override\n    protected void writeFooter(ReportData data) {\n        System.out.println(\"Writing footer...\");\n    }\n\n    // Hook method – optional for subclasses to override\n    protected void closeFile(String filePath) {\n        System.out.println(\"Closing file: \" + filePath);\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/CsvReportExporter.java",
    "content": "import java.util.Map;\n\npublic class CsvReportExporter extends AbstractReportExporter {\n    //prepareData() not overridden - default will be used\n    //openFile() not overridden - default will be used\n\n    @Override\n    protected void writeHeader(ReportData data) {\n        System.out.println(\"CSV: Writing header: \" + String.join(\",\", data.getHeaders()));\n    }\n\n    @Override\n    protected void writeDataRows(ReportData data) {\n        System.out.println(\"CSV: Writing data rows...\");\n        for (Map<String, Object> row : data.getRows()) {\n            System.out.println(\"CSV: \" + row.values());\n        }\n    }\n\n    // writeFooter() not overridden - default will be used\n    // closeFile() not overridden - default will be used\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/CsvReportExporterNaive.java",
    "content": "class CsvReportExporterNaive {\n    public void export(ReportData data, String filePath) {\n        System.out.println(\"CSV Exporter: Preparing data (common)...\");\n        // ... data preparation logic ...\n\n        System.out.println(\"CSV Exporter: Opening file '\" + filePath + \".csv' (common)...\");\n        // ... file opening logic ...\n\n        System.out.println(\"CSV Exporter: Writing CSV header (specific)...\");\n        // String.join(\",\", data.getHeaders());\n        // ... write header to file ...\n\n        System.out.println(\"CSV Exporter: Writing CSV data rows (specific)...\");\n        // for (Map<String, Object> row : data.getRows()) { ... format and write row ... }\n\n        System.out.println(\"CSV Exporter: Writing CSV footer (if any) (common)...\");\n\n        System.out.println(\"CSV Exporter: Closing file '\" + filePath + \".csv' (common)...\");\n        // ... file closing logic ...\n        System.out.println(\"CSV Report exported to \" + filePath + \".csv\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/templatemethod/ExcelReportExporter.java",
    "content": "import java.util.Map;\n\npublic class ExcelReportExporter extends AbstractReportExporter {\n    //prepareData() not overridden - default will be used\n    //openFile() not overridden - default will be used\n\n    @Override\n    protected void writeHeader(ReportData data) {\n        System.out.println(\"Excel: Writing header: \" + String.join(\",\", data.getHeaders()));\n    }\n\n    @Override\n    protected void writeDataRows(ReportData data) {\n        System.out.println(\"Excel: Writing data rows...\");\n        for (Map<String, Object> row : data.getRows()) {\n            System.out.println(\"Excel: \" + row.values());\n        }\n    }\n\n    // writeFooter() not overridden - default will be used\n    // closeFile() not overridden - default will be used\n}"
  },
  {
    "path": "design-patterns/java/templatemethod/ExcelReportExporterNaive.java",
    "content": "public class ExcelReportExporterNaive {\n    public void export(ReportData data, String filePath) {\n        System.out.println(\"Excel Report Exporter: Preparing data...\");\n        // ... data preparation logic ...\n\n        System.out.println(\"Excel Report Exporter: Opening file '\" + filePath + \".xlsx'...\");\n        // ... file opening logic ...\n\n        System.out.println(\"Excel Report Exporter: Writing Excel header...\");\n        // ... Excel header writing logic ...\n\n        System.out.println(\"Excel Report Exporter: Writing Excel data rows...\");\n        // ... Excel data rows writing logic ...\n\n        System.out.println(\"Excel Report Exporter: Writing Excel footer...\");\n        // ... Excel footer writing logic ...\n\n        System.out.println(\"Excel Report Exporter: Closing file '\" + filePath + \".xlsx'...\");\n        // ... file closing logic ...\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/PdfReportExporter.java",
    "content": "import java.util.Map;\n\npublic class PdfReportExporter extends AbstractReportExporter {\n    //prepareData() not overridden - default will be used\n    //openFile() not overridden - default will be used\n\n    @Override\n    protected void writeHeader(ReportData data) {\n        System.out.println(\"PDF: Writing header: \" + String.join(\",\", data.getHeaders()));\n    }\n\n    @Override\n    protected void writeDataRows(ReportData data) {\n        System.out.println(\"PDF: Writing data rows...\");\n        for (Map<String, Object> row : data.getRows()) {\n            System.out.println(\"PDF: \" + row.values());\n        }\n    }\n\n    // writeFooter() not overridden - default will be used\n    // closeFile() not overridden - default will be used\n}"
  },
  {
    "path": "design-patterns/java/templatemethod/PdfReportExporterNaive.java",
    "content": "class PdfReportExporterNaive {\n    public void export(ReportData data, String filePath) {\n        System.out.println(\"PDF Exporter: Preparing data (common)...\");\n        // ... data preparation logic ...\n\n        System.out.println(\"PDF Exporter: Opening file '\" + filePath + \".pdf' (common)...\");\n        // ... PDF library specific file opening ...\n\n        System.out.println(\"PDF Exporter: Writing PDF header (specific)...\");\n        // ... PDF library specific header writing ...\n\n        System.out.println(\"PDF Exporter: Writing PDF data rows (specific)...\");\n        // ... PDF library specific data row writing ...\n\n        System.out.println(\"PDF Exporter: Writing PDF footer (if any) (common)...\");\n\n        System.out.println(\"PDF Exporter: Closing file '\" + filePath + \".pdf' (common)...\");\n        // ... PDF library specific file closing ...\n        System.out.println(\"PDF Report exported to \" + filePath + \".pdf\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/templatemethod/ReportAppNaive.java",
    "content": "public class ReportAppNaive {\n    public static void main(String[] args) {\n        ReportData reportData = new ReportData();\n\n        CsvReportExporterNaive csvExporter = new CsvReportExporterNaive();\n        csvExporter.export(reportData, \"sales_report\");\n\n        System.out.println();\n\n        PdfReportExporterNaive pdfExporter = new PdfReportExporterNaive();\n        pdfExporter.export(reportData, \"financial_summary\");\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/ReportAppTemplateMethod.java",
    "content": "public class ReportAppTemplateMethod {\n    public static void main(String[] args) {\n        ReportData reportData = new ReportData();\n\n        AbstractReportExporter csvExporter = new CsvReportExporter();\n        csvExporter.exportReport(reportData, \"sales_report\");\n\n        System.out.println();\n\n        AbstractReportExporter pdfExporter = new PdfReportExporter();\n        pdfExporter.exportReport(reportData, \"financial_summary\");\n    }\n}\n"
  },
  {
    "path": "design-patterns/java/templatemethod/ReportData.java",
    "content": "import java.util.List;\nimport java.util.Map;\nimport java.util.Arrays;\n\npublic class ReportData {\n    public List<String> getHeaders() {\n        return Arrays.asList(\"ID\", \"Name\", \"Value\");\n    }\n    public List<Map<String, Object>> getRows() {\n        return Arrays.asList(\n            Map.of(\"ID\", 1, \"Name\", \"Item A\", \"Value\", 100.0),\n            Map.of(\"ID\", 2, \"Name\", \"Item B\", \"Value\", 150.5),\n            Map.of(\"ID\", 3, \"Name\", \"Item C\", \"Value\", 75.25)\n        );\n    }    \n}\n"
  },
  {
    "path": "design-patterns/java/visitor/AreaCalculatorVisitor.java",
    "content": "public class AreaCalculatorVisitor implements ShapeVisitor {\n    @Override\n    public void visitCircle(Circle circle) {\n        double area = Math.PI * circle.getRadius() * circle.getRadius();\n        System.out.println(\"Area of Circle: \" + area);\n    }\n\n    @Override\n    public void visitRectangle(Rectangle rectangle) {\n        double area = rectangle.getWidth() * rectangle.getHeight();\n        System.out.println(\"Area of Rectangle: \" + area);\n    }\n}"
  },
  {
    "path": "design-patterns/java/visitor/Circle.java",
    "content": "public class Circle implements Shape {\n    private final double radius;\n\n    public Circle(double radius) {\n        this.radius = radius;\n    }\n\n    public double getRadius() {\n        return radius;\n    }\n\n    @Override\n    public void accept(ShapeVisitor visitor) {\n        visitor.visitCircle(this);\n    }\n}"
  },
  {
    "path": "design-patterns/java/visitor/Rectangle.java",
    "content": "public class Rectangle implements Shape {\n    private final double width;\n    private final double height;\n\n    public Rectangle(double width, double height) {\n        this.width = width;\n        this.height = height;\n    }\n\n    public double getWidth() {\n        return width;\n    }\n\n    public double getHeight() {\n        return height;\n    }\n\n    @Override\n    public void accept(ShapeVisitor visitor) {\n        visitor.visitRectangle(this);\n    }\n}"
  },
  {
    "path": "design-patterns/java/visitor/Shape.java",
    "content": "public interface Shape {\n    void accept(ShapeVisitor visitor);\n}"
  },
  {
    "path": "design-patterns/java/visitor/ShapeVisitor.java",
    "content": "public interface ShapeVisitor {\n    void visitCircle(Circle circle);\n    void visitRectangle(Rectangle rectangle);\n}"
  },
  {
    "path": "design-patterns/java/visitor/SvgExporterVisitor.java",
    "content": "public class SvgExporterVisitor implements ShapeVisitor {\n    @Override\n    public void visitCircle(Circle circle) {\n        System.out.println(\"<circle r=\\\"\" + circle.getRadius() + \"\\\" />\");\n    }\n\n    @Override\n    public void visitRectangle(Rectangle rectangle) {\n        System.out.println(\"<rect width=\\\"\" + rectangle.getWidth() +\n                           \"\\\" height=\\\"\" + rectangle.getHeight() + \"\\\" />\");\n    }\n}"
  },
  {
    "path": "design-patterns/java/visitor/VisitorPatternDemo.java",
    "content": "public class VisitorPatternDemo {\n    public static void main(String[] args) {\n        List<Shape> shapes = List.of(\n            new Circle(5),\n            new Rectangle(10, 4),\n            new Circle(2.5)\n        );\n\n        System.out.println(\"=== Calculating Areas ===\");\n        ShapeVisitor areaCalculator = new AreaCalculatorVisitor();\n        for (Shape shape : shapes) {\n            shape.accept(areaCalculator);\n        }\n\n        System.out.println(\"\\n=== Exporting to SVG ===\");\n        ShapeVisitor svgExporter = new SvgExporterVisitor();\n        for (Shape shape : shapes) {\n            shape.accept(svgExporter);\n        }\n    }\n}"
  },
  {
    "path": "design-patterns/python/README.md",
    "content": "# Design Patterns in Python\n\nThis directory contains Python implementations of various design patterns, following the same examples and structure as the Java implementations.\n\n## Implemented Patterns\n\n### Creational Patterns\n- **[Adapter Pattern](adapter/)** - Convert interface of a class into another interface\n- **[Factory Method Pattern](factory/)** - Create objects without specifying exact classes\n- **[Builder Pattern](builder/)** - Construct complex objects step by step\n- **[Singleton Pattern](singleton/)** - Ensure only one instance of a class exists\n\n### Behavioral Patterns\n- **[Observer Pattern](observer/)** - Define one-to-many dependency between objects\n- **[Strategy Pattern](strategy/)** - Define family of algorithms and make them interchangeable\n\n### Structural Patterns\n- **Abstract Factory Pattern** - Create families of related objects\n- **Bridge Pattern** - Separate abstraction from implementation\n- **Composite Pattern** - Compose objects into tree structures\n- **Decorator Pattern** - Add behavior to objects dynamically\n- **Facade Pattern** - Provide simplified interface to complex subsystem\n- **Flyweight Pattern** - Minimize memory usage with shared objects\n- **Proxy Pattern** - Provide placeholder/surrogate for another object\n\n### Additional Behavioral Patterns\n- **Chain of Responsibility** - Pass requests along handler chain\n- **Command Pattern** - Encapsulate requests as objects\n- **Iterator Pattern** - Access elements sequentially without exposing structure\n- **Mediator Pattern** - Define how objects interact with each other\n- **Memento Pattern** - Capture and restore object state\n- **State Pattern** - Allow object to alter behavior when state changes\n- **Template Method Pattern** - Define skeleton of algorithm in base class\n- **Visitor Pattern** - Define new operations without changing classes\n\n## Running the Examples\n\nEach pattern directory contains demo files that can be run independently:\n\n```bash\n# Run adapter pattern demo\npython -m design-patterns.python.adapter.ecommerce_app\n\n# Run factory pattern demo\npython -m design-patterns.python.factory.factory_method_demo\n\n# Run builder pattern demo\npython -m design-patterns.python.builder.http_app_builder\n\n# Run singleton pattern demo\npython -m design-patterns.python.singleton.singleton_demo\n\n# Run observer pattern demo\npython -m design-patterns.python.observer.fitness_app_observer_demo\n\n# Run strategy pattern demo\npython -m design-patterns.python.strategy.ecommerce_app_demo\n```\n\n## Key Features\n\n- **Same Examples**: Uses identical examples as Java implementations for consistency\n- **Pythonic Code**: Follows Python conventions and best practices\n- **Type Hints**: Includes type annotations for better code clarity\n- **Separate Files**: Each class is in its own file for better organization\n- **Abstract Base Classes**: Uses ABC for interfaces and abstract classes\n- **Documentation**: Comprehensive docstrings and comments\n\n## Pattern Structure\n\nEach pattern follows this structure:\n```\npattern_name/\n├── __init__.py\n├── interface_or_abstract.py      # Abstract base classes/interfaces\n├── concrete_implementations.py   # Concrete classes\n├── context_or_client.py          # Context classes or clients\n├── demo.py                       # Demonstration of the pattern\n└── README.md                     # Pattern-specific documentation\n```\n\n## Design Principles Demonstrated\n\n- **Open/Closed Principle**: Open for extension, closed for modification\n- **Dependency Inversion**: Depend on abstractions, not concretions\n- **Single Responsibility**: Each class has one reason to change\n- **Composition over Inheritance**: Favor object composition\n- **Encapsulation**: Hide implementation details behind interfaces\n\n## Contributing\n\nWhen adding new patterns or modifying existing ones:\n1. Follow the existing file structure and naming conventions\n2. Include comprehensive type hints\n3. Add detailed docstrings\n4. Create meaningful demo examples\n5. Maintain consistency with Java implementations\n6. Include README documentation for each pattern"
  },
  {
    "path": "design-patterns/python/adapter/README.md",
    "content": "# Adapter Design Pattern in Python\n\n## Problem Statement\n\nThe Adapter pattern allows incompatible interfaces to work together. It acts as a bridge between two incompatible interfaces by converting the interface of one class into another interface that clients expect.\n\n---\n\n## Core Components\n\n### 1. Target Interface (PaymentProcessor)\n```python\nclass PaymentProcessor(ABC):\n    @abstractmethod\n    def process_payment(self, amount: float, currency: str) -> None:\n        pass\n```\n\n### 2. Adaptee (LegacyGateway)\n```python\nclass LegacyGateway:\n    def make_payment(self, currency: str, amount: float) -> None:\n        # Legacy payment processing logic\n        pass\n```\n\n### 3. Adapter (LegacyGatewayAdapter)\n```python\nclass LegacyGatewayAdapter(PaymentProcessor):\n    def __init__(self, legacy_gateway: LegacyGateway):\n        self.legacy_gateway = legacy_gateway\n\n    def process_payment(self, amount: float, currency: str) -> None:\n        self.legacy_gateway.make_payment(currency, amount)\n```\n\n### 4. Client (CheckoutService)\n```python\nclass CheckoutService:\n    def __init__(self, payment_processor: PaymentProcessor):\n        self.payment_processor = payment_processor\n\n    def checkout(self, amount: float, currency: str) -> None:\n        self.payment_processor.process_payment(amount, currency)\n```\n\n---\n\n## Example Usage\n\n```python\ndef main():\n    # Using the in-house payment processor\n    in_house_processor = InHousePaymentProcessor()\n    checkout_service = CheckoutService(in_house_processor)\n    checkout_service.checkout(100, \"USD\")\n\n    # Using the legacy payment gateway through adapter\n    legacy_processor = LegacyGatewayAdapter(LegacyGateway())\n    checkout_service = CheckoutService(legacy_processor)\n    checkout_service.checkout(100, \"USD\")\n```\n\n---\n\n## Benefits\n\n1. **Single Responsibility Principle:**\n   - Separates the interface conversion logic from the business logic\n   - Each class has a single responsibility\n\n2. **Open/Closed Principle:**\n   - New adapters can be added without modifying existing code\n   - System remains open for extension but closed for modification\n\n3. **Reusability:**\n   - Existing classes can be reused with new interfaces\n   - Reduces code duplication\n\n4. **Flexibility:**\n   - Multiple adapters can be created for different purposes\n   - Easy to switch between different implementations\n\n---\n\n## When to Use\n\n1. **When integrating incompatible interfaces:**\n   - Working with legacy systems\n   - Using third-party libraries\n   - Migrating between different versions\n\n2. **When creating a reusable class:**\n   - The class needs to work with unrelated classes\n   - The class needs to work with classes that don't have compatible interfaces\n\n3. **When implementing multiple interfaces:**\n   - A class needs to implement multiple interfaces\n   - Different clients need different views of the same class\n\n---\n\n## Best Practices\n\n1. **Keep it Simple:**\n   - Adapters should be simple and focused\n   - Avoid adding unnecessary functionality\n\n2. **Documentation:**\n   - Clearly document the purpose of the adapter\n   - Explain the conversion logic\n\n3. **Testing:**\n   - Test the adapter thoroughly\n   - Ensure it works with both the target and adaptee\n\n4. **Error Handling:**\n   - Handle conversion errors gracefully\n   - Provide meaningful error messages\n\n---\n\n## Common Pitfalls\n\n1. **Over-engineering:**\n   - Creating adapters when not needed\n   - Adding unnecessary complexity\n\n2. **Tight Coupling:**\n   - Creating dependencies between adapters\n   - Making the system less flexible\n\n3. **Performance Issues:**\n   - Adding too many layers of adaptation\n   - Impacting system performance\n\n--- "
  },
  {
    "path": "oop/cpp/abstraction/README.md",
    "content": "# Abstraction in C++\n\n## Introduction\n\n**Abstraction** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows you to hide **implementation details** while exposing only the necessary parts of an object. This helps in reducing complexity and increasing maintainability.\n\nAbstraction in C++ is mainly achieved using:\n1. **Abstract Classes**\n2. **Interfaces (Pure Virtual Functions)**\n\n---\n\n## **What is Abstraction?**\n\n**Abstraction** means showing only the **essential details** and hiding the **implementation**. It allows programmers to focus on **what an object does** rather than **how it does it**.\n\n### **Key Benefits of Abstraction**\n- **Reduces complexity**: Hides unnecessary implementation details.\n- **Increases code reusability**: Encourages the reuse of abstracted logic.\n- **Enhances security**: Protects internal object details from unintended modifications.\n- **Improves maintainability**: Makes code easier to manage and update.\n\n---\n\n## **1. Abstraction Using Abstract Classes**\n\nAn **abstract class** in C++ is a class that **cannot be instantiated**. It is used to define common behavior that multiple subclasses should implement.\n\n### **Example: Abstract Class in C++**\n\n```cpp\n#include <iostream>\n#include <memory>\nusing namespace std;\n\n// Abstract class\nclass Vehicle {\nprotected:\n    string brand;\npublic:\n    Vehicle(string b) : brand(b) {}\n    virtual void start() = 0; // Pure virtual function\n    virtual ~Vehicle() = default; // virtual destructor\n    void displayBrand() {\n        cout << \"Brand: \" << brand << endl;\n    }\n};\n\n// Subclass implementing the abstract method\nclass Car : public Vehicle {\npublic:\n    Car(string b) : Vehicle(b) {}\n    void start() override {\n        cout << \"Car is starting...\" << endl;\n    }\n};\n\nint main() {\n    unique_ptr<Vehicle> myCar = make_unique<Car>(\"Toyota\");\n    myCar->displayBrand();\n    myCar->start();\n    return 0;\n}\n```\n\n### **Output:**\n```\nBrand: Toyota\nCar is starting...\n```\n\n**Why Use Abstract Classes?**\n- Allows defining common behavior that subclasses must implement.\n- Enables partial abstraction (can have both abstract and concrete methods).\n- Prevents direct instantiation of base classes.\n\n---\n\n## **2. Abstraction Using Interfaces (Pure Virtual Functions)**\n\nAn **interface** in C++ is created using a class that contains **only pure virtual functions**.\n\n### **Example: Interface in C++**\n\n```cpp\n#include <iostream>\n#include <memory>\nusing namespace std;\n\n// Defining an interface\nclass Animal {\npublic:\n    virtual ~Animal() = default; // virtual destructor\n    virtual void makeSound() = 0; // Pure virtual function\n};\n\n// Implementing the interface in Dog class\nclass Dog : public Animal {\npublic:\n    void makeSound() override {\n        cout << \"Dog barks\" << endl;\n    }\n};\n\n// Implementing the interface in Cat class\nclass Cat : public Animal {\npublic:\n    void makeSound() override {\n        cout << \"Cat meows\" << endl;\n    }\n};\n\nint main() {\n    unique_ptr<Animal> myDog = make_unique<Dog>();\n    myDog->makeSound();\n    \n    unique_ptr<Animal> myCat = make_unique<Cat>();\n    myCat->makeSound();\n    \n    return 0;\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Interfaces?**\n- Promotes **full abstraction** (hides all implementation details).\n- Supports **multiple inheritance** in C++.\n- Provides a standard way for different classes to implement behaviors.\n\n---\n\n## **Abstract Class vs Interface: Key Differences**\n\n| Feature | Abstract Class | Interface (Pure Virtual Functions) |\n|---------|---------------|----------------------------------|\n| Methods | Can have abstract and concrete methods | Only pure virtual methods |\n| Fields | Can have member variables | Should not have data members |\n| Constructor | Can have constructors | Cannot have constructors |\n| Multiple Inheritance | Not recommended | Supported |\n| Access Modifiers | Can have private, protected, public members | Methods are public by default |\n\n---\n\n## **Real-World Example: Payment System**\n\nAbstraction is widely used in real-world applications, such as payment processing.\n\n### **Example: Payment System with Abstraction**\n\n```cpp\n#include <iostream>\n#include <memory>\nusing namespace std;\n\n// Abstract class for Payment\nclass Payment {\nprotected:\n    double amount;\npublic:\n    Payment(double amt) : amount(amt) {}\n    virtual ~Payment() = default; // virtual destructor\n    virtual void pay() = 0; // Abstract method\n};\n\n// Implementing payment methods\nclass CreditCardPayment : public Payment {\npublic:\n    CreditCardPayment(double amt) : Payment(amt) {}\n    void pay() override {\n        cout << \"Paid \" << amount << \" using Credit Card\" << endl;\n    }\n};\n\nclass PayPalPayment : public Payment {\npublic:\n    PayPalPayment(double amt) : Payment(amt) {}\n    void pay() override {\n        cout << \"Paid \" << amount << \" using PayPal\" << endl;\n    }\n};\n\nint main() {\n    unique_ptr<Payment> payment;\n    \n    payment = make_unique<CreditCardPayment>(150.75);\n    payment->pay();\n    \n    payment = make_unique<PayPalPayment>(200.50);\n    payment->pay();\n    \n    return 0;\n}\n```\n\n### **Output:**\n```\nPaid 150.75 using Credit Card\nPaid 200.50 using PayPal\n```\n\n**Why Use Abstraction in Payment Systems?**\n- Allows multiple payment methods without modifying existing code.\n- Improves maintainability and scalability.\n- Provides a **common contract** for different payment types.\n"
  },
  {
    "path": "oop/cpp/aggregation/README.md",
    "content": "# Aggregation in C++\n\n## Introduction\n\nAggregation is a key concept in object-oriented programming (OOP) that represents a \"has-a\" relationship between two classes, but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one class contains another, the contained object can exist independently of the container.\n\nAggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained object cannot exist without the container.\n\n## What is Aggregation?\n\nAggregation is a form of association in OOP where an object of one class contains a reference to an object of another class. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.\n\n### Key Characteristics of Aggregation:\n- Represents a **has-a** relationship.\n- The contained object **can exist independently** of the container.\n- Implemented using references (pointers) to objects.\n- Promotes **loose coupling** between objects.\n\n### Example: A University and its Professors\n\nConsider a scenario where a `University` contains multiple `Professor` objects. However, a `Professor` can exist independently of any university. This is an example of aggregation.\n\n```cpp\n#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nclass Professor {\nprivate:\n    string name;\n    string subject;\npublic:\n    Professor(string name, string subject) : name(name), subject(subject) {}\n    void teach() {\n        cout << name << \" is teaching \" << subject << endl;\n    }\n    string getName() { return name; }\n};\n\nclass University {\nprivate:\n    string universityName;\n    vector<Professor*> professors; // Aggregation: University has a list of professors\npublic:\n    University(string name) : universityName(name) {}\n    \n    void addProfessor(Professor* professor) {\n        professors.push_back(professor);\n    }\n    \n    void showProfessors() {\n        cout << \"Professors at \" << universityName << \":\" << endl;\n        for (auto professor : professors) {\n            cout << \" - \" << professor->getName() << endl;\n        }\n    }\n};\n\nint main() {\n    Professor prof1(\"Dr. Smith\", \"Computer Science\");\n    Professor prof2(\"Dr. Johnson\", \"Mathematics\");\n    \n    University university(\"Harvard University\");\n    university.addProfessor(&prof1);\n    university.addProfessor(&prof2);\n    \n    university.showProfessors();\n    \n    // Professors can exist independently\n    prof1.teach();\n    prof2.teach();\n    \n    return 0;\n}\n```\n\n### Output:\n```\nProfessors at Harvard University:\n - Dr. Smith\n - Dr. Johnson\nDr. Smith is teaching Computer Science\nDr. Johnson is teaching Mathematics\n```\n\n---\n\n## Aggregation vs Composition\n\n| Feature       | Aggregation | Composition |\n|--------------|------------|-------------|\n| Relationship | \"Has-a\"    | \"Has-a\"     |\n| Ownership    | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime     | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example      | University and Professors | Car and Engine |\n\n---\n\n## Why Use Aggregation?\n\n### 1. **Promotes Code Reusability**\n   - Aggregated objects can be used in multiple places without being tightly coupled to a single container class.\n\n### 2. **Encourages Loose Coupling**\n   - Aggregation allows objects to interact without being dependent on the lifecycle of each other.\n\n### 3. **Better Maintainability**\n   - Changes in one class do not heavily impact the other, making the codebase easier to modify and extend.\n\n### 4. **Real-World Applicability**\n   - Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.\n\n---\n\n## Aggregation with Interfaces (Abstract Classes)\n\nUsing abstract classes, we can further enhance the flexibility of aggregation.\n\n```cpp\n#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nclass Teachable {\npublic:\n    virtual void teach() = 0; // Pure virtual function\n    virtual string getName() = 0;\n};\n\nclass Professor : public Teachable {\nprivate:\n    string name;\n    string subject;\npublic:\n    Professor(string name, string subject) : name(name), subject(subject) {}\n    void teach() override {\n        cout << name << \" is teaching \" << subject << endl;\n    }\n    string getName() override { return name; }\n};\n\nclass University {\nprivate:\n    string universityName;\n    vector<Teachable*> professors;\npublic:\n    University(string name) : universityName(name) {}\n    \n    void addProfessor(Teachable* professor) {\n        professors.push_back(professor);\n    }\n    \n    void showProfessors() {\n        cout << \"Professors at \" << universityName << \":\" << endl;\n        for (auto professor : professors) {\n            professor->teach();\n        }\n    }\n};\n\nint main() {\n    Professor prof1(\"Dr. Adams\", \"Physics\");\n    Professor prof2(\"Dr. Lee\", \"Chemistry\");\n    \n    University university(\"MIT\");\n    university.addProfessor(&prof1);\n    university.addProfessor(&prof2);\n    \n    university.showProfessors();\n    \n    return 0;\n}\n```\n\n### Output:\n```\nProfessors at MIT:\nDr. Adams is teaching Physics\nDr. Lee is teaching Chemistry\n```\n\n---\n\n## When to Use Aggregation?\n\n- When an object **can exist independently** from the container.\n- When designing **loosely coupled** systems.\n- When different objects need to be **shared** across multiple containers.\n- When following **SOLID principles**, particularly the **Dependency Inversion Principle (DIP)**."
  },
  {
    "path": "oop/cpp/association/README.md",
    "content": "# Association in C++\n\n## Introduction\n\nAssociation is a key concept in object-oriented programming (OOP) that defines a relationship between two or more objects. It represents how objects interact with each other while maintaining their independence.\n\nAssociation is **not inheritance**—rather, it is a relationship between objects that allows communication while ensuring they remain loosely coupled.\n\n## What is Association?\n\nAssociation defines a connection between two classes, where one class is linked to another. The association can be **one-to-one**, **one-to-many**, **many-to-one**, or **many-to-many**. Objects in an association can exist independently of each other.\n\n### Key Characteristics of Association:\n- Represents a **uses-a** or **knows-a** relationship.\n- Objects in an association **can exist independently**.\n- Can be **unidirectional** or **bidirectional**.\n- Promotes **modularity** and **code reusability**.\n\n### Example: A Student and a Teacher\n\nA `Student` can be associated with multiple `Teacher` objects, and a `Teacher` can have multiple `Student` objects. This represents a **many-to-many** association.\n\n```cpp\n#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nclass Student;\n\nclass Teacher {\nprivate:\n    string name;\n    vector<Student*> students;\npublic:\n    Teacher(string name) : name(name) {}\n    void addStudent(Student* student);\n    void showStudents();\n    string getName() { return name; }\n};\n\nclass Student {\nprivate:\n    string name;\npublic:\n    Student(string name) : name(name) {}\n    string getName() { return name; }\n};\n\nvoid Teacher::addStudent(Student* student) {\n    students.push_back(student);\n}\n\nvoid Teacher::showStudents() {\n    cout << name << \" teaches:\" << endl;\n    for (Student* student : students) {\n        cout << \" - \" << student->getName() << endl;\n    }\n}\n\nint main() {\n    Teacher teacher1(\"Mr. Smith\");\n    Teacher teacher2(\"Mrs. Johnson\");\n    \n    Student student1(\"Alice\");\n    Student student2(\"Bob\");\n    \n    teacher1.addStudent(&student1);\n    teacher1.addStudent(&student2);\n    teacher2.addStudent(&student2);\n    \n    teacher1.showStudents();\n    teacher2.showStudents();\n    \n    return 0;\n}\n```\n\n### Output:\n```\nMr. Smith teaches:\n - Alice\n - Bob\nMrs. Johnson teaches:\n - Bob\n```\n\n---\n\n## Types of Association\n\n### 1. **One-to-One Association**\n   - Each object of class A is associated with one object of class B.\n   - Example: A `Person` has one `Passport`.\n\n### 2. **One-to-Many Association**\n   - One object of class A can be associated with multiple objects of class B.\n   - Example: A `Teacher` teaches multiple `Students`.\n\n### 3. **Many-to-One Association**\n   - Multiple objects of class A can be associated with one object of class B.\n   - Example: Multiple `Students` belong to one `School`.\n\n### 4. **Many-to-Many Association**\n   - Multiple objects of class A can be associated with multiple objects of class B.\n   - Example: `Teachers` and `Students` (a student can have multiple teachers, and a teacher can have multiple students).\n\n---\n\n## Why Use Association?\n\n### 1. **Promotes Code Reusability**\n   - Objects can be reused across multiple associations without duplication.\n\n### 2. **Encourages Loose Coupling**\n   - Objects interact without depending on the internal implementation of each other.\n\n### 3. **Improves Maintainability**\n   - Changing one object does not heavily impact others, making code easier to manage.\n\n### 4. **Better System Design**\n   - Allows modeling of real-world relationships between entities effectively.\n\n---\n\n## Bidirectional Association\n\nAssociations can be **unidirectional** (one object knows about another) or **bidirectional** (both objects know about each other).\n\n### Example: A Library and Books (Bidirectional Association)\n\n```cpp\n#include <iostream>\n#include <vector>\n#include <string>\nusing namespace std;\n\nclass Library;\n\nclass Book {\nprivate:\n    string title;\n    Library* library;\npublic:\n    Book(string title, Library* library);\n    void showLibrary();\n    string getTitle() { return title; }\n};\n\nclass Library {\nprivate:\n    string name;\n    vector<Book*> books;\npublic:\n    Library(string name) : name(name) {}\n    void addBook(Book* book) { books.push_back(book); }\n    string getName() { return name; }\n    void showBooks();\n};\n\nBook::Book(string title, Library* library) : title(title), library(library) {}\n\nvoid Book::showLibrary() {\n    cout << title << \" is in \" << library->getName() << endl;\n}\n\nvoid Library::showBooks() {\n    cout << \"Books in \" << name << \":\" << endl;\n    for (Book* book : books) {\n        cout << \" - \" << book->getTitle() << endl;\n    }\n}\n\nint main() {\n    Library library(\"City Library\");\n    Book book1(\"1984\", &library);\n    Book book2(\"Brave New World\", &library);\n    \n    library.addBook(&book1);\n    library.addBook(&book2);\n    \n    library.showBooks();\n    book1.showLibrary();\n    book2.showLibrary();\n    \n    return 0;\n}\n```\n\n### Output:\n```\nBooks in City Library:\n - 1984\n - Brave New World\n1984 is in City Library\nBrave New World is in City Library\n```"
  },
  {
    "path": "oop/cpp/classesandobjects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nA class is a blueprint or template. It defines the attributes (fields) and behaviors (methods) of an object.\n\n### Defining a Class in C++\n\nTo define a class in C++, you use the `class` keyword followed by the name of the class. \n\nHere's a simple example:\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Car {\n    // Attributes\n    private:\n    string color;\n    string make;\n    string model;\n    int year;\n\n    public:\n    // Constructor\n    Car(string color, string make, string model, int year) {\n        this->color = color;\n        this->make = make;\n        this->model = model;\n        this->year = year;\n    }\n\n    // Method to display car details\n    void displayInfo() {\n        cout << \"Car Make: \" << make << endl;\n        cout << \"Car Model: \" << model << endl;\n        cout << \"Car Year: \" << year << endl;\n        cout << \"Car Color: \" << color << endl;\n    }\n};\n```\n- **Attributes**: The class `Car` has four attributes that describe its state: `color`, `make`, `model`, and `year`.\n- **Constructor**: The constructor `Car(string color, string make, string model, int year)` initializes new objects of the class.\n- **Methods**: The `displayInfo` method is responsible for showcasing the car details.\n\n## What is an Object?\n\nAn object is an instance of a class. When you create an object, you are bringing the blueprint of the class into reality. It consists of state and behavior defined by the class, with each object holding its own copy of the data.\n\n### Creating Objects in C++\n\nTo create an object, you use the class constructor. \n\nHere's how you can instantiate objects from the `Car` class:\n\n```cpp\nint main() {\n    // Creating an object of the Car class\n    Car car1 = Car(\"Red\", \"Toyota\", \"Corolla\", 2020);\n    Car car2 = Car(\"Blue\", \"Ford\", \"Mustang\", 2021);\n\n    // Displaying information of each car\n    car1.displayInfo();\n    cout << \"-----------------\";\n    car2.displayInfo();\n\n    return 0;\n}\n```\n\n1. **Instantiation**: The `Car` constructor is used to create an object, which allocates memory for it.\n2. **Initialization**: The constructor (`Car`) initializes the object state with given parameters.\n3. **Reference**: The object is referenced through a variable (`car1`, `car2`) that points to its memory location.\n"
  },
  {
    "path": "oop/cpp/composition/README.md",
    "content": "# Composition in C++\n\n## Introduction\n\nComposition is one of the key concepts of object-oriented programming (OOP). It allows objects to be built using other objects, promoting code reuse, flexibility, and better maintainability. Unlike inheritance, which establishes an \"is-a\" relationship, composition represents a \"has-a\" relationship.\n\n## What is Composition?\n\nComposition is a design principle in OOP where one class contains an instance (or instances) of another class as a field. The contained class is often called a component, and the containing class is referred to as a composite class. This helps in building complex systems by combining simpler objects.\n\n### Example: A Car and its Components\n\nConsider a `Car` that consists of multiple components like an `Engine`, `Wheel`, and `Transmission`. Instead of inheriting from these components, a `Car` object will contain them as fields.\n\n```cpp\n#include <iostream>\n#include <string>\n\nclass Engine {\nprivate:\n    int horsepower;\npublic:\n    Engine(int hp) : horsepower(hp) {}\n    void start() {\n        std::cout << \"Engine started with \" << horsepower << \" HP.\" << std::endl;\n    }\n};\n\nclass Wheel {\nprivate:\n    std::string type;\npublic:\n    Wheel(std::string t) : type(t) {}\n    void rotate() {\n        std::cout << \"The \" << type << \" wheel is rotating.\" << std::endl;\n    }\n};\n\nclass Transmission {\nprivate:\n    std::string type;\npublic:\n    Transmission(std::string t) : type(t) {}\n    void shiftGear() {\n        std::cout << \"Transmission shifted: \" << type << std::endl;\n    }\n};\n\nclass Car {\nprivate:\n    Engine engine;\n    Wheel wheel;\n    Transmission transmission;\npublic:\n    Car() : engine(150), wheel(\"Alloy\"), transmission(\"Automatic\") {}\n    void drive() {\n        engine.start();\n        wheel.rotate();\n        transmission.shiftGear();\n        std::cout << \"Car is moving!\" << std::endl;\n    }\n};\n\nint main() {\n    Car car;\n    car.drive();\n    return 0;\n}\n```\n\n### Output:\n```\nEngine started with 150 HP.\nThe Alloy wheel is rotating.\nTransmission shifted: Automatic\nCar is moving!\n```\n\n---\n\n## Why Prefer Composition Over Inheritance?\n\n### 1. **Encapsulation and Flexibility**\n   - Composition allows us to change the behavior of an object dynamically by replacing components at runtime.\n   - Inheritance makes it difficult to modify an existing class hierarchy without breaking existing code.\n\n### 2. **Better Code Reusability**\n   - Composition promotes reusable components. The `Engine`, `Wheel`, and `Transmission` classes can be used in multiple types of vehicles (Car, Bike, Truck) without modification.\n\n### 3. **Avoids Inheritance Pitfalls**\n   - Inheritance can lead to deep class hierarchies, making maintenance difficult.\n   - It enforces strict parent-child relationships, which can be too rigid for some designs.\n\n### 4. **Supports Interface-Based Design**\n   - Composition can be combined with abstract classes to achieve powerful decoupling.\n\n---\n\n## Composition with Abstract Classes\n\nUsing abstract classes with composition allows for greater flexibility and loose coupling.\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Engine {\npublic:\n    virtual void start() = 0; // Pure virtual function\n};\n\nclass PetrolEngine : public Engine {\npublic:\n    void start() override {\n        cout << \"Petrol Engine started.\" << endl;\n    }\n};\n\nclass DieselEngine : public Engine {\npublic:\n    void start() override {\n        cout << \"Diesel Engine started.\" << endl;\n    }\n};\n\nclass Car {\nprivate:\n    Engine* engine;\npublic:\n    Car(Engine* e) : engine(e) {}\n    void startCar() {\n        engine->start();\n        cout << \"Car is ready to go!\" << endl;\n    }\n};\n\nint main() {\n    PetrolEngine petrolEngine;\n    DieselEngine dieselEngine;\n    \n    Car petrolCar(&petrolEngine);\n    petrolCar.startCar();\n    \n    Car dieselCar(&dieselEngine);\n    dieselCar.startCar();\n    \n    return 0;\n}\n```\n\n### Output:\n```\nPetrol Engine started.\nCar is ready to go!\nDiesel Engine started.\nCar is ready to go!\n```\n\n---\n\n## When to Use Composition?\n\n- When building complex objects that consist of multiple components.\n- When you want to achieve **code reusability** without rigid inheritance hierarchies.\n- When different behaviors need to be swapped dynamically (e.g., using different types of engines in a vehicle).\n- When following the **favor composition over inheritance** principle."
  },
  {
    "path": "oop/cpp/encapsulation/README.md",
    "content": "# Encapsulation in C++\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of Object-Oriented Programming (OOP). It is the practice of **bundling data (variables) and methods** that operate on that data into a single unit (class) while restricting direct access to the internal details.\n\nEncapsulation in C++ is achieved using:\n1. **Access Specifiers** (`private`, `protected`, `public`)\n2. **Getters and Setters**\n3. **Data Hiding**\n\nEncapsulation helps in **data protection, modularity, and maintainability** of the code.\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** the data (variables) and code (methods) together into a single unit (class). It restricts direct access to some of an object's components, which helps protect data integrity and prevents unintended modifications.\n\n### **Key Benefits of Encapsulation**\n- **Data Hiding**: Prevents direct access to sensitive data.\n- **Increased Security**: Controls how data is accessed and modified.\n- **Improved Code Maintainability**: Allows changes without affecting other parts of the code.\n- **Better Modularity**: Organizes the code into logical components.\n\n---\n\n## **Encapsulation Using Access Specifiers**\n\nC++ provides **access specifiers** to enforce encapsulation:\n- **`private`**: Accessible only within the same class.\n- **`protected`**: Accessible within the same class and derived classes.\n- **`public`**: Accessible from anywhere.\n\n### **Example: Encapsulation with Private Variables**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\n// Class with encapsulated data\nclass BankAccount {\nprivate:\n    string accountHolder;\n    double balance;\n\npublic:\n    // Constructor\n    BankAccount(string name, double bal) {\n        accountHolder = name;\n        balance = bal;\n    }\n\n    // Getter method to access balance\n    double getBalance() {\n        return balance;\n    }\n\n    // Setter method to modify balance\n    void deposit(double amount) {\n        if (amount > 0) {\n            balance += amount;\n            cout << \"Deposited: \" << amount << endl;\n        } else {\n            cout << \"Invalid deposit amount\" << endl;\n        }\n    }\n};\n\nint main() {\n    BankAccount account(\"Alice\", 1000);\n    cout << \"Current Balance: \" << account.getBalance() << endl;\n    account.deposit(500);\n    cout << \"Updated Balance: \" << account.getBalance() << endl;\n    return 0;\n}\n```\n\n### **Output:**\n```\nCurrent Balance: 1000\nDeposited: 500\nUpdated Balance: 1500\n```\n\n**Why Use Encapsulation?**\n- Prevents unauthorized access to the data.\n- Allows controlled modifications through methods.\n\n---\n\n## **Encapsulation Using Getters and Setters**\n\nEncapsulation ensures that **data cannot be directly accessed** but must be retrieved or modified through methods.\n\n### **Example: Getters and Setters in C++**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Employee {\nprivate:\n    string name;\n    int age;\n\npublic:\n    // Getter method\n    string getName() {\n        return name;\n    }\n\n    // Setter method\n    void setName(string newName) {\n        name = newName;\n    }\n\n    int getAge() {\n        return age;\n    }\n\n    void setAge(int newAge) {\n        if (newAge > 18) {\n            age = newAge;\n        } else {\n            cout << \"Age must be greater than 18\" << endl;\n        }\n    }\n};\n\nint main() {\n    Employee emp;\n    emp.setName(\"John Doe\");\n    emp.setAge(25);\n    cout << \"Employee Name: \" << emp.getName() << endl;\n    cout << \"Employee Age: \" << emp.getAge() << endl;\n    return 0;\n}\n```\n\n### **Output:**\n```\nEmployee Name: John Doe\nEmployee Age: 25\n```\n\n---\n\n## **Encapsulation and Data Hiding**\n\nEncapsulation helps **hide implementation details** while exposing only necessary methods.\n\n### **Example: Hiding Implementation Details**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Account {\nprivate:\n    double balance;\n\n    bool validateWithdrawal(double amount) {\n        return amount > 0 && amount <= balance;\n    }\n\npublic:\n    Account(double initialBalance) {\n        balance = initialBalance;\n    }\n\n    void withdraw(double amount) {\n        if (validateWithdrawal(amount)) {\n            balance -= amount;\n            cout << \"Withdrawal Successful: \" << amount << endl;\n        } else {\n            cout << \"Insufficient balance or invalid amount\" << endl;\n        }\n    }\n\n    double getBalance() {\n        return balance;\n    }\n};\n\nint main() {\n    Account myAccount(1000);\n    myAccount.withdraw(300);\n    cout << \"Remaining Balance: \" << myAccount.getBalance() << endl;\n    return 0;\n}\n```\n\n### **Output:**\n```\nWithdrawal Successful: 300\nRemaining Balance: 700\n```\n\n**Why Hide Data?**\n- Prevents direct modification of important fields.\n- Ensures data integrity by validating inputs.\n\n---\n\n## **Encapsulation in Real-World Applications**\n\nEncapsulation is used in many real-world applications such as:\n1. **Banking Systems** - Ensuring account details are private.\n2. **Healthcare Applications** - Protecting patient records.\n3. **E-Commerce Platforms** - Hiding payment processing details.\n\n### **Example: Encapsulation in Payment Processing**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass PaymentProcessor {\nprivate:\n    string cardNumber;\n    double amount;\n\n    string maskCardNumber(string cardNumber) {\n        return \"****-****-****-\" + cardNumber.substr(cardNumber.length() - 4);\n    }\n\npublic:\n    PaymentProcessor(string card, double amt) : cardNumber(card), amount(amt) {}\n\n    void processPayment() {\n        cout << \"Processing payment of \" << amount << \" for card \" << maskCardNumber(cardNumber) << endl;\n    }\n};\n\nint main() {\n    PaymentProcessor payment(\"1234567812345678\", 250.00);\n    payment.processPayment();\n    return 0;\n}\n```\n\n### **Output:**\n```\nProcessing payment of 250 for card ****-****-****-5678\n```\n\n**Why Use Encapsulation in Payment Processing?**\n- Protects sensitive data (e.g., credit card numbers).\n- Hides unnecessary details from users.\n- Ensures secure transactions."
  },
  {
    "path": "oop/cpp/inheritance/README.md",
    "content": "# Inheritance in C++\n\n## Introduction\n\n**Inheritance** is one of the core principles of Object-Oriented Programming (OOP). It allows a class (subclass or child class) to acquire the properties and behaviors of another class (superclass or parent class). This promotes **code reuse**, **scalability**, and **maintainability**.\n\n---\n\n## **What is Inheritance?**\n\n**Inheritance** is a mechanism where a child class derives properties and behaviors from a parent class. The child class can:\n\n- Use the fields and methods of the parent class\n- Override parent class methods to provide a specific implementation\n- Add its own additional properties and methods\n\n### **Key Benefits of Inheritance**\n\n- **Code Reusability**: Avoids code duplication by reusing fields and methods of the parent class.\n- **Improves Maintainability**: Reduces redundancy, making code easier to manage.\n- **Enhances Extensibility**: New functionality can be added easily without modifying existing code.\n\n---\n\n## **How to Implement Inheritance in C++**\n\n### **Step 1: Create a Parent Class**\n\nThe parent class contains common fields and methods.\n\n```cpp\n#include <iostream>\nusing namespace std;\n\n// Parent class\nclass Animal {\npublic:\n    string name;\n    void eat() {\n        cout << name << \" is eating...\" << endl;\n    }\n};\n```\n\n### **Step 2: Create a Child Class using `public` Inheritance**\n\nThe child class inherits the properties and methods of the parent class.\n\n```cpp\n// Child class\nclass Dog : public Animal {\npublic:\n    void bark() {\n        cout << name << \" is barking...\" << endl;\n    }\n};\n```\n\n### **Step 3: Use the Child Class**\n\nNow, let's create an object and use the inherited methods.\n\n```cpp\nint main() {\n    Dog myDog;\n    myDog.name = \"Buddy\";\n    myDog.eat(); // Inherited from Animal class\n    myDog.bark(); // Defined in Dog class\n    return 0;\n}\n```\n\n### **Output:**\n\n```\nBuddy is eating...\nBuddy is barking...\n```\n\n---\n\n## **Types of Inheritance in C++**\n\nC++ supports different types of inheritance:\n\n### **1. Single Inheritance**\n\nA subclass inherits from one superclass.\n\n```cpp\nclass Parent {\npublic:\n    void show() {\n        cout << \"This is the parent class\" << endl;\n    }\n};\n\nclass Child : public Parent {\npublic:\n    void display() {\n        cout << \"This is the child class\" << endl;\n    }\n};\n```\n\n### **2. Multilevel Inheritance**\n\nA subclass inherits from another subclass, forming a chain.\n\n```cpp\nclass Grandparent {\npublic:\n    void show() {\n        cout << \"Grandparent class\" << endl;\n    }\n};\n\nclass Parent : public Grandparent {\npublic:\n    void display() {\n        cout << \"Parent class\" << endl;\n    }\n};\n\nclass Child : public Parent {\npublic:\n    void print() {\n        cout << \"Child class\" << endl;\n    }\n};\n```\n\n### **3. Hierarchical Inheritance**\n\nA single parent class has multiple child classes.\n\n```cpp\nclass Parent {\npublic:\n    void show() {\n        cout << \"Parent class\" << endl;\n    }\n};\n\nclass Child1 : public Parent {\npublic:\n    void display() {\n        cout << \"Child1 class\" << endl;\n    }\n};\n\nclass Child2 : public Parent {\npublic:\n    void print() {\n        cout << \"Child2 class\" << endl;\n    }\n};\n```\n\n### **4. Multiple Inheritance** (Supported in C++)\n\nUnlike Java, C++ allows a child class to inherit from multiple parent classes.\n\n```cpp\nclass Parent1 {\npublic:\n    void show1() {\n        cout << \"Parent1 class\" << endl;\n    }\n};\n\nclass Parent2 {\npublic:\n    void show2() {\n        cout << \"Parent2 class\" << endl;\n    }\n};\n\nclass Child : public Parent1, public Parent2 {\n};\n```\n\n---\n\n## **Method Overriding in Inheritance**\n\nMethod overriding allows a child class to **redefine** a method from the parent class.\n\n```cpp\nclass Animal {\npublic:\n    virtual void makeSound() {\n        cout << \"Animal makes a sound\" << endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    void makeSound() override {\n        cout << \"Dog barks\" << endl;\n    }\n};\n```\n\n### **Usage**\n\n```cpp\nint main() {\n    Animal* myAnimal = new Dog(); // Polymorphism\n    myAnimal->makeSound();\n    delete myAnimal;\n    return 0;\n}\n```\n\n### **Output:**\n\n```\nDog barks\n```\n\n---\n\n## **The `super` Equivalent: Using `Base Class` Constructor in C++**\n\nC++ uses the **constructor of the base class** to initialize inherited fields.\n\n```cpp\nclass Animal {\npublic:\n    Animal() {\n        cout << \"Animal Constructor\" << endl;\n    }\n    void makeSound() {\n        cout << \"Animal makes a sound\" << endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    Dog() {\n        cout << \"Dog Constructor\" << endl;\n    }\n    void makeSound() {\n        Animal::makeSound(); // Calls parent method\n        cout << \"Dog barks\" << endl;\n    }\n};\n```\n\n### **Usage**\n\n```cpp\nint main() {\n    Dog myDog;\n    myDog.makeSound();\n    return 0;\n}\n```\n\n### **Output:**\n\n```\nAnimal Constructor\nDog Constructor\nAnimal makes a sound\nDog barks\n```\n"
  },
  {
    "path": "oop/cpp/interfaces/README.md",
    "content": "# Interfaces in C++\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **interface** is a crucial concept that defines a contract for classes to follow. It allows multiple classes to share a common structure while enforcing certain behaviors. While C++ does not have explicit support for interfaces like Java, it achieves the same functionality using **pure virtual functions** in abstract classes.\n\n## What is an Interface?\n\nAn **interface** is a collection of method definitions that a class must implement. It defines a contract that implementing classes must adhere to.\n\n### **Key Characteristics of Interfaces in C++**\n- Uses **abstract classes with pure virtual functions** to define interfaces.\n- Defines methods without implementation that must be overridden.\n- Supports **multiple inheritance**, unlike normal classes.\n- Improves **code flexibility and maintainability**.\n\n---\n\n## **Defining and Implementing an Interface in C++**\n\n### **Step 1: Define an Interface using an Abstract Class**\nTo define an interface, we use a class with at least one **pure virtual function**.\n\n```cpp\n#include <iostream>\nusing namespace std;\n\n// Defining an interface\nclass Vehicle {\npublic:\n    virtual void start() = 0; // Pure virtual function\n    virtual void stop() = 0;  // Pure virtual function\n};\n```\n\n### **Step 2: Implement the Interface**\nA class implements an interface by inheriting from it and providing concrete implementations of the pure virtual functions.\n\n```cpp\n// Implementing the Vehicle interface in a Car class\nclass Car : public Vehicle {\npublic:\n    void start() override {\n        cout << \"Car is starting...\" << endl;\n    }\n    \n    void stop() override {\n        cout << \"Car is stopping...\" << endl;\n    }\n};\n```\n\n### **Step 3: Using the Implemented Class**\nNow, let's create objects and call the methods.\n\n```cpp\nint main() {\n    Vehicle* myCar = new Car(); // Polymorphism: Interface reference\n    myCar->start();\n    myCar->stop();\n    \n    delete myCar; // Clean up memory\n    return 0;\n}\n```\n\n### **Output:**\n```\nCar is starting...\nCar is stopping...\n```\n\n---\n\n## **Multiple Inheritance with Interfaces**\n\nUnlike normal classes, C++ **supports multiple inheritance** with interfaces.\n\n```cpp\n// First interface\nclass Flyable {\npublic:\n    virtual void fly() = 0;\n};\n\n// Second interface\nclass Drivable {\npublic:\n    virtual void drive() = 0;\n};\n\n// Implementing multiple interfaces\nclass FlyingCar : public Flyable, public Drivable {\npublic:\n    void fly() override {\n        cout << \"FlyingCar is flying...\" << endl;\n    }\n    \n    void drive() override {\n        cout << \"FlyingCar is driving...\" << endl;\n    }\n};\n```\n\n### **Usage**\n```cpp\nint main() {\n    FlyingCar myVehicle;\n    myVehicle.fly();\n    myVehicle.drive();\n    \n    return 0;\n}\n```\n\n### **Output:**\n```\nFlyingCar is flying...\nFlyingCar is driving...\n```\n\n---\n\n## **Providing Default Implementations in Interfaces**\n\nUnlike Java, C++ does not have **default methods** in interfaces, but we can provide default implementations in base classes.\n\n```cpp\nclass Animal {\npublic:\n    virtual void sound() = 0;\n    void sleep() { // Default method\n        cout << \"Sleeping...\" << endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    void sound() override {\n        cout << \"Dog barks\" << endl;\n    }\n};\n```\n\n### **Usage**\n```cpp\nint main() {\n    Dog myDog;\n    myDog.sound();\n    myDog.sleep();\n    \n    return 0;\n}\n```\n\n### **Output:**\n```\nDog barks\nSleeping...\n```\n\n---\n\n## **Real-World Example: Payment System**\n\n```cpp\nclass Payment {\npublic:\n    virtual void pay(double amount) = 0;\n};\n\nclass CreditCardPayment : public Payment {\npublic:\n    void pay(double amount) override {\n        cout << \"Paid \" << amount << \" using Credit Card\" << endl;\n    }\n};\n\nclass PayPalPayment : public Payment {\npublic:\n    void pay(double amount) override {\n        cout << \"Paid \" << amount << \" using PayPal\" << endl;\n    }\n};\n```\n\n### **Usage**\n```cpp\nint main() {\n    Payment* payment1 = new CreditCardPayment();\n    payment1->pay(100.50);\n    \n    Payment* payment2 = new PayPalPayment();\n    payment2->pay(200.75);\n    \n    delete payment1;\n    delete payment2;\n    \n    return 0;\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```"
  },
  {
    "path": "oop/cpp/polymorphism/README.md",
    "content": "# Polymorphism in C++\n\n## Introduction\n\n**Polymorphism** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nPolymorphism in C++ can be classified into two types:\n1. **Compile-time Polymorphism (Function Overloading & Operator Overloading)**\n2. **Run-time Polymorphism (Function Overriding & Virtual Functions)**\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a method, function, or object to behave differently based on the context. Polymorphism enables **dynamic method resolution** and **method flexibility**, making applications easier to extend and maintain.\n\n### **Key Benefits of Polymorphism**\n- **Code Reusability**: Write a single interface that works for multiple types.\n- **Scalability**: Add new functionalities with minimal code changes.\n- **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **1. Compile-Time Polymorphism (Function Overloading)**\n\nCompile-time polymorphism occurs when multiple functions in the same class share the same name but have **different method signatures** (parameters). The method to be called is determined **at compile time**.\n\n### **Example of Function Overloading**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass MathOperations {\npublic:\n    // Function with two parameters\n    int add(int a, int b) {\n        return a + b;\n    }\n    \n    // Function with three parameters (overloaded)\n    int add(int a, int b, int c) {\n        return a + b + c;\n    }\n};\n\nint main() {\n    MathOperations math;\n    cout << \"Sum (2 numbers): \" << math.add(5, 10) << endl;\n    cout << \"Sum (3 numbers): \" << math.add(5, 10, 15) << endl;\n    return 0;\n}\n```\n\n### **Output:**\n```\nSum (2 numbers): 15\nSum (3 numbers): 30\n```\n\n**Why Use Function Overloading?**\n- Provides a cleaner and more intuitive interface.\n- Reduces redundancy by using a single function name for similar operations.\n\n---\n\n## **2. Run-Time Polymorphism (Function Overriding & Virtual Functions)**\n\nRun-time polymorphism occurs when a subclass provides a **specific implementation** of a method already defined in its parent class. The method to be called is determined **at runtime** using **virtual functions**.\n\n### **Example of Function Overriding with Virtual Functions**\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Animal {\npublic:\n    virtual void makeSound() {\n        cout << \"Animal makes a sound\" << endl;\n    }\n};\n\nclass Dog : public Animal {\npublic:\n    void makeSound() override {\n        cout << \"Dog barks\" << endl;\n    }\n};\n\nclass Cat : public Animal {\npublic:\n    void makeSound() override {\n        cout << \"Cat meows\" << endl;\n    }\n};\n\nint main() {\n    Animal* myAnimal = new Dog(); // Upcasting\n    myAnimal->makeSound();\n    \n    myAnimal = new Cat(); // Dynamic method dispatch\n    myAnimal->makeSound();\n    \n    delete myAnimal;\n    return 0;\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Function Overriding?**\n- Enables **dynamic method resolution**.\n- Supports **polymorphic behavior**, where one interface can be used for multiple implementations.\n- Makes code **extensible** by allowing future modifications.\n\n---\n\n## **Using Polymorphism with Abstract Classes**\n\nPolymorphism is widely used with **abstract classes**, allowing multiple derived classes to share a common contract.\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Vehicle {\npublic:\n    virtual void start() = 0; // Pure virtual function\n};\n\nclass Car : public Vehicle {\npublic:\n    void start() override {\n        cout << \"Car is starting...\" << endl;\n    }\n};\n\nclass Bike : public Vehicle {\npublic:\n    void start() override {\n        cout << \"Bike is starting...\" << endl;\n    }\n};\n\nint main() {\n    Vehicle* myVehicle = new Car();\n    myVehicle->start();\n    \n    myVehicle = new Bike();\n    myVehicle->start();\n    \n    delete myVehicle;\n    return 0;\n}\n```\n\n### **Output:**\n```\nCar is starting...\nBike is starting...\n```\n\n**Why Use Abstract Classes with Polymorphism?**\n- Promotes **loose coupling**, making code more flexible.\n- Allows multiple implementations of the same behavior.\n- Enforces common structure in derived classes.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case of polymorphism is in **payment processing**.\n\n```cpp\n#include <iostream>\nusing namespace std;\n\nclass Payment {\npublic:\n    virtual void pay(double amount) = 0; // Pure virtual function\n};\n\nclass CreditCardPayment : public Payment {\npublic:\n    void pay(double amount) override {\n        cout << \"Paid \" << amount << \" using Credit Card\" << endl;\n    }\n};\n\nclass PayPalPayment : public Payment {\npublic:\n    void pay(double amount) override {\n        cout << \"Paid \" << amount << \" using PayPal\" << endl;\n    }\n};\n\nint main() {\n    Payment* payment;\n    \n    payment = new CreditCardPayment();\n    payment->pay(100.50);\n    \n    payment = new PayPalPayment();\n    payment->pay(200.75);\n    \n    delete payment;\n    return 0;\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```\n\n**Why Use Polymorphism in Payment Systems?**\n- Allows new payment methods to be added **without modifying existing code**.\n- Provides a **flexible and scalable** design.\n- Improves **code readability and maintainability**."
  },
  {
    "path": "oop/csharp/abstraction/README.md",
    "content": "# Abstraction in C#\n\n## Introduction\n\n**Abstraction** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows you to hide **implementation details** while exposing only the necessary parts of an object. This helps in reducing complexity and increasing maintainability.\n\nAbstraction in C# is mainly achieved using:\n1. **Abstract Classes**\n2. **Interfaces**\n\n---\n\n## **What is Abstraction?**\n\n**Abstraction** means showing only the **essential details** and hiding the **implementation**. It allows programmers to focus on **what an object does** rather than **how it does it**.\n\n### **Key Benefits of Abstraction**\n- **Reduces complexity**: Hides unnecessary implementation details.\n- **Increases code reusability**: Encourages the reuse of abstracted logic.\n- **Enhances security**: Protects internal object details from unintended modifications.\n- **Improves maintainability**: Makes code easier to manage and update.\n\n---\n\n## **1. Abstraction Using Abstract Classes**\n\nAn **abstract class** in C# is a class that **cannot be instantiated**. It is used to define common behavior that multiple subclasses should implement.\n\n### **Example: Abstract Class in C#**\n\n```csharp\nusing System;\n\n// Abstract class\nabstract class Vehicle {\n    protected string Brand;\n    \n    public Vehicle(string brand) {\n        Brand = brand;\n    }\n    \n    public abstract void Start(); // Abstract method\n    \n    public void DisplayBrand() {\n        Console.WriteLine(\"Brand: \" + Brand);\n    }\n}\n\n// Subclass implementing the abstract method\nclass Car : Vehicle {\n    public Car(string brand) : base(brand) {}\n    \n    public override void Start() {\n        Console.WriteLine(\"Car is starting...\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        Vehicle myCar = new Car(\"Toyota\");\n        myCar.DisplayBrand();\n        myCar.Start();\n    }\n}\n```\n\n### **Output:**\n```\nBrand: Toyota\nCar is starting...\n```\n\n**Why Use Abstract Classes?**\n- Allows defining common behavior that subclasses must implement.\n- Enables partial abstraction (can have both abstract and concrete methods).\n- Prevents direct instantiation of base classes.\n\n---\n\n## **2. Abstraction Using Interfaces**\n\nAn **interface** in C# is a contract that defines methods a class must implement.\n\n### **Example: Interface in C#**\n\n```csharp\nusing System;\n\n// Defining an interface\ninterface IAnimal {\n    void MakeSound(); // Abstract method\n}\n\n// Implementing the interface in Dog class\nclass Dog : IAnimal {\n    public void MakeSound() {\n        Console.WriteLine(\"Dog barks\");\n    }\n}\n\n// Implementing the interface in Cat class\nclass Cat : IAnimal {\n    public void MakeSound() {\n        Console.WriteLine(\"Cat meows\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        IAnimal myDog = new Dog();\n        myDog.MakeSound();\n        \n        IAnimal myCat = new Cat();\n        myCat.MakeSound();\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Interfaces?**\n- Promotes **full abstraction** (hides all implementation details).\n- Supports **multiple inheritance** in C#.\n- Provides a standard way for different classes to implement behaviors.\n\n---\n\n## **Abstract Class vs Interface: Key Differences**\n\n| Feature | Abstract Class | Interface |\n|---------|---------------|-----------|\n| Methods | Can have abstract and concrete methods | Only abstract methods (before C# 8) |\n| Fields | Can have member variables | Cannot have instance variables |\n| Constructor | Can have constructors | Cannot have constructors |\n| Multiple Inheritance | Not supported | Supported |\n| Access Modifiers | Can have different access modifiers | Methods are `public` by default |\n\n---\n\n## **Real-World Example: Payment System**\n\nAbstraction is widely used in real-world applications, such as payment processing.\n\n### **Example: Payment System with Abstraction**\n\n```csharp\nusing System;\n\n// Abstract class for Payment\nabstract class Payment {\n    protected double Amount;\n    \n    public Payment(double amount) {\n        Amount = amount;\n    }\n    \n    public abstract void Pay(); // Abstract method\n}\n\n// Implementing payment methods\nclass CreditCardPayment : Payment {\n    public CreditCardPayment(double amount) : base(amount) {}\n    \n    public override void Pay() {\n        Console.WriteLine(\"Paid \" + Amount + \" using Credit Card\");\n    }\n}\n\nclass PayPalPayment : Payment {\n    public PayPalPayment(double amount) : base(amount) {}\n    \n    public override void Pay() {\n        Console.WriteLine(\"Paid \" + Amount + \" using PayPal\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        Payment payment;\n        \n        payment = new CreditCardPayment(150.75);\n        payment.Pay();\n        \n        payment = new PayPalPayment(200.50);\n        payment.Pay();\n    }\n}\n```\n\n### **Output:**\n```\nPaid 150.75 using Credit Card\nPaid 200.50 using PayPal\n```\n\n**Why Use Abstraction in Payment Systems?**\n- Allows multiple payment methods without modifying existing code.\n- Improves maintainability and scalability.\n- Provides a **common contract** for different payment types."
  },
  {
    "path": "oop/csharp/aggregation/README.md",
    "content": "# Aggregation in C#\n\n## Introduction\n\nAggregation is a key concept in object-oriented programming (OOP) that represents a \"has-a\" relationship between two classes, but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one class contains another, the contained object can exist independently of the container.\n\nAggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained object cannot exist without the container.\n\n## What is Aggregation?\n\nAggregation is a form of association in OOP where an object of one class contains a reference to an object of another class. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.\n\n### Key Characteristics of Aggregation:\n- Represents a **has-a** relationship.\n- The contained object **can exist independently** of the container.\n- Implemented using references to objects.\n- Promotes **loose coupling** between objects.\n\n### Example: A University and its Professors\n\nConsider a scenario where a `University` contains multiple `Professor` objects. However, a `Professor` can exist independently of any university. This is an example of aggregation.\n\n```csharp\nusing System;\nusing System.Collections.Generic;\n\nclass Professor {\n    public string Name { get; private set; }\n    public string Subject { get; private set; }\n    \n    public Professor(string name, string subject) {\n        Name = name;\n        Subject = subject;\n    }\n    \n    public void Teach() {\n        Console.WriteLine($\"{Name} is teaching {Subject}\");\n    }\n}\n\nclass University {\n    private string universityName;\n    private List<Professor> professors;\n    \n    public University(string universityName) {\n        this.universityName = universityName;\n        professors = new List<Professor>();\n    }\n    \n    public void AddProfessor(Professor professor) {\n        professors.Add(professor);\n    }\n    \n    public void ShowProfessors() {\n        Console.WriteLine($\"Professors at {universityName}:\");\n        foreach (var professor in professors) {\n            Console.WriteLine($\" - {professor.Name}\");\n        }\n    }\n}\n\nclass AggregationExample {\n    static void Main() {\n        Professor prof1 = new Professor(\"Dr. Smith\", \"Computer Science\");\n        Professor prof2 = new Professor(\"Dr. Johnson\", \"Mathematics\");\n        \n        University university = new University(\"Harvard University\");\n        university.AddProfessor(prof1);\n        university.AddProfessor(prof2);\n        \n        university.ShowProfessors();\n        \n        // Professors can exist independently\n        prof1.Teach();\n        prof2.Teach();\n    }\n}\n```\n\n### Output:\n```\nProfessors at Harvard University:\n - Dr. Smith\n - Dr. Johnson\nDr. Smith is teaching Computer Science\nDr. Johnson is teaching Mathematics\n```\n\n---\n\n## Aggregation vs Composition\n\n| Feature       | Aggregation | Composition |\n|--------------|------------|-------------|\n| Relationship | \"Has-a\"    | \"Has-a\"     |\n| Ownership    | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime     | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example      | University and Professors | Car and Engine |\n\n---\n\n## Why Use Aggregation?\n\n### 1. **Promotes Code Reusability**\n   - Aggregated objects can be used in multiple places without being tightly coupled to a single container class.\n\n### 2. **Encourages Loose Coupling**\n   - Aggregation allows objects to interact without being dependent on the lifecycle of each other.\n\n### 3. **Better Maintainability**\n   - Changes in one class do not heavily impact the other, making the codebase easier to modify and extend.\n\n### 4. **Real-World Applicability**\n   - Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.\n\n---\n\n## Aggregation with Interfaces\n\nUsing interfaces, we can further enhance the flexibility of aggregation.\n\n```csharp\nusing System;\nusing System.Collections.Generic;\n\ninterface ITeachable {\n    void Teach();\n}\n\nclass Professor : ITeachable {\n    public string Name { get; private set; }\n    public string Subject { get; private set; }\n    \n    public Professor(string name, string subject) {\n        Name = name;\n        Subject = subject;\n    }\n    \n    public void Teach() {\n        Console.WriteLine($\"{Name} is teaching {Subject}\");\n    }\n}\n\nclass University {\n    private string universityName;\n    private List<ITeachable> professors;\n    \n    public University(string universityName) {\n        this.universityName = universityName;\n        professors = new List<ITeachable>();\n    }\n    \n    public void AddProfessor(ITeachable professor) {\n        professors.Add(professor);\n    }\n    \n    public void ShowProfessors() {\n        Console.WriteLine($\"Professors at {universityName}:\");\n        foreach (var professor in professors) {\n            professor.Teach();\n        }\n    }\n}\n\nclass InterfaceAggregationExample {\n    static void Main() {\n        Professor prof1 = new Professor(\"Dr. Adams\", \"Physics\");\n        Professor prof2 = new Professor(\"Dr. Lee\", \"Chemistry\");\n        \n        University university = new University(\"MIT\");\n        university.AddProfessor(prof1);\n        university.AddProfessor(prof2);\n        \n        university.ShowProfessors();\n    }\n}\n```\n\n### Output:\n```\nProfessors at MIT:\nDr. Adams is teaching Physics\nDr. Lee is teaching Chemistry\n```\n\n---\n\n## When to Use Aggregation?\n\n- When an object **can exist independently** from the container.\n- When designing **loosely coupled** systems.\n- When different objects need to be **shared** across multiple containers.\n- When following **SOLID principles**, particularly the **Dependency Inversion Principle (DIP)**."
  },
  {
    "path": "oop/csharp/association/README.md",
    "content": "# Association in C#\n\n## Introduction\n\nAssociation is a key concept in object-oriented programming (OOP) that defines a relationship between two or more objects. It represents how objects interact with each other while maintaining their independence.\n\nAssociation is **not inheritance**—rather, it is a relationship between objects that allows communication while ensuring they remain loosely coupled.\n\n## What is Association?\n\nAssociation defines a connection between two classes, where one class is linked to another. The association can be **one-to-one**, **one-to-many**, **many-to-one**, or **many-to-many**. Objects in an association can exist independently of each other.\n\n### Key Characteristics of Association:\n- Represents a **uses-a** or **knows-a** relationship.\n- Objects in an association **can exist independently**.\n- Can be **unidirectional** or **bidirectional**.\n- Promotes **modularity** and **code reusability**.\n\n### Example: A Student and a Teacher\n\nA `Student` can be associated with multiple `Teacher` objects, and a `Teacher` can have multiple `Student` objects. This represents a **many-to-many** association.\n\n```csharp\nusing System;\nusing System.Collections.Generic;\n\nclass Teacher {\n    public string Name { get; private set; }\n    private List<Student> students;\n    \n    public Teacher(string name) {\n        Name = name;\n        students = new List<Student>();\n    }\n    \n    public void AddStudent(Student student) {\n        students.Add(student);\n    }\n    \n    public void ShowStudents() {\n        Console.WriteLine($\"{Name} teaches:\");\n        foreach (var student in students) {\n            Console.WriteLine($\" - {student.Name}\");\n        }\n    }\n}\n\nclass Student {\n    public string Name { get; private set; }\n    \n    public Student(string name) {\n        Name = name;\n    }\n}\n\nclass AssociationExample {\n    static void Main() {\n        Teacher teacher1 = new Teacher(\"Mr. Smith\");\n        Teacher teacher2 = new Teacher(\"Mrs. Johnson\");\n        \n        Student student1 = new Student(\"Alice\");\n        Student student2 = new Student(\"Bob\");\n        \n        teacher1.AddStudent(student1);\n        teacher1.AddStudent(student2);\n        teacher2.AddStudent(student2);\n        \n        teacher1.ShowStudents();\n        teacher2.ShowStudents();\n    }\n}\n```\n\n### Output:\n```\nMr. Smith teaches:\n - Alice\n - Bob\nMrs. Johnson teaches:\n - Bob\n```\n\n---\n\n## Types of Association\n\n### 1. **One-to-One Association**\n   - Each object of class A is associated with one object of class B.\n   - Example: A `Person` has one `Passport`.\n\n### 2. **One-to-Many Association**\n   - One object of class A can be associated with multiple objects of class B.\n   - Example: A `Teacher` teaches multiple `Students`.\n\n### 3. **Many-to-One Association**\n   - Multiple objects of class A can be associated with one object of class B.\n   - Example: Multiple `Students` belong to one `School`.\n\n### 4. **Many-to-Many Association**\n   - Multiple objects of class A can be associated with multiple objects of class B.\n   - Example: `Teachers` and `Students` (a student can have multiple teachers, and a teacher can have multiple students).\n\n---\n\n## Why Use Association?\n\n### 1. **Promotes Code Reusability**\n   - Objects can be reused across multiple associations without duplication.\n\n### 2. **Encourages Loose Coupling**\n   - Objects interact without depending on the internal implementation of each other.\n\n### 3. **Improves Maintainability**\n   - Changing one object does not heavily impact others, making code easier to manage.\n\n### 4. **Better System Design**\n   - Allows modeling of real-world relationships between entities effectively.\n\n---\n\n## Bidirectional Association\n\nAssociations can be **unidirectional** (one object knows about another) or **bidirectional** (both objects know about each other).\n\n### Example: A Library and Books (Bidirectional Association)\n\n```csharp\nusing System;\nusing System.Collections.Generic;\n\nclass Book {\n    public string Title { get; private set; }\n    private Library library;\n    \n    public Book(string title, Library library) {\n        Title = title;\n        this.library = library;\n    }\n    \n    public void ShowLibrary() {\n        Console.WriteLine($\"{Title} is in {library.Name}\");\n    }\n}\n\nclass Library {\n    public string Name { get; private set; }\n    private List<Book> books;\n    \n    public Library(string name) {\n        Name = name;\n        books = new List<Book>();\n    }\n    \n    public void AddBook(Book book) {\n        books.Add(book);\n    }\n    \n    public void ShowBooks() {\n        Console.WriteLine($\"Books in {Name}:\");\n        foreach (var book in books) {\n            Console.WriteLine($\" - {book.Title}\");\n        }\n    }\n}\n\nclass BidirectionalAssociationExample {\n    static void Main() {\n        Library library = new Library(\"City Library\");\n        Book book1 = new Book(\"1984\", library);\n        Book book2 = new Book(\"Brave New World\", library);\n        \n        library.AddBook(book1);\n        library.AddBook(book2);\n        \n        library.ShowBooks();\n        book1.ShowLibrary();\n        book2.ShowLibrary();\n    }\n}\n```\n\n### Output:\n```\nBooks in City Library:\n - 1984\n - Brave New World\n1984 is in City Library\nBrave New World is in City Library\n```"
  },
  {
    "path": "oop/csharp/classesandobjects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nA class is a blueprint or template. It defines the attributes (fields) and behaviors (methods) of an object.\n\n### Defining a Class in C#\n\nTo define a class in C#, you use the `class` keyword followed by the name of the class. \n\nHere's a simple example:\n\n```csharp\npublic class Car {\n    // Attributes\n    private string color;\n    private string make;\n    private string model;\n    private int year;\n\n    // Constructor\n    public Car(string color, string make, string model, int year) {\n        this.color = color;\n        this.make = make;\n        this.model = model;\n        this.year = year;\n    }\n\n    // Method to display car details\n    public void displayInfo() {\n        Console.WriteLine(\"Car Make: \" + make);\n        Console.WriteLine(\"Car Model: \" + model);\n        Console.WriteLine(\"Car Year: \" + year);\n        Console.WriteLine(\"Car Color: \" + color);\n    }\n}\n```\n- **Attributes**: The class `Car` has four attributes that describe its state: `color`, `make`, `model`, and `year`.\n- **Constructor**: The constructor `Car(string color, string make, string model, int year)` initializes new objects of the class.\n- **Methods**: The `displayInfo` method is responsible for showcasing the car details.\n\n## What is an Object?\n\nAn object is an instance of a class. When you create an object, you are bringing the blueprint of the class into reality. It consists of state and behavior defined by the class, with each object holding its own copy of the data.\n\n### Creating Objects in C#\n\nTo create an object, you use the `new` keyword followed by the class constructor. \n\nHere's how you can instantiate objects from the `Car` class:\n\n```csharp\npublic class Main {\n    public static void main(string[] args) {\n        // Creating an object of the Car class\n        Car car1 = new Car(\"Red\", \"Toyota\", \"Corolla\", 2020);\n        Car car2 = new Car(\"Blue\", \"Ford\", \"Mustang\", 2021);\n\n        // Displaying information of each car\n        car1.displayInfo();\n        Console.WriteLine(\"-----------------\");\n        car2.displayInfo();\n    }\n}\n```\n\n1. **Instantiation**: The `new` keyword is used to create an object, which allocates memory for it.\n2. **Initialization**: The constructor (`Car`) initializes the object state with given parameters.\n3. **Reference**: The object is referenced through a variable (`car1`, `car2`) that points to its memory location."
  },
  {
    "path": "oop/csharp/composition/README.md",
    "content": "# Composition in C#\n\n## Introduction\n\nComposition is one of the key concepts of object-oriented programming (OOP). It allows objects to be built using other objects, promoting code reuse, flexibility, and better maintainability. Unlike inheritance, which establishes an \"is-a\" relationship, composition represents a \"has-a\" relationship.\n\n## What is Composition?\n\nComposition is a design principle in OOP where one class contains an instance (or instances) of another class as a field. The contained class is often called a component, and the containing class is referred to as a composite class. This helps in building complex systems by combining simpler objects.\n\n### Example: A Car and its Components\n\nConsider a `Car` that consists of multiple components like an `Engine`, `Wheel`, and `Transmission`. Instead of inheriting from these components, a `Car` object will contain them as fields.\n\n```csharp\nusing System;\n\nclass Engine\n{\n    private int horsepower;\n    \n    public Engine(int horsepower)\n    {\n        this.horsepower = horsepower;\n    }\n\n    public void Start()\n    {\n        Console.WriteLine($\"Engine started with {horsepower} HP.\");\n    }\n}\n\nclass Wheel\n{\n    private string type;\n    \n    public Wheel(string type)\n    {\n        this.type = type;\n    }\n\n    public void Rotate()\n    {\n        Console.WriteLine($\"The {type} wheel is rotating.\");\n    }\n}\n\nclass Transmission\n{\n    private string type;\n    \n    public Transmission(string type)\n    {\n        this.type = type;\n    }\n\n    public void ShiftGear()\n    {\n        Console.WriteLine($\"Transmission shifted: {type}\");\n    }\n}\n\nclass Car\n{\n    private Engine engine;\n    private Wheel wheel;\n    private Transmission transmission;\n\n    public Car(Engine engine, Wheel wheel, Transmission transmission)\n    {\n        this.engine = engine;\n        this.wheel = wheel;\n        this.transmission = transmission;\n    }\n\n    public void Drive()\n    {\n        engine.Start();\n        wheel.Rotate();\n        transmission.ShiftGear();\n        Console.WriteLine(\"Car is moving!\");\n    }\n}\n\nclass CompositionExample\n{\n    static void Main()\n    {   \n        Car car = new Car(new Engine(150), new Wheel(\"Alloy\"), new Transmission(\"Automatic\"));\n        car.Drive();\n    }\n}\n```\n\n### Output:\n```\nEngine started with 150 HP.\nThe Alloy wheel is rotating.\nTransmission shifted: Automatic\nCar is moving!\n```\n\n---\n\n## Why Prefer Composition Over Inheritance?\n\n### 1. **Encapsulation and Flexibility**\n   - Composition allows us to change the behavior of an object dynamically by replacing components at runtime.\n   - Inheritance makes it difficult to modify an existing class hierarchy without breaking existing code.\n\n### 2. **Better Code Reusability**\n   - Composition promotes reusable components. The `Engine`, `Wheel`, and `Transmission` classes can be used in multiple types of vehicles (Car, Bike, Truck) without modification.\n\n### 3. **Avoids Inheritance Pitfalls**\n   - Inheritance can lead to deep class hierarchies, making maintenance difficult.\n   - It enforces strict parent-child relationships, which can be too rigid for some designs.\n\n### 4. **Supports Interface-Based Design**\n   - Composition can be combined with interfaces to achieve powerful decoupling.\n\n---\n\n## Composition with Interfaces\n\nUsing interfaces with composition allows for greater flexibility and loose coupling.\n\n```csharp\nusing System;\n\ninterface IEngine\n{\n    void Start();\n}\n\nclass PetrolEngine : IEngine\n{\n    public void Start()\n    {\n        Console.WriteLine(\"Petrol Engine started.\");\n    }\n}\n\nclass DieselEngine : IEngine\n{\n    public void Start()\n    {\n        Console.WriteLine(\"Diesel Engine started.\");\n    }\n}\n\nclass Car\n{\n    private IEngine engine;\n\n    public Car(IEngine engine)\n    {\n        this.engine = engine;\n    }\n\n    public void StartCar()\n    {\n        engine.Start();\n        Console.WriteLine(\"Car is ready to go!\");\n    }\n}\n\nclass InterfaceCompositionExample\n{\n    static void Main()\n    {\n        Car petrolCar = new Car(new PetrolEngine());\n        petrolCar.StartCar();\n        \n        Car dieselCar = new Car(new DieselEngine());\n        dieselCar.StartCar();\n    }\n}\n```\n\n### Output:\n```\nPetrol Engine started.\nCar is ready to go!\nDiesel Engine started.\nCar is ready to go!\n```\n\n---\n\n## When to Use Composition?\n\n- When building complex objects that consist of multiple components.\n- When you want to achieve **code reusability** without rigid inheritance hierarchies.\n- When different behaviors need to be swapped dynamically (e.g., using different types of engines in a vehicle).\n- When following the **favor composition over inheritance** principle."
  },
  {
    "path": "oop/csharp/encapsulation/README.md",
    "content": "# Encapsulation in C#\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of **Object-Oriented Programming (OOP)**. It is the practice of **bundling data (fields) and methods** that operate on that data into a single unit (**class**) while **restricting direct access** to the internal details.\n\nEncapsulation in C# is achieved using:\n1. **Access Modifiers** (`private`, `protected`, `public`)\n2. **Properties (Getters and Setters)**\n3. **Data Hiding**\n\nEncapsulation helps in **data protection, modularity, and maintainability** of the code.\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** the data (fields) and code (methods) together into a single unit (class). It restricts direct access to some of an object's components, ensuring **data integrity and security**.\n\n### **Key Benefits of Encapsulation**\n- **Data Hiding**: Prevents direct access to sensitive data.\n- **Increased Security**: Controls how data is accessed and modified.\n- **Improved Code Maintainability**: Allows changes without affecting other parts of the code.\n- **Better Modularity**: Organizes the code into logical components.\n\n---\n\n## **Encapsulation Using Access Modifiers in C#**\n\nC# provides **access modifiers** to enforce encapsulation:\n- **`private`**: Accessible only within the same class.\n- **`protected`**: Accessible within the same class and derived (child) classes.\n- **`public`**: Accessible from anywhere.\n- **`internal`**: Accessible only within the same assembly.\n\n### **Example: Encapsulation with Private Fields**\n```csharp\nusing System;\n\nclass BankAccount\n{\n    private string accountHolder;\n    private double balance;\n\n    // Constructor\n    public BankAccount(string accountHolder, double balance)\n    {\n        this.accountHolder = accountHolder;\n        this.balance = balance;\n    }\n\n    // Getter method to access balance\n    public double GetBalance()\n    {\n        return balance;\n    }\n\n    // Setter method to modify balance\n    public void Deposit(double amount)\n    {\n        if (amount > 0)\n        {\n            balance += amount;\n            Console.WriteLine($\"Deposited: {amount}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Invalid deposit amount\");\n        }\n    }\n}\n\nclass Program\n{\n    static void Main()\n    {\n        BankAccount account = new BankAccount(\"Alice\", 1000);\n        Console.WriteLine($\"Current Balance: {account.GetBalance()}\");\n        account.Deposit(500);\n        Console.WriteLine($\"Updated Balance: {account.GetBalance()}\");\n    }\n}\n```\n\n### **Output:**\n```\nCurrent Balance: 1000\nDeposited: 500\nUpdated Balance: 1500\n```\n\n---\n\n## **Encapsulation Using Properties (Getters and Setters)**\n\nEncapsulation ensures that **data cannot be directly accessed** but must be retrieved or modified through **properties**.\n\n### **Example: Properties in C#**\n```csharp\nusing System;\n\nclass Employee\n{\n    private string name;\n    private int age;\n\n    // Property for Name\n    public string Name\n    {\n        get { return name; }\n        set { name = value; }\n    }\n\n    // Property for Age with validation\n    public int Age\n    {\n        get { return age; }\n        set\n        {\n            if (value > 18)\n                age = value;\n            else\n                Console.WriteLine(\"Age must be greater than 18\");\n        }\n    }\n}\n\nclass Program\n{\n    static void Main()\n    {\n        Employee emp = new Employee();\n        emp.Name = \"John Doe\";\n        emp.Age = 25;\n        Console.WriteLine($\"Employee Name: {emp.Name}\");\n        Console.WriteLine($\"Employee Age: {emp.Age}\");\n    }\n}\n```\n\n### **Output:**\n```\nEmployee Name: John Doe\nEmployee Age: 25\n```\n\n---\n\n## **Encapsulation in Real-World Applications**\n\nEncapsulation is used in many real-world applications such as:\n1. **Banking Systems** - Ensuring account details are private.\n2. **Healthcare Applications** - Protecting patient records.\n3. **E-Commerce Platforms** - Hiding payment processing details.\n\n### **Example: Encapsulation in Payment Processing**\n```csharp\nusing System;\n\nclass PaymentProcessor\n{\n    private string cardNumber;\n    private double amount;\n\n    public PaymentProcessor(string cardNumber, double amount)\n    {\n        this.cardNumber = MaskCardNumber(cardNumber);\n        this.amount = amount;\n    }\n\n    private string MaskCardNumber(string cardNumber)\n    {\n        return \"****-****-****-\" + cardNumber.Substring(cardNumber.Length - 4);\n    }\n\n    public void ProcessPayment()\n    {\n        Console.WriteLine($\"Processing payment of {amount} for card {cardNumber}\");\n    }\n}\n\nclass Program\n{\n    static void Main()\n    {\n        PaymentProcessor payment = new PaymentProcessor(\"1234567812345678\", 250.00);\n        payment.ProcessPayment();\n    }\n}\n```\n\n### **Output:**\n```\nProcessing payment of 250 for card ****-****-****-5678\n```"
  },
  {
    "path": "oop/csharp/inheritance/README.md",
    "content": "# Inheritance in C#\n\n## Introduction\n\n**Inheritance** is one of the core principles of Object-Oriented Programming (OOP). It allows a class (subclass or child class) to acquire the properties and behaviors of another class (superclass or parent class). This promotes **code reuse**, **scalability**, and **maintainability**.\n\n---\n\n## **What is Inheritance?**\n\n**Inheritance** is a mechanism where a child class derives properties and behaviors from a parent class. The child class can:\n- Use the fields and methods of the parent class\n- Override parent class methods to provide a specific implementation\n- Add its own additional properties and methods\n\n### **Key Benefits of Inheritance**\n- **Code Reusability**: Avoids code duplication by reusing fields and methods of the parent class.\n- **Improves Maintainability**: Reduces redundancy, making code easier to manage.\n- **Enhances Extensibility**: New functionality can be added easily without modifying existing code.\n\n---\n\n## **How to Implement Inheritance in C#**\n\n### **Step 1: Create a Parent Class**\nThe parent class contains common fields and methods.\n\n```csharp\nusing System;\n\n// Parent class\nclass Animal {\n    public string Name;\n    \n    public void Eat() {\n        Console.WriteLine(Name + \" is eating...\");\n    }\n}\n```\n\n### **Step 2: Create a Child Class using `:`**\nThe child class inherits the properties and methods of the parent class.\n\n```csharp\n// Child class\nclass Dog : Animal {\n    public void Bark() {\n        Console.WriteLine(Name + \" is barking...\");\n    }\n}\n```\n\n### **Step 3: Use the Child Class**\nNow, let's create an object and use the inherited methods.\n\n```csharp\nclass Program {\n    static void Main() {\n        Dog myDog = new Dog();\n        myDog.Name = \"Buddy\";\n        myDog.Eat(); // Inherited from Animal class\n        myDog.Bark(); // Defined in Dog class\n    }\n}\n```\n\n### **Output:**\n```\nBuddy is eating...\nBuddy is barking...\n```\n\n---\n\n## **Types of Inheritance in C#**\n\nC# supports different types of inheritance:\n\n### **1. Single Inheritance**\nA subclass inherits from one superclass.\n\n```csharp\nclass Parent {\n    public void Show() {\n        Console.WriteLine(\"This is the parent class\");\n    }\n}\n\nclass Child : Parent {\n    public void Display() {\n        Console.WriteLine(\"This is the child class\");\n    }\n}\n```\n\n### **2. Multilevel Inheritance**\nA subclass inherits from another subclass, forming a chain.\n\n```csharp\nclass Grandparent {\n    public void Show() {\n        Console.WriteLine(\"Grandparent class\");\n    }\n}\n\nclass Parent : Grandparent {\n    public void Display() {\n        Console.WriteLine(\"Parent class\");\n    }\n}\n\nclass Child : Parent {\n    public void Print() {\n        Console.WriteLine(\"Child class\");\n    }\n}\n```\n\n### **3. Hierarchical Inheritance**\nA single parent class has multiple child classes.\n\n```csharp\nclass Parent {\n    public void Show() {\n        Console.WriteLine(\"Parent class\");\n    }\n}\n\nclass Child1 : Parent {\n    public void Display() {\n        Console.WriteLine(\"Child1 class\");\n    }\n}\n\nclass Child2 : Parent {\n    public void Print() {\n        Console.WriteLine(\"Child2 class\");\n    }\n}\n```\n\n**Note:** C# **does not support multiple inheritance** (i.e., a child class inheriting from multiple parents) due to ambiguity problems.\n\n---\n\n## **Method Overriding in Inheritance**\n\nMethod overriding allows a child class to **redefine** a method from the parent class.\n\n```csharp\nclass Animal {\n    public virtual void MakeSound() {\n        Console.WriteLine(\"Animal makes a sound\");\n    }\n}\n\nclass Dog : Animal {\n    public override void MakeSound() {\n        Console.WriteLine(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n```csharp\nclass Program {\n    static void Main() {\n        Animal myAnimal = new Dog(); // Polymorphism\n        myAnimal.MakeSound();\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\n```\n\n---\n\n## **The `base` Keyword in Inheritance**\n\nThe `base` keyword is used to **refer to the parent class**. It helps to:\n1. Call the parent class constructor.\n2. Access the parent class methods.\n3. Access the parent class fields.\n\n```csharp\nclass Animal {\n    public Animal() {\n        Console.WriteLine(\"Animal Constructor\");\n    }\n    public virtual void MakeSound() {\n        Console.WriteLine(\"Animal makes a sound\");\n    }\n}\n\nclass Dog : Animal {\n    public Dog() {\n        Console.WriteLine(\"Dog Constructor\");\n    }\n    public override void MakeSound() {\n        base.MakeSound(); // Calls parent method\n        Console.WriteLine(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n```csharp\nclass Program {\n    static void Main() {\n        Dog myDog = new Dog();\n        myDog.MakeSound();\n    }\n}\n```\n\n### **Output:**\n```\nAnimal Constructor\nDog Constructor\nAnimal makes a sound\nDog barks\n```"
  },
  {
    "path": "oop/csharp/interfaces/README.md",
    "content": "# Interfaces in C#\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **interface** is a crucial concept that defines a contract for classes to follow. It allows multiple classes to share a common structure while enforcing certain behaviors. Interfaces are widely used in C# and other OOP languages to achieve **abstraction, polymorphism, and loose coupling**.\n\n## What is an Interface?\n\nAn **interface** is a collection of method definitions that a class must implement. It defines a contract that implementing classes must adhere to.\n\n### **Key Characteristics of Interfaces in C#**\n- Defines a **contract** that implementing classes must follow.\n- All methods are **implicitly public and abstract** (unless they have a default implementation).\n- Cannot have instance variables (only static and constant fields are allowed).\n- Supports **multiple inheritance**, unlike classes.\n- Improves **code flexibility and maintainability**.\n\n---\n\n## **Defining and Implementing an Interface in C#**\n\n### **Step 1: Define an Interface**\nTo define an interface, use the `interface` keyword.\n\n```csharp\n// Defining an interface\npublic interface IVehicle {\n    void Start(); // Abstract method (no implementation)\n    void Stop();  // Abstract method (no implementation)\n}\n```\n\n### **Step 2: Implement the Interface**\nA class implements an interface using the `: (colon)` symbol.\n\n```csharp\n// Implementing the IVehicle interface in a Car class\npublic class Car : IVehicle {\n    public void Start() {\n        Console.WriteLine(\"Car is starting...\");\n    }\n    \n    public void Stop() {\n        Console.WriteLine(\"Car is stopping...\");\n    }\n}\n```\n\n### **Step 3: Using the Implemented Class**\nNow, let's create objects and call the methods.\n\n```csharp\npublic class Program {\n    public static void Main(string[] args) {\n        IVehicle myCar = new Car(); // Polymorphism: Interface reference\n        myCar.Start();\n        myCar.Stop();\n    }\n}\n```\n\n### **Output:**\n```\nCar is starting...\nCar is stopping...\n```\n\n---\n\n## **Multiple Inheritance with Interfaces**\n\nUnlike classes, C# **supports multiple inheritance** with interfaces.\n\n```csharp\n// First interface\npublic interface IFlyable {\n    void Fly();\n}\n\n// Second interface\npublic interface IDrivable {\n    void Drive();\n}\n\n// Implementing multiple interfaces\npublic class FlyingCar : IFlyable, IDrivable {\n    public void Fly() {\n        Console.WriteLine(\"FlyingCar is flying...\");\n    }\n    \n    public void Drive() {\n        Console.WriteLine(\"FlyingCar is driving...\");\n    }\n}\n```\n\n### **Usage**\n```csharp\npublic class Program {\n    public static void Main(string[] args) {\n        FlyingCar myVehicle = new FlyingCar();\n        myVehicle.Fly();\n        myVehicle.Drive();\n    }\n}\n```\n\n### **Output:**\n```\nFlyingCar is flying...\nFlyingCar is driving...\n```\n\n---\n\n## **Default Method Behavior in Interfaces**\n\nC# 8 introduced **default methods** in interfaces, allowing methods with a body.\n\n```csharp\npublic interface IAnimal {\n    void Sound();\n    \n    // Default method with implementation\n    public void Sleep() {\n        Console.WriteLine(\"Sleeping...\");\n    }\n}\n\npublic class Dog : IAnimal {\n    public void Sound() {\n        Console.WriteLine(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n```csharp\npublic class Program {\n    public static void Main(string[] args) {\n        Dog myDog = new Dog();\n        myDog.Sound();\n        myDog.Sleep(); // Calling default method\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nSleeping...\n```\n\n---\n\n## **Real-World Example: Payment System**\n\n```csharp\npublic interface IPayment {\n    void Pay(double amount);\n}\n\npublic class CreditCardPayment : IPayment {\n    public void Pay(double amount) {\n        Console.WriteLine($\"Paid {amount} using Credit Card\");\n    }\n}\n\npublic class PayPalPayment : IPayment {\n    public void Pay(double amount) {\n        Console.WriteLine($\"Paid {amount} using PayPal\");\n    }\n}\n```\n\n### **Usage**\n```csharp\npublic class Program {\n    public static void Main(string[] args) {\n        IPayment payment1 = new CreditCardPayment();\n        payment1.Pay(100.50);\n        \n        IPayment payment2 = new PayPalPayment();\n        payment2.Pay(200.75);\n    }\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```"
  },
  {
    "path": "oop/csharp/polymorphism/README.md",
    "content": "# Polymorphism in C#\n\n## Introduction\n\n**Polymorphism** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nPolymorphism in C# can be classified into two types:\n1. **Compile-time Polymorphism (Method Overloading & Operator Overloading)**\n2. **Run-time Polymorphism (Method Overriding & Interfaces)**\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a method, function, or object to behave differently based on the context. Polymorphism enables **dynamic method resolution** and **method flexibility**, making applications easier to extend and maintain.\n\n### **Key Benefits of Polymorphism**\n- **Code Reusability**: Write a single interface that works for multiple types.\n- **Scalability**: Add new functionalities with minimal code changes.\n- **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **1. Compile-Time Polymorphism (Method Overloading)**\n\nCompile-time polymorphism occurs when multiple methods in the same class share the same name but have **different method signatures** (parameters). The method to be called is determined **at compile time**.\n\n### **Example of Method Overloading**\n\n```csharp\nusing System;\n\nclass MathOperations {\n    // Method with two parameters\n    public int Add(int a, int b) {\n        return a + b;\n    }\n    \n    // Method with three parameters (overloaded)\n    public int Add(int a, int b, int c) {\n        return a + b + c;\n    }\n}\n\nclass Program {\n    static void Main() {\n        MathOperations math = new MathOperations();\n        Console.WriteLine(\"Sum (2 numbers): \" + math.Add(5, 10));\n        Console.WriteLine(\"Sum (3 numbers): \" + math.Add(5, 10, 15));\n    }\n}\n```\n\n### **Output:**\n```\nSum (2 numbers): 15\nSum (3 numbers): 30\n```\n\n**Why Use Method Overloading?**\n- Provides a cleaner and more intuitive interface.\n- Reduces redundancy by using a single method name for similar operations.\n\n---\n\n## **2. Run-Time Polymorphism (Method Overriding)**\n\nRun-time polymorphism occurs when a subclass provides a **specific implementation** of a method already defined in its parent class. The method to be called is determined **at runtime**.\n\n### **Example of Method Overriding**\n\n```csharp\nusing System;\n\nclass Animal {\n    public virtual void MakeSound() {\n        Console.WriteLine(\"Animal makes a sound\");\n    }\n}\n\nclass Dog : Animal {\n    public override void MakeSound() {\n        Console.WriteLine(\"Dog barks\");\n    }\n}\n\nclass Cat : Animal {\n    public override void MakeSound() {\n        Console.WriteLine(\"Cat meows\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        Animal myAnimal = new Dog(); // Upcasting\n        myAnimal.MakeSound();\n        \n        myAnimal = new Cat(); // Dynamic method dispatch\n        myAnimal.MakeSound();\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Method Overriding?**\n- Enables **dynamic method resolution**.\n- Supports **polymorphic behavior**, where one interface can be used for multiple implementations.\n- Makes code **extensible** by allowing future modifications.\n\n---\n\n## **Using Polymorphism with Interfaces**\n\nPolymorphism is widely used with **interfaces**, allowing multiple classes to share a common contract.\n\n```csharp\nusing System;\n\ninterface IVehicle {\n    void Start();\n}\n\nclass Car : IVehicle {\n    public void Start() {\n        Console.WriteLine(\"Car is starting...\");\n    }\n}\n\nclass Bike : IVehicle {\n    public void Start() {\n        Console.WriteLine(\"Bike is starting...\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        IVehicle myVehicle = new Car();\n        myVehicle.Start();\n        \n        myVehicle = new Bike();\n        myVehicle.Start();\n    }\n}\n```\n\n### **Output:**\n```\nCar is starting...\nBike is starting...\n```\n\n**Why Use Interfaces with Polymorphism?**\n- Promotes **loose coupling**, making code more flexible.\n- Allows multiple implementations of the same behavior.\n- Enables **dependency injection**, improving testability.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case of polymorphism is in **payment processing**.\n\n```csharp\nusing System;\n\ninterface IPayment {\n    void Pay(double amount);\n}\n\nclass CreditCardPayment : IPayment {\n    public void Pay(double amount) {\n        Console.WriteLine(\"Paid \" + amount + \" using Credit Card\");\n    }\n}\n\nclass PayPalPayment : IPayment {\n    public void Pay(double amount) {\n        Console.WriteLine(\"Paid \" + amount + \" using PayPal\");\n    }\n}\n\nclass Program {\n    static void Main() {\n        IPayment payment;\n        \n        payment = new CreditCardPayment();\n        payment.Pay(100.50);\n        \n        payment = new PayPalPayment();\n        payment.Pay(200.75);\n    }\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```\n\n**Why Use Polymorphism in Payment Systems?**\n- Allows new payment methods to be added **without modifying existing code**.\n- Provides a **flexible and scalable** design.\n- Improves **code readability and maintainability**."
  },
  {
    "path": "oop/golang/abstraction/README.md",
    "content": "# Abstraction in Go\n\n## Introduction\n\n**Abstraction** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows you to hide **implementation details** while exposing only the necessary parts of an object. This helps in reducing complexity and increasing maintainability.\n\nUnlike traditional OOP languages like Java or C++, **Golang does not support classes**. However, abstraction in Go is achieved using:\n1. **Interfaces**\n2. **Structs with Methods**\n\n## **What is Abstraction?**\n\n**Abstraction** means showing only the **essential details** and hiding the **implementation**. It allows programmers to focus on **what an object does** rather than **how it does it**.\n\n### **Key Benefits of Abstraction**\n- **Reduces complexity**: Hides unnecessary implementation details.\n- **Increases code reusability**: Encourages the reuse of abstracted logic.\n- **Improves maintainability**: Makes code easier to manage and update.\n- **Enhances flexibility**: Enables polymorphic behavior in Go.\n\n---\n\n## **1. Abstraction Using Interfaces**\n\nAn **interface** in Go defines a set of methods that a type must implement. This allows different types to be treated uniformly.\n\n### **Example: Interface in Golang**\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Defining an interface\ntype Vehicle interface {\n    Start()\n    DisplayBrand()\n}\n\n// Concrete implementation of Vehicle (Car)\ntype Car struct {\n    brand string\n}\n\nfunc (c Car) Start() {\n    fmt.Println(\"Car is starting...\")\n}\n\nfunc (c Car) DisplayBrand() {\n    fmt.Println(\"Brand:\", c.brand)\n}\n\nfunc main() {\n    var myCar Vehicle = Car{\"Toyota\"}\n    myCar.DisplayBrand()\n    myCar.Start()\n}\n```\n\n### **Output:**\n```\nBrand: Toyota\nCar is starting...\n```\n\n**Why Use Interfaces?**\n- Promotes **abstraction** by defining behaviors without implementation details.\n- Allows multiple types to adhere to the same contract.\n- Supports **polymorphism** by enabling different implementations to be used interchangeably.\n\n---\n\n## **2. Abstraction Using Structs with Methods**\n\nGo does not have traditional classes, but **structs with methods** provide an alternative way to achieve abstraction.\n\n### **Example: Abstracting Animal Behavior**\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Abstract behavior using an interface\ntype Animal interface {\n    MakeSound()\n}\n\n// Concrete struct (Dog)\ntype Dog struct {}\n\nfunc (d Dog) MakeSound() {\n    fmt.Println(\"Dog barks\")\n}\n\n// Concrete struct (Cat)\ntype Cat struct {}\n\nfunc (c Cat) MakeSound() {\n    fmt.Println(\"Cat meows\")\n}\n\nfunc main() {\n    var myAnimal Animal\n    \n    myAnimal = Dog{}\n    myAnimal.MakeSound()\n    \n    myAnimal = Cat{}\n    myAnimal.MakeSound()\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Structs with Methods?**\n- Provides a clean and flexible way to define behavior.\n- Makes it easy to extend functionality.\n- Improves code readability and organization.\n\n---\n\n## **Real-World Example: Payment System**\n\nAbstraction is widely used in real-world applications, such as payment processing.\n\n### **Example: Payment System with Abstraction**\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Payment interface\ntype Payment interface {\n    Pay(amount float64)\n}\n\n// CreditCardPayment struct\n\ntype CreditCardPayment struct {}\n\nfunc (c CreditCardPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using Credit Card\\n\", amount)\n}\n\n// PayPalPayment struct\ntype PayPalPayment struct {}\n\nfunc (p PayPalPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using PayPal\\n\", amount)\n}\n\nfunc main() {\n    var payment Payment\n    \n    payment = CreditCardPayment{}\n    payment.Pay(150.75)\n    \n    payment = PayPalPayment{}\n    payment.Pay(200.50)\n}\n```\n\n### **Output:**\n```\nPaid 150.75 using Credit Card\nPaid 200.50 using PayPal\n```\n\n**Why Use Abstraction in Payment Systems?**\n- Allows multiple payment methods without modifying existing code.\n- Improves maintainability and scalability.\n- Provides a **common contract** for different payment types."
  },
  {
    "path": "oop/golang/aggregation/README.md",
    "content": "# Aggregation in Golang\n\n## Introduction\n\nAggregation is a key concept in object-oriented programming (OOP) that represents a \"has-a\" relationship between two classes (or structs in Golang), but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one struct contains another, the contained struct can exist independently of the container.\n\nAggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained struct cannot exist without the container.\n\n## What is Aggregation?\n\nAggregation is a form of association in OOP where an object of one struct contains a reference (pointer) to an object of another struct. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.\n\n### Key Characteristics of Aggregation:\n- Represents a **has-a** relationship.\n- The contained object **can exist independently** of the container.\n- Implemented using references (pointers) to objects.\n- Promotes **loose coupling** between objects.\n\n### Example: A University and its Professors\n\nConsider a scenario where a `University` contains multiple `Professor` objects. However, a `Professor` can exist independently of any university. This is an example of aggregation.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Professor struct (independent entity)\ntype Professor struct {\n    Name    string\n    Subject string\n}\n\nfunc (p Professor) Teach() {\n    fmt.Printf(\"%s is teaching %s\\n\", p.Name, p.Subject)\n}\n\n// University struct contains a list of professors (aggregation)\ntype University struct {\n    Name       string\n    Professors []*Professor // Aggregation: University has a list of professors\n}\n\nfunc (u *University) AddProfessor(professor *Professor) {\n    u.Professors = append(u.Professors, professor)\n}\n\nfunc (u University) ShowProfessors() {\n    fmt.Printf(\"Professors at %s:\\n\", u.Name)\n    for _, professor := range u.Professors {\n        fmt.Printf(\" - %s\\n\", professor.Name)\n    }\n}\n\nfunc main() {\n    prof1 := &Professor{Name: \"Dr. Smith\", Subject: \"Computer Science\"}\n    prof2 := &Professor{Name: \"Dr. Johnson\", Subject: \"Mathematics\"}\n    \n    university := &University{Name: \"Harvard University\"}\n    university.AddProfessor(prof1)\n    university.AddProfessor(prof2)\n    \n    university.ShowProfessors()\n    \n    // Professors can exist independently\n    prof1.Teach()\n    prof2.Teach()\n}\n```\n\n### Output:\n```\nProfessors at Harvard University:\n - Dr. Smith\n - Dr. Johnson\nDr. Smith is teaching Computer Science\nDr. Johnson is teaching Mathematics\n```\n\n---\n\n## Aggregation vs Composition\n\n| Feature       | Aggregation | Composition |\n|--------------|------------|-------------|\n| Relationship | \"Has-a\"    | \"Has-a\"     |\n| Ownership    | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime     | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example      | University and Professors | Car and Engine |\n\n---\n\n## Why Use Aggregation?\n\n### 1. **Promotes Code Reusability**\n   - Aggregated objects can be used in multiple places without being tightly coupled to a single container struct.\n\n### 2. **Encourages Loose Coupling**\n   - Aggregation allows objects to interact without being dependent on the lifecycle of each other.\n\n### 3. **Better Maintainability**\n   - Changes in one struct do not heavily impact the other, making the codebase easier to modify and extend.\n\n### 4. **Real-World Applicability**\n   - Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.\n\n---\n\n## Aggregation with Interfaces\n\nUsing interfaces, we can further enhance the flexibility of aggregation.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Teachable interface\ntype Teachable interface {\n    Teach()\n}\n\n// Professor struct implementing Teachable interface\ntype Professor struct {\n    Name    string\n    Subject string\n}\n\nfunc (p Professor) Teach() {\n    fmt.Printf(\"%s is teaching %s\\n\", p.Name, p.Subject)\n}\n\n// University struct containing a list of professors\ntype University struct {\n    Name       string\n    Professors []Teachable\n}\n\nfunc (u *University) AddProfessor(professor Teachable) {\n    u.Professors = append(u.Professors, professor)\n}\n\nfunc (u University) ShowProfessors() {\n    fmt.Printf(\"Professors at %s:\\n\", u.Name)\n    for _, professor := range u.Professors {\n        professor.Teach()\n    }\n}\n\nfunc main() {\n    prof1 := Professor{Name: \"Dr. Adams\", Subject: \"Physics\"}\n    prof2 := Professor{Name: \"Dr. Lee\", Subject: \"Chemistry\"}\n    \n    university := &University{Name: \"MIT\"}\n    university.AddProfessor(prof1)\n    university.AddProfessor(prof2)\n    \n    university.ShowProfessors()\n}\n```\n\n### Output:\n```\nProfessors at MIT:\nDr. Adams is teaching Physics\nDr. Lee is teaching Chemistry\n```\n\n---\n\n## When to Use Aggregation?\n\n- When an object **can exist independently** from the container.\n- When designing **loosely coupled** systems.\n- When different objects need to be **shared** across multiple containers.\n- When following **SOLID principles**, particularly the **Dependency Inversion Principle (DIP)**."
  },
  {
    "path": "oop/golang/association/README.md",
    "content": "# Association in Golang\n\n## Introduction\n\nAssociation is a key concept in object-oriented programming (OOP) that defines a relationship between two or more objects. It represents how objects interact with each other while maintaining their independence.\n\nAssociation is **not inheritance**—rather, it is a relationship between objects that allows communication while ensuring they remain loosely coupled.\n\n## What is Association?\n\nAssociation defines a connection between two structs, where one struct is linked to another. The association can be **one-to-one**, **one-to-many**, **many-to-one**, or **many-to-many**. Objects in an association can exist independently of each other.\n\n### Key Characteristics of Association:\n- Represents a **uses-a** or **knows-a** relationship.\n- Objects in an association **can exist independently**.\n- Can be **unidirectional** or **bidirectional**.\n- Promotes **modularity** and **code reusability**.\n\n### Example: A Student and a Teacher\n\nA `Student` can be associated with multiple `Teacher` objects, and a `Teacher` can have multiple `Student` objects. This represents a **many-to-many** association.\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Student struct {\n    Name string\n}\n\ntype Teacher struct {\n    Name     string\n    Students []*Student\n}\n\nfunc (t *Teacher) AddStudent(s *Student) {\n    t.Students = append(t.Students, s)\n}\n\nfunc (t *Teacher) ShowStudents() {\n    fmt.Println(t.Name, \"teaches:\")\n    for _, student := range t.Students {\n        fmt.Println(\" -\", student.Name)\n    }\n}\n\nfunc main() {\n    teacher1 := Teacher{Name: \"Mr. Smith\"}\n    teacher2 := Teacher{Name: \"Mrs. Johnson\"}\n    \n    student1 := Student{Name: \"Alice\"}\n    student2 := Student{Name: \"Bob\"}\n    \n    teacher1.AddStudent(&student1)\n    teacher1.AddStudent(&student2)\n    teacher2.AddStudent(&student2)\n    \n    teacher1.ShowStudents()\n    teacher2.ShowStudents()\n}\n```\n\n### Output:\n```\nMr. Smith teaches:\n - Alice\n - Bob\nMrs. Johnson teaches:\n - Bob\n```\n\n---\n\n## Types of Association\n\n### 1. **One-to-One Association**\n   - Each object of struct A is associated with one object of struct B.\n   - Example: A `Person` has one `Passport`.\n\n### 2. **One-to-Many Association**\n   - One object of struct A can be associated with multiple objects of struct B.\n   - Example: A `Teacher` teaches multiple `Students`.\n\n### 3. **Many-to-One Association**\n   - Multiple objects of struct A can be associated with one object of struct B.\n   - Example: Multiple `Students` belong to one `School`.\n\n### 4. **Many-to-Many Association**\n   - Multiple objects of struct A can be associated with multiple objects of struct B.\n   - Example: `Teachers` and `Students`.\n\n---\n\n## Why Use Association?\n\n- **Promotes Code Reusability**: Objects can be reused across multiple associations without duplication.\n- **Encourages Loose Coupling**: Objects interact without depending on the internal implementation of each other.\n- **Improves Maintainability**: Changing one object does not heavily impact others, making code easier to manage.\n- **Better System Design**: Allows modeling of real-world relationships between entities effectively.\n\n---\n\n## Association vs Aggregation vs Composition\n\n| Feature       | Association | Aggregation | Composition |\n|--------------|------------|------------|------------|\n| Relationship | \"Knows-a\"  | \"Has-a\"    | \"Has-a\"    |\n| Object Independence | Objects are independent | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime | Objects exist separately | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example | Teacher and Student | University and Professors | Car and Engine |\n\n---\n\n## Bidirectional Association\n\nAssociations can be **unidirectional** (one object knows about another) or **bidirectional** (both objects know about each other).\n\n### Example: A Library and Books (Bidirectional Association)\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Library struct {\n    Name  string\n    Books []*Book\n}\n\ntype Book struct {\n    Title   string\n    Library *Library\n}\n\nfunc (l *Library) AddBook(b *Book) {\n    l.Books = append(l.Books, b)\n}\n\nfunc (l *Library) ShowBooks() {\n    fmt.Println(\"Books in\", l.Name, \":\")\n    for _, book := range l.Books {\n        fmt.Println(\" -\", book.Title)\n    }\n}\n\nfunc (b *Book) ShowLibrary() {\n    fmt.Println(b.Title, \"is in\", b.Library.Name)\n}\n\nfunc main() {\n    library := Library{Name: \"City Library\"}\n    book1 := Book{Title: \"1984\", Library: &library}\n    book2 := Book{Title: \"Brave New World\", Library: &library}\n    \n    library.AddBook(&book1)\n    library.AddBook(&book2)\n    \n    library.ShowBooks()\n    book1.ShowLibrary()\n    book2.ShowLibrary()\n}\n```\n\n### Output:\n```\nBooks in City Library:\n - 1984\n - Brave New World\n1984 is in City Library\nBrave New World is in City Library\n```"
  },
  {
    "path": "oop/golang/classesandobjects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nA class is a blueprint or template. It defines the attributes (fields) and behaviors (methods) of an object.\n\n### Defining a Class in Go\n\nGo does not have traditional classes, but you can achieve similar behavior using `struct` and methods.\n\nHere's a simple example:\n\n```go\ntype Car struct {\n    // Attributes\n    Color string\n    Make string\n    Model string\n    Year int\n}\n\n// Method defined with Car as the receiver\nfunc (c Car) DisplayInfo() {\n    fmt.Println(\"Car Make: \" + c.Make)\n    fmt.Println(\"Car Model: \" + c.Model)\n    fmt.Println(\"Car Year:\", c.Year)\n    fmt.Println(\"Car Color: \" + c.Color)\n}\n```\n- **Attributes**: The struct `Car` has four attributes that describe its state: `Color`, `Make`, `Model`, and `Year`.\n- **Methods**: The `DisplayInfo` function is responsible for showcasing the car details.\n\n## What is an Object?\n\nAn object is an instance of a struct. When you create an object, you are bringing the blueprint of the struct into reality. It consists of state and behavior defined by the struct, with each object holding its own copy of the data.\n\n### Creating Objects in Go\n\nTo create an object, you instantiate the struct `Car`. \n\nHere's how you can instantiate objects from the `Car` struct:\n\n```go\nfunc main() {\n    // Creating an object of the Car class\n    car1 := Car{\"Red\", \"Toyota\", \"Corolla\", 2020}\n    car2 := Car{\"Blue\", \"Ford\", \"Mustang\", 2021}\n\n    // Displaying information of each car\n    car1.DisplayInfo()\n    fmt.Println(\"-----------------\")\n    car2.DisplayInfo()\n}\n```\n\n1. **Instantiation**: The struct `Car` is used to create an object, which allocates memory for it.\n2. **Initialization**: The struct instance holds its own set of values.\n3. **Reference**: The object is referenced using a variable (`car1`, `car2`) that holds its memory location."
  },
  {
    "path": "oop/golang/composition/README.md",
    "content": "# Composition in Golang\n\n## Introduction\n\nComposition is one of the key concepts of object-oriented programming (OOP). It allows objects to be built using other objects, promoting code reuse, flexibility, and better maintainability. Unlike inheritance, which establishes an \"is-a\" relationship, composition represents a \"has-a\" relationship.\n\n## What is Composition?\n\nComposition is a design principle in OOP where one struct contains an instance (or instances) of another struct as a field. The contained struct is often called a component, and the containing struct is referred to as a composite struct. This helps in building complex systems by combining simpler objects.\n\n### Example: A Car and its Components\n\nConsider a `Car` that consists of multiple components like an `Engine`, `Wheel`, and `Transmission`. Instead of inheriting from these components, a `Car` object will contain them as fields.\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Engine struct {\n    Horsepower int\n}\n\nfunc (e Engine) Start() {\n    fmt.Printf(\"Engine started with %d HP.\\n\", e.Horsepower)\n}\n\ntype Wheel struct {\n    Type string\n}\n\nfunc (w Wheel) Rotate() {\n    fmt.Printf(\"The %s wheel is rotating.\\n\", w.Type)\n}\n\ntype Transmission struct {\n    Type string\n}\n\nfunc (t Transmission) ShiftGear() {\n    fmt.Printf(\"Transmission shifted: %s\\n\", t.Type)\n}\n\ntype Car struct {\n    Engine       Engine\n    Wheel        Wheel\n    Transmission Transmission\n}\n\nfunc NewCar() Car {\n    return Car{\n        Engine:       Engine{Horsepower: 150},\n        Wheel:        Wheel{Type: \"Alloy\"},\n        Transmission: Transmission{Type: \"Automatic\"},\n    }\n}\n\nfunc (c Car) Drive() {\n    c.Engine.Start()\n    c.Wheel.Rotate()\n    c.Transmission.ShiftGear()\n    fmt.Println(\"Car is moving!\")\n}\n\nfunc main() {\n    car := NewCar()\n    car.Drive()\n}\n```\n\n### Output:\n```\nEngine started with 150 HP.\nThe Alloy wheel is rotating.\nTransmission shifted: Automatic\nCar is moving!\n```\n\n---\n\n## Why Prefer Composition Over Inheritance?\n\n### 1. **Encapsulation and Flexibility**\n   - Composition allows us to change the behavior of an object dynamically by replacing components at runtime.\n   - Inheritance makes it difficult to modify an existing class hierarchy without breaking existing code.\n\n### 2. **Better Code Reusability**\n   - Composition promotes reusable components. The `Engine`, `Wheel`, and `Transmission` structs can be used in multiple types of vehicles (Car, Bike, Truck) without modification.\n\n### 3. **Avoids Inheritance Pitfalls**\n   - Inheritance can lead to deep struct hierarchies, making maintenance difficult.\n   - It enforces strict parent-child relationships, which can be too rigid for some designs.\n\n### 4. **Supports Interface-Based Design**\n   - Composition can be combined with interfaces to achieve powerful decoupling.\n\n---\n\n## Composition with Interfaces\n\nUsing interfaces with composition allows for greater flexibility and loose coupling.\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Engine interface {\n    Start()\n}\n\ntype PetrolEngine struct {}\n\nfunc (p PetrolEngine) Start() {\n    fmt.Println(\"Petrol Engine started.\")\n}\n\ntype DieselEngine struct {}\n\nfunc (d DieselEngine) Start() {\n    fmt.Println(\"Diesel Engine started.\")\n}\n\ntype Car struct {\n    engine Engine\n}\n\nfunc (c Car) StartCar() {\n    c.engine.Start()\n    fmt.Println(\"Car is ready to go!\")\n}\n\nfunc main() {\n    petrolCar := Car{engine: PetrolEngine{}}\n    petrolCar.StartCar()\n    \n    dieselCar := Car{engine: DieselEngine{}}\n    dieselCar.StartCar()\n}\n```\n\n### Output:\n```\nPetrol Engine started.\nCar is ready to go!\nDiesel Engine started.\nCar is ready to go!\n```\n\n---\n\n## When to Use Composition?\n\n- When building complex objects that consist of multiple components.\n- When you want to achieve **code reusability** without rigid inheritance hierarchies.\n- When different behaviors need to be swapped dynamically (e.g., using different types of engines in a vehicle).\n- When following the **favor composition over inheritance** principle."
  },
  {
    "path": "oop/golang/encapsulation/README.md",
    "content": "# Encapsulation in Golang\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of Object-Oriented Programming (OOP). It is the practice of **bundling data (variables) and methods** that operate on that data into a single unit (struct) while restricting direct access to the internal details.\n\nEncapsulation in Golang is achieved using:\n1. **Exported and Unexported Fields (Visibility Control)**\n2. **Getters and Setters (Methods for Data Access)**\n3. **Data Hiding**\n\nEncapsulation helps in **data protection, modularity, and maintainability** of the code.\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** the data (fields) and code (methods) together into a single unit (struct). It restricts direct access to some of an object's components, which helps protect data integrity and prevents unintended modifications.\n\n### **Key Benefits of Encapsulation**\n- **Data Hiding**: Prevents direct access to sensitive data.\n- **Increased Security**: Controls how data is accessed and modified.\n- **Improved Code Maintainability**: Allows changes without affecting other parts of the code.\n- **Better Modularity**: Organizes the code into logical components.\n\n---\n\n## **Encapsulation Using Exported and Unexported Fields**\n\nGolang does not have traditional access modifiers like `private`, `protected`, or `public`. Instead, it uses **capitalization** to determine visibility:\n- **Exported fields (Public)**: Fields that start with an **uppercase letter** can be accessed outside the package.\n- **Unexported fields (Private)**: Fields that start with a **lowercase letter** are only accessible within the same package.\n\n### **Example: Encapsulation with Unexported Fields**\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n)\n\n// BankAccount struct with encapsulated data\ntype BankAccount struct {\n    accountHolder string  // Unexported field (private)\n    balance       float64 // Unexported field (private)\n}\n\n// Constructor function to initialize BankAccount\nfunc NewBankAccount(holder string, balance float64) *BankAccount {\n    return &BankAccount{accountHolder: holder, balance: balance}\n}\n\n// Getter method to access balance\nfunc (b *BankAccount) GetBalance() float64 {\n    return b.balance\n}\n\n// Setter method to modify balance\nfunc (b *BankAccount) Deposit(amount float64) {\n    if amount > 0 {\n        b.balance += amount\n        fmt.Println(\"Deposited:\", amount)\n    } else {\n        fmt.Println(\"Invalid deposit amount\")\n    }\n}\n\nfunc main() {\n    account := NewBankAccount(\"Alice\", 1000)\n    fmt.Println(\"Current Balance:\", account.GetBalance())\n    account.Deposit(500)\n    fmt.Println(\"Updated Balance:\", account.GetBalance())\n}\n```\n\n### **Output:**\n```\nCurrent Balance: 1000\nDeposited: 500\nUpdated Balance: 1500\n```\n\n**Why Use Encapsulation?**\n- Prevents unauthorized access to the data.\n- Allows controlled modifications through methods.\n\n---\n\n## **Encapsulation Using Getters and Setters**\n\nEncapsulation ensures that **data cannot be directly accessed** but must be retrieved or modified through methods.\n\n### **Example: Getters and Setters in Golang**\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n)\n\n// Employee struct with private fields\ntype Employee struct {\n    name string\n    age  int\n}\n\n// Getter for name\nfunc (e *Employee) GetName() string {\n    return e.name\n}\n\n// Setter for name\nfunc (e *Employee) SetName(name string) {\n    e.name = name\n}\n\n// Getter for age\nfunc (e *Employee) GetAge() int {\n    return e.age\n}\n\n// Setter for age with validation\nfunc (e *Employee) SetAge(age int) {\n    if age > 18 {\n        e.age = age\n    } else {\n        fmt.Println(\"Age must be greater than 18\")\n    }\n}\n\nfunc main() {\n    emp := Employee{}\n    emp.SetName(\"John Doe\")\n    emp.SetAge(25)\n    fmt.Println(\"Employee Name:\", emp.GetName())\n    fmt.Println(\"Employee Age:\", emp.GetAge())\n}\n```\n\n### **Output:**\n```\nEmployee Name: John Doe\nEmployee Age: 25\n```\n\n---\n\n## **Encapsulation and Data Hiding**\n\nEncapsulation helps **hide implementation details** while exposing only necessary methods.\n\n### **Example: Hiding Implementation Details**\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n)\n\n// Account struct with private balance\ntype Account struct {\n    balance float64\n}\n\n// Constructor function\nfunc NewAccount(initialBalance float64) *Account {\n    return &Account{balance: initialBalance}\n}\n\n// Private method for withdrawal validation\nfunc (a *Account) validateWithdrawal(amount float64) bool {\n    return amount > 0 && amount <= a.balance\n}\n\n// Public method to withdraw\nfunc (a *Account) Withdraw(amount float64) {\n    if a.validateWithdrawal(amount) {\n        a.balance -= amount\n        fmt.Println(\"Withdrawal Successful:\", amount)\n    } else {\n        fmt.Println(\"Insufficient balance or invalid amount\")\n    }\n}\n\n// Getter for balance\nfunc (a *Account) GetBalance() float64 {\n    return a.balance\n}\n\nfunc main() {\n    myAccount := NewAccount(1000)\n    myAccount.Withdraw(300)\n    fmt.Println(\"Remaining Balance:\", myAccount.GetBalance())\n}\n```\n\n### **Output:**\n```\nWithdrawal Successful: 300\nRemaining Balance: 700\n```\n\n**Why Hide Data?**\n- Prevents direct modification of important fields.\n- Ensures data integrity by validating inputs.\n\n---\n\n## **Encapsulation in Real-World Applications**\n\nEncapsulation is used in many real-world applications such as:\n1. **Banking Systems** - Ensuring account details are private.\n2. **Healthcare Applications** - Protecting patient records.\n3. **E-Commerce Platforms** - Hiding payment processing details.\n\n### **Example: Encapsulation in Payment Processing**\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"strings\"\n)\n\n// PaymentProcessor struct\ntype PaymentProcessor struct {\n    cardNumber string\n    amount     float64\n}\n\n// Constructor function\nfunc NewPaymentProcessor(cardNumber string, amount float64) *PaymentProcessor {\n    return &PaymentProcessor{cardNumber: maskCardNumber(cardNumber), amount: amount}\n}\n\n// Private function to mask card number\nfunc maskCardNumber(cardNumber string) string {\n    return \"****-****-****-\" + cardNumber[len(cardNumber)-4:]\n}\n\n// Public method to process payment\nfunc (p *PaymentProcessor) ProcessPayment() {\n    fmt.Println(\"Processing payment of\", p.amount, \"for card\", p.cardNumber)\n}\n\nfunc main() {\n    payment := NewPaymentProcessor(\"1234567812345678\", 250.00)\n    payment.ProcessPayment()\n}\n```\n\n### **Output:**\n```\nProcessing payment of 250 for card ****-****-****-5678\n```\n\n**Why Use Encapsulation in Payment Processing?**\n- Protects sensitive data (e.g., credit card numbers).\n- Hides unnecessary details from users.\n- Ensures secure transactions."
  },
  {
    "path": "oop/golang/inheritance/README.md",
    "content": "# Inheritance in Go\n\n## Introduction\n\nUnlike traditional OOP languages like Java and C++, **Go does not have classical inheritance**. Instead, Go achieves similar functionality using **struct embedding and interfaces**. This promotes **code reuse**, **composition over inheritance**, and **flexibility**.\n\n---\n\n## **What is Inheritance (or its Alternative in Go)?**\n\nGo does not support class-based inheritance. Instead, it uses **struct embedding**, which allows one struct to include another, inheriting its fields and methods. This achieves a similar effect to traditional inheritance.\n\n### **Key Benefits of Struct Embedding in Go**\n- **Composition over Inheritance**: Encourages modular and maintainable design.\n- **Code Reusability**: Allows reusing functionality without rigid class hierarchies.\n- **Method Overriding**: Embedded structs’ methods can be overridden in the outer struct.\n- **Polymorphism**: Achieved using interfaces rather than class-based inheritance.\n\n---\n\n## **How to Implement Inheritance-like Behavior in Go**\n\n### **Step 1: Define a Parent Struct**\nA struct in Go acts like a class with fields and methods.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Parent struct\ntype Animal struct {\n    Name string\n}\n\nfunc (a Animal) Eat() {\n    fmt.Println(a.Name, \"is eating...\")\n}\n```\n\n### **Step 2: Embed the Parent Struct in a Child Struct**\nThe `Dog` struct embeds `Animal`, inheriting its fields and methods.\n\n```go\n// Child struct embedding Animal\ntype Dog struct {\n    Animal // Embedding Animal struct\n}\n\nfunc (d Dog) Bark() {\n    fmt.Println(d.Name, \"is barking...\")\n}\n```\n\n### **Step 3: Use the Child Struct**\nWe create an instance of `Dog`, which has access to both `Animal` and `Dog` methods.\n\n```go\nfunc main() {\n    myDog := Dog{Animal{Name: \"Buddy\"}}\n    myDog.Eat()  // Inherited from Animal struct\n    myDog.Bark() // Defined in Dog struct\n}\n```\n\n### **Output:**\n```\nBuddy is eating...\nBuddy is barking...\n```\n\n---\n\n## **Multiple Inheritance Alternative: Composition**\n\nGo does not support multiple inheritance, but struct embedding allows a struct to include multiple embedded structs.\n\n```go\n// First embedded struct\ntype Engine struct {\n    Horsepower int\n}\n\n// Second embedded struct\ntype Wheels struct {\n    Count int\n}\n\n// Car struct embedding Engine and Wheels\ntype Car struct {\n    Engine\n    Wheels\n}\n```\n\n### **Usage**\n```go\nfunc main() {\n    myCar := Car{Engine{200}, Wheels{4}}\n    fmt.Println(\"Horsepower:\", myCar.Horsepower)\n    fmt.Println(\"Wheels:\", myCar.Count)\n}\n```\n\n### **Output:**\n```\nHorsepower: 200\nWheels: 4\n```\n\n---\n\n## **Method Overriding in Struct Embedding**\n\nA child struct can override an inherited method by defining a new method with the same name.\n\n```go\ntype Animal struct {\n    Name string\n}\n\nfunc (a Animal) Speak() {\n    fmt.Println(a.Name, \"makes a sound\")\n}\n\n// Overriding Speak method\ntype Dog struct {\n    Animal\n}\n\nfunc (d Dog) Speak() {\n    fmt.Println(d.Name, \"barks\")\n}\n```\n\n### **Usage**\n```go\nfunc main() {\n    myDog := Dog{Animal{Name: \"Buddy\"}}\n    myDog.Speak() // Calls the overridden method\n}\n```\n\n### **Output:**\n```\nBuddy barks\n```\n\n---\n\n## **Using Interfaces for Polymorphism**\n\nIn Go, **interfaces** allow struct-based polymorphism, similar to inheritance in OOP languages.\n\n```go\ntype Animal interface {\n    Speak()\n}\n\ntype Dog struct {\n    Name string\n}\n\nfunc (d Dog) Speak() {\n    fmt.Println(d.Name, \"barks\")\n}\n```\n\n### **Usage**\n```go\nfunc main() {\n    var myAnimal Animal = Dog{Name: \"Buddy\"}\n    myAnimal.Speak()\n}\n```\n\n### **Output:**\n```\nBuddy barks\n```"
  },
  {
    "path": "oop/golang/interfaces/README.md",
    "content": "# Interfaces in Go (Golang)\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **interface** is a crucial concept that defines a contract for types to follow. It allows multiple types to share a common structure while enforcing certain behaviors. Unlike Java and C++, Go interfaces are **implicit**—a type satisfies an interface simply by implementing its methods.\n\n## What is an Interface?\n\nAn **interface** is a set of method signatures that a type must implement. It defines a contract that implementing types must adhere to.\n\n### **Key Characteristics of Interfaces in Go**\n- Interfaces in Go are **implicit**, meaning types don’t explicitly declare they implement an interface.\n- They define **method signatures** that types must implement.\n- Interfaces **enable polymorphism**, allowing functions to operate on different types that share a common behavior.\n- They support **multiple interface implementation**, unlike struct embedding.\n\n---\n\n## **Defining and Implementing an Interface in Go**\n\n### **Step 1: Define an Interface**\nTo define an interface, we use the `interface` keyword.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Defining an interface\ntype Vehicle interface {\n    Start()\n    Stop()\n}\n```\n\n### **Step 2: Implement the Interface**\nA type implements an interface by defining methods with the same signatures.\n\n```go\n// Implementing the Vehicle interface in a Car struct\ntype Car struct {\n    brand string\n}\n\nfunc (c Car) Start() {\n    fmt.Println(\"Car is starting...\")\n}\n\nfunc (c Car) Stop() {\n    fmt.Println(\"Car is stopping...\")\n}\n```\n\n### **Step 3: Using the Implemented Interface**\nNow, let's create an instance and call the methods.\n\n```go\nfunc main() {\n    var myCar Vehicle = Car{brand: \"Toyota\"} // Interface reference\n    myCar.Start()\n    myCar.Stop()\n}\n```\n\n### **Output:**\n```\nCar is starting...\nCar is stopping...\n```\n\n---\n\n## **Multiple Interface Implementation in Go**\n\nGo allows a struct to implement multiple interfaces implicitly.\n\n```go\n// First interface\ntype Flyable interface {\n    Fly()\n}\n\n// Second interface\ntype Drivable interface {\n    Drive()\n}\n\n// Implementing multiple interfaces\ntype FlyingCar struct {}\n\nfunc (f FlyingCar) Fly() {\n    fmt.Println(\"FlyingCar is flying...\")\n}\n\nfunc (f FlyingCar) Drive() {\n    fmt.Println(\"FlyingCar is driving...\")\n}\n```\n\n### **Usage**\n```go\nfunc main() {\n    var myVehicle Flyable = FlyingCar{}\n    myVehicle.Fly()\n    \n    var myCar Drivable = FlyingCar{}\n    myCar.Drive()\n}\n```\n\n### **Output:**\n```\nFlyingCar is flying...\nFlyingCar is driving...\n```\n\n---\n\n## **Interface Composition in Go**\n\nGo interfaces can be composed of other interfaces.\n\n```go\ntype Engine interface {\n    Start()\n    Stop()\n}\n\ntype Transmission interface {\n    ShiftGear(gear int)\n}\n\ntype CarInterface interface {\n    Engine\n    Transmission\n}\n```\n\nThis means any type that implements `Start()`, `Stop()`, and `ShiftGear()` automatically implements `CarInterface`.\n\n---\n\n## **Real-World Example: Payment System**\n\n```go\ntype Payment interface {\n    Pay(amount float64)\n}\n\ntype CreditCardPayment struct {}\n\nfunc (c CreditCardPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using Credit Card\\n\", amount)\n}\n\ntype PayPalPayment struct {}\n\nfunc (p PayPalPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using PayPal\\n\", amount)\n}\n```\n\n### **Usage**\n```go\nfunc main() {\n    var payment1 Payment = CreditCardPayment{}\n    payment1.Pay(100.50)\n    \n    var payment2 Payment = PayPalPayment{}\n    payment2.Pay(200.75)\n}\n```\n\n### **Output:**\n```\nPaid 100.50 using Credit Card\nPaid 200.75 using PayPal\n```"
  },
  {
    "path": "oop/golang/polymorphism/README.md",
    "content": "# Polymorphism in Object-Oriented Programming (OOP) in Golang\n\n## Introduction\n\n**Polymorphism** is one of the fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nPolymorphism in Go is primarily achieved using **interfaces**, as Go does not support method overloading or classical inheritance like Java or C#.\n\n---\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a method, function, or object to behave differently based on the context. Polymorphism enables **dynamic method resolution** and **method flexibility**, making applications easier to extend and maintain.\n\n### **Key Benefits of Polymorphism**\n- **Code Reusability**: Write a single interface that works for multiple types.\n- **Scalability**: Add new functionalities with minimal code changes.\n- **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **Polymorphism using Interfaces in Go**\n\nGo achieves polymorphism through **interfaces**. An interface defines a set of method signatures, and any type that implements those methods satisfies the interface.\n\n### **Example: Polymorphism using Interfaces**\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Define an interface\ntype Animal interface {\n    MakeSound()\n}\n\n// Implementing the interface in Dog\ntype Dog struct{}\n\nfunc (d Dog) MakeSound() {\n    fmt.Println(\"Dog barks\")\n}\n\n// Implementing the interface in Cat\ntype Cat struct{}\n\nfunc (c Cat) MakeSound() {\n    fmt.Println(\"Cat meows\")\n}\n\nfunc main() {\n    var animal Animal\n    \n    animal = Dog{}\n    animal.MakeSound()\n    \n    animal = Cat{}\n    animal.MakeSound()\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Interfaces for Polymorphism?**\n- Provides a flexible and modular design.\n- Encourages dependency inversion and loose coupling.\n- Allows multiple types to satisfy the same interface.\n\n---\n\n## **Using Polymorphism with Functions**\n\nA common use of polymorphism in Go is passing different types to the same function.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Define an interface\ntype Vehicle interface {\n    Start()\n}\n\n// Implementing the interface in Car\ntype Car struct{}\n\nfunc (c Car) Start() {\n    fmt.Println(\"Car is starting...\")\n}\n\n// Implementing the interface in Bike\ntype Bike struct{}\n\nfunc (b Bike) Start() {\n    fmt.Println(\"Bike is starting...\")\n}\n\n// Function that takes any Vehicle\nfunc StartVehicle(v Vehicle) {\n    v.Start()\n}\n\nfunc main() {\n    car := Car{}\n    bike := Bike{}\n    \n    StartVehicle(car)\n    StartVehicle(bike)\n}\n```\n\n### **Output:**\n```\nCar is starting...\nBike is starting...\n```\n\n**Why Use Function Parameters for Polymorphism?**\n- Allows flexible function behavior based on the type passed.\n- Enhances code modularity and testability.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case of polymorphism is in **payment processing**.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// Define an interface\ntype Payment interface {\n    Pay(amount float64)\n}\n\n// Implementing the interface in CreditCardPayment\ntype CreditCardPayment struct{}\n\nfunc (c CreditCardPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using Credit Card\\n\", amount)\n}\n\n// Implementing the interface in PayPalPayment\ntype PayPalPayment struct{}\n\nfunc (p PayPalPayment) Pay(amount float64) {\n    fmt.Printf(\"Paid %.2f using PayPal\\n\", amount)\n}\n\nfunc main() {\n    var payment Payment\n    \n    payment = CreditCardPayment{}\n    payment.Pay(100.50)\n    \n    payment = PayPalPayment{}\n    payment.Pay(200.75)\n}\n```\n\n### **Output:**\n```\nPaid 100.50 using Credit Card\nPaid 200.75 using PayPal\n```\n\n**Why Use Polymorphism in Payment Systems?**\n- Allows new payment methods to be added **without modifying existing code**.\n- Provides a **flexible and scalable** design.\n- Improves **code readability and maintainability**."
  },
  {
    "path": "oop/java/AggregationVsComposition/README.MD",
    "content": "# Aggregation vs Composition in Java (Code-Focused)\n\nIn OOP, **Aggregation** and **Composition** both express \"has-a\" relationships, but they differ in **ownership**, **object lifecycle**, and **instantiation strategy**.\n\n---\n\n## 🔗 Aggregation — External Object Reference\n\n### ✅ Key Code Characteristic:\n> The referenced object is **passed from outside** and can exist independently.\n\n```java\nclass Engine {\n    String type;\n    Engine(String type) {\n        this.type = type;\n    }\n}\n\nclass Car {\n    Engine engine; // Aggregation - reference passed from outside\n\n    Car(Engine engine) {\n        this.engine = engine;\n    }\n\n    void showEngineType() {\n        System.out.println(\"Engine: \" + engine.type);\n    }\n}\n\npublic class AggregationDemo {\n    public static void main(String[] args) {\n        Engine e1 = new Engine(\"V8\");       // Created externally\n        Car car1 = new Car(e1);             // Shared with car1\n\n        Engine e2 = new Engine(\"V6\");\n        Car car2 = new Car(e2);             // Shared with car2\n\n        car1.showEngineType(); // Engine: V8\n        car2.showEngineType(); // Engine: V6\n    }\n}\n```\n\n**🧠 Key Point:**  \n- `Car` does **not own** `Engine`.\n- The same `Engine` can be reused across multiple `Car` objects.\n- `Engine` can outlive or live independently of `Car`.\n\n---\n\n## 🔒 Composition — Object Created Internally\n\n### ✅ Key Code Characteristic:\n> The referenced object is **created inside** the constructor. It **cannot exist without the parent.**\n\n```java\nclass Engine {\n    String type;\n    Engine(String type) {\n        this.type = type;\n    }\n}\n\nclass Car {\n    private Engine engine; // Composition - created inside\n\n    Car(String engineType) {\n        this.engine = new Engine(engineType); // tightly coupled\n    }\n\n    void showEngineType() {\n        System.out.println(\"Engine: \" + engine.type);\n    }\n}\n\npublic class CompositionDemo {\n    public static void main(String[] args) {\n        Car car = new Car(\"Electric\");  // Engine is part of Car\n        car.showEngineType();           // Engine: Electric\n    }\n}\n```\n\n**🧠 Key Point:**  \n- `Car` **fully owns** `Engine`.\n- `Engine` cannot be reused or accessed independently.\n- Lifecycle of `Engine` is strictly bound to `Car`.\n\n---\n\n## 🔍 Code-Level Differences Summary\n\n| Aspect                 | Aggregation                                | Composition                               |\n|------------------------|---------------------------------------------|--------------------------------------------|\n| Object creation        | Object is passed from outside               | Object is created internally               |\n| Ownership              | Parent has a reference                      | Parent owns the object                     |\n| Lifecycle dependency   | Child can live without parent               | Child dies with parent                     |\n| Reusability            | Child can be reused by multiple parents     | Child is bound to one parent only          |\n| Code style             | `this.child = child;`                       | `this.child = new Child();` or similar     |\n\n---\n\n## 💡 When to Use\n\n- **Use Aggregation** when you want to share or reuse the same instance.\n- **Use Composition** when you want a part to be a core, non-detachable component of the object.\n\n---\n"
  },
  {
    "path": "oop/java/abstraction/README.md",
    "content": "# Abstraction in Java\n\n## Introduction\n\n**Abstraction** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows you to hide **implementation details** while exposing only the necessary parts of an object. This helps in reducing complexity and increasing maintainability.\n\nAbstraction in Java is mainly achieved using:\n1. **Abstract Classes**\n2. **Interfaces**\n\n---\n\n## **What is Abstraction?**\n\n**Abstraction** means showing only the **essential details** and hiding the **implementation**. It allows programmers to focus on **what an object does** rather than **how it does it**.\n\n### **Key Benefits of Abstraction**\n- **Reduces complexity**: Hides unnecessary implementation details.\n- **Increases code reusability**: Encourages the reuse of abstracted logic.\n- **Enhances security**: Protects internal object details from unintended modifications.\n- **Improves maintainability**: Makes code easier to manage and update.\n\n---\n\n## **1. Abstraction Using Abstract Classes**\n\nAn **abstract class** in Java is a class that cannot be instantiated. It is used to define common behavior that multiple subclasses should implement.\n\n### **Example: Abstract Class in Java**\n\n```java\n// Abstract class\nabstract class Vehicle {\n    String brand;\n    \n    // Constructor\n    Vehicle(String brand) {\n        this.brand = brand;\n    }\n    \n    // Abstract method (must be implemented by subclasses)\n    abstract void start();\n    \n    // Concrete method (can be inherited)\n    void displayBrand() {\n        System.out.println(\"Brand: \" + brand);\n    }\n}\n\n// Subclass implementing the abstract method\nclass Car extends Vehicle {\n    Car(String brand) {\n        super(brand);\n    }\n    \n    @Override\n    void start() {\n        System.out.println(\"Car is starting...\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Vehicle myCar = new Car(\"Toyota\");\n        myCar.displayBrand();\n        myCar.start();\n    }\n}\n```\n\n### **Output:**\n```\nBrand: Toyota\nCar is starting...\n```\n\n**Why Use Abstract Classes?**\n- Allows defining common behavior that subclasses must implement.\n- Enables partial abstraction (can have both abstract and concrete methods).\n- Prevents direct instantiation of base classes.\n\n---\n\n## **2. Abstraction Using Interfaces**\n\nAn **interface** in Java is a blueprint that defines a contract for classes to follow. It contains **only abstract methods** (until Java 8 introduced default and static methods).\n\n### **Example: Interface in Java**\n\n```java\n// Defining an interface\ninterface Animal {\n    void makeSound(); // Abstract method\n}\n\n// Implementing the interface in Dog class\nclass Dog implements Animal {\n    @Override\n    public void makeSound() {\n        System.out.println(\"Dog barks\");\n    }\n}\n\n// Implementing the interface in Cat class\nclass Cat implements Animal {\n    @Override\n    public void makeSound() {\n        System.out.println(\"Cat meows\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Animal myDog = new Dog();\n        myDog.makeSound();\n        \n        Animal myCat = new Cat();\n        myCat.makeSound();\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Interfaces?**\n- Promotes **full abstraction** (hides all implementation details).\n- Supports **multiple inheritance** in Java (a class can implement multiple interfaces).\n- Provides a standard way for different classes to implement behaviors.\n\n---\n\n## **Abstract Class vs Interface: Key Differences**\n\n| Feature                | Abstract Class                                      | Interface                                      |\n|------------------------|----------------------------------------------------|-----------------------------------------------|\n| **Inheritance**        | A class **extends** only **one** abstract class    | A class **implements multiple** interfaces    |\n| **Methods**            | Can have **abstract + concrete** methods           | Only abstract methods (before Java 8)        |\n| **Default Methods**    | Concrete methods work without `default` keyword    | Supports `default` methods (Java 8+)         |\n| **Static Methods**     | Can have static methods                            | Supports static methods (Java 8+)            |\n| **Fields**             | Can have **instance variables** (non-final)        | Only **public static final** (constants)     |\n| **Constructor**        | Can have constructors                              | **No constructors** allowed                  |\n| **Multiple Inheritance** | Not supported (only **single** inheritance)   | Supports **multiple** inheritance         |\n| **Access Modifiers**   | Methods/fields can be `public`, `protected`, `private`, or default | Methods are `public` by default |\n| **Purpose**            | **Partial implementation** (code reuse)           | **Full abstraction** (contract definition)   |\n| **Object Creation**    | Cannot be instantiated directly                | Cannot be instantiated directly           |\n| **`super` Keyword**    | Can use `super()` to call parent constructor       | No `super()` (no constructors)            |\n| **Private Methods**    | Supports `private` methods (Java 9+)              | Supports `private` methods (Java 9+)         |\n| **`final` Methods**    | Can have `final` methods                       | Cannot have `final` methods               |\n\n---\n\n## **Real-World Example: Payment System**\n\nAbstraction is widely used in real-world applications, such as payment processing.\n\n### **Example: Payment System with Abstraction**\n\n```java\n// Abstract class for Payment\nabstract class Payment {\n    double amount;\n    \n    Payment(double amount) {\n        this.amount = amount;\n    }\n    \n    abstract void pay(); // Abstract method\n}\n\n// Implementing payment methods\nclass CreditCardPayment extends Payment {\n    CreditCardPayment(double amount) {\n        super(amount);\n    }\n    \n    @Override\n    void pay() {\n        System.out.println(\"Paid \" + amount + \" using Credit Card\");\n    }\n}\n\nclass PayPalPayment extends Payment {\n    PayPalPayment(double amount) {\n        super(amount);\n    }\n    \n    @Override\n    void pay() {\n        System.out.println(\"Paid \" + amount + \" using PayPal\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Payment payment;\n        \n        payment = new CreditCardPayment(150.75);\n        payment.pay();\n        \n        payment = new PayPalPayment(200.50);\n        payment.pay();\n    }\n}\n```\n\n### **Output:**\n```\nPaid 150.75 using Credit Card\nPaid 200.50 using PayPal\n```\n\n**Why Use Abstraction in Payment Systems?**\n- Allows multiple payment methods without modifying existing code.\n- Improves maintainability and scalability.\n- Provides a **common contract** for different payment types."
  },
  {
    "path": "oop/java/aggregation/README.md",
    "content": "# Aggregation in Java\n\n## Introduction\n\nAggregation is a key concept in object-oriented programming (OOP) that represents a \"has-a\" relationship between two classes, but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one class contains another, the contained object can exist independently of the container.\n\nAggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained object cannot exist without the container.\n\n---\n\n## What is Aggregation?\n\nAggregation is a form of association in OOP where an object of one class contains a reference to an object of another class. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.\n\n### Key Characteristics of Aggregation:\n- Represents a **has-a** relationship.\n- The contained object **can exist independently** of the container.\n- Implemented using references (pointers) to objects.\n- Promotes **loose coupling** between objects.\n\n### Example: A University and its Professors\n\nConsider a scenario where a `University` contains multiple `Professor` objects. However, a `Professor` can exist independently of any university. This is an example of aggregation.\n\n```java\nclass Professor {\n    private String name;\n    private String subject;\n    \n    public Professor(String name, String subject) {\n        this.name = name;\n        this.subject = subject;\n    }\n    \n    public String getName(){\n        return name;\n    }\n    \n    public void teach() {\n        System.out.println(name + \" is teaching \" + subject);\n    }\n}\n\nclass University {\n    private String universityName;\n    private List<Professor> professors;\n    \n    public University(String universityName) {\n        this.universityName = universityName;\n        this.professors = new ArrayList<>();\n    }\n    \n    public void addProfessor(Professor professor) {\n        professors.add(professor);\n    }\n    \n    public void showProfessors() {\n        System.out.println(\"Professors at \" + universityName + \":\");\n        for (Professor professor : professors) {\n            System.out.println(\" - \" + professor.getName());\n        }\n    }\n}\n\nimport java.util.*;\n\npublic class AggregationExample {\n    public static void main(String[] args) {\n        Professor prof1 = new Professor(\"Dr. Smith\", \"Computer Science\");\n        Professor prof2 = new Professor(\"Dr. Johnson\", \"Mathematics\");\n        \n        University university = new University(\"Harvard University\");\n        university.addProfessor(prof1);\n        university.addProfessor(prof2);\n        \n        university.showProfessors();\n        \n        // Professors can exist independently\n        prof1.teach();\n        prof2.teach();\n    }\n}\n```\n\n### Output:\n```\nProfessors at Harvard University:\n - Dr. Smith\n - Dr. Johnson\nDr. Smith is teaching Computer Science\nDr. Johnson is teaching Mathematics\n```\n\n---\n\n## Aggregation vs Composition\n\n| Feature       | Aggregation | Composition |\n|--------------|------------|-------------|\n| Relationship | \"Has-a\"    | \"Has-a\"     |\n| Ownership    | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime     | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example      | University and Professors | Car and Engine |\n\n---\n\n## Why Use Aggregation?\n\n### 1. **Promotes Code Reusability**\n   - Aggregated objects can be used in multiple places without being tightly coupled to a single container class.\n\n### 2. **Encourages Loose Coupling**\n   - Aggregation allows objects to interact without being dependent on the lifecycle of each other.\n\n### 3. **Better Maintainability**\n   - Changes in one class do not heavily impact the other, making the codebase easier to modify and extend.\n\n### 4. **Real-World Applicability**\n   - Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.\n\n---\n\n## Aggregation with Interfaces\n\nUsing interfaces, we can further enhance the flexibility of aggregation.\n\n```java\ninterface Teachable {\n    void teach();\n}\n\nclass Professor implements Teachable {\n    private String name;\n    private String subject;\n    \n    public Professor(String name, String subject) {\n        this.name = name;\n        this.subject = subject;\n    }\n    \n    public void teach() {\n        System.out.println(name + \" is teaching \" + subject);\n    }\n}\n\nclass University {\n    private String universityName;\n    private List<Teachable> professors;\n    \n    public University(String universityName) {\n        this.universityName = universityName;\n        this.professors = new ArrayList<>();\n    }\n    \n    public void addProfessor(Teachable professor) {\n        professors.add(professor);\n    }\n    \n    public void showProfessors() {\n        System.out.println(\"Professors at \" + universityName + \":\");\n        for (Teachable professor : professors) {\n            professor.teach();\n        }\n    }\n}\n\nimport java.util.*;\n\npublic class InterfaceAggregationExample {\n    public static void main(String[] args) {\n        Professor prof1 = new Professor(\"Dr. Adams\", \"Physics\");\n        Professor prof2 = new Professor(\"Dr. Lee\", \"Chemistry\");\n        \n        University university = new University(\"MIT\");\n        university.addProfessor(prof1);\n        university.addProfessor(prof2);\n        \n        university.showProfessors();\n    }\n}\n```\n\n### Output:\n```\nProfessors at MIT:\nDr. Adams is teaching Physics\nDr. Lee is teaching Chemistry\n```\n\n---\n\n## When to Use Aggregation?\n\n- When an object **can exist independently** from the container.\n- When designing **loosely coupled** systems.\n- When different objects need to be **shared** across multiple containers.\n- When following **SOLID principles**, particularly the **Dependency Inversion Principle (DIP)**."
  },
  {
    "path": "oop/java/association/README.md",
    "content": "# Association in Object-Oriented Programming (OOP)\n\n## Introduction\n\nAssociation is a key concept in object-oriented programming (OOP) that defines a relationship between two or more objects. It represents how objects interact with each other while maintaining their independence.\n\nAssociation is **not inheritance**—rather, it is a relationship between objects that allows communication while ensuring they remain loosely coupled.\n\n## What is Association?\n\nAssociation defines a connection between two classes, where one class is linked to another. The association can be **one-to-one**, **one-to-many**, **many-to-one**, or **many-to-many**. Objects in an association can exist independently of each other.\n\n### Key Characteristics of Association:\n- Represents a **uses-a** or **knows-a** relationship.\n- Objects in an association **can exist independently**.\n- Can be **unidirectional** or **bidirectional**.\n- Promotes **modularity** and **code reusability**.\n\n### Example: A Student and a Teacher\n\nA `Student` can be associated with multiple `Teacher` objects, and a `Teacher` can have multiple `Student` objects. This represents a **many-to-many** association.\n\n```java\nimport java.util.*;\n\nclass Teacher {\n    private String name;\n    private List<Student> students;\n    \n    public Teacher(String name) {\n        this.name = name;\n        this.students = new ArrayList<>();\n    }\n    \n    public void addStudent(Student student) {\n        students.add(student);\n    }\n    \n    public void showStudents() {\n        System.out.println(name + \" teaches:\");\n        for (Student student : students) {\n            System.out.println(\" - \" + student.getName());\n        }\n    }\n    \n    public String getName() {\n        return name;\n    }\n}\n\nclass Student {\n    private String name;\n    \n    public Student(String name) {\n        this.name = name;\n    }\n    \n    public String getName() {\n        return name;\n    }\n}\n\npublic class AssociationExample {\n    public static void main(String[] args) {\n        Teacher teacher1 = new Teacher(\"Mr. Smith\");\n        Teacher teacher2 = new Teacher(\"Mrs. Johnson\");\n        \n        Student student1 = new Student(\"Alice\");\n        Student student2 = new Student(\"Bob\");\n        \n        teacher1.addStudent(student1);\n        teacher1.addStudent(student2);\n        teacher2.addStudent(student2);\n        \n        teacher1.showStudents();\n        teacher2.showStudents();\n    }\n}\n```\n\n### Output:\n```\nMr. Smith teaches:\n - Alice\n - Bob\nMrs. Johnson teaches:\n - Bob\n```\n\n---\n\n## Types of Association\n\n### 1. **One-to-One Association**\n   - Each object of class A is associated with one object of class B.\n   - Example: A `Person` has one `Passport`.\n\n### 2. **One-to-Many Association**\n   - One object of class A can be associated with multiple objects of class B.\n   - Example: A `Teacher` teaches multiple `Students`.\n\n### 3. **Many-to-One Association**\n   - Multiple objects of class A can be associated with one object of class B.\n   - Example: Multiple `Students` belong to one `School`.\n\n### 4. **Many-to-Many Association**\n   - Multiple objects of class A can be associated with multiple objects of class B.\n   - Example: `Teachers` and `Students` (a student can have multiple teachers, and a teacher can have multiple students).\n\n---\n\n## Why Use Association?\n\n### 1. **Promotes Code Reusability**\n   - Objects can be reused across multiple associations without duplication.\n\n### 2. **Encourages Loose Coupling**\n   - Objects interact without depending on the internal implementation of each other.\n\n### 3. **Improves Maintainability**\n   - Changing one object does not heavily impact others, making code easier to manage.\n\n### 4. **Better System Design**\n   - Allows modeling of real-world relationships between entities effectively.\n\n---\n\n## Association vs Aggregation vs Composition\n\n| Feature       | Association | Aggregation | Composition |\n|--------------|------------|------------|------------|\n| Relationship | \"Knows-a\"  | \"Has-a\"    | \"Has-a\"    |\n| Object Independence | Objects are independent | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime | Objects exist separately | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example | Teacher and Student | University and Professors | Car and Engine |\n\n---\n\n## Bidirectional Association\n\nAssociations can be **unidirectional** (one object knows about another) or **bidirectional** (both objects know about each other).\n\n### Example: A Library and Books (Bidirectional Association)\n\n```java\nimport java.util.*;\n\nclass Book {\n    private String title;\n    private Library library;\n    \n    public Book(String title, Library library) {\n        this.title = title;\n        this.library = library;\n    }\n    \n    public void showLibrary() {\n        System.out.println(title + \" is in \" + library.getName());\n    }\n    \n    public String getTitle() {\n        return title;\n    }\n}\n\nclass Library {\n    private String name;\n    private List<Book> books;\n    \n    public Library(String name) {\n        this.name = name;\n        this.books = new ArrayList<>();\n    }\n    \n    public void addBook(Book book) {\n        books.add(book);\n    }\n    \n    public String getName() {\n        return name;\n    }\n    \n    public void showBooks() {\n        System.out.println(\"Books in \" + name + \":\");\n        for (Book book : books) {\n            System.out.println(\" - \" + book.getTitle());\n        }\n    }\n}\n\npublic class BidirectionalAssociationExample {\n    public static void main(String[] args) {\n        Library library = new Library(\"City Library\");\n        Book book1 = new Book(\"1984\", library);\n        Book book2 = new Book(\"Brave New World\", library);\n        \n        library.addBook(book1);\n        library.addBook(book2);\n        \n        library.showBooks();\n        book1.showLibrary();\n        book2.showLibrary();\n    }\n}\n```\n\n### Output:\n```\nBooks in City Library:\n - 1984\n - Brave New World\n1984 is in City Library\nBrave New World is in City Library\n```"
  },
  {
    "path": "oop/java/classesandobjects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nA class is a blueprint or template. It defines the attributes (fields) and behaviors (methods) of an object.\n\n### Defining a Class in Java\n\nTo define a class in Java, you use the `class` keyword followed by the name of the class. \n\nHere's a simple example:\n\n```java\npublic class Car {\n    // Attributes\n    private String color;\n    private String make;\n    private String model;\n    private int year;\n\n    // Constructor\n    public Car(String color, String make, String model, int year) {\n        this.color = color;\n        this.make = make;\n        this.model = model;\n        this.year = year;\n    }\n\n    // Method to display car details\n    public void displayInfo() {\n        System.out.println(\"Car Make: \" + make);\n        System.out.println(\"Car Model: \" + model);\n        System.out.println(\"Car Year: \" + year);\n        System.out.println(\"Car Color: \" + color);\n    }\n}\n```\n- **Attributes**: The class `Car` has four attributes that describe its state: `color`, `make`, `model`, and `year`.\n- **Constructor**: The constructor `Car(String color, String make, String model, int year)` initializes new objects of the class.\n- **Methods**: The `displayInfo` method is responsible for showcasing the car details.\n\n## What is an Object?\n\nAn object is an instance of a class. When you create an object, you are bringing the blueprint of the class into reality. It consists of state and behavior defined by the class, with each object holding its own copy of the data.\n\n### Creating Objects in Java\n\nTo create an object, you use the `new` keyword followed by the class constructor. \n\nHere's how you can instantiate objects from the `Car` class:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        // Creating an object of the Car class\n        Car car1 = new Car(\"Red\", \"Toyota\", \"Corolla\", 2020);\n        Car car2 = new Car(\"Blue\", \"Ford\", \"Mustang\", 2021);\n\n        // Displaying information of each car\n        car1.displayInfo();\n        System.out.println(\"-----------------\");\n        car2.displayInfo();\n    }\n}\n```\n\n1. **Instantiation**: The `new` keyword is used to create an object, which allocates memory for it.\n2. **Initialization**: The constructor (`Car`) initializes the object state with given parameters.\n3. **Reference**: The object is referenced through a variable (`car1`, `car2`) that points to its memory location."
  },
  {
    "path": "oop/java/composition/README.md",
    "content": "# Composition in Java\n\n## Introduction\n\nComposition is one of the key concepts of object-oriented programming (OOP). It allows objects to be built using other objects, promoting code reuse, flexibility, and better maintainability. Unlike inheritance, which establishes an \"is-a\" relationship, composition represents a \"has-a\" relationship.\n\n## What is Composition?\n\nComposition is a design principle in OOP where one class contains an instance (or instances) of another class as a field. The contained class is often called a component, and the containing class is referred to as a composite class. This helps in building complex systems by combining simpler objects.\n\n### Example: A Car and its Components\n\nConsider a `Car` that consists of multiple components like an `Engine`, `Wheel`, and `Transmission`. Instead of inheriting from these components, a `Car` object will contain them as fields.\n\n```java\nclass Engine {\n    private int horsepower;\n\n    public Engine(int horsepower) {\n        this.horsepower = horsepower;\n    }\n\n    public void start() {\n        System.out.println(\"Engine started with \" + horsepower + \" HP.\");\n    }\n}\n\nclass Wheel {\n    private String type;\n\n    public Wheel(String type) {\n        this.type = type;\n    }\n\n    public void rotate() {\n        System.out.println(\"The \" + type + \" wheel is rotating.\");\n    }\n}\n\nclass Transmission {\n    private String type;\n\n    public Transmission(String type) {\n        this.type = type;\n    }\n\n    public void shiftGear() {\n        System.out.println(\"Transmission shifted: \" + type);\n    }\n}\n\nclass Car {\n    private Engine engine;\n    private Wheel wheel;\n    private Transmission transmission;\n\n    public Car(Engine engine, Wheel wheel, Transmission transmission) {\n        this.engine = engine;\n        this.wheel = wheel;\n        this.transmission = transmission;\n    }\n\n    public void drive() {\n        engine.start();\n        wheel.rotate();\n        transmission.shiftGear();\n        System.out.println(\"Car is moving!\");\n    }\n}\n\npublic class CompositionExample {\n    public static void main(String[] args) {        \n        Car car = new Car(new Engine(150), new Wheel(\"Alloy\"), new Transmission(\"Automatic\"));\n        car.drive();\n    }\n}\n```\n\n### Output:\n```\nEngine started with 150 HP.\nThe Alloy wheel is rotating.\nTransmission shifted: Automatic\nCar is moving!\n```\n\n---\n\n## Why Prefer Composition Over Inheritance?\n\n### 1. **Encapsulation and Flexibility**\n   - Composition allows us to change the behavior of an object dynamically by replacing components at runtime.\n   - Inheritance makes it difficult to modify an existing class hierarchy without breaking existing code.\n\n### 2. **Better Code Reusability**\n   - Composition promotes reusable components. The `Engine`, `Wheel`, and `Transmission` classes can be used in multiple types of vehicles (Car, Bike, Truck) without modification.\n\n### 3. **Avoids Inheritance Pitfalls**\n   - Inheritance can lead to deep class hierarchies, making maintenance difficult.\n   - It enforces strict parent-child relationships, which can be too rigid for some designs.\n\n### 4. **Supports Interface-Based Design**\n   - Composition can be combined with interfaces to achieve powerful decoupling.\n\n---\n\n## Composition with Interfaces\n\nUsing interfaces with composition allows for greater flexibility and loose coupling.\n\n```java\ninterface Engine {\n    void start();\n}\n\nclass PetrolEngine implements Engine {\n    public void start() {\n        System.out.println(\"Petrol Engine started.\");\n    }\n}\n\nclass DieselEngine implements Engine {\n    public void start() {\n        System.out.println(\"Diesel Engine started.\");\n    }\n}\n\nclass Car {\n    private Engine engine;\n\n    public Car(Engine engine) {\n        this.engine = engine;\n    }\n\n    public void startCar() {\n        engine.start();\n        System.out.println(\"Car is ready to go!\");\n    }\n}\n\npublic class InterfaceCompositionExample {\n    public static void main(String[] args) {\n        Car petrolCar = new Car(new PetrolEngine());\n        petrolCar.startCar();\n        \n        Car dieselCar = new Car(new DieselEngine());\n        dieselCar.startCar();\n    }\n}\n```\n\n### Output:\n```\nPetrol Engine started.\nCar is ready to go!\nDiesel Engine started.\nCar is ready to go!\n```\n\n---\n\n## When to Use Composition?\n\n- When building complex objects that consist of multiple components.\n- When you want to achieve **code reusability** without rigid inheritance hierarchies.\n- When different behaviors need to be swapped dynamically (e.g., using different types of engines in a vehicle).\n- When following the **favor composition over inheritance** principle."
  },
  {
    "path": "oop/java/encapsulation/README.md",
    "content": "# Encapsulation in Java\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of Object-Oriented Programming (OOP). It is the practice of **bundling data (variables) and methods** that operate on that data into a single unit (class) while restricting direct access to the internal details.\n\nEncapsulation in Java is achieved using:\n1. **Access Modifiers** (`private`, `protected`, `public`)\n2. **Getters and Setters**\n3. **Data Hiding**\n\nEncapsulation helps in **data protection, modularity, and maintainability** of the code.\n\n---\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** the data (variables) and code (methods) together into a single unit (class). It restricts direct access to some of an object's components, which helps protect data integrity and prevents unintended modifications.\n\n### **Key Benefits of Encapsulation**\n- **Data Hiding**: Prevents direct access to sensitive data.\n- **Increased Security**: Controls how data is accessed and modified.\n- **Improved Code Maintainability**: Allows changes without affecting other parts of the code.\n- **Better Modularity**: Organizes the code into logical components.\n\n---\n\n## **Encapsulation Using Access Modifiers**\n\nJava provides **access modifiers** to enforce encapsulation:\n- **`private`**: Accessible only within the same class.\n- **`protected`**: Accessible within the same package and subclasses.\n- **`public`**: Accessible from anywhere.\n\n### **Example: Encapsulation with Private Variables**\n\n```java\n// Class with encapsulated data\nclass BankAccount {\n    private String accountHolder;\n    private double balance;\n\n    // Constructor\n    public BankAccount(String accountHolder, double balance) {\n        this.accountHolder = accountHolder;\n        this.balance = balance;\n    }\n\n    // Getter method to access balance\n    public double getBalance() {\n        return balance;\n    }\n\n    // Setter method to modify balance\n    public void deposit(double amount) {\n        if (amount > 0) {\n            balance += amount;\n            System.out.println(\"Deposited: \" + amount);\n        } else {\n            System.out.println(\"Invalid deposit amount\");\n        }\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        BankAccount account = new BankAccount(\"Alice\", 1000);\n        System.out.println(\"Current Balance: \" + account.getBalance());\n        account.deposit(500);\n        System.out.println(\"Updated Balance: \" + account.getBalance());\n    }\n}\n```\n\n### **Output:**\n```\nCurrent Balance: 1000.0\nDeposited: 500.0\nUpdated Balance: 1500.0\n```\n\n**Why Use Encapsulation?**\n- Prevents unauthorized access to the data.\n- Allows controlled modifications through methods.\n\n---\n\n## **Encapsulation Using Getters and Setters**\n\nEncapsulation ensures that **data cannot be directly accessed** but must be retrieved or modified through methods.\n\n### **Example: Getters and Setters in Java**\n\n```java\nclass Employee {\n    private String name;\n    private int age;\n\n    // Getter method\n    public String getName() {\n        return name;\n    }\n\n    // Setter method\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getAge() {\n        return age;\n    }\n\n    public void setAge(int age) {\n        if (age > 18) {\n            this.age = age;\n        } else {\n            System.out.println(\"Age must be greater than 18\");\n        }\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Employee emp = new Employee();\n        emp.setName(\"John Doe\");\n        emp.setAge(25);\n        System.out.println(\"Employee Name: \" + emp.getName());\n        System.out.println(\"Employee Age: \" + emp.getAge());\n    }\n}\n```\n\n### **Output:**\n```\nEmployee Name: John Doe\nEmployee Age: 25\n```\n\n---\n\n## **Encapsulation and Data Hiding**\n\nEncapsulation helps **hide implementation details** while exposing only necessary methods.\n\n### **Example: Hiding Implementation Details**\n\n```java\nclass Account {\n    private double balance;\n\n    public Account(double initialBalance) {\n        this.balance = initialBalance;\n    }\n\n    private boolean validateWithdrawal(double amount) {\n        return amount > 0 && amount <= balance;\n    }\n\n    public void withdraw(double amount) {\n        if (validateWithdrawal(amount)) {\n            balance -= amount;\n            System.out.println(\"Withdrawal Successful: \" + amount);\n        } else {\n            System.out.println(\"Insufficient balance or invalid amount\");\n        }\n    }\n\n    public double getBalance() {\n        return balance;\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Account myAccount = new Account(1000);\n        myAccount.withdraw(300);\n        System.out.println(\"Remaining Balance: \" + myAccount.getBalance());\n    }\n}\n```\n\n### **Output:**\n```\nWithdrawal Successful: 300.0\nRemaining Balance: 700.0\n```\n\n**Why Hide Data?**\n- Prevents direct modification of important fields.\n- Ensures data integrity by validating inputs.\n\n---\n\n## **Encapsulation in Real-World Applications**\n\nEncapsulation is used in many real-world applications such as:\n1. **Banking Systems** - Ensuring account details are private.\n2. **Healthcare Applications** - Protecting patient records.\n3. **E-Commerce Platforms** - Hiding payment processing details.\n\n### **Example: Encapsulation in Payment Processing**\n\n```java\nclass PaymentProcessor {\n    private String cardNumber;\n    private double amount;\n\n    public PaymentProcessor(String cardNumber, double amount) {\n        this.cardNumber = maskCardNumber(cardNumber);\n        this.amount = amount;\n    }\n\n    private String maskCardNumber(String cardNumber) {\n        return \"****-****-****-\" + cardNumber.substring(cardNumber.length() - 4);\n    }\n\n    public void processPayment() {\n        System.out.println(\"Processing payment of \" + amount + \" for card \" + cardNumber);\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        PaymentProcessor payment = new PaymentProcessor(\"1234567812345678\", 250.00);\n        payment.processPayment();\n    }\n}\n```\n\n### **Output:**\n```\nProcessing payment of 250.0 for card ****-****-****-5678\n```\n\n**Why Use Encapsulation in Payment Processing?**\n- Protects sensitive data (e.g., credit card numbers).\n- Hides unnecessary details from users.\n- Ensures secure transactions."
  },
  {
    "path": "oop/java/inheritance/README.md",
    "content": "# Inheritance in Object-Oriented Programming (OOP)\n\n## Introduction\n\n**Inheritance** is one of the core principles of Object-Oriented Programming (OOP). It allows a class (subclass or child class) to acquire the properties and behaviors of another class (superclass or parent class). This promotes **code reuse**, **scalability**, and **maintainability**.\n\n## **What is Inheritance?**\n\n**Inheritance** is a mechanism where a child class derives properties and behaviors from a parent class. The child class can:\n\n- Use the fields and methods of the parent class\n- Override parent class methods to provide a specific implementation\n- Add its own additional properties and methods\n\n### **Key Benefits of Inheritance**\n\n- **Code Reusability**: Avoids code duplication by reusing fields and methods of the parent class.\n- **Improves Maintainability**: Reduces redundancy, making code easier to manage.\n- **Enhances Extensibility**: New functionality can be added easily without modifying existing code.\n\n---\n\n## **How to Implement Inheritance in Java**\n\n### **Step 1: Create a Parent Class**\n\nThe parent class contains common fields and methods.\n\n```java\n// Parent class\npublic class Animal {\n    String name;\n\n    void eat() {\n        System.out.println(name + \" is eating...\");\n    }\n}\n```\n\n### **Step 2: Create a Child Class using `extends`**\n\nThe child class inherits the properties and methods of the parent class.\n\n```java\n// Child class\npublic class Dog extends Animal {\n    void bark() {\n        System.out.println(name + \" is barking...\");\n    }\n}\n```\n\n### **Step 3: Use the Child Class**\n\nNow, let's create an object and use the inherited methods.\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Dog myDog = new Dog();\n        myDog.name = \"Buddy\";\n        myDog.eat(); // Inherited from Animal class\n        myDog.bark(); // Defined in Dog class\n    }\n}\n```\n\n### **Output:**\n\n```\nBuddy is eating...\nBuddy is barking...\n```\n\n---\n\n## **Types of Inheritance in Java**\n\nJava supports different types of inheritance:\n\n### **1. Single Inheritance**\n\nA subclass inherits from one superclass.\n\n```java\nclass Parent {\n    void show() {\n        System.out.println(\"This is the parent class\");\n    }\n}\n\nclass Child extends Parent {\n    void display() {\n        System.out.println(\"This is the child class\");\n    }\n}\n```\n\n### **2. Multilevel Inheritance**\n\nA subclass inherits from another subclass, forming a chain.\n\n```java\nclass Grandparent {\n    void show() {\n        System.out.println(\"Grandparent class\");\n    }\n}\n\nclass Parent extends Grandparent {\n    void display() {\n        System.out.println(\"Parent class\");\n    }\n}\n\nclass Child extends Parent {\n    void print() {\n        System.out.println(\"Child class\");\n    }\n}\n```\n\n### **3. Hierarchical Inheritance**\n\nA single parent class has multiple child classes.\n\n```java\nclass Parent {\n    void show() {\n        System.out.println(\"Parent class\");\n    }\n}\n\nclass Child1 extends Parent {\n    void display() {\n        System.out.println(\"Child1 class\");\n    }\n}\n\nclass Child2 extends Parent {\n    void print() {\n        System.out.println(\"Child2 class\");\n    }\n}\n```\n\n**Note:** Java **does not support multiple inheritance** (i.e., a child class inheriting from multiple parents) due to ambiguity problems.\n\n---\n\n## **Method Overriding in Inheritance**\n\nMethod overriding allows a child class to **redefine** a method from the parent class.\n\n```java\nclass Animal {\n    void makeSound() {\n        System.out.println(\"Animal makes a sound\");\n    }\n}\n\nclass Dog extends Animal {\n    @Override\n    void makeSound() {\n        System.out.println(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Animal myAnimal = new Dog(); // Polymorphism\n        myAnimal.makeSound();\n    }\n}\n```\n\n### **Output:**\n\n```\nDog barks\n```\n\n---\n\n## **The `super` Keyword in Inheritance**\n\nThe `super` keyword is used to **refer to the parent class**. It helps to:\n\n1. Call the parent class constructor.\n2. Access the parent class methods.\n3. Access the parent class fields.\n\n```java\nclass Animal {\n    Animal() {\n        System.out.println(\"Animal Constructor\");\n    }\n    void makeSound() {\n        System.out.println(\"Animal makes a sound\");\n    }\n}\n\nclass Dog extends Animal {\n    Dog() {\n        super(); // Calls the parent class constructor\n        System.out.println(\"Dog Constructor\");\n    }\n    void makeSound() {\n        super.makeSound(); // Calls parent method\n        System.out.println(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Dog myDog = new Dog();\n        myDog.makeSound();\n    }\n}\n```\n\n### **Output:**\n\n```\nAnimal Constructor\nDog Constructor\nAnimal makes a sound\nDog barks\n```\n"
  },
  {
    "path": "oop/java/interfaces/README.md",
    "content": "# Interfaces\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **interface** is a crucial concept that defines a contract for classes to follow. It allows multiple classes to share a common structure while enforcing certain behaviors. Interfaces are widely used in Java and other OOP languages to achieve **abstraction, polymorphism, and loose coupling**.\n\n## What is an Interface?\n\nAn **interface** in Java is a collection of abstract methods (methods without implementation) that a class can implement. It defines a contract that the implementing classes must adhere to.\n\n### **Key Characteristics of Interfaces**\n- Defines a **contract** that implementing classes must follow.\n- Cannot have instance variables (only `public static final` constants).\n- All methods are **implicitly public and abstract** (unless they have a default or static implementation).\n- Supports **multiple inheritance**, unlike classes.\n- Improves **code flexibility and testability**.\n\n---\n\n## **Defining and Implementing an Interface in Java**\n\n### **Step 1: Define an Interface**\nTo define an interface, use the `interface` keyword.\n\n```java\n// Defining an interface\npublic interface Vehicle {\n    void start(); // Abstract method (no implementation)\n    void stop();  // Abstract method (no implementation)\n}\n```\n\n### **Step 2: Implement the Interface**\nA class implements an interface using the `implements` keyword.\n\n```java\n// Implementing the Vehicle interface in a Car class\npublic class Car implements Vehicle {\n    @Override\n    public void start() {\n        System.out.println(\"Car is starting...\");\n    }\n    \n    @Override\n    public void stop() {\n        System.out.println(\"Car is stopping...\");\n    }\n}\n```\n\n### **Step 3: Using the Implemented Class**\nNow, let's create objects and call the methods.\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Vehicle myCar = new Car(); // Polymorphism: Interface reference\n        myCar.start();\n        myCar.stop();\n    }\n}\n```\n\n### **Output:**\n```\nCar is starting...\nCar is stopping...\n```\n\n---\n\n## **Multiple Inheritance with Interfaces**\n\nUnlike C++, Java **does not support multiple inheritance** with classes, but it does support **multiple inheritance** with interfaces.\n\n```java\n// First interface\ninterface Flyable {\n    void fly();\n}\n\n// Second interface\ninterface Drivable {\n    void drive();\n}\n\n// Implementing multiple interfaces\npublic class FlyingCar implements Flyable, Drivable {\n    @Override\n    public void fly() {\n        System.out.println(\"FlyingCar is flying...\");\n    }\n    \n    @Override\n    public void drive() {\n        System.out.println(\"FlyingCar is driving...\");\n    }\n}\n```\n\n### **Usage**\n```java\npublic class Main {\n    public static void main(String[] args) {\n        FlyingCar myVehicle = new FlyingCar();\n        myVehicle.fly();\n        myVehicle.drive();\n    }\n}\n```\n\n### **Output:**\n```\nFlyingCar is flying...\nFlyingCar is driving...\n```\n\n---\n\n## **Default and Static Methods in Interfaces**\n\n### **Default Methods**\nJava 8 introduced **default methods** in interfaces, allowing methods with a body.\n\n```java\ninterface Animal {\n    void sound();\n    \n    // Default method with implementation\n    default void sleep() {\n        System.out.println(\"Sleeping...\");\n    }\n}\n\nclass Dog implements Animal {\n    @Override\n    public void sound() {\n        System.out.println(\"Dog barks\");\n    }\n}\n```\n\n### **Usage**\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Dog myDog = new Dog();\n        myDog.sound();\n        myDog.sleep(); // Calling default method\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nSleeping...\n```\n\n### **Static Methods**\nInterfaces can also have **static methods**.\n\n```java\ninterface MathOperations {\n    static int add(int a, int b) {\n        return a + b;\n    }\n}\n```\n\n### **Usage**\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int result = MathOperations.add(5, 10);\n        System.out.println(\"Sum: \" + result);\n    }\n}\n```\n\n### **Output:**\n```\nSum: 15\n```\n\n---\n\n## **Real-World Example: Payment System**\n\n```java\ninterface Payment {\n    void pay(double amount);\n}\n\nclass CreditCardPayment implements Payment {\n    @Override\n    public void pay(double amount) {\n        System.out.println(\"Paid \" + amount + \" using Credit Card\");\n    }\n}\n\nclass PayPalPayment implements Payment {\n    @Override\n    public void pay(double amount) {\n        System.out.println(\"Paid \" + amount + \" using PayPal\");\n    }\n}\n```\n\n### **Usage**\n```java\npublic class Main {\n    public static void main(String[] args) {\n        Payment payment1 = new CreditCardPayment();\n        payment1.pay(100.50);\n        \n        Payment payment2 = new PayPalPayment();\n        payment2.pay(200.75);\n    }\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```\n"
  },
  {
    "path": "oop/java/polymorphism/README.md",
    "content": "# Polymorphism in Java\n\n## Introduction\n\n**Polymorphism** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nPolymorphism in Java can be classified into two types:\n1. **Compile-time Polymorphism (Method Overloading)**\n2. **Run-time Polymorphism (Method Overriding)**\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a method, function, or object to behave differently based on the context. Polymorphism enables **dynamic method resolution** and **method flexibility**, making applications easier to extend and maintain.\n\n### **Key Benefits of Polymorphism**\n- **Code Reusability**: Write a single interface that works for multiple types.\n- **Scalability**: Add new functionalities with minimal code changes.\n- **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **1. Compile-Time Polymorphism (Method Overloading)**\n\nCompile-time polymorphism occurs when multiple methods in the same class share the same name but have **different method signatures** (parameters). The method to be called is determined **at compile time**.\n\n### **Example of Method Overloading**\n\n```java\nclass MathOperations {\n    // Method with two parameters\n    int add(int a, int b) {\n        return a + b;\n    }\n    \n    // Method with three parameters (overloaded)\n    int add(int a, int b, int c) {\n        return a + b + c;\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        MathOperations math = new MathOperations();\n        System.out.println(\"Sum (2 numbers): \" + math.add(5, 10));\n        System.out.println(\"Sum (3 numbers): \" + math.add(5, 10, 15));\n    }\n}\n```\n\n### **Output:**\n```\nSum (2 numbers): 15\nSum (3 numbers): 30\n```\n\n**Why Use Method Overloading?**\n- Provides a cleaner and more intuitive interface.\n- Reduces redundancy by using a single method name for similar operations.\n\n---\n\n## **2. Run-Time Polymorphism (Method Overriding)**\n\nRun-time polymorphism occurs when a subclass provides a **specific implementation** of a method already defined in its parent class. The method to be called is determined **at runtime**.\n\n### **Example of Method Overriding**\n\n```java\nclass Animal {\n    void makeSound() {\n        System.out.println(\"Animal makes a sound\");\n    }\n}\n\nclass Dog extends Animal {\n    @Override\n    void makeSound() {\n        System.out.println(\"Dog barks\");\n    }\n}\n\nclass Cat extends Animal {\n    @Override\n    void makeSound() {\n        System.out.println(\"Cat meows\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Animal myAnimal = new Dog(); // Upcasting\n        myAnimal.makeSound();\n        \n        myAnimal = new Cat(); // Dynamic method dispatch\n        myAnimal.makeSound();\n    }\n}\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Method Overriding?**\n- Enables **dynamic method resolution**.\n- Supports **polymorphic behavior**, where one interface can be used for multiple implementations.\n- Makes code **extensible** by allowing future modifications.\n\n---\n\n## **Using Polymorphism with Interfaces**\n\nPolymorphism is widely used with **interfaces**, allowing multiple classes to share a common contract.\n\n```java\ninterface Vehicle {\n    void start();\n}\n\nclass Car implements Vehicle {\n    public void start() {\n        System.out.println(\"Car is starting...\");\n    }\n}\n\nclass Bike implements Vehicle {\n    public void start() {\n        System.out.println(\"Bike is starting...\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Vehicle myVehicle = new Car();\n        myVehicle.start();\n        \n        myVehicle = new Bike();\n        myVehicle.start();\n    }\n}\n```\n\n### **Output:**\n```\nCar is starting...\nBike is starting...\n```\n\n**Why Use Interfaces with Polymorphism?**\n- Promotes **loose coupling**, making code more flexible.\n- Allows multiple implementations of the same behavior.\n- Enables **dependency injection**, improving testability.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case of polymorphism is in **payment processing**.\n\n```java\ninterface Payment {\n    void pay(double amount);\n}\n\nclass CreditCardPayment implements Payment {\n    @Override\n    public void pay(double amount) {\n        System.out.println(\"Paid \" + amount + \" using Credit Card\");\n    }\n}\n\nclass PayPalPayment implements Payment {\n    @Override\n    public void pay(double amount) {\n        System.out.println(\"Paid \" + amount + \" using PayPal\");\n    }\n}\n\npublic class Main {\n    public static void main(String[] args) {\n        Payment payment;\n        \n        payment = new CreditCardPayment();\n        payment.pay(100.50);\n        \n        payment = new PayPalPayment();\n        payment.pay(200.75);\n    }\n}\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```\n\n**Why Use Polymorphism in Payment Systems?**\n- Allows new payment methods to be added **without modifying existing code**.\n- Provides a **flexible and scalable** design.\n- Improves **code readability and maintainability**."
  },
  {
    "path": "oop/python/abstraction/README.md",
    "content": "# Abstraction in Python\n\n## Introduction\n\n**Abstraction** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows you to hide **implementation details** while exposing only the necessary parts of an object. This helps in reducing complexity and increasing maintainability.\n\nAbstraction in Python is mainly achieved using:\n1. **Abstract Classes**\n2. **Interfaces (via Abstract Base Classes - ABCs)**\n\n## **What is Abstraction?**\n\n**Abstraction** means showing only the **essential details** and hiding the **implementation**. It allows programmers to focus on **what an object does** rather than **how it does it**.\n\n### **Key Benefits of Abstraction**\n- **Reduces complexity**: Hides unnecessary implementation details.\n- **Increases code reusability**: Encourages the reuse of abstracted logic.\n- **Enhances security**: Protects internal object details from unintended modifications.\n- **Improves maintainability**: Makes code easier to manage and update.\n\n---\n\n## **1. Abstraction Using Abstract Classes**\n\nAn **abstract class** in Python is a class that **cannot be instantiated**. It is used to define common behavior that multiple subclasses should implement.\n\nPython provides the `ABC` module to define abstract classes.\n\n### **Example: Abstract Class in Python**\n\n```python\nfrom abc import ABC, abstractmethod\n\n# Abstract class\nclass Vehicle(ABC):\n    def __init__(self, brand):\n        self.brand = brand\n    \n    @abstractmethod\n    def start(self):\n        pass  # Abstract method (must be implemented by subclasses)\n    \n    def display_brand(self):\n        print(f\"Brand: {self.brand}\")\n\n# Subclass implementing the abstract method\nclass Car(Vehicle):\n    def start(self):\n        print(\"Car is starting...\")\n\n# Usage\nmy_car = Car(\"Toyota\")\nmy_car.display_brand()\nmy_car.start()\n```\n\n### **Output:**\n```\nBrand: Toyota\nCar is starting...\n```\n\n**Why Use Abstract Classes?**\n- Allows defining common behavior that subclasses must implement.\n- Enables partial abstraction (can have both abstract and concrete methods).\n- Prevents direct instantiation of base classes.\n\n---\n\n## **2. Abstraction Using Interfaces (Abstract Base Classes - ABCs)**\n\nAn **interface** in Python can be implemented using **Abstract Base Classes (ABCs)**, which enforce method implementation.\n\n### **Example: Interface in Python**\n\n```python\nfrom abc import ABC, abstractmethod\n\n# Defining an interface\nclass Animal(ABC):\n    @abstractmethod\n    def make_sound(self):\n        pass\n\n# Implementing the interface in Dog class\nclass Dog(Animal):\n    def make_sound(self):\n        print(\"Dog barks\")\n\n# Implementing the interface in Cat class\nclass Cat(Animal):\n    def make_sound(self):\n        print(\"Cat meows\")\n\n# Usage\nmy_dog = Dog()\nmy_dog.make_sound()\n\nmy_cat = Cat()\nmy_cat.make_sound()\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Interfaces?**\n- Promotes **full abstraction** (hides all implementation details).\n- Provides a standard way for different classes to implement behaviors.\n\n---\n\n## **Abstract Class vs Interface: Key Differences**\n\n| Feature | Abstract Class | Interface (ABCs) |\n|---------|---------------|------------------|\n| Methods | Can have abstract and concrete methods | Only abstract methods |\n| Fields | Can have instance variables | Should not have instance variables |\n| Constructor | Can have constructors | Cannot have constructors |\n| Multiple Inheritance | Supported | Supported |\n| Access Modifiers | Can have private, protected, public members | Methods are public by default |\n\n---\n\n## **Real-World Example: Payment System**\n\nAbstraction is widely used in real-world applications, such as payment processing.\n\n### **Example: Payment System with Abstraction**\n\n```python\nfrom abc import ABC, abstractmethod\n\n# Abstract class for Payment\nclass Payment(ABC):\n    def __init__(self, amount):\n        self.amount = amount\n    \n    @abstractmethod\n    def pay(self):\n        pass\n\n# Implementing payment methods\nclass CreditCardPayment(Payment):\n    def pay(self):\n        print(f\"Paid {self.amount} using Credit Card\")\n\nclass PayPalPayment(Payment):\n    def pay(self):\n        print(f\"Paid {self.amount} using PayPal\")\n\n# Usage\npayment = CreditCardPayment(150.75)\npayment.pay()\n\npayment = PayPalPayment(200.50)\npayment.pay()\n```\n\n### **Output:**\n```\nPaid 150.75 using Credit Card\nPaid 200.50 using PayPal\n```\n\n**Why Use Abstraction in Payment Systems?**\n- Allows multiple payment methods without modifying existing code.\n- Improves maintainability and scalability.\n- Provides a **common contract** for different payment types."
  },
  {
    "path": "oop/python/aggregation/README.md",
    "content": "# Aggregation in Python\n\n## Introduction\n\nAggregation is a key concept in object-oriented programming (OOP) that represents a \"has-a\" relationship between two classes, but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one class contains another, the contained object can exist independently of the container.\n\nAggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained object cannot exist without the container.\n\n## What is Aggregation?\n\nAggregation is a form of association in OOP where an object of one class contains a reference to an object of another class. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.\n\n### Key Characteristics of Aggregation:\n- Represents a **has-a** relationship.\n- The contained object **can exist independently** of the container.\n- Implemented using references to objects.\n- Promotes **loose coupling** between objects.\n\n### Example: A University and its Professors\n\nConsider a scenario where a `University` contains multiple `Professor` objects. However, a `Professor` can exist independently of any university. This is an example of aggregation.\n\n```python\nclass Professor:\n    def __init__(self, name, subject):\n        self.name = name\n        self.subject = subject\n\n    def teach(self):\n        print(f\"{self.name} is teaching {self.subject}\")\n\n\nclass University:\n    def __init__(self, university_name):\n        self.university_name = university_name\n        self.professors = []\n\n    def add_professor(self, professor):\n        self.professors.append(professor)\n\n    def show_professors(self):\n        print(f\"Professors at {self.university_name}:\")\n        for professor in self.professors:\n            print(f\" - {professor.name}\")\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    prof1 = Professor(\"Dr. Smith\", \"Computer Science\")\n    prof2 = Professor(\"Dr. Johnson\", \"Mathematics\")\n    \n    university = University(\"Harvard University\")\n    university.add_professor(prof1)\n    university.add_professor(prof2)\n    \n    university.show_professors()\n    \n    # Professors can exist independently\n    prof1.teach()\n    prof2.teach()\n```\n\n### Output:\n```\nProfessors at Harvard University:\n - Dr. Smith\n - Dr. Johnson\nDr. Smith is teaching Computer Science\nDr. Johnson is teaching Mathematics\n```\n\n---\n\n## Aggregation vs Composition\n\n| Feature       | Aggregation | Composition |\n|--------------|------------|-------------|\n| Relationship | \"Has-a\"    | \"Has-a\"     |\n| Ownership    | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime     | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example      | University and Professors | Car and Engine |\n\n---\n\n## Why Use Aggregation?\n\n### 1. **Promotes Code Reusability**\n   - Aggregated objects can be used in multiple places without being tightly coupled to a single container class.\n\n### 2. **Encourages Loose Coupling**\n   - Aggregation allows objects to interact without being dependent on the lifecycle of each other.\n\n### 3. **Better Maintainability**\n   - Changes in one class do not heavily impact the other, making the codebase easier to modify and extend.\n\n### 4. **Real-World Applicability**\n   - Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.\n\n---\n\n## Aggregation with Interfaces (Abstract Base Classes)\n\nUsing abstract base classes, we can further enhance the flexibility of aggregation.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Teachable(ABC):\n    @abstractmethod\n    def teach(self):\n        pass\n\n\nclass Professor(Teachable):\n    def __init__(self, name, subject):\n        self.name = name\n        self.subject = subject\n\n    def teach(self):\n        print(f\"{self.name} is teaching {self.subject}\")\n\n\nclass University:\n    def __init__(self, university_name):\n        self.university_name = university_name\n        self.professors = []\n\n    def add_professor(self, professor):\n        self.professors.append(professor)\n\n    def show_professors(self):\n        print(f\"Professors at {self.university_name}:\")\n        for professor in self.professors:\n            professor.teach()\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    prof1 = Professor(\"Dr. Adams\", \"Physics\")\n    prof2 = Professor(\"Dr. Lee\", \"Chemistry\")\n    \n    university = University(\"MIT\")\n    university.add_professor(prof1)\n    university.add_professor(prof2)\n    \n    university.show_professors()\n```\n\n### Output:\n```\nProfessors at MIT:\nDr. Adams is teaching Physics\nDr. Lee is teaching Chemistry\n```\n\n---\n\n## When to Use Aggregation?\n\n- When an object **can exist independently** from the container.\n- When designing **loosely coupled** systems.\n- When different objects need to be **shared** across multiple containers.\n- When following **SOLID principles**, particularly the **Dependency Inversion Principle (DIP)**."
  },
  {
    "path": "oop/python/association/README.md",
    "content": "# Association in Python\n\n## Introduction\n\nAssociation is a key concept in object-oriented programming (OOP) that defines a relationship between two or more objects. It represents how objects interact with each other while maintaining their independence.\n\nAssociation is **not inheritance**—rather, it is a relationship between objects that allows communication while ensuring they remain loosely coupled.\n\n## What is Association?\n\nAssociation defines a connection between two classes, where one class is linked to another. The association can be **one-to-one**, **one-to-many**, **many-to-one**, or **many-to-many**. Objects in an association can exist independently of each other.\n\n### Key Characteristics of Association:\n- Represents a **uses-a** or **knows-a** relationship.\n- Objects in an association **can exist independently**.\n- Can be **unidirectional** or **bidirectional**.\n- Promotes **modularity** and **code reusability**.\n\n### Example: A Student and a Teacher\n\nA `Student` can be associated with multiple `Teacher` objects, and a `Teacher` can have multiple `Student` objects. This represents a **many-to-many** association.\n\n```python\nclass Teacher:\n    def __init__(self, name):\n        self.name = name\n        self.students = []\n    \n    def add_student(self, student):\n        self.students.append(student)\n    \n    def show_students(self):\n        print(f\"{self.name} teaches:\")\n        for student in self.students:\n            print(f\" - {student.name}\")\n\nclass Student:\n    def __init__(self, name):\n        self.name = name\n\n# Example Usage\nif __name__ == \"__main__\":\n    teacher1 = Teacher(\"Mr. Smith\")\n    teacher2 = Teacher(\"Mrs. Johnson\")\n    \n    student1 = Student(\"Alice\")\n    student2 = Student(\"Bob\")\n    \n    teacher1.add_student(student1)\n    teacher1.add_student(student2)\n    teacher2.add_student(student2)\n    \n    teacher1.show_students()\n    teacher2.show_students()\n```\n\n### Output:\n```\nMr. Smith teaches:\n - Alice\n - Bob\nMrs. Johnson teaches:\n - Bob\n```\n\n---\n\n## Types of Association\n\n### 1. **One-to-One Association**\n   - Each object of class A is associated with one object of class B.\n   - Example: A `Person` has one `Passport`.\n\n### 2. **One-to-Many Association**\n   - One object of class A can be associated with multiple objects of class B.\n   - Example: A `Teacher` teaches multiple `Students`.\n\n### 3. **Many-to-One Association**\n   - Multiple objects of class A can be associated with one object of class B.\n   - Example: Multiple `Students` belong to one `School`.\n\n### 4. **Many-to-Many Association**\n   - Multiple objects of class A can be associated with multiple objects of class B.\n   - Example: `Teachers` and `Students`.\n\n---\n\n## Why Use Association?\n\n- **Promotes Code Reusability**: Objects can be reused across multiple associations without duplication.\n- **Encourages Loose Coupling**: Objects interact without depending on the internal implementation of each other.\n- **Improves Maintainability**: Changing one object does not heavily impact others, making code easier to manage.\n- **Better System Design**: Allows modeling of real-world relationships between entities effectively.\n\n---\n\n## Association vs Aggregation vs Composition\n\n| Feature       | Association | Aggregation | Composition |\n|--------------|------------|------------|------------|\n| Relationship | \"Knows-a\"  | \"Has-a\"    | \"Has-a\"    |\n| Object Independence | Objects are independent | Contained object **can exist independently** | Contained object **cannot exist without** the container |\n| Lifetime | Objects exist separately | Contained object **outlives** the container | Contained object **is destroyed** with the container |\n| Example | Teacher and Student | University and Professors | Car and Engine |\n\n---\n\n## Bidirectional Association\n\nAssociations can be **unidirectional** (one object knows about another) or **bidirectional** (both objects know about each other).\n\n### Example: A Library and Books (Bidirectional Association)\n\n```python\nclass Library:\n    def __init__(self, name):\n        self.name = name\n        self.books = []\n    \n    def add_book(self, book):\n        self.books.append(book)\n    \n    def show_books(self):\n        print(f\"Books in {self.name}:\")\n        for book in self.books:\n            print(f\" - {book.title}\")\n\nclass Book:\n    def __init__(self, title, library):\n        self.title = title\n        self.library = library\n    \n    def show_library(self):\n        print(f\"{self.title} is in {self.library.name}\")\n\n# Example Usage\nif __name__ == \"__main__\":\n    library = Library(\"City Library\")\n    book1 = Book(\"1984\", library)\n    book2 = Book(\"Brave New World\", library)\n    \n    library.add_book(book1)\n    library.add_book(book2)\n    \n    library.show_books()\n    book1.show_library()\n    book2.show_library()\n```\n\n### Output:\n```\nBooks in City Library:\n - 1984\n - Brave New World\n1984 is in City Library\nBrave New World is in City Library\n```"
  },
  {
    "path": "oop/python/classesandobjects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nA class is a blueprint or template. It defines the attributes (fields) and behaviors (methods) of an object.\n\n### Defining a Class in Python\n\nTo define a class in Python, you use the `class` keyword followed by the name of the class. \n\nHere's a simple example:\n\n```python\nclass Car:\n    # Constructor\n    def __init__(self, color, make, model, year):\n        self.color = color\n        self.make = make\n        self.model = model\n        self.year = year\n\n    # Method to display car details\n    def display_info(self):\n        print(f\"Car Make: {self.make}\")\n        print(f\"Car Model: {self.model}\")\n        print(f\"Car Year: {self.year}\")\n        print(f\"Car Color: {self.color}\")\n```\n- **Attributes**: The class `Car` has four attributes that describe its state: `color`, `make`, `model`, and `year`.\n- **Constructor**: The constructor `__init__(self, color, make, model, year)` initializes new objects of the class.\n- **Methods**: The `display_info` method is responsible for showcasing the car details.\n\n## What is an Object?\n\nAn object is an instance of a class. When you create an object, you are bringing the blueprint of the class into reality. It consists of state and behavior defined by the class, with each object holding its own copy of the data.\n\n### Creating Objects in Python\n\nTo create an object, you call the class constructor. \n\nHere's how you can instantiate objects from the `Car` class:\n\n```python\ncar1 = Car(\"Red\", \"Toyota\", \"Corolla\", 2020)\ncar2 = Car(\"Blue\", \"Ford\", \"Mustang\", 2021)\n\n# Displaying information of each car\ncar1.display_info()\nprint(\"-----------------\")\ncar2.display_info()\n```\n\n1. **Initialization**: The constructor (`Car`) initializes the object state with given parameters.\n2. **Reference**: The object is referenced through a variable (`car1`, `car2`) that points to its memory location."
  },
  {
    "path": "oop/python/composition/README.md",
    "content": "# Composition in Python\n\n## Introduction\n\nComposition is one of the key concepts of object-oriented programming (OOP). It allows objects to be built using other objects, promoting code reuse, flexibility, and better maintainability. Unlike inheritance, which establishes an \"is-a\" relationship, composition represents a \"has-a\" relationship.\n\n## What is Composition?\n\nComposition is a design principle in OOP where one class contains an instance (or instances) of another class as a field. The contained class is often called a component, and the containing class is referred to as a composite class. This helps in building complex systems by combining simpler objects.\n\n### Example: A Car and its Components\n\nConsider a `Car` that consists of multiple components like an `Engine`, `Wheel`, and `Transmission`. Instead of inheriting from these components, a `Car` object will contain them as fields.\n\n```python\nclass Engine:\n    def __init__(self, horsepower):\n        self.horsepower = horsepower\n\n    def start(self):\n        print(f\"Engine started with {self.horsepower} HP.\")\n\n\nclass Wheel:\n    def __init__(self, type):\n        self.type = type\n\n    def rotate(self):\n        print(f\"The {self.type} wheel is rotating.\")\n\n\nclass Transmission:\n    def __init__(self, type):\n        self.type = type\n\n    def shift_gear(self):\n        print(f\"Transmission shifted: {self.type}\")\n\n\nclass Car:\n    def __init__(self):\n        self.engine = Engine(150)\n        self.wheel = Wheel(\"Alloy\")\n        self.transmission = Transmission(\"Automatic\")\n\n    def drive(self):\n        self.engine.start()\n        self.wheel.rotate()\n        self.transmission.shift_gear()\n        print(\"Car is moving!\")\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    car = Car()\n    car.drive()\n```\n\n### Output:\n```\nEngine started with 150 HP.\nThe Alloy wheel is rotating.\nTransmission shifted: Automatic\nCar is moving!\n```\n\n---\n\n## Why Prefer Composition Over Inheritance?\n\n### 1. **Encapsulation and Flexibility**\n   - Composition allows us to change the behavior of an object dynamically by replacing components at runtime.\n   - Inheritance makes it difficult to modify an existing class hierarchy without breaking existing code.\n\n### 2. **Better Code Reusability**\n   - Composition promotes reusable components. The `Engine`, `Wheel`, and `Transmission` classes can be used in multiple types of vehicles (Car, Bike, Truck) without modification.\n\n### 3. **Avoids Inheritance Pitfalls**\n   - Inheritance can lead to deep class hierarchies, making maintenance difficult.\n   - It enforces strict parent-child relationships, which can be too rigid for some designs.\n\n### 4. **Supports Interface-Based Design**\n   - Composition can be combined with interfaces (or abstract classes) to achieve powerful decoupling.\n\n---\n\n## Composition with Abstract Classes\n\nUsing abstract base classes with composition allows for greater flexibility and loose coupling.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Engine(ABC):\n    @abstractmethod\n    def start(self):\n        pass\n\n\nclass PetrolEngine(Engine):\n    def start(self):\n        print(\"Petrol Engine started.\")\n\n\nclass DieselEngine(Engine):\n    def start(self):\n        print(\"Diesel Engine started.\")\n\n\nclass Car:\n    def __init__(self, engine: Engine):\n        self.engine = engine\n    \n    def start_car(self):\n        self.engine.start()\n        print(\"Car is ready to go!\")\n\n\n# Example Usage\nif __name__ == \"__main__\":\n    petrol_car = Car(PetrolEngine())\n    petrol_car.start_car()\n    \n    diesel_car = Car(DieselEngine())\n    diesel_car.start_car()\n```\n\n### Output:\n```\nPetrol Engine started.\nCar is ready to go!\nDiesel Engine started.\nCar is ready to go!\n```\n\n---\n\n## When to Use Composition?\n\n- When building complex objects that consist of multiple components.\n- When you want to achieve **code reusability** without rigid inheritance hierarchies.\n- When different behaviors need to be swapped dynamically (e.g., using different types of engines in a vehicle).\n- When following the **favor composition over inheritance** principle."
  },
  {
    "path": "oop/python/encapsulation/README.md",
    "content": "# Encapsulation in Python\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of Object-Oriented Programming (OOP). It is the practice of **bundling data (variables) and methods** that operate on that data into a single unit (class) while restricting direct access to the internal details.\n\nEncapsulation in Python is achieved using:\n1. **Access Modifiers** (`public`, `_protected`, `__private`)\n2. **Getters and Setters**\n3. **Data Hiding**\n\nEncapsulation helps in **data protection, modularity, and maintainability** of the code.\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** the data (variables) and code (methods) together into a single unit (class). It restricts direct access to some of an object's components, which helps protect data integrity and prevents unintended modifications.\n\n### **Key Benefits of Encapsulation**\n- **Data Hiding**: Prevents direct access to sensitive data.\n- **Increased Security**: Controls how data is accessed and modified.\n- **Improved Code Maintainability**: Allows changes without affecting other parts of the code.\n- **Better Modularity**: Organizes the code into logical components.\n\n---\n\n## **Encapsulation Using Access Modifiers**\n\nPython provides **access modifiers** to enforce encapsulation:\n- **`public`**: Accessible from anywhere.\n- **`_protected`**: Accessible within the class and subclasses.\n- **`__private`**: Accessible only within the class.\n\n### **Example: Encapsulation with Private Variables**\n\n```python\nclass BankAccount:\n    def __init__(self, account_holder, balance):\n        self.__account_holder = account_holder  # Private attribute\n        self.__balance = balance  # Private attribute\n\n    # Getter method to access balance\n    def get_balance(self):\n        return self.__balance\n\n    # Setter method to modify balance\n    def deposit(self, amount):\n        if amount > 0:\n            self.__balance += amount\n            print(f\"Deposited: {amount}\")\n        else:\n            print(\"Invalid deposit amount\")\n\n# Usage\naccount = BankAccount(\"Alice\", 1000)\nprint(\"Current Balance:\", account.get_balance())\naccount.deposit(500)\nprint(\"Updated Balance:\", account.get_balance())\n```\n\n### **Output:**\n```\nCurrent Balance: 1000\nDeposited: 500\nUpdated Balance: 1500\n```\n\n**Why Use Encapsulation?**\n- Prevents unauthorized access to the data.\n- Allows controlled modifications through methods.\n\n---\n\n## **Encapsulation Using Getters and Setters**\n\nEncapsulation ensures that **data cannot be directly accessed** but must be retrieved or modified through methods.\n\n### **Example: Getters and Setters in Python**\n\n```python\nclass Employee:\n    def __init__(self):\n        self.__name = \"\"\n        self.__age = 0\n\n    # Getter method\n    def get_name(self):\n        return self.__name\n\n    # Setter method\n    def set_name(self, name):\n        self.__name = name\n\n    def get_age(self):\n        return self.__age\n\n    def set_age(self, age):\n        if age > 18:\n            self.__age = age\n        else:\n            print(\"Age must be greater than 18\")\n\n# Usage\nemp = Employee()\nemp.set_name(\"John Doe\")\nemp.set_age(25)\nprint(\"Employee Name:\", emp.get_name())\nprint(\"Employee Age:\", emp.get_age())\n```\n\n### **Output:**\n```\nEmployee Name: John Doe\nEmployee Age: 25\n```\n\n---\n\n## **Encapsulation and Data Hiding**\n\nEncapsulation helps **hide implementation details** while exposing only necessary methods.\n\n### **Example: Hiding Implementation Details**\n\n```python\nclass Account:\n    def __init__(self, initial_balance):\n        self.__balance = initial_balance\n\n    def __validate_withdrawal(self, amount):\n        return amount > 0 and amount <= self.__balance\n\n    def withdraw(self, amount):\n        if self.__validate_withdrawal(amount):\n            self.__balance -= amount\n            print(f\"Withdrawal Successful: {amount}\")\n        else:\n            print(\"Insufficient balance or invalid amount\")\n\n    def get_balance(self):\n        return self.__balance\n\n# Usage\nmy_account = Account(1000)\nmy_account.withdraw(300)\nprint(\"Remaining Balance:\", my_account.get_balance())\n```\n\n### **Output:**\n```\nWithdrawal Successful: 300\nRemaining Balance: 700\n```\n\n**Why Hide Data?**\n- Prevents direct modification of important fields.\n- Ensures data integrity by validating inputs.\n\n---\n\n## **Encapsulation in Real-World Applications**\n\nEncapsulation is used in many real-world applications such as:\n1. **Banking Systems** - Ensuring account details are private.\n2. **Healthcare Applications** - Protecting patient records.\n3. **E-Commerce Platforms** - Hiding payment processing details.\n\n### **Example: Encapsulation in Payment Processing**\n\n```python\nclass PaymentProcessor:\n    def __init__(self, card_number, amount):\n        self.__card_number = self.__mask_card_number(card_number)\n        self.__amount = amount\n\n    def __mask_card_number(self, card_number):\n        return \"****-****-****-\" + card_number[-4:]\n\n    def process_payment(self):\n        print(f\"Processing payment of {self.__amount} for card {self.__card_number}\")\n\n# Usage\npayment = PaymentProcessor(\"1234567812345678\", 250.00)\npayment.process_payment()\n```\n\n### **Output:**\n```\nProcessing payment of 250.0 for card ****-****-****-5678\n```\n\n**Why Use Encapsulation in Payment Processing?**\n- Protects sensitive data (e.g., credit card numbers).\n- Hides unnecessary details from users.\n- Ensures secure transactions."
  },
  {
    "path": "oop/python/inheritance/README.md",
    "content": "# Inheritance in Python\n\n## Introduction\n\n**Inheritance** is one of the core principles of Object-Oriented Programming (OOP). It allows a class (subclass or child class) to acquire the properties and behaviors of another class (superclass or parent class). This promotes **code reuse**, **scalability**, and **maintainability**.\n\n## **What is Inheritance?**\n\n**Inheritance** is a mechanism where a child class derives properties and behaviors from a parent class. The child class can:\n\n- Use the attributes and methods of the parent class\n- Override parent class methods to provide a specific implementation\n- Add its own additional attributes and methods\n\n### **Key Benefits of Inheritance**\n\n- **Code Reusability**: Avoids code duplication by reusing attributes and methods of the parent class.\n- **Improves Maintainability**: Reduces redundancy, making code easier to manage.\n- **Enhances Extensibility**: New functionality can be added easily without modifying existing code.\n\n---\n\n## **How to Implement Inheritance in Python**\n\n### **Step 1: Create a Parent Class**\n\nThe parent class contains common attributes and methods.\n\n```python\n# Parent class\nclass Animal:\n    def __init__(self, name):\n        self.name = name\n\n    def eat(self):\n        print(f\"{self.name} is eating...\")\n```\n\n### **Step 2: Create a Child Class using Parent Class**\n\nThe child class inherits the properties and methods of the parent class.\n\n```python\n# Child class\nclass Dog(Animal):\n    def bark(self):\n        print(f\"{self.name} is barking...\")\n```\n\n### **Step 3: Use the Child Class**\n\nNow, let's create an object and use the inherited methods.\n\n```python\n# Using the child class\nif __name__ == \"__main__\":\n    my_dog = Dog(\"Buddy\")\n    my_dog.eat()  # Inherited from Animal class\n    my_dog.bark()  # Defined in Dog class\n```\n\n### **Output:**\n\n```\nBuddy is eating...\nBuddy is barking...\n```\n\n---\n\n## **Types of Inheritance in Python**\n\nPython supports different types of inheritance:\n\n### **1. Single Inheritance**\n\nA subclass inherits from one superclass.\n\n```python\nclass Parent:\n    def show(self):\n        print(\"This is the parent class\")\n\nclass Child(Parent):\n    def display(self):\n        print(\"This is the child class\")\n```\n\n### **2. Multilevel Inheritance**\n\nA subclass inherits from another subclass, forming a chain.\n\n```python\nclass Grandparent:\n    def show(self):\n        print(\"Grandparent class\")\n\nclass Parent(Grandparent):\n    def display(self):\n        print(\"Parent class\")\n\nclass Child(Parent):\n    def print_info(self):\n        print(\"Child class\")\n```\n\n### **3. Hierarchical Inheritance**\n\nA single parent class has multiple child classes.\n\n```python\nclass Parent:\n    def show(self):\n        print(\"Parent class\")\n\nclass Child1(Parent):\n    def display(self):\n        print(\"Child1 class\")\n\nclass Child2(Parent):\n    def print_info(self):\n        print(\"Child2 class\")\n```\n\n### **4. Multiple Inheritance**\n\nUnlike Java, Python **supports multiple inheritance**, allowing a subclass to inherit from multiple parent classes.\n\n```python\nclass Parent1:\n    def show1(self):\n        print(\"Parent1 class\")\n\nclass Parent2:\n    def show2(self):\n        print(\"Parent2 class\")\n\nclass Child(Parent1, Parent2):\n    def display(self):\n        print(\"Child class\")\n```\n\n---\n\n## **Method Overriding in Inheritance**\n\nMethod overriding allows a child class to **redefine** a method from the parent class.\n\n```python\nclass Animal:\n    def make_sound(self):\n        print(\"Animal makes a sound\")\n\nclass Dog(Animal):\n    def make_sound(self):\n        print(\"Dog barks\")\n```\n\n### **Usage**\n\n```python\nif __name__ == \"__main__\":\n    my_animal = Dog()  # Polymorphism\n    my_animal.make_sound()\n```\n\n### **Output:**\n\n```\nDog barks\n```\n\n---\n\n## **The `super()` Function in Inheritance**\n\nThe `super()` function is used to **refer to the parent class**. It helps to:\n\n1. Call the parent class constructor.\n2. Access the parent class methods.\n\n```python\nclass Animal:\n    def __init__(self):\n        print(\"Animal Constructor\")\n\n    def make_sound(self):\n        print(\"Animal makes a sound\")\n\nclass Dog(Animal):\n    def __init__(self):\n        super().__init__()  # Calls the parent class constructor\n        print(\"Dog Constructor\")\n\n    def make_sound(self):\n        super().make_sound()  # Calls parent method\n        print(\"Dog barks\")\n```\n\n### **Usage**\n\n```python\nif __name__ == \"__main__\":\n    my_dog = Dog()\n    my_dog.make_sound()\n```\n\n### **Output:**\n\n```\nAnimal Constructor\nDog Constructor\nAnimal makes a sound\nDog barks\n```\n"
  },
  {
    "path": "oop/python/interfaces/README.md",
    "content": "# Interfaces in Python\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **interface** is a crucial concept that defines a contract for classes to follow. It allows multiple classes to share a common structure while enforcing certain behaviors. While Python does not have built-in support for interfaces like Java, it achieves the same functionality using **abstract base classes (ABCs)** from the `abc` module.\n\n## What is an Interface?\n\nAn **interface** is a collection of method definitions that a class must implement. It defines a contract that implementing classes must adhere to.\n\n### **Key Characteristics of Interfaces in Python**\n- Uses the `abc` module to create abstract base classes (ABCs).\n- Defines methods without implementation that must be overridden.\n- Supports **multiple inheritance**, like normal classes.\n- Improves **code flexibility and maintainability**.\n\n---\n\n## **Defining and Implementing an Interface in Python**\n\n### **Step 1: Define an Interface using `ABC`**\nTo define an interface, we use the `ABC` class from the `abc` module.\n\n```python\nfrom abc import ABC, abstractmethod\n\n# Defining an interface\nclass Vehicle(ABC):\n    @abstractmethod\n    def start(self):\n        pass  # Abstract method (no implementation)\n    \n    @abstractmethod\n    def stop(self):\n        pass  # Abstract method (no implementation)\n```\n\n### **Step 2: Implement the Interface**\nA class implements an interface by inheriting from it and providing concrete implementations of the abstract methods.\n\n```python\n# Implementing the Vehicle interface in a Car class\nclass Car(Vehicle):\n    def start(self):\n        print(\"Car is starting...\")\n    \n    def stop(self):\n        print(\"Car is stopping...\")\n```\n\n### **Step 3: Using the Implemented Class**\nNow, let's create objects and call the methods.\n\n```python\nif __name__ == \"__main__\":\n    my_car = Car()  # Instantiating the class\n    my_car.start()\n    my_car.stop()\n```\n\n### **Output:**\n```\nCar is starting...\nCar is stopping...\n```\n\n---\n\n## **Multiple Inheritance with Interfaces**\n\nUnlike normal classes, Python **supports multiple inheritance** with interfaces.\n\n```python\nfrom abc import ABC, abstractmethod\n\n# First interface\nclass Flyable(ABC):\n    @abstractmethod\n    def fly(self):\n        pass\n\n# Second interface\nclass Drivable(ABC):\n    @abstractmethod\n    def drive(self):\n        pass\n\n# Implementing multiple interfaces\nclass FlyingCar(Flyable, Drivable):\n    def fly(self):\n        print(\"FlyingCar is flying...\")\n    \n    def drive(self):\n        print(\"FlyingCar is driving...\")\n```\n\n### **Usage**\n```python\nif __name__ == \"__main__\":\n    my_vehicle = FlyingCar()\n    my_vehicle.fly()\n    my_vehicle.drive()\n```\n\n### **Output:**\n```\nFlyingCar is flying...\nFlyingCar is driving...\n```\n\n---\n\n## **Default Method Behavior in Interfaces**\n\nUnlike Java, Python does not have **default methods** in interfaces, but we can provide default implementations in base classes.\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Animal(ABC):\n    @abstractmethod\n    def sound(self):\n        pass\n    \n    def sleep(self):  # Default method\n        print(\"Sleeping...\")\n\nclass Dog(Animal):\n    def sound(self):\n        print(\"Dog barks\")\n```\n\n### **Usage**\n```python\nif __name__ == \"__main__\":\n    my_dog = Dog()\n    my_dog.sound()\n    my_dog.sleep()\n```\n\n### **Output:**\n```\nDog barks\nSleeping...\n```\n\n---\n\n## **Real-World Example: Payment System**\n\n```python\nfrom abc import ABC, abstractmethod\n\nclass Payment(ABC):\n    @abstractmethod\n    def pay(self, amount):\n        pass\n\nclass CreditCardPayment(Payment):\n    def pay(self, amount):\n        print(f\"Paid {amount} using Credit Card\")\n\nclass PayPalPayment(Payment):\n    def pay(self, amount):\n        print(f\"Paid {amount} using PayPal\")\n```\n\n### **Usage**\n```python\nif __name__ == \"__main__\":\n    payment1 = CreditCardPayment()\n    payment1.pay(100.50)\n    \n    payment2 = PayPalPayment()\n    payment2.pay(200.75)\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 200.75 using PayPal\n```\n"
  },
  {
    "path": "oop/python/polymorphism/README.md",
    "content": "# Polymorphism in Python\n\n## Introduction\n\n**Polymorphism** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nPolymorphism in Python can be classified into two types:\n1. **Compile-time Polymorphism (Method Overloading - Python handles it differently)**\n2. **Run-time Polymorphism (Method Overriding & Duck Typing)**\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a method, function, or object to behave differently based on the context. Polymorphism enables **dynamic method resolution** and **method flexibility**, making applications easier to extend and maintain.\n\n### **Key Benefits of Polymorphism**\n- **Code Reusability**: Write a single interface that works for multiple types.\n- **Scalability**: Add new functionalities with minimal code changes.\n- **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **1. Compile-Time Polymorphism (Method Overloading in Python)**\n\nUnlike Java or C++, Python does not support method overloading in the traditional sense. However, we can achieve similar functionality by using **default parameters** or variable arguments (`*args`).\n\n### **Example of Method Overloading using Default Arguments**\n\n```python\nclass MathOperations:\n    def add(self, a, b, c=0):\n        return a + b + c\n\nmath = MathOperations()\nprint(\"Sum (2 numbers):\", math.add(5, 10))\nprint(\"Sum (3 numbers):\", math.add(5, 10, 15))\n```\n\n### **Output:**\n```\nSum (2 numbers): 15\nSum (3 numbers): 30\n```\n\n**Why Use Default Arguments?**\n- Simulates method overloading by providing optional parameters.\n- Reduces redundancy by using a single method name for similar operations.\n\n---\n\n## **2. Run-Time Polymorphism (Method Overriding)**\n\nRun-time polymorphism occurs when a subclass provides a **specific implementation** of a method already defined in its parent class. The method to be called is determined **at runtime**.\n\n### **Example of Method Overriding**\n\n```python\nclass Animal:\n    def make_sound(self):\n        print(\"Animal makes a sound\")\n\nclass Dog(Animal):\n    def make_sound(self):\n        print(\"Dog barks\")\n\nclass Cat(Animal):\n    def make_sound(self):\n        print(\"Cat meows\")\n\n# Demonstrating runtime polymorphism\nanimals = [Dog(), Cat()]\nfor animal in animals:\n    animal.make_sound()\n```\n\n### **Output:**\n```\nDog barks\nCat meows\n```\n\n**Why Use Method Overriding?**\n- Enables **dynamic method resolution**.\n- Supports **polymorphic behavior**, where one interface can be used for multiple implementations.\n- Makes code **extensible** by allowing future modifications.\n\n---\n\n## **Using Polymorphism with Duck Typing**\n\nPython follows the **Duck Typing** principle: \"If it looks like a duck and quacks like a duck, it is a duck.\" This means that Python does not require explicit implementation of interfaces.\n\n```python\nclass Car:\n    def start(self):\n        print(\"Car is starting...\")\n\nclass Bike:\n    def start(self):\n        print(\"Bike is starting...\")\n\n# Polymorphic function\ndef vehicle_start(vehicle):\n    vehicle.start()\n\nvehicle_start(Car())\nvehicle_start(Bike())\n```\n\n### **Output:**\n```\nCar is starting...\nBike is starting...\n```\n\n**Why Use Duck Typing?**\n- Promotes **loose coupling**, making code more flexible.\n- Allows multiple implementations of the same behavior without inheritance.\n- Enables **dependency injection**, improving testability.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case of polymorphism is in **payment processing**.\n\n```python\nclass Payment:\n    def pay(self, amount):\n        pass  # Abstract method\n\nclass CreditCardPayment(Payment):\n    def pay(self, amount):\n        print(f\"Paid {amount} using Credit Card\")\n\nclass PayPalPayment(Payment):\n    def pay(self, amount):\n        print(f\"Paid {amount} using PayPal\")\n\n# Demonstrating polymorphism\npayments = [CreditCardPayment(), PayPalPayment()]\nfor payment in payments:\n    payment.pay(100.50)\n```\n\n### **Output:**\n```\nPaid 100.5 using Credit Card\nPaid 100.5 using PayPal\n```\n\n**Why Use Polymorphism in Payment Systems?**\n- Allows new payment methods to be added **without modifying existing code**.\n- Provides a **flexible and scalable** design.\n- Improves **code readability and maintainability**."
  },
  {
    "path": "oop/rust/.gitignore",
    "content": "# Generated by Cargo\ntarget/\n\n# Ignoring the lockfile because this is an educational library, not a binary deployment\nCargo.lock\n\n# Ignoring rustfmt backups\n**/*.rs.bk"
  },
  {
    "path": "oop/rust/Cargo.toml",
    "content": "[package]\nname = \"rust_oop_concepts\"\nversion = \"0.1.0\"\nedition = \"2021\"\n\n# BINARY TARGETS\n# According to Cargo docs, we can explicitly define binaries \n# that are located outside the standard 'src/bin' directory.\n\n[[bin]]\nname = \"classes_and_objects\"\npath = \"classes_and_objects/main.rs\"\n\n[[bin]]\nname = \"interfaces\"\npath = \"interfaces/main.rs\"\n\n[[bin]]\nname = \"abstraction\"\npath = \"abstraction/main.rs\"\n\n\n[[bin]]\nname = \"inheritance\"\npath = \"inheritance/main.rs\"\n\n[[bin]]\nname = \"polymorphism\"\npath = \"polymorphism/main.rs\"\n\n[[bin]]\nname = \"encapsulation\"\npath = \"encapsulation/main.rs\"\n\n[[bin]]\nname = \"aggregation\"\npath = \"aggregation/main.rs\"\n\n[[bin]]\nname = \"composition\"\npath = \"composition/main.rs\"\n\n[[bin]]\nname = \"association\"\npath = \"association/main.rs\"\n"
  },
  {
    "path": "oop/rust/abstraction/README.md",
    "content": "# Abstraction in Rust\n\n**Abstraction** is the design pattern of hiding complex implementation details and exposing only the necessary functionality to the user.\n\n> **Simple Definition:** \"Show what it does, hide how it does it.\"\n\n---\n\n## 🏗️ Prerequisites: The Building Blocks\nBefore understanding Abstraction in Rust, we must understand two fundamental concepts that replace \"Classes\" in other languages: **Structs** and **Traits**.\n\n### 1. What is a Struct?\nIn Java/C++, a Class holds both data and methods. In Rust, data is separated.\nA **Struct** is strictly for holding **Data**. It has no behavior on its own.\n\n**Example:**\n```rust\n// Just data. No logic here.\nstruct CoffeeMachine {\n    water_level: u32,\n    beans: u32,\n}\n```\n\n### 2. What is a Trait?\nA **Trait** is Rust's version of an **Interface**. It defines **Behavior**.\nIt tells us *what* functionality an object must provide, but not *how* it does it.\n\n**Example:**\n```rust\n// This is the \"Contract\" or \"Interface\"\ntrait Brewable {\n    fn make_coffee(&self); // abstract method (no body)\n}\n```\n\n### 3. What is `impl`?\nThe `impl` keyword is the glue. It implements the **Trait** (Behavior) for a specific **Struct** (Data).\n\n---\n\n## ☕ Abstraction: The Real-World Example\nLet's apply these concepts to build a **Coffee Machine**.\n\n### The Problem (Without Abstraction)\nIf we don't use abstraction, the user has to manually handle the machine's internal parts. This is dangerous and complex.\n\n```rust\nlet mut machine = CoffeeMachine { water: 0, beans: 0 };\n\n// BAD: User has to know how the machine works internally!\nmachine.water = 100;       // User manually filling water?\nmachine.beans = 50;        // User manually loading beans?\nmachine.grind_beans();     // User manually starting the grinder?\n// This is too complex for a normal user.\n```\n\n### The Solution (With Abstraction)\nWe want to hide the grinding and heating logic. The user should only see one simple button: `brew()`.\n\n#### Step 1: Define the Abstraction (The Interface)\nWe create a public Trait. This is the **only** thing the user needs to understand.\n\n```rust\n// PUBLIC: The user sees this.\npub trait CoffeeMaker {\n    fn add_ingredients(&mut self);\n    fn press_button(&mut self);\n}\n```\n\n#### Step 2: Implement the Hidden Logic\nWe hide the complex steps (`grind_beans`, `heat_water`) inside private helper methods. The user cannot call these directly.\n\n```rust\npub struct PremiumMachine {\n    water: u32,\n    beans: u32,\n}\n\nimpl PremiumMachine {\n    // PRIVATE: Internal logic (Hidden details)\n    fn grind_beans(&self) {\n        println!(\"Grinding beans... 🚜\");\n    }\n\n    fn heat_water(&self) {\n        println!(\"Heating water... 🔥\");\n    }\n}\n\n// CONNECTING THEM: Implementing the Public Trait\nimpl CoffeeMaker for PremiumMachine {\n    fn add_ingredients(&mut self) {\n        self.water = 100;\n        self.beans = 50;\n    }\n\n    fn press_button(&mut self) {\n        // The abstraction happens here!\n        // One simple call triggers complex internal logic.\n        self.grind_beans();\n        self.heat_water();\n        println!(\"Coffee is ready! ☕\");\n    }\n}\n```\n\n---\n\n## 🆚 Comparison: Rust vs. OOP Languages\n\nRust handles abstraction differently than Java or Python because it emphasizes **memory safety** and **separation of concerns**.\n\n| Feature | Java / C++ / Python | Rust |\n| :--- | :--- | :--- |\n| **Container** | `Class` (Data + Methods together) | `Struct` (Data) + `impl` (Methods) separated |\n| **Interface** | `interface` or `abstract class` | `trait` |\n| **Hiding Data** | `private` / `protected` keywords | Struct fields are **private by default** to other modules |\n| **Override** | `@Override` annotation | Explicit implementation of Trait methods |\n\n---\n\n## 🧠 Why is this useful?\n1.  **Safety:** The user cannot accidentally change the `water_level` to a wrong value because the field is private.\n2.  **Simplicity:** The user doesn't need to know *how* to grind beans; they just press the button.\n3.  **Flexibility:** We can swap the `PremiumMachine` with a `CheapMachine`, and as long as they both implement the `CoffeeMaker` trait, the user code doesn't change.\n"
  },
  {
    "path": "oop/rust/abstraction/main.rs",
    "content": "/*\n * ABSTRACTION EXAMPLE: A Coffee Machine\n *\n * Goal: The user interacts with a simple interface (make_coffee),\n * hiding the complex logic (grinding, heating, checking water) inside.\n */\n\n// 1. THE ABSTRACTION (The Interface)\n// We define a Trait to specify WHAT a Coffee Machine should do.\n// The user strictly interacts with these methods.\npub trait CoffeeMaker {\n    fn brew(&mut self);\n    fn add_water(&mut self, amount: u32);\n}\n\n// 2. THE CONCRETE TYPE (The Data)\n// These fields represent the internal state.\n// Notice we do NOT make the fields 'pub'. They are hidden from the outside world.\npub struct PremiumCoffeeMachine {\n    water_level: u32,\n    beans_level: u32,\n}\n\n// 3. INTERNAL LOGIC (Helper methods)\n// These methods are NOT part of the Trait. They are private internal logic\n// used to support the public abstraction.\nimpl PremiumCoffeeMachine {\n    pub fn new(water: u32, beans: u32) -> Self {\n        PremiumCoffeeMachine {\n            water_level: water,\n            beans_level: beans,\n        }\n    }\n\n    // This is an internal detail (Encapsulated logic).\n    // The user doesn't need to call this manually.\n    fn grind_beans(&mut self) -> bool {\n        if self.beans_level > 10 {\n            self.beans_level -= 10;\n            println!(\"* Grinding beans... *\");\n            return true;\n        }\n        println!(\"Error: Not enough beans!\");\n        false\n    }\n\n    // Another internal detail.\n    fn heat_water(&mut self) -> bool {\n        if self.water_level > 20 {\n            self.water_level -= 20;\n            println!(\"* Heating water... *\");\n            return true;\n        }\n        println!(\"Error: Add more water!\");\n        false\n    }\n}\n\n// 4. IMPLEMENTING THE ABSTRACTION\n// We expose only the high-level 'brew' functionality to the user.\nimpl CoffeeMaker for PremiumCoffeeMachine {\n    fn add_water(&mut self, amount: u32) {\n        self.water_level += amount;\n        println!(\"Added {}ml of water. Current level: {}ml\", amount, self.water_level);\n    }\n\n    // This is the implementation of the Abstraction.\n    // The complexity of grinding and heating is HIDDEN behind this single function call.\n    fn brew(&mut self) {\n        println!(\"\\n--- Starting Brew Process ---\");\n        // We chain internal steps here. The user doesn't know this complexity exists.\n        if self.grind_beans() && self.heat_water() {\n            println!(\"Success: Here is your hot coffee! ☕\");\n        } else {\n            println!(\"Failure: Could not brew coffee.\");\n        }\n        println!(\"-----------------------------\\n\");\n    }\n}\n\nfn main() {\n    // User creates the machine\n    let mut machine = PremiumCoffeeMachine::new(0, 100);\n\n    // USAGE\n    // The user doesn't verify water temp or grind size manually.\n    // They just use the abstract interface methods: add_water() and brew().\n    \n    machine.add_water(50); // User interacts with the interface\n    machine.brew();        // User interacts with the interface\n\n    // Trying to brew again without water\n    machine.brew();\n}\n"
  },
  {
    "path": "oop/rust/aggregation/README.md",
    "content": "# Aggregation in Rust (References & Lifetimes)\n\n## Introduction\n\n**Aggregation** is a specific type of association in Object-Oriented Programming (OOP) representing a **\"Has-A\"** relationship.\n* **Crucial Distinction:** The lifecycle of the contained object (Child) is **independent** of the container object (Parent).\n* **In plain English:** If the University closes down (is destroyed), the Professors do not die; they go home.\n\n**Does Rust support Aggregation?**\nYes, but it is stricter than Java. In Rust, Aggregation is implemented using **References (`&T`)** and **Lifetimes (`'a`)**.\n\n\n\n---\n\n## **1. The Core Concept: Borrowing vs. Owning**\n\nTo understand Aggregation, you must understand Rust's memory model:\n\n1.  **Composition (Strong):** The Parent **OWNS** the Child.\n    * *Rust:* `struct Parent { child: Child }`\n    * *Result:* If Parent dies, Child dies immediately.\n2.  **Aggregation (Weak):** The Parent **BORROWS** the Child.\n    * *Rust:* `struct Parent<'a> { child: &'a Child }`\n    * *Result:* Parent holds a pointer. If Parent dies, the Child is unaffected because the Parent never owned it.\n\n---\n\n## **2. The \"Lifetime\" Problem (`'a`)**\n\nThis is the most unique part of Rust. If a struct holds a reference, the borrow checker will reject invalid lifetimes at compile time:\n> *\"What if the University holds a pointer to a Professor, but the Professor has already been deleted? The University would be pointing to garbage memory!\"*\n\nTo prevent this, we use **Lifetime Annotations (`'a`)**.\n\n```rust\n// <'a> reads as: \"This struct lives for a duration called 'a\"\nstruct University<'a> {\n    // This reference must live AT LEAST as long as 'a\n    professor: &'a Professor,\n}\n\n```\n\n**What this tells the compiler:**\n*\"I promise that the `Professor` will stay alive longer than (or at least as long as) the `University`.\"*\n\n---\n\n## **3. Code Implementation**\n\n### **Step 1: The Independent Object**\n\nThe `Professor` owns its own data. It doesn't know about the University.\n\n```rust\nstruct Professor {\n    name: String,\n}\n\n```\n\n### **Step 2: The Container (With Lifetimes)**\n\nThe `University` holds a **Reference** (`&`) to the Professor.\n\n```rust\nstruct University<'a> {\n    name: String,\n    // Aggregation: We borrow the professor\n    staff: Vec<&'a Professor>,\n}\n\n```\n\n### **Step 3: Usage**\n\n```rust\nfn main() {\n    // 1. Create the Child (Owner)\n    let prof = Professor { name: \"Dr. Smith\".into() };\n\n    {\n        // 2. Create the Parent (Borrower)\n        let mut uni = University { \n            name: \"MIT\".into(), \n            staff: vec![&prof] // Borrowing here\n        }; \n        \n        // uni is destroyed here...\n    } \n\n    // 3. PROOF OF AGGREGATION:\n    // The Professor is still alive!\n    println!(\"{} is currently unemployed but alive.\", prof.name);\n}\n\n```\n\n---\n\n## **4. Advanced: Shared Ownership (`Rc<T>`)**\n\nSometimes, you don't know who will die first. Maybe the Professor belongs to 3 Universities at once.\nFor this, Rust uses **Reference Counting (`Rc`)**.\n\n* **`Rc<T>`**: A smart pointer that keeps track of how many owners exist.\n* The object is only deleted when the **count reaches 0**.\n\n```rust\nuse std::rc::Rc;\n\nstruct Company {\n    // Shared Ownership Aggregation\n    employee: Rc<Employee>,\n}\n\n```\n\n---\n\n## **Comparison: Aggregation vs Composition**\n\n| Feature | Aggregation (Weak) | Composition (Strong) |\n| --- | --- | --- |\n| **Relationship** | **\"Uses a\"** / **\"Has access to\"** | **\"Consists of\"** |\n| **Rust Syntax** | `&'a T` (Reference) | `T` (Direct Value) |\n| **Ownership** | **Borrowed** (Parent does not own) | **Owned** (Parent owns Child) |\n| **Lifecycle** | **Independent** (Child survives Parent) | **Dependent** (Child dies with Parent) |\n| **Drop Rule** | Dropping Parent **does nothing** to Child. | Dropping Parent **drops** Child. |\n\n---\n\n## 📚 New Terminology\n\n| Term | Detailed Explanation |\n| --- | --- |\n| **Lifetime (`'a`)** | A generic parameter that restricts how long a Reference is valid. It ensures a struct never points to dead memory. |\n| **Borrow Checker** | The part of the Rust compiler that enforces Aggregation rules. It ensures the \"Child\" lives longer than the \"Parent\". |\n| **Dangling Pointer** | A pointer that points to invalid memory. Rust's Aggregation rules exist specifically to prevent this. |\n| **`Vec<&T>`** | A Vector that stores *addresses* of objects, not the objects themselves. |\n\n\n\n"
  },
  {
    "path": "oop/rust/aggregation/main.rs",
    "content": "/*\n * AGGREGATION IN RUST\n *\n * Goal: Demonstrate Independent Lifecycles using References and Lifetimes.\n * Scenario: A Library (Container) holds references to Books (Independent Objects).\n */\n\n#[derive(Debug)]\nstruct Book {\n    title: String,\n    author: String,\n}\n\nimpl Book {\n    fn new(title: &str, author: &str) -> Self {\n        Book {\n            title: title.to_string(),\n            author: author.to_string(),\n        }\n    }\n\n    fn read(&self) {\n        println!(\"  Reading '{}' by {}...\", self.title, self.author);\n    }\n}\n\n// THE CONTAINER (AGGREGATION)\n// <'a> ensures Library cannot outlive the Books it holds.\nstruct Library<'a> {\n    name: String,\n    // Aggregation: Library 'has' books, but does not 'own' them.\n    collection: Vec<&'a Book>,\n}\n\nimpl<'a> Library<'a> {\n    fn new(name: &str) -> Self {\n        Library {\n            name: name.to_string(),\n            collection: Vec::new(),\n        }\n    }\n\n    // We take a reference with lifetime 'a\n    fn add_book(&mut self, book: &'a Book) {\n        self.collection.push(book);\n    }\n\n    fn list_books(&self) {\n        println!(\"Library '{}' contains:\", self.name);\n        for book in &self.collection {\n            book.read();\n        }\n    }\n}\n\n// ADVANCED: SHARED AGGREGATION (Rc)\nuse std::rc::Rc;\n\nstruct Reader {\n    name: String,\n    // Multiple readers can hold the SAME book\n    favorite_book: Rc<Book>, \n}\n\nfn main() {\n    println!(\"--- 1. Standard Aggregation (References & Lifetimes) ---\");\n\n    // STEP A: Create the Independent Objects (Books)\n    // These live in the 'main' scope.\n    let book1 = Book::new(\"The Rust Book\", \"Steve Klabnik\");\n    let book2 = Book::new(\"Clean Code\", \"Robert C. Martin\");\n\n    {\n        // STEP B: Create the Container (Library) inside a smaller scope\n        let mut my_library = Library::new(\"City Central Lib\");\n\n        // STEP C: Aggregate (Borrow the books)\n        my_library.add_book(&book1);\n        my_library.add_book(&book2);\n\n        my_library.list_books();\n\n        println!(\"--- Library is closing (Variable 'my_library' dropped) ---\");\n    } // 'my_library' dies here.\n\n    // STEP D: Verify Independence\n    // The library is gone, but the books are still here!\n    println!(\"Verification: '{}' is still on my shelf at home.\", book1.title);\n\n\n    println!(\"\\n--- 2. Shared Aggregation (Rc Smart Pointer) ---\");\n    \n    // We wrap a book in Rc (Reference Counted)\n    let shared_book = Rc::new(Book::new(\"Design Patterns\", \"Gang of Four\"));\n\n    let reader1 = Reader { name: \"Alice\".into(), favorite_book: Rc::clone(&shared_book) };\n    let reader2 = Reader { name: \"Bob\".into(), favorite_book: Rc::clone(&shared_book) };\n\n    println!(\"{} loves {}.\", reader1.name, reader1.favorite_book.title);\n    println!(\"{} also loves {}.\", reader2.name, reader2.favorite_book.title);\n    \n    // The book stays alive as long as EITHER Alice OR Bob (or the original var) holds it.\n}\n\n\n"
  },
  {
    "path": "oop/rust/association/README.md",
    "content": "# Association in Rust (Shared Ownership & Weak Pointers)\n\n## Introduction\n\n**Association** represents a **\"Knows-a\"** or **\"Uses-a\"** relationship. Unlike Composition (where objects die together) or Aggregation (where one borrows the other), Association often implies that multiple objects interact as peers.\n\n**The Rust Challenge:**\nIn Java, a `Teacher` can hold a list of `Student` objects, and those same `Student` objects can be held by another `Teacher`.\nIn Rust, a value can strictly have **only one owner**.\n\nTo allow multiple Teachers to \"know\" the same Student, we must use **Shared Ownership**.\n\n---\n\n## **1. Unidirectional Association (Shared Ownership)**\n\nWhen multiple parents need to access the same child, we use **`Rc<T>` (Reference Counting)**.\n* `Rc` keeps track of how many things are pointing to the data.\n* The data is only deleted when the count hits 0.\n\n### **Example: Many Teachers, One Student**\nTeacher A and Teacher B both teach \"Alice\". They both need to point to the *same* Alice in memory.\n\n```rust\nuse std::rc::Rc;\n\nstruct Student { name: String }\n\nstruct Teacher {\n    name: String,\n    // Rc allows multiple teachers to own the same student\n    students: Vec<Rc<Student>>, \n}\n\n```\n\n---\n\n## **2. Bidirectional Association (The \"Cycle\" Problem)**\n\nThis is the hardest concept in Rust OOP.\nIf a `Library` owns a `Book` (`Rc<Book>`), and the `Book` owns the `Library` (`Rc<Library>`), the Reference Count for both will **never reach zero**.\n\n1. Library waits for Book to die.\n2. Book waits for Library to die.\n3. **Result:** Memory Leak.\n\n### **The Solution: Weak Pointers (`Weak<T>`)**\n\nTo fix this, the Child (Book) must hold a **Weak Reference** to the Parent (Library).\n\n* **Strong Reference (`Rc`)**: \"I own this. Don't delete it.\"\n* **Weak Reference (`Weak`)**: \"I point to this, but I don't own it. If it gets deleted, I'll just point to nothing.\"\n\n---\n\n## **3. Implementation Details (RefCell)**\n\nIn Association, we often need to modify an object (like adding a student to a teacher) even though it is shared. Rust doesn't allow mutating `Rc` data directly.\nWe use **`RefCell<T>`** for interior mutability. It enforces borrowing rules at **runtime**, which allows mutation through shared references but can panic if you violate the rules.\n\n### **The Pattern for Bidirectional Association**\n\n* **Parent:** Holds `Rc<RefCell<Child>>` (Strong ownership, Mutable).\n* **Child:** Holds `Weak<RefCell<Parent>>` (Weak link, Mutable).\n\n---\n\n## 📚 New Terminology (Advanced)\n\n| Term | Java Equivalent | Detailed Explanation |\n| --- | --- | --- |\n| **`Rc<T>`** | Shared Reference | \"Reference Counted\". Allows multiple parts of code to own the same data in the Heap. |\n| **`Weak<T>`** | Weak Reference | A pointer that does *not* increase the reference count. Used to break infinite loops (cycles) in bidirectional relationships. |\n| **`RefCell<T>`** | N/A (Magic) | \"Interior Mutability\". Allows you to modify data even if you only have an immutable reference to it. Essential for linked data structures. |\n| **`upgrade()`** | Checking for null | The method used to convert a `Weak` pointer into a real `Rc`. It returns `None` if the parent object has already been destroyed. |\n\n"
  },
  {
    "path": "oop/rust/association/main.rs",
    "content": "/*\n * ASSOCIATION IN RUST\n * * Scenario 1: Unidirectional (One-to-Many) using Rc.\n * Scenario 2: Bidirectional (Many-to-Many) using Rc, Weak, and RefCell.\n *\n * NOTE: This uses advanced smart pointers to replicate Java's flexible references.\n */\n\nuse std::rc::{Rc, Weak};\nuse std::cell::RefCell;\n\n// ==========================================\n// SCENARIO 1: UNIDIRECTIONAL (Teacher -> Student)\n// Multiple Teachers share the SAME Students.\n// ==========================================\n\n#[derive(Debug)]\nstruct Student {\n    name: String,\n}\n\nstruct Teacher {\n    name: String,\n    // We use Rc so multiple teachers can refer to the SAME student instance\n    students: Vec<Rc<Student>>,\n}\n\nimpl Teacher {\n    fn new(name: &str) -> Self {\n        Teacher {\n            name: name.to_string(),\n            students: Vec::new(),\n        }\n    }\n\n    fn add_student(&mut self, student: Rc<Student>) {\n        self.students.push(student);\n    }\n\n    fn show_students(&self) {\n        println!(\"{} teaches:\", self.name);\n        for s in &self.students {\n            // Rc auto-dereferences to the inner Student\n            println!(\" - {}\", s.name);\n        }\n    }\n}\n\n// ==========================================\n// SCENARIO 2: BIDIRECTIONAL (Library <-> Book)\n// Library owns Books. Books know their Library.\n// ==========================================\n\n// We need RefCell to allow mutation (adding books) after creation\nstruct Library {\n    name: String,\n    books: RefCell<Vec<Rc<Book>>>, // Library owns Books (Strong)\n}\n\nstruct Book {\n    title: String,\n    // Book holds a WEAK reference to Library to prevent memory leaks (Cycles)\n    library: Weak<Library>, \n}\n\nimpl Library {\n    // Returns Rc<Library> so it can be shared with Books\n    fn new(name: &str) -> Rc<Self> {\n        Rc::new(Library {\n            name: name.to_string(),\n            books: RefCell::new(Vec::new()),\n        })\n    }\n\n    fn add_book(library: &Rc<Library>, title: &str) {\n        // Create the book with a Weak pointer back to the Library\n        let book = Rc::new(Book {\n            title: title.to_string(),\n            library: Rc::downgrade(library), // Convert Strong Rc to Weak\n        });\n\n        // Add to library's list (using borrow_mut because of RefCell)\n        library.books.borrow_mut().push(book);\n    }\n\n    fn show_books(&self) {\n        println!(\"Books in {}:\", self.name);\n        for book in self.books.borrow().iter() {\n            println!(\" - {}\", book.title);\n        }\n    }\n}\n\nimpl Book {\n    fn show_library(&self) {\n        // We must attempt to \"upgrade\" the weak pointer to see if the Library still exists\n        match self.library.upgrade() {\n            Some(lib) => println!(\"'{}' belongs to library: {}\", self.title, lib.name),\n            None => println!(\"'{}' belongs to a library that no longer exists!\", self.title),\n        }\n    }\n}\n\nfn main() {\n    println!(\"--- 1. Unidirectional Association (Shared Ownership) ---\");\n    \n    // 1. Create Students (Wrapped in Rc for sharing)\n    let s1 = Rc::new(Student { name: \"Alice\".into() });\n    let s2 = Rc::new(Student { name: \"Bob\".into() });\n\n    // 2. Create Teachers\n    let mut t1 = Teacher::new(\"Mr. Smith\");\n    let mut t2 = Teacher::new(\"Mrs. Johnson\");\n\n    // 3. Associate (Cloning Rc just increases the reference count, not memory)\n    t1.add_student(Rc::clone(&s1)); // Alice -> Smith\n    t1.add_student(Rc::clone(&s2)); // Bob -> Smith\n    t2.add_student(Rc::clone(&s2)); // Bob -> Johnson (Shared!)\n\n    t1.show_students();\n    t2.show_students();\n\n    // Proof of shared memory:\n    // Rc::strong_count(&s2) would be 3 (Original + Teacher1 + Teacher2)\n\n\n    println!(\"\\n--- 2. Bidirectional Association (Weak Pointers) ---\");\n    \n    // 1. Create the Library\n    let city_lib = Library::new(\"City Library\");\n\n    // 2. Add Books (Internally links Book -> Library)\n    Library::add_book(&city_lib, \"1984\");\n    Library::add_book(&city_lib, \"Brave New World\");\n\n    // 3. Show relations\n    city_lib.show_books();\n\n    // Accessing the books to show their library\n    let books = city_lib.books.borrow();\n    for b in books.iter() {\n        b.show_library();\n    }\n\n    println!(\"\\n--- 3. Testing Lifecycle (Weak Pointer Safety) ---\");\n    // Create a temporary library scope\n    let floating_book = {\n        let temp_lib = Library::new(\"Temporary Pop-up Library\");\n        Library::add_book(&temp_lib, \"Temporary Manual\");\n        \n        // We clone the book out of the library\n        let book_ref = Rc::clone(&temp_lib.books.borrow()[0]);\n        book_ref // Return the book, but the Library gets dropped here\n    };\n\n    println!(\"The book '{}' still exists...\", floating_book.title);\n    // This should fail gracefully because the Library is dead\n    floating_book.show_library(); \n}\n"
  },
  {
    "path": "oop/rust/classes_and_objects/README.md",
    "content": "# Classes and Objects\n\nClasses and objects form the foundation of Object-Oriented Programming (OOP).\n\n## What is a Class?\n\nIn traditional OOP languages (like Java/C++), a **Class** is a blueprint that bundles data (attributes) and behavior (methods) together.\n\n**Rust is different.** It separates these two concepts:\n1.  **Data** is defined in a `struct`.\n2.  **Behavior** is defined in an `impl` (implementation) block.\n\n### Defining a Class (Struct + Impl) in Rust\n\nTo define the equivalent of a class in Rust, we use the `struct` keyword for the data layout and the `impl` keyword to define methods.\n\nHere's the `Car` example translated to idiomatic Rust:\n\n```rust\n// 1. The Blueprint (Data only)\n// We use 'pub' to make the struct and fields accessible to other modules.\npub struct Car {\n    // Attributes\n    pub color: String,\n    pub make: String,\n    pub model: String,\n    pub year: u32,\n}\n\n// 2. The Behavior (Methods)\nimpl Car {\n    // Constructor-like function (Associated Function)\n    // Rust does not have a 'new' keyword. We create a static function typically named 'new'.\n    pub fn new(color: String, make: String, model: String, year: u32) -> Self {\n        Car {\n            color, // Shorthand initialization (same as color: color)\n            make,\n            model,\n            year,\n        }\n    }\n\n    // Method to display car details\n    // '&self' is a reference to the current object instance (like 'this' in Java)\n    pub fn display_info(&self) {\n        println!(\"Car Make: {}\", self.make);\n        println!(\"Car Model: {}\", self.model);\n        println!(\"Car Year: {}\", self.year);\n        println!(\"Car Color: {}\", self.color);\n    }\n}\n```\n\n### 🧠 New Rust Terminology\n* **`struct`**: Defines the \"shape\" of the object (the fields).\n* **`impl`**: A block where we define functions and methods for a specific struct.\n* **`&self`**: A reference to the instance itself. It means \"read-only access to my own data\". It is equivalent to `this` in Java.\n* **Associated Function (`new`)**: Functions defined inside `impl` that do **not** take `self`. They are like `static` methods in Java. We use them as constructors.\n\n---\n\n## What is an Object?\n\nAn object is an **instance** of a struct. When you create an instance, you are allocating memory for that specific blueprint and filling it with real data.\n\n### Creating Objects in Rust\n\nIn Rust, we don't use the `new` keyword to instantiate. Instead, we call the associated function we created (`Car::new`) or initialize the struct directly.\n\nHere's how you can instantiate objects from the `Car` struct:\n\n```rust\nfn main() {\n    // Creating an object (Instance) of the Car struct\n    // We use \"::\" to call static methods (associated functions)\n    // Note: We use .to_string() because \"Red\" is a string slice (&str), \n    // but our Struct expects an owned String.\n    let car1 = Car::new(\n        \"Red\".to_string(), \n        \"Toyota\".to_string(), \n        \"Corolla\".to_string(), \n        2020\n    );\n\n    let car2 = Car::new(\n        \"Blue\".to_string(), \n        \"Ford\".to_string(), \n        \"Mustang\".to_string(), \n        2021\n    );\n\n    // Displaying information of each car\n    // We use \".\" to call instance methods\n    car1.display_info();\n    println!(\"-----------------\");\n    car2.display_info();\n}\n```\n\n### Key Differences from Java/Go\n1.  **Instantiation**: No `new Car(...)`. We call `Car::new(...)` which is just a normal function we wrote.\n2.  **Reference**: Variables (`car1`) **own** the data by default. In Java, variables are just references (pointers).\n3.  **Strings**: We use `.to_string()` because string literals (`\"Red\"`) are string slices (`&str`), but our struct wants an owned `String`.\n\n\n---\n\n## 💡 Why Rust prefers Structs over Classes?\n\nIf you are coming from Java or C++, you might wonder: *\"Why didn't Rust just add Classes?\"*\n\nThe answer lies in **Composition over Inheritance**.\n\n### 1. The \"Banana in the Jungle\" Problem\nIn traditional OOP (Classes), you often create deep inheritance hierarchies (`Animal` -> `Mammal` -> `Dog`).\nJoe Armstrong (creator of Erlang) famously said:\n\n> \"The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. **You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.**\"\n\nIn Rust:\n* **Structs** are just data (The Banana).\n* **Traits** are just behavior (Eating).\n* You don't inherit the \"Gorilla\" just to get the \"Banana.\"\n\n### 2. No \"Diamond Problem\"\nIn languages like C++, allowing a class to inherit from two parents leads to conflicts (The Diamond Problem). Rust avoids this entirely because **Structs cannot inherit from other Structs**. You strictly use **Traits** (Interfaces) to share behavior, which is much cleaner and safer.\n\n### 3. Better Memory Control\n* **Classes** (in Java/Python) are usually references (pointers) to memory on the Heap. This is slower and causes \"Garbage Collection\" pauses.\n* **Structs** in Rust are values; they can live on the stack or heap depending on how you store them (`Box`, `Rc`, etc.). Some fields (like `String`) include heap pointers, so layout depends on the data you put inside.\n\n### Summary\nRust replaces **\"Is-A\"** relationships (Inheritance) with **\"Has-A\"** and **\"Can-Do\"** relationships (Composition and Traits).\n\n* **Bad (OOP):** A `Car` **is a** `Vehicle`. (Forces rigid hierarchy)\n* **Good (Rust):** A `Car` **has** `Engine` data (Struct) and **can** `drive` (Trait).\n\n"
  },
  {
    "path": "oop/rust/classes_and_objects/main.rs",
    "content": "/*\n * CLASSES AND OBJECTS IN RUST\n *\n * Goal: Demonstrate how Rust replaces the \"Class\" keyword with:\n * 1. Struct (for Data)\n * 2. Impl (for Behavior)\n */\n\n// 1. THE CLASS BLUEPRINT (Data Only)\n// In Java, this would be the fields inside 'public class Car'.\n// In Rust, we use a Struct to define the \"shape\" of the data.\npub struct Car {\n    pub color: String,\n    pub make: String,\n    pub model: String,\n    pub year: u32,\n}\n\n// 2. THE CLASS BEHAVIOR (Methods)\n// In Java, these methods would be inside the class curly braces {}.\n// In Rust, we use an 'impl' block to attach functions to the Struct.\nimpl Car {\n    // A. CONSTRUCTOR\n    // Rust has no 'new' keyword for objects. We create a static function\n    // (Associated Function) that returns a new instance of Self.\n    pub fn new(color: String, make: String, model: String, year: u32) -> Self {\n        Car {\n            color: color, \n            make: make,\n            model: model,\n            year: year,\n        }\n    }\n\n    // B. INSTANCE METHOD\n    // '&self' allows this function to read the data of the specific object calling it.\n    // It is exactly like 'this' in Java/C++.\n    pub fn display_info(&self) {\n        println!(\"----------------------------\");\n        println!(\"Car Details:\");\n        println!(\"Make:  {}\", self.make);\n        println!(\"Model: {}\", self.model);\n        println!(\"Year:  {}\", self.year);\n        println!(\"Color: {}\", self.color);\n        println!(\"----------------------------\");\n    }\n}\n\n// 3. CREATING OBJECTS (Instances)\nfn main() {\n    // Instantiation\n    // We call the associated function 'Car::new' to create an object.\n    // 'car1' is now the Owner of this data.\n    let car1 = Car::new(\n        \"Red\".to_string(), \n        \"Toyota\".to_string(), \n        \"Corolla\".to_string(), \n        2020\n    );\n\n    let car2 = Car::new(\n        \"Blue\".to_string(), \n        \"Ford\".to_string(), \n        \"Mustang\".to_string(), \n        2021\n    );\n\n    // Usage\n    // We access methods using the dot operator, just like Java.\n    car1.display_info();\n    car2.display_info();\n}\n"
  },
  {
    "path": "oop/rust/composition/README.md",
    "content": "# Composition in Rust (Ownership & Embedding)\n\n## Introduction\n\n**Composition** is a fundamental Object-Oriented Programming (OOP) principle that represents a **\"Has-A\"** relationship. It allows complex objects to be built from simpler ones.\n\nIn Rust, Composition is not just a design choice; it is the **primary way** to build data structures since Rust does not support Inheritance (`extends`).\n\n**The Core Rule of Composition in Rust:**\nWhen Struct A contains Struct B, **A owns B**.\n* They share the same lifecycle.\n* They share the same memory region.\n* When A is dropped (freed), B is automatically dropped.\n\n## **What is Composition?**\n\nComposition is when one struct embeds another struct as a field.\n\n### **Example: A Car and its Components**\n\nIn this example, a `Car` is composed of an `Engine`, `Wheels`, and `Transmission`.\nUnlike Aggregation (where we used references `&`), here we use the concrete types directly. This means the `Car` takes full **ownership** of these components.\n\n```rust\nstruct Engine { horsepower: u32 }\n\nstruct Car {\n    // Direct Composition (Ownership)\n    // The Engine actually lives INSIDE the Car struct in memory.\n    engine: Engine, \n    model: String,\n}\n\n```\n\n### **Memory Layout Difference**\n\n* **Java (Reference):** `Car` -> (pointer) -> `Engine` (Heap)\n* **Rust (Composition):** `Car` [ `Engine` data ... `model` data ] (Stack or Heap, but contiguous)\n\n---\n\n## **Why Prefer Composition Over Inheritance?**\n\nSince Rust does not have Inheritance, Composition is the standard. However, even in languages that do have Inheritance, Composition is preferred because:\n\n1. **Flexibility:** You can swap components (e.g., change a `GasEngine` to an `ElectricEngine`) without changing the `Car` class hierarchy.\n2. **Encapsulation:** The wrapper (`Car`) controls exactly how the inner objects (`Engine`) are accessed. It can hide dangerous methods.\n3. **Loose Coupling:** The `Car` doesn't need to know the internal details of how `Engine` works; it just calls public methods.\n\n---\n\n## **Composition with Traits (Polymorphism)**\n\nTo achieve the flexibility of Java interfaces (e.g., swapping different engine types), Rust uses **Trait Objects** inside `Box`.\n\nSince different engines (Petrol vs Diesel) might have different sizes in memory, we cannot compose them directly on the stack if we want to swap them dynamically. We must put them in a `Box` (Pointer).\n\n```rust\ntrait Engine {\n    fn start(&self);\n}\n\nstruct PetrolEngine;\nimpl Engine for PetrolEngine { ... }\n\nstruct Car {\n    // Box<dyn Engine> allows us to hold ANY struct that implements Engine\n    engine: Box<dyn Engine>,\n}\n\n```\n\n---\n\n## **Composition vs Aggregation (The \"Drop\" Difference)**\n\nThe most important detail in Rust is **Lifecycle**.\n\n| Feature | Composition (Strong) | Aggregation (Weak) |\n| --- | --- | --- |\n| **Rust Syntax** | `struct A { b: B }` | `struct A<'a> { b: &'a B }` |\n| **Ownership** | **Owned** (A owns B) | **Borrowed** (A borrows B) |\n| **Memory** | B is stored *inside* A. | B is stored elsewhere; A points to it. |\n| **Destruction** | If A dies, **B dies too.** | If A dies, **B lives on.** |\n\n---\n\n## 📚 New Terminology\n\n| Term | Explanation |\n| --- | --- |\n| **Ownership** | The Rust rule that says a value can only have one owner. In composition, the container is the owner. |\n| **`Box<T>`** | A smart pointer that stores data on the Heap. Required when composing Dynamic Trait Objects (`dyn Trait`) because their size is unknown at compile time. |\n| **Contiguous Memory** | In Rust composition, fields are stored side-by-side in memory. This improves CPU cache performance compared to Java's scattered pointers. |\n| **Delegate** | A pattern where the wrapper struct (Car) calls a method on the inner struct (Engine). `car.start()` simply calls `self.engine.start()`. |\n\n\n\n"
  },
  {
    "path": "oop/rust/composition/main.rs",
    "content": "/*\n * COMPOSITION IN RUST\n *\n * Concept: \"Has-a\" relationship with Strong Ownership.\n * Pattern: Structs embedding other Structs.\n */\n\n// --- 1. COMPONENT STRUCTS ---\n\nstruct Engine {\n    horsepower: u32,\n}\n\nimpl Engine {\n    fn new(horsepower: u32) -> Self {\n        Engine { horsepower }\n    }\n\n    fn start(&self) {\n        println!(\"  -> Engine started with {} HP.\", self.horsepower);\n    }\n}\n\nstruct Wheel {\n    wheel_type: String,\n}\n\nimpl Wheel {\n    fn new(wheel_type: &str) -> Self {\n        Wheel {\n            wheel_type: wheel_type.to_string(),\n        }\n    }\n\n    fn rotate(&self) {\n        println!(\"  -> The {} wheel is rotating.\", self.wheel_type);\n    }\n}\n\nstruct Transmission {\n    trans_type: String,\n}\n\nimpl Transmission {\n    fn new(trans_type: &str) -> Self {\n        Transmission {\n            trans_type: trans_type.to_string(),\n        }\n    }\n\n    fn shift(&self) {\n        println!(\"  -> Transmission shifted: {}\", self.trans_type);\n    }\n}\n\n// --- 2. THE COMPOSITE STRUCT (Strong Ownership) ---\n\nstruct Car {\n    // The Car OWNS these objects. \n    // If Car is dropped, these are dropped.\n    engine: Engine,\n    wheels: Wheel, // Simplified to 1 wheel for demo\n    transmission: Transmission,\n}\n\nimpl Car {\n    fn new(hp: u32, wheel_type: &str, trans_type: &str) -> Self {\n        Car {\n            engine: Engine::new(hp),\n            wheels: Wheel::new(wheel_type),\n            transmission: Transmission::new(trans_type),\n        }\n    }\n\n    fn drive(&self) {\n        println!(\"Driving Car...\");\n        self.engine.start();\n        self.wheels.rotate();\n        self.transmission.shift();\n        println!(\"Car is moving!\\n\");\n    }\n}\n\n\n// --- 3. COMPOSITION WITH TRAITS (Dynamic Swapping) ---\n\ntrait PowerSource {\n    fn power_up(&self);\n}\n\nstruct ElectricMotor;\nimpl PowerSource for ElectricMotor {\n    fn power_up(&self) {\n        println!(\"  -> Electric motor humming silently... ⚡\");\n    }\n}\n\nstruct DieselMotor;\nimpl PowerSource for DieselMotor {\n    fn power_up(&self) {\n        println!(\"  -> Diesel motor rumbling... ⛽\");\n    }\n}\n\nstruct HybridVehicle {\n    // We use Box<dyn Trait> to hold any type of engine\n    power_source: Box<dyn PowerSource>,\n}\n\nimpl HybridVehicle {\n    fn new(source: Box<dyn PowerSource>) -> Self {\n        HybridVehicle { power_source: source }\n    }\n\n    fn start(&self) {\n        self.power_source.power_up();\n    }\n}\n\nfn main() {\n    println!(\"--- 1. Direct Composition (Static) ---\");\n    // We create the parts INSIDE the constructor call\n    let my_car = Car::new(150, \"Alloy\", \"Automatic\");\n    my_car.drive();\n\n\n    println!(\"--- 2. Composition with Interfaces (Dynamic) ---\");\n    \n    // We can inject dependencies dynamically\n    let ev = HybridVehicle::new(Box::new(ElectricMotor));\n    print!(\"EV: \");\n    ev.start();\n\n    let truck = HybridVehicle::new(Box::new(DieselMotor));\n    print!(\"Truck: \");\n    truck.start();\n\n    // PROOF OF OWNERSHIP\n    // Unlike Aggregation, we cannot access the 'ElectricMotor' independently \n    // after passing it to HybridVehicle. It has been moved inside.\n    println!(\"\\n(Note: The motors are now owned by the vehicles and cannot be accessed separately.)\");\n}\n"
  },
  {
    "path": "oop/rust/encapsulation/README.md",
    "content": "# Encapsulation in Rust (Modules & Visibility)\n\n## Introduction\n\n**Encapsulation** is one of the four fundamental principles of Object-Oriented Programming (OOP). It is the practice of **bundling data (variables) and methods** into a single unit while restricting direct access to the internal details.\n\n**Does Rust support Encapsulation?**\nYes, but it works differently than Java.\n1.  **Java:** Uses classes and access modifiers (`private`, `protected`, `public`) to hide data.\n2.  **Rust:** Uses **Modules** (`mod`) and the `pub` keyword. Encapsulation boundaries are set at the *Module* level, not the *Struct* level.\n\n## **What is Encapsulation?**\n\nEncapsulation means **wrapping** data and code together and restricting access.\n\n### **Key Benefits of Encapsulation**\n-   **Data Protection**: Prevents external code from corrupting internal state (e.g., negative bank balance).\n-   **Modularity**: Changes to internal logic (like how interest is calculated) don't break the code that uses it.\n-   **Interface Clarity**: Users only interact with `pub` methods, ignoring the complex details inside.\n\n---\n\n## **Encapsulation Using Visibility Modifiers (`pub`)**\n\nIn Java, you have `private`, `protected`, `public`, and package-private.\nIn Rust, everything is **private by default**.\n\n-   **Private (Default):** Accessible only within the current module (and its sub-modules).\n-   **`pub`:** Accessible from outside the module.\n-   **`pub(crate)`:** Accessible anywhere inside the same project (crate), but not by external users.\n\n### **Example: Encapsulation with Modules**\n\n```rust\n// We define a module to create a privacy boundary\nmod bank {\n    pub struct BankAccount {\n        pub owner: String, // Public: Anyone can read/write\n        balance: f64,      // Private: Only this 'bank' module can see it\n    }\n\n    impl BankAccount {\n        pub fn new(owner: &str, balance: f64) -> Self {\n            BankAccount {\n                owner: owner.to_string(),\n                balance,\n            }\n        }\n\n        pub fn get_balance(&self) -> f64 {\n            self.balance\n        }\n    }\n}\n\nfn main() {\n    let account = bank::BankAccount::new(\"Alice\", 1000.0);\n    \n    // Allowed: 'owner' is pub\n    println!(\"{}\", account.owner);\n\n    // ERROR: 'balance' is private!\n    // println!(\"{}\", account.balance); \n}\n\n```\n\n**Why Use Encapsulation?**\n\n* It ensures you cannot accidentally set `balance = -500.0`. You *must* go through a method that validates the input.\n\n---\n\n## **Encapsulation Using Getters and Setters**\n\nSince Rust fields are often private, we access them using methods.\n\n**Rust Idiom:**\n\n* **Getter:** naming convention is `field_name()`, not `get_field_name()`.\n* **Setter:** naming convention is `set_field_name()`.\n\n### **Example: Getters and Setters in Rust**\n\n```rust\npub struct Employee {\n    name: String,\n    age: u8,\n}\n\nimpl Employee {\n    // Setter\n    pub fn set_age(&mut self, age: u8) {\n        if age > 18 {\n            self.age = age;\n        } else {\n            println!(\"Age must be greater than 18\");\n        }\n    }\n\n    // Getter (Note: no 'get_' prefix)\n    pub fn age(&self) -> u8 {\n        self.age\n    }\n}\n\n```\n\n---\n\n## **Encapsulation and Data Hiding**\n\nWe hide implementation details so the user doesn't need to worry about complex validation logic.\n\n### **Example: Hiding Implementation Details**\n\n```rust\nmod finance {\n    pub struct Account {\n        balance: f64,\n    }\n\n    impl Account {\n        pub fn new(balance: f64) -> Self {\n            Account { balance }\n        }\n\n        // Private helper method (Not 'pub', so invisible outside)\n        fn validate(&self, amount: f64) -> bool {\n            amount > 0.0 && amount <= self.balance\n        }\n\n        // Public API\n        pub fn withdraw(&mut self, amount: f64) {\n            if self.validate(amount) {\n                self.balance -= amount;\n                println!(\"Withdrawal Successful: {}\", amount);\n            } else {\n                println!(\"Invalid transaction\");\n            }\n        }\n    }\n}\n\n```\n\n**Why Hide Data?**\n\n* **Safety:** The `validate` logic cannot be bypassed by external code.\n* **Simplicity:** The user just calls `withdraw`; they don't need to know *how* validation works.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case is processing payments where sensitive data (like card numbers) should never be exposed directly.\n\n```rust\nmod payment_system {\n    pub struct CreditCard {\n        number: String, // Private!\n        amount: f64,\n    }\n\n    impl CreditCard {\n        pub fn new(number: &str, amount: f64) -> Self {\n            CreditCard {\n                number: CreditCard::mask(number), // Internal logic\n                amount,\n            }\n        }\n\n        // Private utility function\n        fn mask(real_number: &str) -> String {\n            let last_4 = &real_number[real_number.len()-4..];\n            format!(\"****-****-****-{}\", last_4)\n        }\n\n        pub fn process(&self) {\n            println!(\"Charging {} to card {}\", self.amount, self.number);\n        }\n    }\n}\n\n```\n\n---\n\n## 📚 New Terminology (Java vs. Rust)\n\n| Term | Java Equivalent | Detailed Explanation |\n| --- | --- | --- |\n| **Module (`mod`)** | Package / Class | In Rust, the boundary for privacy is the **Module**, not the Class. Private items in a struct are visible to everything in the same `mod`. |\n| **`pub`** | `public` | Makes an item visible to other modules. |\n| **(No modifier)** | `private` / package-private | By default, everything in Rust is private. It is only visible within the current module and its children. |\n| **`pub(crate)`** | N/A | Visible to the entire project (crate), but hidden from anyone who uses your project as a library. |\n| **`&mut self`** | `this` (implicitly mutable) | In Java, you can always modify `this`. In Rust, you must explicitly say `&mut self` if a method changes data (like a Setter). |\n| **Getter convention** | `getName()` | In Rust, we simply use the field name: `name()`. |\n\n\n\n\n"
  },
  {
    "path": "oop/rust/encapsulation/main.rs",
    "content": "/*\n * ENCAPSULATION IN RUST\n *\n * Goal: Demonstrate Access Control, Data Hiding, and Modularity using Modules.\n */\n\n// 1. ENCAPSULATION WITH MODULES (Access Modifiers)\n// We define a module to simulate a separate file/package\nmod bank {\n    pub struct BankAccount {\n        pub owner: String, // Public: Accessible everywhere\n        balance: f64,      // Private: Accessible only inside 'mod bank'\n    }\n\n    impl BankAccount {\n        pub fn new(owner: &str, balance: f64) -> Self {\n            BankAccount {\n                owner: owner.to_string(),\n                balance,\n            }\n        }\n\n        // Getter\n        pub fn balance(&self) -> f64 {\n            self.balance\n        }\n\n        // Setter (Mutating method)\n        pub fn deposit(&mut self, amount: f64) {\n            if amount > 0.0 {\n                self.balance += amount;\n                println!(\"Deposited: {:.2}\", amount);\n            } else {\n                println!(\"Invalid deposit amount\");\n            }\n        }\n    }\n}\n\n// 2. GETTERS AND SETTERS (Idiomatic Rust)\nmod hr {\n    pub struct Employee {\n        name: String,\n        age: u8,\n    }\n\n    impl Employee {\n        pub fn new(name: &str, age: u8) -> Self {\n            Employee {\n                name: name.to_string(),\n                age,\n            }\n        }\n\n        // Getter (Rust style: no 'get_' prefix)\n        pub fn name(&self) -> &str {\n            &self.name\n        }\n\n        // Setter\n        pub fn set_age(&mut self, age: u8) {\n            if age > 18 {\n                self.age = age;\n            } else {\n                println!(\"Error: Age must be greater than 18\");\n            }\n        }\n\n        pub fn age(&self) -> u8 {\n            self.age\n        }\n    }\n}\n\n// 3. REAL WORLD: PAYMENT PROCESSING (Data Hiding)\nmod payment {\n    pub struct Processor {\n        card_number: String, // Private to keep secure\n        amount: f64,\n    }\n\n    impl Processor {\n        pub fn new(card_number: &str, amount: f64) -> Self {\n            Processor {\n                // We mask the data immediately upon creation\n                card_number: Processor::mask_card(card_number),\n                amount,\n            }\n        }\n\n        // Private helper method (Data Hiding)\n        fn mask_card(real_no: &str) -> String {\n            if real_no.len() > 4 {\n                let last_4 = &real_no[real_no.len() - 4..];\n                format!(\"****-****-****-{}\", last_4)\n            } else {\n                \"****\".to_string()\n            }\n        }\n\n        pub fn process(&self) {\n            println!(\"Processing payment of ${:.2} for card {}\", self.amount, self.card_number);\n        }\n    }\n}\n\nfn main() {\n    println!(\"--- 1. Access Modifiers ---\");\n    // We use the full path 'bank::BankAccount'\n    let mut account = bank::BankAccount::new(\"Alice\", 1000.0);\n    \n    // Valid: 'owner' is pub\n    println!(\"Account Holder: {}\", account.owner);\n    \n    // Valid: Accessing private data via public method\n    println!(\"Current Balance: {:.2}\", account.balance());\n    \n    // Invalid: Direct access would cause compile error\n    // println!(\"{}\", account.balance); // ERROR: field `balance` is private\n    \n    account.deposit(500.0);\n    println!(\"Updated Balance: {:.2}\", account.balance());\n\n\n    println!(\"\\n--- 2. Getters & Setters ---\");\n    let mut emp = hr::Employee::new(\"John Doe\", 25);\n    emp.set_age(30);\n    // emp.name = \"Jane\".to_string(); // ERROR: 'name' is private\n    println!(\"Employee: {}, Age: {}\", emp.name(), emp.age());\n\n\n    println!(\"\\n--- 3. Real World: Data Hiding ---\");\n    let p = payment::Processor::new(\"1234567812345678\", 250.00);\n    // The internal logic hid the real card number automatically\n    p.process();\n}\n"
  },
  {
    "path": "oop/rust/inheritance/README.md",
    "content": "# Inheritance in Rust (Traits & Composition)\n\n## Introduction\n\n**Inheritance** is one of the core principles of Object-Oriented Programming (OOP). It allows a class (subclass or child class) to acquire the properties and behaviors of another class (superclass or parent class). This promotes **code reuse**, **scalability**, and **maintainability**.\n\n**Does Rust support Inheritance?**\nNo, Rust does **not** support classical inheritance (e.g., `class Dog extends Animal`). Rust takes a different approach called **Composition over Inheritance**.\n\nInstead of inheriting fields and methods from a parent class, Rust uses:\n1.  **Traits:** To share behavior (methods).\n2.  **Composition:** To share state (data/fields).\n\n## **What is Inheritance?**\n\nIn traditional OOP (Java), **Inheritance** is a mechanism where a child class derives properties and behaviors from a parent class.\n\nIn Rust, since we cannot use `extends`, we achieve the same functionality by:\n- **Implementing Traits:** A struct implements a specific trait to gain its behavior.\n- **Embedding Structs:** A struct contains another struct as a field to reuse its data.\n\n### **Key Benefits of the Rust Approach**\n\n- **Avoids the \"Diamond Problem\":** Multiple inheritance of state is impossible, preventing complex conflicts.\n- **Explicit Dependencies:** You clearly see what data a struct depends on (it's listed in the fields).\n- **Flexible Behavior:** You can implement many traits for a single struct, offering more flexibility than single inheritance.\n\n---\n\n## **How to Implement \"Inheritance\" in Rust**\n\nSince Rust does not have `extends`, we use **Traits** for behavior and **Composition** for data.\n\n### **Step 1: Create a Parent Behavior (Trait)**\n\nThe parent trait contains common method signatures and default implementations.\n\n```rust\n// Parent Trait (Behavior)\npub trait Animal {\n    fn name(&self) -> &String; // Abstract method (getter)\n\n    // Default implementation (Shared Behavior)\n    fn eat(&self) {\n        println!(\"{} is eating...\", self.name());\n    }\n}\n\n```\n\n### **Step 2: Create a Child Struct using `impl`**\n\nThe child struct implements the properties and methods of the parent trait.\n\n```rust\n// Child Struct (Data)\npub struct Dog {\n    pub name: String,\n    pub breed: String,\n}\n\n// Implementing the Trait (The \"Inheritance\" link)\nimpl Animal for Dog {\n    fn name(&self) -> &String {\n        &self.name\n    }\n    \n    // 'eat()' is inherited automatically from the Trait\n}\n\nimpl Dog {\n    // Dog-specific method\n    fn bark(&self) {\n        println!(\"{} is barking...\", self.name);\n    }\n}\n\n```\n\n### **Step 3: Use the Child Struct**\n\nNow, let's create an object and use the inherited methods.\n\n```rust\nfn main() {\n    let my_dog = Dog { \n        name: \"Buddy\".to_string(),\n        breed: \"Golden Retriever\".to_string(),\n    };\n    \n    // Inherited from Animal trait\n    my_dog.eat(); \n    \n    // Defined in Dog impl block\n    my_dog.bark(); \n}\n\n```\n\n### **Output:**\n\n```\nBuddy is eating...\nBuddy is barking...\n\n```\n\n---\n\n## **Types of \"Inheritance\" Patterns in Rust**\n\nAlthough Rust lacks class inheritance, we can replicate standard OOP patterns.\n\n### **1. Single Inheritance (Trait Implementation)**\n\nA struct implements a single trait.\n\n```rust\ntrait Parent {\n    fn show(&self) {\n        println!(\"This is the parent behavior\");\n    }\n}\n\nstruct Child;\n\nimpl Parent for Child {} // Inherits 'show'\n\n```\n\n### **2. Multilevel Inheritance (Supertraits)**\n\nA trait inherits from another trait. This is called a **Supertrait**.\n\n```rust\ntrait Grandparent {\n    fn show_grand(&self);\n}\n\n// Parent requires Grandparent to be implemented first\ntrait Parent: Grandparent {\n    fn show_parent(&self);\n}\n\nstruct Child;\n\n// You must implement both\nimpl Grandparent for Child { \n    fn show_grand(&self) { println!(\"Grandparent\"); } \n}\nimpl Parent for Child { \n    fn show_parent(&self) { println!(\"Parent\"); } \n}\n\n```\n\n### **3. Hierarchical Inheritance**\n\nA single parent trait is implemented by multiple different structs.\n\n```rust\ntrait Entity {\n    fn id(&self) -> u32;\n}\n\nstruct User { id: u32 }\nimpl Entity for User { fn id(&self) -> u32 { self.id } }\n\nstruct Product { id: u32 }\nimpl Entity for Product { fn id(&self) -> u32 { self.id } }\n\n```\n\n---\n\n## **Method Overriding in Rust**\n\nMethod overriding allows a struct to **redefine** a default method provided by a Trait.\n\n```rust\ntrait Animal {\n    fn make_sound(&self) {\n        println!(\"Generic Animal Sound\");\n    }\n}\n\nstruct Dog;\n\nimpl Animal for Dog {\n    // Overriding the default method\n    fn make_sound(&self) {\n        println!(\"Dog barks! 🐶\");\n    }\n}\n\n```\n\n### **Usage**\n\n```rust\nfn main() {\n    let my_animal = Dog;\n    my_animal.make_sound(); // Runs overridden version\n}\n\n```\n\n### **Output:**\n\n```\nDog barks! 🐶\n\n```\n\n---\n\n## **The `super` Concept in Rust (Accessing Parent)**\n\nIn Java, `super` calls the parent class. In Rust, we use **Composition** to access \"parent\" data explicitly.\n\n1. **Composition:** Embedding one struct inside another.\n2. **Delegation:** Calling the inner struct's methods.\n\n```rust\n// The \"Parent\" Data\nstruct Organism {\n    age: u8,\n}\n\nimpl Organism {\n    fn breathe(&self) { println!(\"Breathing...\"); }\n}\n\n// The \"Child\" Struct\nstruct Dog {\n    organism: Organism, // Composition (Has-a)\n}\n\nimpl Dog {\n    fn breathe(&self) {\n        // Explicitly calling the \"Parent\" (inner struct)\n        self.organism.breathe(); \n        println!(\"...and panting!\");\n    }\n}\n\n```\n\n### **Summary Table**\n\n| Concept | Java (Inheritance) | Rust (Idiomatic) |\n| --- | --- | --- |\n| **Relationship** | `Dog extends Animal` | `Dog implements Animal` (Trait) |\n| **Data Sharing** | Inherited automatically | Composition (`dog.animal.field`) |\n| **Method Sharing** | Inherited from Parent Class | Default Trait Methods |\n| **Overriding** | `@Override` | `impl Trait` block |\n| **Philosophy** | **Is-a** relationship | **Has-a** & **Can-do** relationship |\n\n\n"
  },
  {
    "path": "oop/rust/inheritance/main.rs",
    "content": "/*\n * INHERITANCE IN RUST (TRAITS & COMPOSITION)\n *\n * Goal: Demonstrate how to achieve OOP Inheritance patterns using Rust.\n * * 1. Behavior Inheritance -> Traits\n * 2. Data Inheritance -> Composition\n */\n\n// --- 1. BASIC INHERITANCE (TRAITS) ---\n\n// Parent Trait\ntrait Animal {\n    fn name(&self) -> &String;\n\n    // Default method (Acts like a Parent Class method)\n    fn eat(&self) {\n        println!(\"{} is eating...\", self.name());\n    }\n}\n\n// Child Struct\nstruct Dog {\n    name: String,\n    breed: String,\n}\n\n// Implement the Trait\nimpl Animal for Dog {\n    fn name(&self) -> &String {\n        &self.name\n    }\n}\n\nimpl Dog {\n    fn bark(&self) {\n        println!(\"{} (a {}) is barking!\", self.name, self.breed);\n    }\n}\n\n\n// --- 2. MULTILEVEL INHERITANCE (SUPERTRAITS) ---\n\ntrait Living {\n    fn live(&self) { println!(\"I am alive.\"); }\n}\n\n// 'Mammal' requires 'Living' to be implemented\ntrait Mammal: Living {\n    fn walk(&self) { println!(\"I can walk.\"); }\n}\n\nstruct Cat;\n\n// Must implement the base trait\nimpl Living for Cat {}\n\n// Can now implement the sub-trait\nimpl Mammal for Cat {}\n\n\n// --- 3. METHOD OVERRIDING ---\n\ntrait SoundMaker {\n    fn make_sound(&self) {\n        println!(\"(Generic Sound)\");\n    }\n}\n\nstruct Cow;\n\nimpl SoundMaker for Cow {\n    // Override the default implementation\n    fn make_sound(&self) {\n        println!(\"Moo! 🐮\");\n    }\n}\n\n\n// --- 4. COMPOSITION (THE 'SUPER' REPLACEMENT) ---\n\n// The \"Parent\" Data\nstruct BaseEntity {\n    id: u32,\n}\n\nimpl BaseEntity {\n    fn save(&self) {\n        println!(\"Saving Entity ID: {} to database...\", self.id);\n    }\n}\n\n// The \"Child\" Data\nstruct User {\n    base: BaseEntity, // Composition: User HAS-A BaseEntity\n    username: String,\n}\n\nimpl User {\n    fn new(id: u32, username: &str) -> Self {\n        User {\n            base: BaseEntity { id },\n            username: username.to_string(),\n        }\n    }\n\n    fn save_user(&self) {\n        println!(\"Preparing user {}...\", self.username);\n        self.base.save(); // Call \"super\" method explicitly\n    }\n}\n\n\nfn main() {\n    println!(\"--- 1. Basic Inheritance (Traits) ---\");\n    let dog = Dog { \n        name: \"Buddy\".to_string(), \n        breed: \"Golden Retriever\".to_string() \n    };\n    dog.eat(); // Inherited behavior\n    dog.bark(); // Specific behavior\n\n    println!(\"\\n--- 2. Multilevel Inheritance ---\");\n    let cat = Cat;\n    cat.live(); // From Base Trait\n    cat.walk(); // From Sub Trait\n\n    println!(\"\\n--- 3. Method Overriding ---\");\n    let cow = Cow;\n    cow.make_sound(); // Overridden behavior\n\n    println!(\"\\n--- 4. Composition (Data Inheritance) ---\");\n    let user = User::new(101, \"Alice\");\n    user.save_user();\n}\n\n"
  },
  {
    "path": "oop/rust/interfaces/README.md",
    "content": "# Interfaces in Rust (Traits)\n\n## Introduction\n\nIn Object-Oriented Programming (OOP), an **Interface** is a crucial concept that defines a contract for types to follow. It allows multiple types to share a common structure while enforcing certain behaviors. Interfaces are widely used in Java to achieve **abstraction, polymorphism, and loose coupling**.\n\nIn Rust, this concept is called a **Trait**.\n\nA Trait defines functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way.\n\n## What is a Trait?\n\nA **Trait** in Rust is a collection of method signatures that a type can implement. It defines a contract that the implementing types must adhere to.\n\n### **Key Characteristics of Traits**\n- Defines a **contract** of behavior (methods) that implementing types must fulfill.\n- **Strict Separation:** Unlike Java where you write `class Car implements Vehicle`, in Rust, you define the `struct Car` (data) in one block and the `impl Vehicle for Car` (logic) in a completely separate block.\n- **Explicit Context:** Rust methods require you to explicitly say if they use the object's data by passing `&self` as the first argument.\n- Supports **Multiple Trait Implementation** (Rust's version of multiple inheritance).\n- Can contain **Default Implementations** (methods with code) and **Associated Functions** (static methods).\n\n---\n\n## **Defining and Implementing a Trait**\n\n### **Step 1: Define the Trait**\nTo define a trait (interface), use the `trait` keyword.\n\n```rust\n// Defining a trait 'Vehicle'\n// This is the \"Contract\"\npub trait Vehicle {\n    fn start(&self); // Abstract method (no body)\n    fn stop(&self);  // Abstract method (no body)\n}\n\n```\n\n### **Step 2: Implement the Trait**\n\nIn Java, you implement the interface inside the class. In Rust, you use the `impl [Trait] for [Type]` syntax.\n\n```rust\n// 1. Define the Data (Struct)\npub struct Car {\n    pub brand: String,\n}\n\n// 2. Implement the Behavior (Trait) separately\n// \"Implement the Vehicle Trait FOR the Car Struct\"\nimpl Vehicle for Car {\n    fn start(&self) {\n        println!(\"{} is starting... 🚗\", self.brand);\n    }\n\n    fn stop(&self) {\n        println!(\"{} is stopping... 🛑\", self.brand);\n    }\n}\n\n```\n\n### **Step 3: Using the Implemented Struct**\n\nWe create an instance of the struct and call the trait methods.\n\n```rust\nfn main() {\n    let my_car = Car { brand: \"Toyota\".to_string() };\n\n    // We can call methods just like in Java\n    my_car.start();\n    my_car.stop();\n}\n\n```\n\n**Output:**\n\n```text\nToyota is starting... 🚗\nToyota is stopping... 🛑\n\n```\n\n---\n\n## **Multiple Traits (Composition)**\n\nJava uses interfaces to solve the \"Multiple Inheritance\" problem. Rust does the same. A single struct can implement as many traits as necessary.\n\n```rust\n// First Trait\ntrait Flyable {\n    fn fly(&self);\n}\n\n// Second Trait\ntrait Drivable {\n    fn drive(&self);\n}\n\n// The Struct\nstruct FlyingCar;\n\n// Implement Trait 1\nimpl Flyable for FlyingCar {\n    fn fly(&self) {\n        println!(\"FlyingCar is flying... ✈️\");\n    }\n}\n\n// Implement Trait 2\nimpl Drivable for FlyingCar {\n    fn drive(&self) {\n        println!(\"FlyingCar is driving... 🚙\");\n    }\n}\n\n```\n\n### **Usage**\n\n```rust\nfn main() {\n    let my_vehicle = FlyingCar;\n    \n    // The same object can do both actions\n    my_vehicle.fly();\n    my_vehicle.drive();\n}\n\n```\n\n**Output:**\n\n```text\nFlyingCar is flying... ✈️\nFlyingCar is driving... 🚙\n\n```\n\n---\n\n## **Default and Associated Functions**\n\nRust traits are powerful. They can have **Default Implementations** (pre-written logic) and **Associated Functions** (static utility methods).\n\n### **Default Implementations**\n\nJust like Java's `default` keyword, Rust allows you to provide a method body in the trait itself. If a struct doesn't override it, the default logic is used.\n\n```rust\ntrait Animal {\n    fn sound(&self); // Abstract method (Must be implemented)\n\n    // Default method (Optional to implement)\n    fn sleep(&self) {\n        println!(\"Sleeping... 💤\");\n    }\n}\n\nstruct Dog;\n\nimpl Animal for Dog {\n    fn sound(&self) {\n        println!(\"Dog barks! 🐶\");\n    }\n    // We don't implement sleep(), so Dog gets the default behavior.\n}\n\n```\n\n### **Associated Functions (Static Methods)**\n\nIf a function inside a trait does **not** take `&self`, it acts like a Java `static` method. It belongs to the *Type*, not the *Instance*.\n\n```rust\ntrait MathOperations {\n    // No '&self' here, so this is a \"Static Method\"\n    fn add(a: i32, b: i32) -> i32 {\n        a + b\n    }\n}\n\n// We need a dummy struct to attach this trait to\nstruct Calculator;\nimpl MathOperations for Calculator {}\n\n```\n\n### **Usage**\n\n```rust\nfn main() {\n    let my_dog = Dog;\n    my_dog.sound();\n    my_dog.sleep(); // Calls default implementation\n\n    // Call static method using the Type name (::)\n    let result = Calculator::add(5, 10);\n    println!(\"Sum: {}\", result);\n}\n\n```\n\n**Output:**\n\n```text\nDog barks! 🐶\nSleeping... 💤\nSum: 15\n\n```\n\n---\n\n## **Real-World Example: Payment System**\n\nThis example demonstrates **Polymorphism**. We want to write a function that can accept *any* payment method, whether it's a Credit Card or PayPal.\n\n```rust\n// The Contract\ntrait Payment {\n    fn pay(&self, amount: f64);\n}\n\n// Struct 1: Credit Card\nstruct CreditCard;\nimpl Payment for CreditCard {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using Credit Card 💳\", amount);\n    }\n}\n\n// Struct 2: PayPal\nstruct PayPal;\nimpl Payment for PayPal {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using PayPal 🅿️\", amount);\n    }\n}\n\n```\n\n### **Usage**\n\n```rust\nfn main() {\n    let card = CreditCard;\n    let paypal = PayPal;\n\n    // The same function works for different types!\n    // We can use references to the trait object\n    let payments: Vec<&dyn Payment> = vec![&card, &paypal];\n\n    for payment in payments {\n        payment.pay(100.50);\n    }\n}\n\n```\n\n**Output:**\n\n```text\nPaid $100.50 using Credit Card 💳\nPaid $100.50 using PayPal 🅿️\n\n```\n\n---\n\n## 📚 New Terminology (Detailed Explanation)\n\nSince you are moving from Java to Rust, here are the specific new terms introduced in this topic:\n\n| Term | Java Equivalent | Detailed Explanation |\n| --- | --- | --- |\n| **Trait** | `Interface` | A set of method signatures. It defines *what* an object can do, but not *how* it does it. |\n| **`impl Trait for Type`** | `implements` | In Rust, you don't declare implementations inside the struct definition. You use a separate `impl` block to bind the Trait to the Struct. This allows you to add traits to types you didn't even create! |\n| **`&self`** | `this` | In Java, `this` is hidden/implicit. In Rust, you must **explicitly** pass `&self` as the first argument to any method that works on an instance. If you forget `&self`, Rust thinks it is a static method. |\n| **Associated Function** | `static` method | A function defined inside a trait/struct that does **not** have `&self`. It is called using `::` (e.g., `Calculator::add`) instead of `.` (dot). |\n| **`dyn Trait`** | Polymorphism | Short for \"Dynamic Dispatch\". It tells the compiler: \"I don't know the exact size of this object at compile time, but I know it implements this Trait.\" Used when storing different types in the same list (like `Vec<&dyn Payment>`). |\n\n"
  },
  {
    "path": "oop/rust/interfaces/main.rs",
    "content": "/*\n * INTERFACES IN RUST (TRAITS)\n *\n * Goal: Demonstrate how Traits act as contracts (Java Interface equivalent).\n */\n\n// 1. BASIC INTERFACE\n// The Contract\npub trait Vehicle {\n    fn start(&self);\n    fn stop(&self);\n}\n\n// The Data\npub struct Car {\n    pub brand: String,\n}\n\n// The Implementation (Binding Trait to Struct)\nimpl Vehicle for Car {\n    fn start(&self) {\n        println!(\"{} is starting... 🚗\", self.brand);\n    }\n    fn stop(&self) {\n        println!(\"{} is stopping... 🛑\", self.brand);\n    }\n}\n\n// 2. MULTIPLE INTERFACES (Composition)\ntrait Flyable {\n    fn fly(&self);\n}\n\ntrait Drivable {\n    fn drive(&self);\n}\n\nstruct FlyingCar;\n\nimpl Flyable for FlyingCar {\n    fn fly(&self) {\n        println!(\"FlyingCar is flying... ✈️\");\n    }\n}\n\nimpl Drivable for FlyingCar {\n    fn drive(&self) {\n        println!(\"FlyingCar is driving... 🚙\");\n    }\n}\n\n// 3. DEFAULT & STATIC METHODS\ntrait Animal {\n    fn sound(&self);\n    \n    // Default method (Optional to override)\n    fn sleep(&self) {\n        println!(\"Sleeping... 💤\");\n    }\n}\n\nstruct Dog;\n\nimpl Animal for Dog {\n    fn sound(&self) {\n        println!(\"Dog barks! 🐶\");\n    }\n}\n\ntrait MathOperations {\n    // Associated Function (Static Method) - No '&self'\n    fn add(a: i32, b: i32) -> i32 {\n        a + b\n    }\n}\n\nstruct Calculator;\nimpl MathOperations for Calculator {}\n\n// 4. REAL WORLD PAYMENT (POLYMORPHISM)\ntrait Payment {\n    fn pay(&self, amount: f64);\n}\n\nstruct CreditCard;\nimpl Payment for CreditCard {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using Credit Card 💳\", amount);\n    }\n}\n\nstruct PayPal;\nimpl Payment for PayPal {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using PayPal 🅿️\", amount);\n    }\n}\n\nfn main() {\n    println!(\"--- 1. Basic Interface ---\");\n    let my_car = Car { brand: \"Toyota\".to_string() };\n    my_car.start();\n    my_car.stop();\n\n    println!(\"\\n--- 2. Multiple Interfaces ---\");\n    let fly_car = FlyingCar;\n    fly_car.fly();\n    fly_car.drive();\n\n    println!(\"\\n--- 3. Default & Static Methods ---\");\n    let dog = Dog;\n    dog.sound();\n    dog.sleep(); // Uses default implementation\n    \n    // Call static method using the Type name\n    let sum = Calculator::add(5, 10);\n    println!(\"Sum: {}\", sum);\n\n    println!(\"\\n--- 4. Real World Polymorphism ---\");\n    let cc = CreditCard;\n    let pp = PayPal;\n    \n    // Using explicit loop to simulate processing different payments\n    // '&dyn Payment' allows us to store different types in one list\n    let payments: Vec<&dyn Payment> = vec![&cc, &pp];\n    for p in payments {\n        p.pay(100.0);\n    }\n}\n"
  },
  {
    "path": "oop/rust/polymorphism/README.md",
    "content": "# Polymorphism in Rust (Generics & Trait Objects)\n\n## Introduction\n\n**Polymorphism** is one of the four fundamental principles of Object-Oriented Programming (OOP). It allows a single interface to be used for different types of objects, enabling **flexibility**, **scalability**, and **code reuse**.\n\nIn Java, polymorphism is often divided into \"Overloading\" and \"Overriding.\"\nIn Rust, we classify it based on **when** the decision is made:\n1.  **Compile-time Polymorphism (Static Dispatch):** Using **Generics**. fast, zero-cost.\n2.  **Run-time Polymorphism (Dynamic Dispatch):** Using **Trait Objects** (`dyn`). Flexible, like Java.\n\n\n\n## **What is Polymorphism?**\n\n**Polymorphism** means \"many forms.\" It allows a function or method to operate on different types.\n\n### **Key Benefits of Polymorphism**\n-   **Code Reusability**: Write a single function that works for multiple types.\n-   **Scalability**: Add new types with minimal code changes.\n-   **Maintainability**: Reduce complexity and improve code clarity.\n\n---\n\n## **1. Compile-Time Polymorphism (Static Dispatch)**\n\nIn Java, this is Method Overloading. Rust **does not** support traditional Method Overloading (same name, different args).\n\nInstead, Rust uses **Generics**.\nWhen you write a generic function, the compiler generates a unique copy of that function for *every concrete type* you use. This is called **Monomorphization**.\n\n### **Example of Generics (Static Dispatch)**\n\n```rust\ntrait Addable {\n    fn add(&self, other: i32) -> i32;\n}\n\nstruct Number { value: i32 }\nimpl Addable for Number {\n    fn add(&self, other: i32) -> i32 { self.value + other }\n}\n\n// GENERIC FUNCTION:\n// The compiler creates separate machine code for every type 'T' used.\n// It effectively converts 'static_add(num)' into 'static_add_Number(num)'.\nfn static_add<T: Addable>(item: T, extra: i32) -> i32 {\n    item.add(extra)\n}\n\n```\n\n**Why Use Generics?**\n\n* **Zero Runtime Cost:** The decision of which function to call happens during compilation.\n* **Type Safety:** Errors are caught at compile time.\n\n---\n\n## **2. Run-Time Polymorphism (Dynamic Dispatch)**\n\nThis corresponds to Java's Method Overriding. The exact method to be called is determined **at runtime**.\n\nIn Rust, we achieve this using **Trait Objects**.\nA Trait Object involves a pointer (like `&` or `Box`) combined with the `dyn` keyword (e.g., `Box<dyn Animal>`). This tells Rust: *\"I don't know the exact size of this object, so look up its methods in a vtable (virtual table) at runtime.\"*\n\n### **Example of Trait Objects**\n\n```rust\ntrait Animal {\n    fn make_sound(&self);\n}\n\nstruct Dog;\nimpl Animal for Dog { fn make_sound(&self) { println!(\"Bark\"); } }\n\nstruct Cat;\nimpl Animal for Cat { fn make_sound(&self) { println!(\"Meow\"); } }\n\nfn main() {\n    // We store different types in the same list using Box<dyn Animal>\n    let animals: Vec<Box<dyn Animal>> = vec![\n        Box::new(Dog),\n        Box::new(Cat),\n    ];\n\n    for animal in animals {\n        // The specific method is decided dynamically at runtime via vtable lookup\n        animal.make_sound();\n    }\n}\n\n```\n\n**Why Use Trait Objects?**\n\n* Enables **heterogeneous collections** (storing different types in one list).\n* Supports **polymorphic behavior** where the type isn't known until runtime.\n\n---\n\n## **Real-World Example: Payment System**\n\nA common real-world use case is **payment processing**, where we want to process payments regardless of the method (Credit Card, PayPal, etc.).\n\n```rust\ntrait Payment {\n    fn pay(&self, amount: f64);\n}\n\nstruct CreditCard;\nimpl Payment for CreditCard {\n    fn pay(&self, amount: f64) { println!(\"Paid with Card: {}\", amount); }\n}\n\nstruct PayPal;\nimpl Payment for PayPal {\n    fn pay(&self, amount: f64) { println!(\"Paid with PayPal: {}\", amount); }\n}\n\n// Accepts any type that implements Payment at runtime\nfn process(method: &dyn Payment, amount: f64) {\n    method.pay(amount);\n}\n\n```\n\n---\n\n## 📚 New Terminology (Detailed Explanation)\n\nSince you are moving from Java to Rust, here are the specific new terms introduced in this topic:\n\n| Term | Java Equivalent | Detailed Explanation |\n| --- | --- | --- |\n| **Generics (`<T>`)** | Generics | In Java, generics are \"erased\" at runtime (Type Erasure). In Rust, they are \"filled in\" at compile time (Monomorphization), making them much faster. |\n| **Trait Bounds (`T: Animal`)** | `extends Interface` | A rule that says \"I will accept any Type T, *as long as* it implements the Animal Trait.\" |\n| **`dyn` Keyword** | Runtime Type | Short for \"Dynamic\". It tells the compiler: \"I don't know the exact size of this object right now, so treat it as a generic object implementing this trait.\" |\n| **Trait Object** | Interface Reference | A combination of a pointer to data and a pointer to methods (vtable). Example: `Box<dyn Animal>` or `&dyn Animal`. |\n| **Static Dispatch** | N/A (Optimization) | The compiler decides *exactly* which function to call while compiling. This is the default in Rust. |\n| **Dynamic Dispatch** | Method Overriding | The program decides which function to call while running. This is the default in Java. |\n| **Monomorphization** | N/A | The fancy word for the compiler copying your generic code for every concrete type you use. |\n| **VTable** | Virtual Method Table | A hidden table of function pointers used to look up methods at runtime for dynamic dispatch. |\n\n---\n\n"
  },
  {
    "path": "oop/rust/polymorphism/main.rs",
    "content": "/*\n * POLYMORPHISM IN RUST\n *\n * Goal: Demonstrate Static Dispatch (Generics) and Dynamic Dispatch (Trait Objects).\n */\n\n// --- 1. COMPILE-TIME POLYMORPHISM (GENERICS) ---\n\n// Define a trait\ntrait Addable {\n    fn add(&self, other: i32) -> i32;\n}\n\n// Implement for a struct\nstruct Number {\n    value: i32,\n}\n\nimpl Addable for Number {\n    fn add(&self, other: i32) -> i32 {\n        self.value + other\n    }\n}\n\n// Generic Function (Static Dispatch)\n// T: Addable means \"Any type T that implements Addable\"\n// Compiler creates a specific version of this function for 'Number'\nfn static_add<T: Addable>(item: T, extra: i32) -> i32 {\n    item.add(extra)\n}\n\n\n// --- 2. RUN-TIME POLYMORPHISM (TRAIT OBJECTS) ---\n\ntrait Animal {\n    fn make_sound(&self);\n}\n\nstruct Dog;\nimpl Animal for Dog {\n    fn make_sound(&self) {\n        println!(\"Dog barks 🐶\");\n    }\n}\n\nstruct Cat;\nimpl Animal for Cat {\n    fn make_sound(&self) {\n        println!(\"Cat meows 🐱\");\n    }\n}\n\n\n// --- 3. POLYMORPHISM WITH TRAITS (INTERFACES) ---\n\ntrait Vehicle {\n    fn start(&self);\n}\n\nstruct Car;\nimpl Vehicle for Car {\n    fn start(&self) {\n        println!(\"Car is starting... 🚗\");\n    }\n}\n\nstruct Bike;\nimpl Vehicle for Bike {\n    fn start(&self) {\n        println!(\"Bike is starting... 🏍️\");\n    }\n}\n\n\n// --- 4. REAL WORLD EXAMPLE: PAYMENT SYSTEM ---\n\ntrait Payment {\n    fn pay(&self, amount: f64);\n}\n\nstruct CreditCardPayment;\nimpl Payment for CreditCardPayment {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using Credit Card 💳\", amount);\n    }\n}\n\nstruct PayPalPayment;\nimpl Payment for PayPalPayment {\n    fn pay(&self, amount: f64) {\n        println!(\"Paid ${:.2} using PayPal 🅿️\", amount);\n    }\n}\n\n// Helper function accepting a Trait Object (Dynamic Dispatch)\nfn process(payment_method: &dyn Payment, amount: f64) {\n    payment_method.pay(amount);\n}\n\n\nfn main() {\n    println!(\"--- 1. Compile-Time Polymorphism (Generics) ---\");\n    let num = Number { value: 10 };\n    // The compiler generates a specific version of static_add for 'Number'\n    let result = static_add(num, 5); \n    println!(\"Result: {}\", result);\n\n\n    println!(\"\\n--- 2. Run-Time Polymorphism (Dynamic Dispatch) ---\");\n    // We use Box<dyn Animal> to store different types in one Vec\n    // This requires a vtable lookup at runtime\n    let animals: Vec<Box<dyn Animal>> = vec![\n        Box::new(Dog),\n        Box::new(Cat),\n    ];\n\n    for animal in animals {\n        // Method called is determined at runtime\n        animal.make_sound();\n    }\n\n\n    println!(\"\\n--- 3. Using Polymorphism with Traits ---\");\n    let my_car = Car;\n    let my_bike = Bike;\n\n    // References (&dyn Vehicle) are also Trait Objects\n    let vehicles: Vec<&dyn Vehicle> = vec![&my_car, &my_bike];\n    for v in vehicles {\n        v.start();\n    }\n\n\n    println!(\"\\n--- 4. Real-World Example: Payment System ---\");\n    let cc = CreditCardPayment;\n    let pp = PayPalPayment;\n\n    // We can swap implementations easily\n    process(&cc, 100.50);\n    process(&pp, 200.75);\n}\n\n"
  },
  {
    "path": "problems/airline-management-system.md",
    "content": "# Designing an Airline Management System\n\n## Requirements\n\n1. The airline management system should allow users to search for flights based on source, destination, and date.\n2. Users should be able to book flights, select seats, and make payments.\n3. The system should manage flight schedules, aircraft assignments, and crew assignments.\n4. The system should handle passenger information, including personal details and baggage information.\n5. The system should support different types of users, such as passengers, airline staff, and administrators.\n6. The system should be able to handle cancellations, refunds, and flight changes.\n7. The system should ensure data consistency and handle concurrent access to shared resources.\n8. The system should be scalable and extensible to accommodate future enhancements and new features.\n\n## UML Class Diagram\n\n![](../class-diagrams/airlinemanagementsystem-class-diagram.png)\n\n## Implementations\n\n#### [Java Implementation](../solutions/java/src/airlinemanagementsystem/)\n\n#### [Python Implementation](../solutions/python/airlinemanagementsystem/)\n\n#### [C++ Implementation](../solutions/cpp/airlinemanagementsystem/)\n\n#### [C# Implementation](../solutions/csharp/airlinemanagementsystem/)\n\n#### [Go Implementation](../solutions/golang/airlinemanagementsystem/)\n\n## Classes, Interfaces and Enumerations\n\n1. The **Flight** class represents a flight in the airline management system, with properties such as flight number, source, destination, departure time, arrival time, and available seats.\n2. The **Aircraft** class represents an aircraft, with properties like tail number, model, and total seats.\n3. The **Passenger** class represents a passenger, with properties such as ID, name, email, and phone number.\n4. The **Booking** class represents a booking made by a passenger for a specific flight and seat, with properties such as booking number, flight, passenger, seat, price, and booking status.\n5. The **Seat** class represents a seat on a flight, with properties like seat number, seat type, and seat status.\n6. The **Payment** class represents a payment made for a booking, with properties such as payment ID, payment method, amount, and payment status.\n7. The **FlightSearch** class provides functionality to search for flights based on source, destination, and date.\n8. The **BookingManager** class manages the creation and cancellation of bookings. It follows the Singleton pattern to ensure a single instance of the booking manager.\n9. The **PaymentProcessor** class handles the processing of payments. It follows the Singleton pattern to ensure a single instance of the payment processor.\n10. The **AirlineManagementSystem** class serves as the main entry point of the system, combining all the components and providing methods for flight management, booking, payment processing, and other operations.\n"
  },
  {
    "path": "problems/atm.md",
    "content": "# Designing an ATM System\n\n## Requirements\n1. The ATM system should support basic operations such as balance inquiry, cash withdrawal, and cash deposit.\n2. Users should be able to authenticate themselves using a card and a PIN (Personal Identification Number).\n3. The system should interact with a bank's backend system to validate user accounts and perform transactions.\n4. The ATM should have a cash dispenser to dispense cash to users.\n5. The system should handle concurrent access and ensure data consistency.\n6. The ATM should have a user-friendly interface for users to interact with.\n\n## UML Class Diagram\n\n![](../class-diagrams/atm-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/atm/) \n#### [Python Implementation](../solutions/python/atm/)\n#### [C++ Implementation](../solutions/cpp/atm/)\n#### [C# Implementation](../solutions/csharp/atm/)\n#### [Go Implementation](../solutions/golang/atm/)\n\n## Classes, Interfaces and Enumerations\n1. The **Card** class represents an ATM card with a card number and PIN.\n2. The **Account** class represents a bank account with an account number and balance. It provides methods to debit and credit the account balance.\n3. The **Transaction** class is an abstract base class for different types of transactions, such as withdrawal and deposit. It is extended by WithdrawalTransaction and DepositTransaction classes.\n4. The **BankingService** class manages the bank accounts and processes transactions. It uses a thread-safe ConcurrentHashMap to store and retrieve account information.\n5. The **CashDispenser** class represents the ATM's cash dispenser and handles the dispensing of cash. It uses synchronization to ensure thread safety when dispensing cash.\n6. The **ATM** class serves as the main interface for ATM operations. It interacts with the BankingService and CashDispenser to perform user authentication, balance inquiry, cash withdrawal, and cash deposit.\n7. The **ATMDriver** class demonstrates the usage of the ATM system by creating sample accounts and performing ATM operations."
  },
  {
    "path": "problems/car-rental-system.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## UML Class Diagram\n\n![](../class-diagrams/carrentalsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/carrentalsystem/) \n#### [Python Implementation](../solutions/python/carrentalsystem/)\n#### [C++ Implementation](../solutions/cpp/carrentalsystem/)\n#### [C# Implementation](../solutions/csharp/carrentalsystem/)\n#### [Go Implementation](../solutions/golang/carrentalsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "problems/chess-game.md",
    "content": "# Designing a Chess Game\n\n## Requirements\n1. The chess game should follow the standard rules of chess.\n2. The game should support two players, each controlling their own set of pieces.\n3. The game board should be represented as an 8x8 grid, with alternating black and white squares.\n4. Each player should have 16 pieces: 1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.\n5. The game should validate legal moves for each piece and prevent illegal moves.\n6. The game should detect checkmate and stalemate conditions.\n7. The game should handle player turns and allow players to make moves alternately.\n8. The game should provide a user interface for players to interact with the game.\n\n## UML Class Diagram\n\n![](../class-diagrams/chessgame-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/chessgame/) \n#### [Python Implementation](../solutions/python/chessgame/)\n#### [C++ Implementation](../solutions/cpp/chessgame/)\n#### [C# Implementation](../solutions/csharp/chessgame/)\n#### [Go Implementation](../solutions/golang/chessgame/)\n\n## Classes, Interfaces and Enumerations\n1. The **Piece** class is an abstract base class representing a chess piece. It contains common attributes such as color, row, and column, and declares an abstract method canMove to be implemented by each specific piece class.\n2. The **King**, **Queen**, **Rook**, **Bishop**, **Knight**, and **Pawn** classes extend the Piece class and implement their respective movement logic in the canMove method.\n3. The **Board** class represents the chess board and manages the placement of pieces. It provides methods to get and set pieces on the board, check the validity of moves, and determine checkmate and stalemate conditions.\n4. The **Player** class represents a player in the game and has a method to make a move on the board.\n5. The Move class represents a move made by a player, containing the piece being moved and the destination coordinates.\n6. The **Game** class orchestrates the overall game flow. It initializes the board, handles player turns, and determines the game result.\n7. The **ChessGame** class is the entry point of the application and starts the game."
  },
  {
    "path": "problems/coffee-vending-machine.md",
    "content": "# Designing a Coffee Vending Machine\n\n## Requirements\n1. The coffee vending machine should support different types of coffee, such as espresso, cappuccino, and latte.\n2. Each type of coffee should have a specific price and recipe (ingredients and their quantities).\n3. The machine should have a menu to display the available coffee options and their prices.\n4. Users should be able to select a coffee type and make a payment.\n5. The machine should dispense the selected coffee and provide change if necessary.\n6. The machine should track the inventory of ingredients and notify when they are running low.\n7. The machine should handle multiple user requests concurrently and ensure thread safety.\n\n## UML Class Diagram\n\n![](../class-diagrams/coffeevendingmachine-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/coffeevendingmachine/) \n#### [Python Implementation](../solutions/python/coffeevendingmachine/)\n#### [C++ Implementation](../solutions/cpp/coffeevendingmachine/)\n#### [C# Implementation](../solutions/csharp/coffeevendingmachine/)\n#### [Go Implementation](../solutions/golang/coffeevendingmachine/)\n#### [TypeScript Implementation](../solutions/typescript/src/CoffeeVendingMachine/)\n\n## Classes, Interfaces and Enumerations\n1. The **Coffee** class represents a coffee type with its name, price, and recipe (ingredients and their quantities).\n2. The **Ingredient** class represents an ingredient used in making coffee, with its name and quantity. It provides a synchronized method to update the quantity.\n3. The **Payment** class represents a payment made by a user, with the amount paid.\n4. The **CoffeeMachine** class is the main class that manages the coffee vending machine. It follows the Singleton pattern to ensure a single instance of the machine.\n5. The **CoffeeMachine** class initializes the coffee menu and ingredients in its constructor. It provides methods to display the menu, select a coffee, dispense coffee, and update ingredient quantities.\n6. The hasEnoughIngredients method checks if there are sufficient ingredients to make a selected coffee, while the updateIngredients method updates the ingredient quantities after dispensing a coffee.\n7. The **CoffeeVendingMachine** class is the entry point of the application and demonstrates the usage of the coffee vending machine. It creates an instance of the machine, displays the menu, and simulates concurrent user requests using an ExecutorService."
  },
  {
    "path": "problems/concert-ticket-booking-system.md",
    "content": "# Designing a Concert Ticket Booking System\n\n## Requirements\n1. The concert ticket booking system should allow users to view available concerts and their seating arrangements.\n2. Users should be able to search for concerts based on various criteria such as artist, venue, date, and time.\n3. Users should be able to select seats and purchase tickets for a specific concert.\n4. The system should handle concurrent booking requests to avoid double-booking of seats.\n5. The system should ensure fair booking opportunities for all users.\n6. The system should handle payment processing securely.\n7. The system should generate booking confirmations and send them to users via email or SMS.\n8. The system should provide a waiting list functionality for sold-out concerts.\n\n## UML Class Diagram\n\n![](../class-diagrams/concertticketbookingsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/concertticketbookingsystem/) \n#### [Python Implementation](../solutions/python/concertticketbookingsystem/)\n#### [C++ Implementation](../solutions/cpp/concertticketbookingsystem/)\n#### [C# Implementation](../solutions/csharp/concertticketbookingsystem/)\n#### [Go Implementation](../solutions/golang/concertticketbookingsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Concert** class represents a concert event, with properties such as ID, artist, venue, date and time, and a list of seats.\n2. The **Seat** class represents a seat in a concert, with properties like ID, seat number, seat type, price, and status. It provides methods to book and release a seat.\n3. The **SeatType** enum represents the different types of seats available, such as regular, premium, and VIP.\n4. The **SeatStatus** enum represents the status of a seat, which can be available, booked, or reserved.\n5. The **Booking** class represents a booking made by a user for a specific concert and seats. It contains properties such as ID, user, concert, seats, total price, and status. It provides methods to confirm and cancel a booking.\n6. The **BookingStatus** enum represents the status of a booking, which can be pending, confirmed, or cancelled.\n7. The **User** class represents a user of the concert ticket booking system, with properties like ID, name, and email.\n8. The **ConcertTicketBookingSystem** class is the central component of the system. It follows the Singleton pattern to ensure a single instance of the system. It manages concerts, bookings, and provides methods to add concerts, search concerts, book tickets, and cancel bookings.\n9. The **SeatNotAvailableException** is a custom exception used to handle cases where a seat is not available for booking."
  },
  {
    "path": "problems/course-registration-system.md",
    "content": "# Designing a University Course Registration System\n\n## Requirements\n1. The course registration system should allow students to register for courses and view their registered courses.\n2. Each course should have a course code, name, instructor, and maximum enrollment capacity.\n3. Students should be able to search for courses based on course code or name.\n4. The system should prevent students from registering for courses that have reached their maximum enrollment capacity.\n5. The system should handle concurrent registration requests from multiple students.\n6. The system should ensure data consistency and prevent race conditions.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## UML Class Diagram\n\n![](../class-diagrams/courseregistrationsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/courseregistrationsystem/) \n#### [Python Implementation](../solutions/python/courseregistrationsystem/)\n#### [C++ Implementation](../solutions/cpp/courseregistrationsystem/)\n#### [C# Implementation](../solutions/csharp/courseregistrationsystem/)\n#### [Go Implementation](../solutions/golang/courseregistrationsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Student** class represents a student in the course registration system, with properties such as ID, name, email, and a list of registered courses.\n2. The **Course** class represents a course offered in the system, with properties such as code, name, instructor, maximum capacity, and the number of enrolled students.\n3. The **Registration** class represents a registration record, associating a student with a course and capturing the registration timestamp.\n4. The **CourseRegistrationSystem** class is the main class that manages the course registration system. It follows the Singleton pattern to ensure only one instance of the system exists.\n5. The CourseRegistrationSystem class provides methods for adding courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student.\n6. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as courses and registrations.\n7. The registerCourse method is synchronized to ensure thread safety when multiple students are registering for courses simultaneously.\n8. The notifyObservers method is a placeholder for notifying observers (e.g., UI components) about updates to course enrollment.\n9. The **CourseRegistrationDemo** class demonstrates the usage of the course registration system by creating courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student."
  },
  {
    "path": "problems/cricinfo.md",
    "content": "# Designing a Cricket Information System like CricInfo\n\n## Requirements\n1. The Cricinfo system should provide information about cricket matches, teams, players, and live scores.\n2. Users should be able to view the schedule of upcoming matches and the results of completed matches.\n3. The system should allow users to search for specific matches, teams, or players.\n4. Users should be able to view detailed information about a particular match, including the scorecard, commentary, and statistics.\n5. The system should support real-time updates of live scores and match information.\n6. The system should handle concurrent access to match data and ensure data consistency.\n7. The system should be scalable and able to handle a large volume of user requests.\n8. The system should be extensible to accommodate new features and enhancements in the future.\n\n## UML Class Diagram\n\n![](../class-diagrams/cricinfo-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/cricinfo/) \n#### [Python Implementation](../solutions/python/cricinfo/)\n#### [C++ Implementation](../solutions/cpp/cricinfo/)\n#### [C# Implementation](../solutions/csharp/cricinfo/)\n#### [Go Implementation](../solutions/golang/cricinfo/)\n\n## Classes, Interfaces and Enumerations\n1. The **Match** class represents a cricket match, with properties such as ID, title, venue, start time, teams, status, and scorecard.\n2. The **Team** class represents a cricket team, with properties like ID, name, and a list of players.\n3. The **Player** class represents a cricket player, with properties such as ID, name, and role.\n4. The **Scorecard** class represents the scorecard of a match, containing team scores and a list of innings.\n5. The **Innings** class represents an innings in a match, with properties like ID, batting team, bowling team, and a list of overs.\n6. The **Over** class represents an over in an innings, containing a list of balls.\n7. The **Ball** class represents a ball bowled in an over, with properties such as ball number, bowler, batsman, and result.\n8. The **MatchStatus** enum represents the different statuses of a match, such as scheduled, in progress, completed, or abandoned.\n9. The **MatchService** class manages the matches in the system, providing methods to add, retrieve, and update match information. It follows the Singleton pattern to ensure a single instance of the service.\n10. The **ScorecardService** class manages the scorecards of matches, allowing the creation, retrieval, and update of scorecards and their associated data, such as innings and scores. It also follows the Singleton pattern.\n11. The **CricinfoSystem** class serves as the main entry point of the system, integrating the match and scorecard services and providing high-level methods for interacting with the system."
  },
  {
    "path": "problems/digital-wallet-service.md",
    "content": "# Designing a Digital Wallet Service\n\n## Requirements\n1. The digital wallet should allow users to create an account and manage their personal information.\n2. Users should be able to add and remove payment methods, such as credit cards or bank accounts.\n3. The digital wallet should support fund transfers between users and to external accounts.\n4. The system should handle transaction history and provide a statement of transactions.\n5. The digital wallet should support multiple currencies and perform currency conversions.\n6. The system should ensure the security of user information and transactions.\n7. The digital wallet should handle concurrent transactions and ensure data consistency.\n8. The system should be scalable to handle a large number of users and transactions.\n\n## UML Class Diagram\n\n![](../class-diagrams/digitalwalletservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/digitalwalletservice/) \n#### [Python Implementation](../solutions/python/digitalwalletservice/)\n#### [C++ Implementation](../solutions/cpp/digitalwalletservice/)\n#### [C# Implementation](../solutions/csharp/digitalwalletservice/)\n#### [Go Implementation](../solutions/golang/digitalwalletservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the digital wallet, with properties such as ID, name, email, password, and a list of accounts.\n2. The **Account** class represents a user's account within the digital wallet, with properties like ID, user, account number, currency, balance, and a list of transactions. It provides methods to deposit and withdraw funds.\n3. The **Transaction** class represents a financial transaction between two accounts, containing properties such as ID, source account, destination account, amount, currency, and timestamp.\n4. The **PaymentMethod** class is an abstract base class for different payment methods, such as credit cards and bank accounts. It defines the common properties and methods for processing payments.\n5. The **CreditCard** and **BankAccount** classes are concrete implementations of the PaymentMethod class, representing specific payment methods.\n6. The **Currency** enum represents different currencies supported by the digital wallet.\n7. The **CurrencyConverter** class provides a static method to convert amounts between different currencies based on predefined exchange rates.\n8. The **DigitalWallet** class is the central component of the digital wallet system. It follows the Singleton pattern to ensure only one instance of the digital wallet exists. It provides methods to create users, accounts, add payment methods, transfer funds, and retrieve transaction history. It handles concurrent access to shared resources using synchronization.\n9. The **DigitalWalletDemo** class demonstrates the usage of the digital wallet system by creating users, accounts, adding payment methods, depositing funds, transferring funds, and retrieving transaction history."
  },
  {
    "path": "problems/elevator-system.md",
    "content": "# Designing an Elevator System\n\n## Requirements\n1. The elevator system should consist of multiple elevators serving multiple floors.\n2. Each elevator should have a capacity limit and should not exceed it.\n3. Users should be able to request an elevator from any floor and select a destination floor.\n4. The elevator system should efficiently handle user requests and optimize the movement of elevators to minimize waiting time.\n5. The system should prioritize requests based on the direction of travel and the proximity of the elevators to the requested floor.\n6. The elevators should be able to handle multiple requests concurrently and process them in an optimal order.\n7. The system should ensure thread safety and prevent race conditions when multiple threads interact with the elevators.\n\n## UML Class Diagram\n\n![](../class-diagrams/elevatorsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/elevatorsystem/) \n#### [Python Implementation](../solutions/python/elevatorsystem/)\n#### [C++ Implementation](../solutions/cpp/elevatorsystem/)\n#### [C# Implementation](../solutions/csharp/elevatorsystem/)\n#### [Go Implementation](../solutions/golang/elevatorsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Direction** enum represents the possible directions of elevator movement (UP or DOWN).\n2. The **Request** class represents a user request for an elevator, containing the source floor and destination floor.\n3. The **Elevator** class represents an individual elevator in the system. It has a capacity limit and maintains a list of 4. requests. The elevator processes requests concurrently and moves between floors based on the requests.\n4. The **ElevatorController** class manages multiple elevators and handles user requests. It finds the optimal elevator to serve a request based on the proximity of the elevators to the requested floor.\n5. The **ElevatorSystem** class is the entry point of the application and demonstrates the usage of the elevator system."
  },
  {
    "path": "problems/food-delivery-service.md",
    "content": "# Designing an Online Food Delivery Service Like Swiggy\n\n## Requirements\n1. The food delivery service should allow customers to browse restaurants, view menus, and place orders.\n2. Restaurants should be able to manage their menus, prices, and availability.\n3. Delivery agents should be able to accept and fulfill orders.\n4. The system should handle order tracking and status updates.\n5. The system should support multiple payment methods.\n6. The system should handle concurrent orders and ensure data consistency.\n7. The system should be scalable and handle a high volume of orders.\n8. The system should provide real-time notifications to customers, restaurants, and delivery agents.\n\n## UML Class Diagram\n\n![](../class-diagrams/fooddeliveryservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/fooddeliveryservice/) \n#### [Python Implementation](../solutions/python/fooddeliveryservice/)\n#### [C++ Implementation](../solutions/cpp/fooddeliveryservice/)\n#### [C# Implementation](../solutions/csharp/fooddeliveryservice/)\n#### [Go Implementation](../solutions/golang/fooddeliveryservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **Customer** class represents a customer who can place orders. It contains customer details such as ID, name, email, and phone number.\n2. The **Restaurant** class represents a restaurant that offers menu items. It contains restaurant details such as ID, name, address, and a list of menu items. It provides methods to add and remove menu items.\n3. The **MenuItem** class represents an item on a restaurant's menu. It contains details such as ID, name, description, price, and availability status.\n4. The **Order** class represents an order placed by a customer. It contains order details such as ID, customer, restaurant, list of order items, status, and assigned delivery agent. It provides methods to add and remove order items, update order status, and assign a delivery agent.\n5. The **OrderItem** class represents an item within an order. It contains the selected menu item and the quantity ordered.\n6. The **OrderStatus** enum represents the different statuses an order can have, such as PENDING, CONFIRMED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.\n7. The **DeliveryAgent** class represents a delivery agent who fulfills orders. It contains details such as ID, name, phone number, and availability status.\n8. The **FoodDeliveryService** class is the main class that manages the food delivery service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register customers, restaurants, and delivery agents, retrieve available restaurants and menus, place orders, update order status, cancel orders, and assign delivery agents to orders. It also handles notifications to customers, restaurants, and delivery agents."
  },
  {
    "path": "problems/hotel-management-system.md",
    "content": "# Designing a Hotel Management System\n\n## Requirements\n1. The hotel management system should allow guests to book rooms, check-in, and check-out.\n2. The system should manage different types of rooms, such as single, double, deluxe, and suite.\n3. The system should handle room availability and reservation status.\n4. The system should allow the hotel staff to manage guest information, room assignments, and billing.\n5. The system should support multiple payment methods, such as cash, credit card, and online payment.\n6. The system should handle concurrent bookings and ensure data consistency.\n7. The system should provide reporting and analytics features for hotel management.\n8. The system should be scalable and handle a large number of rooms and guests.\n\n## UML Class Diagram\n\n![](../class-diagrams/hotelmanagementsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/hotelmanagementsystem/) \n#### [Python Implementation](../solutions/python/hotelmanagementsystem/)\n#### [C++ Implementation](../solutions/cpp/hotelmanagementsystem/)\n#### [C# Implementation](../solutions/csharp/hotelmanagementsystem/)\n#### [Go Implementation](../solutions/golang/hotelmanagementsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Guest** class represents a guest of the hotel, with properties such as ID, name, email, and phone number.\n2. The **Room** class represents a room in the hotel, with properties like ID, room type, price, and status. It provides methods to book, check-in, and check-out a room.\n3. The **RoomType** enum represents the different types of rooms available in the hotel.\n4. The **RoomStatus** enum represents the status of a room, which can be available, booked, or occupied.\n5. The **Reservation** class represents a reservation made by a guest for a specific room and date range. It contains properties such as ID, guest, room, check-in date, check-out date, and status. It provides a method to cancel a reservation.\n6. The **ReservationStatus** enum represents the status of a reservation, which can be confirmed or cancelled.\n7. The **Payment** interface defines the contract for processing payments. It is implemented by concrete payment classes like CashPayment and CreditCardPayment.\n8. The **HotelManagementSystem** class is the central component of the hotel management system. It follows the Singleton pattern to ensure only one instance of the system exists. It provides methods to add guests and rooms, book rooms, cancel reservations, check-in, check-out, and process payments. It also handles concurrent access to shared resources using synchronization.\n9. The **HotelManagementSystemDemo** class demonstrates the usage of the hotel management system by creating guests, rooms, booking a room, checking in, checking out, and cancelling a reservation."
  },
  {
    "path": "problems/library-management-system.md",
    "content": "# Designing a Library Management System\n\n## Requirements\n1. The library management system should allow librarians to manage books, members, and borrowing activities.\n2. The system should support adding, updating, and removing books from the library catalog.\n3. Each book should have details such as title, author, ISBN, publication year, and availability status.\n4. The system should allow members to borrow and return books.\n5. Each member should have details such as name, member ID, contact information, and borrowing history.\n6. The system should enforce borrowing rules, such as a maximum number of books that can be borrowed at a time and loan duration.\n7. The system should handle concurrent access to the library catalog and member records.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## UML Class Diagram\n\n![](../class-diagrams/librarymanagementsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/librarymanagementsystem/) \n#### [Python Implementation](../solutions/python/librarymanagementsystem/)\n#### [C++ Implementation](../solutions/cpp/librarymanagementsystem/)\n#### [C# Implementation](../solutions/csharp/librarymanagementsystem/)\n#### [Go Implementation](../solutions/golang/librarymanagementsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Book** class represents a book in the library catalog, with properties such as ISBN, title, author, publication year, and availability status.\n2. The **Member** class represents a library member, with properties like member ID, name, contact information, and a list of borrowed books.\n3. The **LibraryManager** class is the core of the library management system and follows the Singleton pattern to ensure a single instance of the library manager.\n4. The LibraryManager class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to the library catalog and member records.\n5. The LibraryManager class provides methods for adding and removing books, registering and unregistering members, borrowing and returning books, and searching for books based on keywords.\n6. The **LibraryManagementSystemDemo** class serves as the entry point of the application and demonstrates the usage of the library management system."
  },
  {
    "path": "problems/linkedin.md",
    "content": "# Designing a Professional Networking Platform like LinkedIn\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their professional information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their professional information, such as profile picture, headline, summary, experience, education, and skills.\n- Users should be able to update their profile information.\n#### Connections:\n- Users should be able to send connection requests to other users.\n- Users should be able to accept or decline connection requests.\n- Users should be able to view their list of connections.\n#### Messaging:\n- Users should be able to send messages to their connections.\n- Users should be able to view their inbox and sent messages.\n#### Job Postings:\n- Employers should be able to post job listings with details such as title, description, requirements, and location.\n- Users should be able to view and apply for job postings.\n#### Search Functionality:\n- Users should be able to search for other users, companies, and job postings based on relevant criteria.\n- Search results should be ranked based on relevance and user preferences.\n#### Notifications:\n- Users should receive notifications for events such as connection requests, messages, and job postings.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## UML Class Diagram\n\n![](../class-diagrams/linkedin-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/linkedin/) \n#### [Python Implementation](../solutions/python/linkedin/)\n#### [C++ Implementation](../solutions/cpp/linkedin/)\n#### [C# Implementation](../solutions/csharp/linkedin/)\n#### [Go Implementation](../solutions/golang/linkedin/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the LinkedIn system, containing properties such as ID, name, email, password, profile, connections, inbox, and sent messages.\n2. The **Profile** class represents a user's profile, containing properties such as profile picture, headline, summary, experiences, educations, and skills.\n3. The **Experience**, **Education**, and **Skill** classes represent different components of a user's profile.\n4. The **Connection** class represents a connection between two users, containing the user and the connection date.\n5. The **Message** class represents a message sent between users, containing properties such as ID, sender, receiver, content, and timestamp.\n6. The **JobPosting** class represents a job listing posted by an employer, containing properties such as ID, title, description, requirements, location, and post date.\n7. The **Notification** class represents a notification generated for a user, containing properties such as ID, user, notification type, content, and timestamp.\n8. The **NotificationType** enum defines the different types of notifications, such as connection request, message, and job posting.\n9. The **LinkedInService** class is the main class that manages the LinkedIn system. It follows the Singleton pattern to ensure only one instance of the service exists.\n10. The **LinkedInService** class provides methods for user registration, login, profile updates, connection requests, job postings, user and job search, messaging, and notifications.\n11. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n12. The **LinkedInDemo** class demonstrates the usage of the LinkedIn system by registering users, logging in, updating profiles, sending connection requests, posting job listings, searching for users and jobs, sending messages, and retrieving notifications."
  },
  {
    "path": "problems/logging-framework.md",
    "content": "# Designing a Logging Framework\n\n## Requirements\n1. The logging framework should support different log levels, such as DEBUG, INFO, WARNING, ERROR, and FATAL.\n2. It should allow logging messages with a timestamp, log level, and message content.\n3. The framework should support multiple output destinations, such as console, file, and database.\n4. It should provide a configuration mechanism to set the log level and output destination.\n5. The logging framework should be thread-safe to handle concurrent logging from multiple threads.\n6. It should be extensible to accommodate new log levels and output destinations in the future.\n\n## UML Class Diagram\n\n![](../class-diagrams/loggingframework-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/loggingframework/) \n#### [Python Implementation](../solutions/python/loggingframework/)\n#### [C++ Implementation](../solutions/cpp/loggingframework/)\n#### [C# Implementation](../solutions/csharp/loggingframework/)\n#### [Go Implementation](../solutions/golang/loggingframework/)\n#### [TypeScript Implementation](../solutions/typescript/src/LoggingFramework/)\n\n## Classes, Interfaces and Enumerations\n1. The **LogLevel** enum defines the different log levels supported by the logging framework.\n2. The **LogMessage** class represents a log message with a timestamp, log level, and message content.\n3. The **LogAppender** interface defines the contract for appending log messages to different output destinations.\n4. The **ConsoleAppender**, **FileAppender**, and **DatabaseAppender** classes are concrete implementations of the LogAppender interface, supporting logging to the console, file, and database, respectively.\n5. The **LoggerConfig** class holds the configuration settings for the logger, including the log level and the selected log appender.\n6. The **Logger** class is a singleton that provides the main logging functionality. It allows setting the configuration, logging messages at different levels, and provides convenience methods for each log level.\n7. The **LoggingExample** class demonstrates the usage of the logging framework, showcasing different log levels, changing the configuration, and logging from multiple threads."
  },
  {
    "path": "problems/lru-cache.md",
    "content": "# Designing a LRU Cache\n\n## Requirements\n1. The LRU cache should support the following operations:\n- put(key, value): Insert a key-value pair into the cache. If the cache is at capacity, remove the least recently used item before inserting the new item.\n- get(key): Get the value associated with the given key. If the key exists in the cache, move it to the front of the cache (most recently used) and return its value. If the key does not exist, return -1.\n2. The cache should have a fixed capacity, specified during initialization.\n3. The cache should be thread-safe, allowing concurrent access from multiple threads.\n4. The cache should be efficient in terms of time complexity for both put and get operations, ideally O(1).\n\n## UML Class Diagram\n\n![](../class-diagrams/lrucache-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/lrucache/) \n#### [Python Implementation](../solutions/python/lrucache/)\n#### [C++ Implementation](../solutions/cpp/lrucache/)\n#### [C# Implementation](../solutions/csharp/lrucache/)\n#### [Go Implementation](../solutions/golang/lrucache/)\n\n## Classes, Interfaces and Enumerations\n1. The **Node** class represents a node in the doubly linked list, containing the key, value, and references to the previous and next nodes.\n2. The **LRUCache** class implements the LRU cache functionality using a combination of a hash map (cache) and a doubly linked list (head and tail).\n3. The get method retrieves the value associated with a given key. If the key exists in the cache, it is moved to the head of the linked list (most recently used) and its value is returned. If the key does not exist, null is returned.\n4. The put method inserts a key-value pair into the cache. If the key already exists, its value is updated, and the node is moved to the head of the linked list. If the key does not exist and the cache is at capacity, the least recently used item (at the tail of the linked list) is removed, and the new item is inserted at the head.\n5. The addToHead, removeNode, moveToHead, and removeTail methods are helper methods to manipulate the doubly linked list.\n6. The synchronized keyword is used on the get and put methods to ensure thread safety, allowing concurrent access from multiple threads.\n7. The **LRUCacheDemo** class demonstrates the usage of the LRU cache by creating an instance of LRUCache with a capacity of 3, performing various put and get operations, and printing the results."
  },
  {
    "path": "problems/movie-ticket-booking-system.md",
    "content": "# Designing a Movie Ticket Booking System like BookMyShow\n\n## Requirements\n1. The system should allow users to view the list of movies playing in different theaters.\n2. Users should be able to select a movie, theater, and show timing to book tickets.\n3. The system should display the seating arrangement of the selected show and allow users to choose seats.\n4. Users should be able to make payments and confirm their booking.\n5. The system should handle concurrent bookings and ensure seat availability is updated in real-time.\n6. The system should support different types of seats (e.g., normal, premium) and pricing.\n7. The system should allow theater administrators to add, update, and remove movies, shows, and seating arrangements.\n8. The system should be scalable to handle a large number of concurrent users and bookings.\n\n## UML Class Diagram\n\n![](../class-diagrams/movieticketbookingsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/movieticketbookingsystem/) \n#### [Python Implementation](../solutions/python/movieticketbookingsystem/)\n#### [C++ Implementation](../solutions/cpp/movieticketbookingsystem/)\n#### [C# Implementation](../solutions/csharp/movieticketbookingsystem/)\n#### [Go Implementation](../solutions/golang/movieticketbookingsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Movie** class represents a movie with properties such as ID, title, description, and duration.\n2. The **Theater** class represents a theater with properties such as ID, name, location, and a list of shows.\n3. The **Show** class represents a movie show in a theater, with properties such as ID, movie, theater, start time, end time, and a map of seats.\n4. The **Seat** class represents a seat in a show, with properties such as ID, row, column, type, price, and status.\n5. The **SeatType** enum defines the different types of seats (normal or premium).\n6. The **SeatStatus** enum defines the different statuses of a seat (available or booked).\n7. The **Booking** class represents a booking made by a user, with properties such as ID, user, show, selected seats, total price, and status.\n8. The **BookingStatus** enum defines the different statuses of a booking (pending, confirmed, or cancelled).\n9. The **User** class represents a user of the booking system, with properties such as ID, name, and email.\n10. The **MovieTicketBookingSystem** class is the main class that manages the movie ticket booking system. It follows the Singleton pattern to ensure only one instance of the system exists.\n11. The MovieTicketBookingSystem class provides methods for adding movies, theaters, and shows, as well as booking tickets, confirming bookings, and cancelling bookings.\n12. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap to handle concurrent access to shared resources like shows and bookings.\n13. The **MovieTicketBookingDemo** class demonstrates the usage of the movie ticket booking system by adding movies, theaters, shows, booking tickets, and confirming or cancelling bookings."
  },
  {
    "path": "problems/music-streaming-service.md",
    "content": "# Designing an Online Music Streaming Service Like Spotify\n\n## Requirements\n1. The music streaming service should allow users to browse and search for songs, albums, and artists.\n2. Users should be able to create and manage playlists.\n3. The system should support user authentication and authorization.\n4. Users should be able to play, pause, skip, and seek within songs.\n5. The system should recommend songs and playlists based on user preferences and listening history.\n6. The system should handle concurrent requests and ensure smooth streaming experience for multiple users.\n7. The system should be scalable and handle a large volume of songs and users.\n8. The system should be extensible to support additional features such as social sharing and offline playback.\n\n## UML Class Diagram\n\n![](../class-diagrams/musicstreamingservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/musicstreamingservice/) \n#### [Python Implementation](../solutions/python/musicstreamingservice/)\n#### [C++ Implementation](../solutions/cpp/musicstreamingservice/)\n#### [C# Implementation](../solutions/csharp/musicstreamingservice/)\n#### [Go Implementation](../solutions/golang/musicstreamingservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **Song**, **Album**, and **Artist** classes represent the basic entities in the music streaming service, with properties such as ID, title, artist, album, duration, and relationships between them.\n2. The **User** class represents a user of the music streaming service, with properties like ID, username, password, and a list of playlists.\n3. The **Playlist** class represents a user-created playlist, containing a list of songs.\n4. The **MusicLibrary** class serves as a central repository for storing and managing songs, albums, and artists. It follows the Singleton pattern to ensure a single instance of the music library.\n5. The **UserManager** class handles user registration, login, and other user-related operations. It also follows the Singleton pattern.\n6. The **MusicPlayer** class represents the music playback functionality, allowing users to play, pause, skip, and seek within songs.\n7. The **MusicRecommender** class generates song recommendations based on user preferences and listening history. It follows the Singleton pattern.\n8. The **MusicStreamingService** class is the main entry point of the music streaming service. It initializes the necessary components, handles user requests, and manages the overall functionality of the service."
  },
  {
    "path": "problems/online-auction-system.md",
    "content": "# Designing an Online Auction System\nIn this article, we delve into the object-oriented design and implementation of an Online Auction System using Java. \n\nThis system allows for the creation and management of auctions, user participation in bidding, and handling transactions.\n\n## Requirements\n1. The online auction system should allow users to register and log in to their accounts.\n2. Users should be able to create new auction listings with details such as item name, description, starting price, and auction duration.\n3. Users should be able to browse and search for auction listings based on various criteria (e.g., item name, category, price range).\n4. Users should be able to place bids on active auction listings.\n5. The system should automatically update the current highest bid and notify the bidders accordingly.\n6. The auction should end when the specified duration is reached, and the highest bidder should be declared the winner.\n7. The system should handle concurrent access to auction listings and ensure data consistency.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## UML Class Diagram\n\n![](../class-diagrams/onlineauctionsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/onlineauctionsystem/) \n#### [Python Implementation](../solutions/python/onlineauctionsystem/)\n#### [C++ Implementation](../solutions/cpp/onlineauctionsystem/)\n#### [C# Implementation](../solutions/csharp/onlineauctionsystem/)\n#### [Go Implementation](../solutions/golang/onlineauctionsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online auction system, with properties such as id, username, and email.\n2. The **AuctionStatus** enum defines the possible states of an auction listing, such as active and closed.\n3. The **AuctionListing** class represents an auction listing in the system, with properties like id, item name, description, starting price, duration, seller, current highest bid, and a list of bids.\n4. The **Bid** class represents a bid placed by a user on an auction listing, with properties such as id, bidder, amount, and timestamp.\n5. The **AuctionSystem** class is the core of the online auction system and follows the Singleton pattern to ensure a single instance of the auction system.\n6. The AuctionSystem class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to auction listings and ensure thread safety.\n7. The AuctionSystem class provides methods for registering users, creating auction listings, searching auction listings, and placing bids.\n8. The **AuctionSystemDemo** class serves as the entry point of the application and demonstrates the usage of the online auction system."
  },
  {
    "path": "problems/online-shopping-service.md",
    "content": "# Designing an Online Shopping System Like Amazon\n\n## Requirements\n1. The online shopping service should allow users to browse products, add them to the shopping cart, and place orders.\n2. The system should support multiple product categories and provide search functionality.\n3. Users should be able to manage their profiles, view order history, and track order status.\n4. The system should handle inventory management and update product availability accordingly.\n5. The system should support multiple payment methods and ensure secure transactions.\n6. The system should handle concurrent user requests and ensure data consistency.\n7. The system should be scalable to handle a large number of products and users.\n8. The system should provide a user-friendly interface for a seamless shopping experience.\n\n## UML Class Diagram\n\n![](../class-diagrams/onlineshoppingservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/onlineshoppingservice/)\n#### [Python Implementation](../solutions/python/onlineshoppingservice/)\n#### [C++ Implementation](../solutions/cpp/onlineshoppingservice/)\n#### [C# Implementation](../solutions/csharp/onlineshoppingservice/)\n#### [Go Implementation](../solutions/golang/onlineshoppingservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online shopping service, with properties such as ID, name, email, password, and a list of orders.\n2. The **Product** class represents a product available for purchase, with properties like ID, name, description, price, and quantity. It provides methods to update the quantity and check product availability.\n3. The **Order** class represents an order placed by a user, containing properties such as ID, user, order items, total amount, and order status. It calculates the total amount based on the order items.\n4. The **OrderItem** class represents an item within an order, consisting of the product and the quantity ordered.\n5. The **OrderStatus** enum represents the different statuses an order can have, such as pending, processing, shipped, delivered, or cancelled.\n6. The **ShoppingCart** class represents the user's shopping cart, allowing them to add, remove, and update item quantities. It maintains a map of product IDs and order items.\n7. The **Payment** interface defines the contract for processing payments, with a concrete implementation CreditCardPayment.\n8. The **OnlineShoppingService** class is the central component of the online shopping service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register users, add products, search products, place orders, and retrieve order information. It handles concurrent access to shared resources using synchronization.\n9. The **OnlineShoppingServiceDemo** class demonstrates the usage of the online shopping service by registering users, adding products, searching for products, placing orders, and viewing order history."
  },
  {
    "path": "problems/online-stock-brokerage-system.md",
    "content": "# Designing an Online Stock Brokerage System\n\n## Requirements\n1. The online stock brokerage system should allow users to create and manage their trading accounts.\n2. Users should be able to buy and sell stocks, as well as view their portfolio and transaction history.\n3. The system should provide real-time stock quotes and market data to users.\n4. The system should handle order placement, execution, and settlement processes.\n5. The system should enforce various business rules and validations, such as checking account balances and stock availability.\n6. The system should handle concurrent user requests and ensure data consistency and integrity.\n7. The system should be scalable and able to handle a large number of users and transactions.\n8. The system should be secure and protect sensitive user information.\n\n## UML Class Diagram\n\n![](../class-diagrams/onlinestockbrokeragesystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/onlinestockbrokeragesystem/) \n#### [Python Implementation](../solutions/python/onlinestockbrokeragesystem/)\n#### [C++ Implementation](../solutions/cpp/onlinestockbrokeragesystem/)\n#### [C# Implementation](../solutions/csharp/onlinestockbrokeragesystem/)\n#### [Go Implementation](../solutions/golang/onlinestockbrokeragesystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the stock brokerage system, with properties such as user ID, name, and email.\n2. The **Account** class represents a user's trading account, with properties like account ID, associated user, and balance. It provides methods for depositing and withdrawing funds.\n3. The **Stock** class represents a stock that can be traded, with properties such as symbol, name, and price. It provides a method for updating the stock price.\n4. The **Order** class is an abstract base class representing an order placed by a user. It contains common properties such as order ID, associated account, stock, quantity, price, and order status. The execute() method is declared as abstract, to be implemented by concrete order classes.\n5. The **BuyOrder** and **SellOrder** classes are concrete implementations of the Order class, representing buy and sell orders respectively. They provide the implementation for the execute() method specific to each order type.\n6. The **OrderStatus** enum represents the possible statuses of an order, such as PENDING, EXECUTED, or REJECTED.\n7. The **Portfolio** class represents a user's portfolio, which holds the stocks owned by the user. It provides methods for adding and removing stocks from the portfolio.\n8. The **StockBroker** class is the central component of the stock brokerage system. It follows the Singleton pattern to ensure a single instance of the stock broker. It manages user accounts, stocks, and order processing. It provides methods for creating accounts, adding stocks, placing orders, and processing orders.\n9. The **InsufficientFundsException** and **InsufficientStockException** classes are custom exceptions used to handle insufficient funds and insufficient stock scenarios respectively.\n10. The **StockBrokerageSystem** class serves as the entry point of the application and demonstrates the usage of the stock brokerage system."
  },
  {
    "path": "problems/parking-lot.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot should have multiple levels, each level with a certain number of parking spots.\n2. The parking lot should support different types of vehicles, such as cars, motorcycles, and trucks.\n3. Each parking spot should be able to accommodate a specific type of vehicle.\n4. The system should assign a parking spot to a vehicle upon entry and release it when the vehicle exits.\n5. The system should track the availability of parking spots and provide real-time information to customers.\n6. The system should handle multiple entry and exit points and support concurrent access.\n\n## UML Class Diagram\n\n![](../class-diagrams/parkinglot-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/parkinglot/) \n#### [Python Implementation](../solutions/python/parkinglot/)\n#### [C++ Implementation](../solutions/cpp/parkinglot/)\n#### [C# Implementation](../solutions/csharp/parkinglot/)\n#### [Go Implementation](../solutions/golang/parkinglot/)\n#### [TypeScript Implementation](../solutions/typescript/src/ParkingLot/)\n\n## Classes, Interfaces and Enumerations\n1. The **ParkingLot** class follows the Singleton pattern to ensure only one instance of the parking lot exists. It maintains a list of levels and provides methods to park and unpark vehicles.\n2. The **ParkingFloor** class represents a level in the parking lot and contains a list of parking spots. It handles parking and unparking of vehicles within the level.\n3. The **ParkingSpot** class represents an individual parking spot and tracks the availability and the parked vehicle.\n4. The **Vehicle** class is an abstract base class for different types of vehicles. It is extended by Car, Motorcycle, and Truck classes.\n5. The **VehicleSize** enum defines the different types of vehicles supported by the parking lot.\n6. Multi-threading is achieved through the use of synchronized keyword on critical sections to ensure thread safety.\n7. The **Main** class demonstrates the usage of the parking lot system.\n\n## Design Patterns Used:\n1. Singleton Pattern: Ensures only one instance of the ParkingLot class.\n2. Factory Pattern (optional extension): Could be used for creating vehicles based on input.\n3. Observer Pattern (optional extension): Could notify customers about available spots.\n"
  },
  {
    "path": "problems/pub-sub-system.md",
    "content": "# Designing a Pub-Sub System in Java\n\n## Requirements\n1. The Pub-Sub system should allow publishers to publish messages to specific topics.\n2. Subscribers should be able to subscribe to topics of interest and receive messages published to those topics.\n3. The system should support multiple publishers and subscribers.\n4. Messages should be delivered to all subscribers of a topic in real-time.\n5. The system should handle concurrent access and ensure thread safety.\n6. The Pub-Sub system should be scalable and efficient in terms of message delivery.\n\n## UML Class Diagram\n\n![](../class-diagrams/pubsubsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/pubsubsystem/)\n#### [Python Implementation](../solutions/python/pubsubsystem/)\n#### [C++ Implementation](../solutions/cpp/pubsubsystem/)\n#### [C# Implementation](../solutions/csharp/pubsubsystem/)\n#### [Go Implementation](../solutions/golang/pubsubsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **Message** class represents a message that can be published and received by subscribers. It contains the message content.\n2. The **Topic** class represents a topic to which messages can be published. It maintains a set of subscribers and provides methods to add and remove subscribers, as well as publish messages to all subscribers.\n3. The **Subscriber** interface defines the contract for subscribers. It declares the onMessage method that is invoked when a subscriber receives a message.\n4. The **PrintSubscriber** class is a concrete implementation of the Subscriber interface. It receives messages and prints them to the console.\n5. The **Publisher** class represents a publisher that publishes messages to a specific topic.\n6. The **PubSubSystem** class is the main class that manages topics, subscribers, and message publishing. It uses a ConcurrentHashMap to store topics and an ExecutorService to handle concurrent message publishing.\n7. The **PubSubDemo** class demonstrates the usage of the Pub-Sub system by creating topics, subscribers, and publishers, and publishing messages.\n"
  },
  {
    "path": "problems/restaurant-management-system.md",
    "content": "# Designing Restaurant Management System\n\n## Requirements\n1. The restaurant management system should allow customers to place orders, view the menu, and make reservations.\n2. The system should manage the restaurant's inventory, including ingredients and menu items.\n3. The system should handle order processing, including order preparation, billing, and payment.\n4. The system should support multiple payment methods, such as cash, credit card, and mobile payments.\n5. The system should manage staff information, including roles, schedules, and performance tracking.\n6. The system should generate reports and analytics for management, such as sales reports and inventory analysis.\n7. The system should handle concurrent access and ensure data consistency.\n\n## UML Class Diagram\n\n![](../class-diagrams/restaurantmanagementsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/restaurantmanagementsystem/) \n#### [Python Implementation](../solutions/python/restaurantmanagementsystem/)\n#### [C++ Implementation](../solutions/cpp/restaurantmanagementsystem/)\n#### [C# Implementation](../solutions/csharp/restaurantmanagementsystem/)\n#### [Go Implementation](../solutions/golang/restaurantmanagementsystem/)\n\n## Classes, Interfaces and Enumerations\n1. The **MenuItem** class represents a menu item in the restaurant, with properties such as ID, name, description, price, and availability.\n2. The **Order** class represents an order placed by a customer, with properties such as ID, list of menu items, total amount, order status, and timestamp.\n3. The **OrderStatus** enum represents the different statuses an order can have, such as pending, preparing, ready, completed, or cancelled.\n4. The **Reservation** class represents a reservation made by a customer, with properties such as ID, customer name, contact number, party size, and reservation time.\n5. The **Payment** class represents a payment made for an order, with properties such as ID, amount, payment method, and payment status.\n6. The **PaymentMethod** enum represents the different payment methods supported by the restaurant, such as cash, credit card, or mobile payment.\n7. The **PaymentStatus** enum represents the status of a payment, which can be pending, completed, or failed.\n8. The Staff class represents a staff member of the restaurant, with properties such as ID, name, role, and contact number.\n9. The **Restaurant** class is the main class that manages the restaurant operations. It follows the Singleton pattern to ensure only one instance of the restaurant exists.\n10. The Restaurant class provides methods for managing menu items, placing orders, updating order status, making reservations, processing payments, and managing staff.\n11. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as orders and reservations.\n12. The notifyKitchen and notifyStaff methods are placeholders for notifying relevant staff about order updates and status changes.\n13. The **RestaurantManagementDemo** class demonstrates the usage of the restaurant management system by adding menu items, placing an order, making a reservation, processing a payment, updating order status, adding staff, and retrieving the menu."
  },
  {
    "path": "problems/ride-sharing-service.md",
    "content": "# Designing a Ride-Sharing Service Like Uber\n\n## Requirements\n1. The ride sharing service should allow passengers to request rides and drivers to accept and fulfill those ride requests.\n2. Passengers should be able to specify their pickup location, destination, and desired ride type (e.g., regular, premium).\n3. Drivers should be able to see available ride requests and choose to accept or decline them.\n4. The system should match ride requests with available drivers based on proximity and other factors.\n5. The system should calculate the fare for each ride based on distance, time, and ride type.\n6. The system should handle payments and process transactions between passengers and drivers.\n7. The system should provide real-time tracking of ongoing rides and notify passengers and drivers about ride status updates.\n8. The system should handle concurrent requests and ensure data consistency.\n\n## UML Class Diagram\n\n![](../class-diagrams/ridesharingservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/ridesharingservice/) \n#### [Python Implementation](../solutions/python/ridesharingservice/)\n#### [C++ Implementation](../solutions/cpp/ridesharingservice/)\n#### [C# Implementation](../solutions/csharp/ridesharingservice/)\n#### [Go Implementation](../solutions/golang/ridesharingservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **Passenger** class represents a passenger in the ride sharing service, with properties such as ID, name, contact information, and location.\n2. The **Driver** class represents a driver in the ride sharing service, with properties such as ID, name, contact information, license plate, location, and status (available or busy).\n3. The **Ride** class represents a ride requested by a passenger and accepted by a driver, with properties such as ID, passenger, driver, source location, destination location, status, and fare.\n4. The **Location** class represents a geographical location with latitude and longitude coordinates.\n5. The **Payment** class represents a payment made for a ride, with properties such as ID, ride, amount, and payment status.\n6. The **RideService** class is the main class that manages the ride sharing service. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The RideService class provides methods for adding passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides.\n8. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and ConcurrentLinkedQueue) to handle concurrent access to shared data, such as ride requests and driver availability.\n9. The notifyDrivers, notifyPassenger, and notifyDriver methods are placeholders for notifying relevant parties about ride status updates.\n10. The calculateFare and processPayment methods are placeholders for calculating ride fares and processing payments, respectively.\n11. The **RideSharingDemo** class demonstrates the usage of the ride sharing service by creating passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides."
  },
  {
    "path": "problems/snake-and-ladder.md",
    "content": "# Designing Snake and Ladder Game\n\n## Requirements\n1. The game should be played on a board with numbered cells, typically with 100 cells.\n2. The board should have a predefined set of snakes and ladders, connecting certain cells.\n3. The game should support multiple players, each represented by a unique game piece.\n4. Players should take turns rolling a dice to determine the number of cells to move forward.\n5. If a player lands on a cell with the head of a snake, they should slide down to the cell with the tail of the snake.\n6. If a player lands on a cell with the base of a ladder, they should climb up to the cell at the top of the ladder.\n7. The game should continue until one of the players reaches the final cell on the board.\n8. The game should handle multiple game sessions concurrently, allowing different groups of players to play independently.\n\n## UML Class Diagram\n\n![](../class-diagrams/snakeandladdergame-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/snakeandladdergame/) \n#### [Python Implementation](../solutions/python/snakeandladdergame/)\n#### [C++ Implementation](../solutions/cpp/snakeandladdergame/)\n#### [C# Implementation](../solutions/csharp/snakeandladdergame/)\n#### [Go Implementation](../solutions/golang/snakeandladdergame/)\n\n## Classes, Interfaces and Enumerations\n1. The **Board** class represents the game board with a fixed size (e.g., 100 cells). It contains the positions of snakes and ladders and provides methods to initialize them and retrieve the new position after encountering a snake or ladder.\n2. The **Player** class represents a player in the game, with properties such as name and current position on the board.\n3. The **Snake** class represents a snake on the board, with properties for the start and end positions.\n4. The **Ladder** class represents a ladder on the board, with properties for the start and end positions.\n5. The **Dice** class represents a dice used in the game, with a method to roll the dice and return a random value between 1 and 6.\n6. The **SnakeAndLadderGame** class represents a single game session. It initializes the game with a board, a list of players, and a dice. The play method handles the game loop, where players take turns rolling the dice and moving their positions on the board. It checks for snakes and ladders and updates the player's position accordingly. The game continues until a player reaches the final position on the board.\n7. The **GameManager** class is a singleton that manages multiple game sessions. It maintains a list of active games and provides a method to start a new game with a list of player names. Each game is started in a separate thread to allow concurrent game sessions.\n8. The **SnakeAndLadderDemo** class demonstrates the usage of the game by creating an instance of the GameManager and starting two separate game sessions with different sets of players."
  },
  {
    "path": "problems/social-networking-service.md",
    "content": "# Designing a Social Network Like Facebook\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their personal information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their information, such as profile picture, bio, and interests.\n- Users should be able to update their profile information.\n#### Friend Connections:\n- Users should be able to send friend requests to other users.\n- Users should be able to accept or decline friend requests.\n- Users should be able to view their list of friends.\n#### Posts and Newsfeed:\n- Users should be able to create posts with text, images, or videos.\n- Users should be able to view a newsfeed consisting of posts from their friends and their own posts.\n- The newsfeed should be sorted in reverse chronological order.\n#### Likes and Comments:\n- Users should be able to like and comment on posts.\n- Users should be able to view the list of likes and comments on a post.\n#### Privacy and Security:\n- Users should be able to control the visibility of their posts and profile information.\n- The system should enforce secure access control to ensure data privacy.\n#### Notifications:\n- Users should receive notifications for events such as friend requests, likes, comments, and mentions.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## UML Class Diagram\n\n![](../class-diagrams/socialnetworkingservice-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/socialnetworkingservice/) \n#### [Python Implementation](../solutions/python/socialnetworkingservice/)\n#### [C++ Implementation](../solutions/cpp/socialnetworkingservice/)\n#### [C# Implementation](../solutions/csharp/socialnetworkingservice/)\n#### [Go Implementation](../solutions/golang/socialnetworkingservice/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the social networking system, containing properties such as ID, name, email, password, profile picture, bio, list of friends, and list of posts.\n2. The **Post** class represents a post created by a user, containing properties such as ID, user ID, content, image URLs, video URLs, timestamp, likes, and comments.\n3. The **Comment** class represents a comment made by a user on a post, containing properties such as ID, user ID, post ID, content, and timestamp.\n4. The **Notification** class represents a notification generated for a user, containing properties such as ID, user ID, notification type, content, and timestamp.\n5. The **NotificationType** enum defines the different types of notifications, such as friend request, friend request accepted, like, comment, and mention.\n6. The **SocialNetworkingService** class is the main class that manages the social networking system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SocialNetworkingService class provides methods for user registration, login, profile updates, friend requests, post creation, newsfeed generation, likes, comments, and notifications.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SocialNetworkingDemo** class demonstrates the usage of the social networking system by registering users, logging in, sending friend requests, creating posts, liking posts, commenting on posts, and retrieving newsfeed and notifications."
  },
  {
    "path": "problems/splitwise.md",
    "content": "# Designing Splitwise\n\n## Requirements\n1. The system should allow users to create accounts and manage their profile information.\n2. Users should be able to create groups and add other users to the groups.\n3. Users should be able to add expenses within a group, specifying the amount, description, and participants.\n4. The system should automatically split the expenses among the participants based on their share.\n5. Users should be able to view their individual balances with other users and settle up the balances.\n6. The system should support different split methods, such as equal split, percentage split, and exact amounts.\n7. Users should be able to view their transaction history and group expenses.\n8. The system should handle concurrent transactions and ensure data consistency.\n\n## UML Class Diagram\n\n![](../class-diagrams/splitwise-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/splitwise/)\n#### [Python Implementation](../solutions/python/splitwise/)\n#### [C++ Implementation](../solutions/cpp/splitwise/)\n#### [C# Implementation](../solutions/csharp/splitwise/)\n#### [Go Implementation](../solutions/golang/splitwise/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the Splitwise system, with properties such as ID, name, email, and a map to store balances with other users.\n2. The **Group** class represents a group in Splitwise, containing a list of member users and a list of expenses.\n3. The **Expense** class represents an expense within a group, with properties such as ID, amount, description, the user who paid, and a list of splits.\n4. The **Split** class is an abstract class representing the split of an expense. It is extended by EqualSplit, PercentSplit, and ExactSplit classes to handle different split methods.\n5. The **Transaction** class represents a transaction between two users, with properties such as ID, sender, receiver, and amount.\n6. The **SplitwiseService** class is the main class that manages the Splitwise system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SplitwiseService class provides methods for adding users, groups, and expenses, splitting expenses, updating balances, settling balances, and creating transactions.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SplitwiseDemo** class demonstrates the usage of the Splitwise system by creating users, a group, adding an expense, settling balances, and printing user balances."
  },
  {
    "path": "problems/stack-overflow.md",
    "content": "# Designing Stack Overflow\n\n## Requirements\n1. Users can post questions, answer questions, and comment on questions and answers.\n2. Users can vote on questions and answers.\n3. Questions should have tags associated with them.\n4. Users can search for questions based on keywords, tags, or user profiles.\n5. The system should assign reputation score to users based on their activity and the quality of their contributions.\n6. The system should handle concurrent access and ensure data consistency.\n\n## UML Class Diagram\n\n![](../class-diagrams/stackoverflow-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/stackoverflow/) \n#### [Python Implementation](../solutions/python/stackoverflow/)\n#### [C++ Implementation](../solutions/cpp/stackoverflow/)\n#### [C# Implementation](../solutions/csharp/stackoverflow/)\n#### [Go Implementation](../solutions/golang/stackoverflow/)\n#### [TypeScript Implementation](../solutions/typescript/src/StackOverflow/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the Stack Overflow system, with properties such as id, username, email, and reputation.\n2. The **Question** class represents a question posted by a user, with properties such as id, title, content, author, answers, comments, tags, votes and creation date.\n3. The **Answer** class represents an answer to a question, with properties such as id, content, author, associated question, comments, votes and creation date.\n4. The **Comment** class represents a comment on a question or an answer, with properties such as id, content, author, and creation date.\n5. The **Tag** class represents a tag associated with a question, with properties such as id and name.\n6. The **Vote** class represents vote associated with a question/answer.\n7. The **StackOverflow** class is the main class that manages the Stack Overflow system. It provides methods for creating user, posting questions, answers, and comments, voting on questions and answers, searching for questions, and retrieving questions by tags and users.\n8.  The **StackOverflowDemo** class demonstrates the usage of the Stack Overflow system by creating users, posting questions and answers, voting, searching for questions, and retrieving questions by tags and users."
  },
  {
    "path": "problems/task-management-system.md",
    "content": "# Designing a Task Management System\n\n## Requirements\n1. The task management system should allow users to create, update, and delete tasks.\n2. Each task should have a title, description, due date, priority, and status (e.g., pending, in progress, completed).\n3. Users should be able to assign tasks to other users and set reminders for tasks.\n4. The system should support searching and filtering tasks based on various criteria (e.g., priority, due date, assigned user).\n5. Users should be able to mark tasks as completed and view their task history.\n6. The system should handle concurrent access to tasks and ensure data consistency.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## UML Class Diagram\n\n![](../class-diagrams/taskmanagementsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/taskmanagementsystem/) \n#### [Python Implementation](../solutions/python/taskmanagementsystem/)\n#### [C++ Implementation](../solutions/cpp/taskmanagementsystem/)\n#### [C# Implementation](../solutions/csharp/taskmanagementsystem/)\n#### [Go Implementation](../solutions/golang/taskmanagementsystem/)\n#### [TypeScript Implementation](../solutions/typescript/src/TaskManagement/)\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the task management system, with properties such as id, name, and email.\n2. The **TaskStatus** enum defines the possible states of a task, such as pending, in progress, and completed.\n3. The **Task** class represents a task in the system, with properties like id, title, description, due date, priority, status, and assigned user.\n4. The **TaskManager** class is the core of the task management system and follows the Singleton pattern to ensure a single instance of the task manager.\n5. The TaskManager class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to tasks and ensure thread safety.\n6. The TaskManager class provides methods for creating, updating, deleting, searching, and filtering tasks, as well as marking tasks as completed and retrieving task history for a user.\n7. The **TaskManagementSystem** class serves as the entry point of the application and demonstrates the usage of the task management system."
  },
  {
    "path": "problems/tic-tac-toe.md",
    "content": "# Designing a Tic Tac Toe Game\n\n## Requirements\n1. The Tic-Tac-Toe game should be played on a 3x3 grid.\n2. Two players take turns marking their symbols (X or O) on the grid.\n3. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game.\n4. If all the cells on the grid are filled and no player has won, the game ends in a draw.\n5. The game should have a user interface to display the grid and allow players to make their moves.\n6. The game should handle player turns and validate moves to ensure they are legal.\n7. The game should detect and announce the winner or a draw at the end of the game.\n\n## UML Class Diagram\n\n![](../class-diagrams/tictactoe-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/tictactoe/) \n#### [Python Implementation](../solutions/python/tictactoe/)\n#### [C++ Implementation](../solutions/cpp/tictactoe/)\n#### [C# Implementation](../solutions/csharp/tictactoe/)\n#### [Go Implementation](../solutions/golang/tictactoe/)\n\n## Classes, Interfaces and Enumerations\n1. The **Player** class represents a player in the game, with a name and a symbol (X or O).\n2. The **Board** class represents the game board, which is a 3x3 grid. It provides methods to make moves, check for a winner, and check if the board is full.\n3. The **Game** class manages the game flow and player interactions. It handles player turns, validates moves, and determines the winner or a draw.\n4. The **TicTacToe** class is the entry point of the application and creates instances of the players and the game."
  },
  {
    "path": "problems/traffic-signal.md",
    "content": "# Designing a Traffic Signal Control System\n\n## Requirements\n1. The traffic signal system should control the flow of traffic at an intersection with multiple roads.\n2. The system should support different types of signals, such as red, yellow, and green.\n3. The duration of each signal should be configurable and adjustable based on traffic conditions.\n4. The system should handle the transition between signals smoothly, ensuring safe and efficient traffic flow.\n5. The system should be able to detect and handle emergency situations, such as an ambulance or fire truck approaching the intersection.\n6. The system should be scalable and extensible to support additional features and functionality.\n\n## UML Class Diagram\n\n![](../class-diagrams/trafficsignalsystem-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/trafficsignalcontrolsystem/)\n#### [Python Implementation](../solutions/python/trafficsignalsystem/)\n#### [C++ Implementation](../solutions/cpp/trafficsignalsystem/)\n#### [C# Implementation](../solutions/csharp/trafficsignalsystem/)\n#### [Go Implementation](../solutions/golang/trafficsignalsystem/)\n#### [TypeScript Implementation](../solutions/typescript/src/TrafficSignalSystem/) \n\n## Classes, Interfaces and Enumerations\n1. The **Signal** enum represents the different states of a traffic light: red, yellow, and green.\n2. The **Road** class represents a road in the traffic signal system, with properties such as ID, name, and an associated traffic light.\n3. The **TrafficLight** class represents a traffic light, with properties such as ID, current signal, and durations for each signal state. It provides methods to change the signal and notify observers (e.g., roads) about signal changes.\n4. The **TrafficController** class serves as the central controller for the traffic signal system. It follows the Singleton pattern to ensure a single instance of the controller. It manages the roads and their associated traffic lights, starts the traffic control process, and handles emergency situations.\n5. The **TrafficSignalSystemDemo** class is the main entry point of the application. It demonstrates the usage of the traffic signal system by creating roads, traffic lights, assigning traffic lights to roads, and starting the traffic control process.\n"
  },
  {
    "path": "problems/vending-machine.md",
    "content": "# Designing a Vending Machine\n\n## Requirements\n1. The vending machine should support multiple products with different prices and quantities.\n1. The machine should accept coins and notes of different denominations.\n1. The machine should dispense the selected product and return change if necessary.\n1. The machine should keep track of the available products and their quantities.\n1. The machine should handle multiple transactions concurrently and ensure data consistency.\n1. The machine should provide an interface for restocking products and collecting money.\n1. The machine should handle exceptional scenarios, such as insufficient funds or out-of-stock products.\n\n## UML Class Diagram\n\n![](../class-diagrams/vendingmachine-class-diagram.png)\n\n## Implementations\n#### [Java Implementation](../solutions/java/src/vendingmachine/) \n#### [Python Implementation](../solutions/python/vendingmachine/)\n#### [C++ Implementation](../solutions/cpp/vendingmachine/)\n#### [C# Implementation](../solutions/csharp/vendingmachine/)\n#### [Go Implementation](../solutions/golang/vending_machine/)\n#### [TypeScript Implementation](../solutions/typescript/src/VendingMachine/)\n\n## Classes, Interfaces and Enumerations\n1. The **Product** class represents a product in the vending machine, with properties such as name and price.\n2. The **Coin** and **Note** enums represent the different denominations of coins and notes accepted by the vending machine.\n3. The **Inventory** class manages the available products and their quantities in the vending machine. It uses a concurrent hash map to ensure thread safety.\n4. The **VendingMachineState** interface defines the behavior of the vending machine in different states, such as idle, ready, and dispense.\n5. The **IdleState**, **ReadyState**, and **DispenseState** classes implement the VendingMachineState interface and define the specific behaviors for each state.\n6. The **VendingMachine** class is the main class that represents the vending machine. It follows the Singleton pattern to ensure only one instance of the vending machine exists.\n7. The VendingMachine class maintains the current state, selected product, total payment, and provides methods for state transitions and payment handling.\n8. The **VendingMachineDemo** class demonstrates the usage of the vending machine by adding products to the inventory, selecting products, inserting coins and notes, dispensing products, and returning change."
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/AirlineManagementSystem.cpp",
    "content": "#include \"AirlineManagementSystem.hpp\"\n#include <iostream>\n\nAirlineManagementSystem::AirlineManagementSystem() : bookingIdCounter(1) {}\n\nAirlineManagementSystem::~AirlineManagementSystem() {\n    for (auto flight : flights) delete flight;\n    for (auto passenger : passengers) delete passenger;\n    for (auto booking : bookings) delete booking;\n}\n\nvoid AirlineManagementSystem::addFlight(Flight* flight) {\n    flights.push_back(flight);\n}\n\nvoid AirlineManagementSystem::addPassenger(Passenger* passenger) {\n    passengers.push_back(passenger);\n}\n\nstd::string AirlineManagementSystem::createBooking(Flight* flight, Passenger* passenger, int seatNumber) {\n    if (!flight->bookSeat(seatNumber)) {\n        return \"\";\n    }\n    \n    std::string bookingId = \"B\" + std::to_string(bookingIdCounter++);\n    Booking* booking = new Booking(bookingId, flight, passenger, seatNumber);\n    bookings.push_back(booking);\n    return bookingId;\n}\n\nbool AirlineManagementSystem::cancelBooking(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking) return false;\n    \n    booking->getFlight()->cancelSeat(booking->getSeatNumber());\n    \n    auto it = std::find(bookings.begin(), bookings.end(), booking);\n    if (it != bookings.end()) {\n        bookings.erase(it);\n        delete booking;\n        return true;\n    }\n    return false;\n}\n\nvoid AirlineManagementSystem::displayAllFlights() const {\n    std::cout << \"\\nAll Flights:\" << std::endl;\n    for (const auto& flight : flights) {\n        flight->displayFlightInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid AirlineManagementSystem::displayAllPassengers() const {\n    std::cout << \"\\nAll Passengers:\" << std::endl;\n    for (const auto& passenger : passengers) {\n        passenger->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid AirlineManagementSystem::displayAllBookings() const {\n    std::cout << \"\\nAll Bookings:\" << std::endl;\n    for (const auto& booking : bookings) {\n        booking->displayBookingInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nFlight* AirlineManagementSystem::findFlight(std::string flightNumber) const {\n    for (auto flight : flights) {\n        if (flight->getFlightNumber() == flightNumber) return flight;\n    }\n    return nullptr;\n}\n\nPassenger* AirlineManagementSystem::findPassenger(std::string passportNumber) const {\n    for (auto passenger : passengers) {\n        if (passenger->getPassportNumber() == passportNumber) return passenger;\n    }\n    return nullptr;\n}\n\nBooking* AirlineManagementSystem::findBooking(std::string bookingId) const {\n    for (auto booking : bookings) {\n        if (booking->getBookingId() == bookingId) return booking;\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/AirlineManagementSystem.hpp",
    "content": "#ifndef AIRLINE_MANAGEMENT_SYSTEM_HPP\n#define AIRLINE_MANAGEMENT_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Flight.hpp\"\n#include \"Passenger.hpp\"\n#include \"Booking.hpp\"\n\nclass AirlineManagementSystem {\nprivate:\n    std::vector<Flight*> flights;\n    std::vector<Passenger*> passengers;\n    std::vector<Booking*> bookings;\n    int bookingIdCounter;\n\npublic:\n    AirlineManagementSystem();\n    ~AirlineManagementSystem();\n    \n    void addFlight(Flight* flight);\n    void addPassenger(Passenger* passenger);\n    std::string createBooking(Flight* flight, Passenger* passenger, int seatNumber);\n    bool cancelBooking(std::string bookingId);\n    \n    void displayAllFlights() const;\n    void displayAllPassengers() const;\n    void displayAllBookings() const;\n    \n    Flight* findFlight(std::string flightNumber) const;\n    Passenger* findPassenger(std::string passportNumber) const;\n    Booking* findBooking(std::string bookingId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/AirlineManagementSystemDemo.cpp",
    "content": "#include \"AirlineManagementSystem.hpp\"\n#include <iostream>\n\nint main() {\n    AirlineManagementSystem ams;\n    \n    // Create flights\n    Flight* flight1 = new Flight(\"FL001\", \"New York\", \"London\", \"2024-03-20 10:00\", 100);\n    Flight* flight2 = new Flight(\"FL002\", \"London\", \"Paris\", \"2024-03-21 15:30\", 80);\n    ams.addFlight(flight1);\n    ams.addFlight(flight2);\n    \n    // Create passengers\n    Passenger* passenger1 = new Passenger(\"John Doe\", \"P123456\", \"+1-555-0123\");\n    Passenger* passenger2 = new Passenger(\"Jane Smith\", \"P789012\", \"+1-555-0124\");\n    ams.addPassenger(passenger1);\n    ams.addPassenger(passenger2);\n    \n    // Display all flights and passengers\n    ams.displayAllFlights();\n    ams.displayAllPassengers();\n    \n    // Create bookings\n    std::string booking1 = ams.createBooking(flight1, passenger1, 1);\n    std::string booking2 = ams.createBooking(flight2, passenger2, 1);\n    \n    if (!booking1.empty()) {\n        std::cout << \"\\nBooking created successfully: \" << booking1 << std::endl;\n    }\n    if (!booking2.empty()) {\n        std::cout << \"Booking created successfully: \" << booking2 << std::endl;\n    }\n    \n    // Display all bookings\n    ams.displayAllBookings();\n    \n    // Cancel a booking\n    if (ams.cancelBooking(booking1)) {\n        std::cout << \"\\nBooking \" << booking1 << \" cancelled successfully\" << std::endl;\n    }\n    \n    // Display updated bookings\n    ams.displayAllBookings();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Booking.cpp",
    "content": "#include \"Booking.hpp\"\n#include <iostream>\n\nBooking::Booking(std::string bookingId, Flight* flight, Passenger* passenger, int seatNumber)\n    : bookingId(bookingId), flight(flight), passenger(passenger), seatNumber(seatNumber) {}\n\nstd::string Booking::getBookingId() const { return bookingId; }\nFlight* Booking::getFlight() const { return flight; }\nPassenger* Booking::getPassenger() const { return passenger; }\nint Booking::getSeatNumber() const { return seatNumber; }\n\nvoid Booking::displayBookingInfo() const {\n    std::cout << \"\\nBooking Details:\" << std::endl;\n    std::cout << \"Booking ID: \" << bookingId << std::endl;\n    std::cout << \"Seat Number: \" << seatNumber << std::endl;\n    passenger->displayInfo();\n    flight->displayFlightInfo();\n} "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Booking.hpp",
    "content": "#ifndef BOOKING_HPP\n#define BOOKING_HPP\n\n#include \"Flight.hpp\"\n#include \"Passenger.hpp\"\n#include <string>\n\nclass Booking {\nprivate:\n    std::string bookingId;\n    Flight* flight;\n    Passenger* passenger;\n    int seatNumber;\n\npublic:\n    Booking(std::string bookingId, Flight* flight, Passenger* passenger, int seatNumber);\n    \n    std::string getBookingId() const;\n    Flight* getFlight() const;\n    Passenger* getPassenger() const;\n    int getSeatNumber() const;\n    void displayBookingInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Flight.cpp",
    "content": "#include \"Flight.hpp\"\n#include <iostream>\n\nFlight::Flight(std::string flightNumber, std::string origin, std::string destination, \n               std::string departureTime, int capacity) \n    : flightNumber(flightNumber), origin(origin), destination(destination),\n      departureTime(departureTime), capacity(capacity) {\n    \n    // Initialize seats\n    for (int i = 1; i <= capacity; i++) {\n        seats.push_back(Seat(i, false));\n    }\n}\n\nstd::string Flight::getFlightNumber() const { return flightNumber; }\nstd::string Flight::getOrigin() const { return origin; }\nstd::string Flight::getDestination() const { return destination; }\nstd::string Flight::getDepartureTime() const { return departureTime; }\nint Flight::getCapacity() const { return capacity; }\nstd::vector<Seat>& Flight::getSeats() { return seats; }\n\nvoid Flight::displayFlightInfo() const {\n    std::cout << \"Flight \" << flightNumber << std::endl;\n    std::cout << \"From: \" << origin << \" To: \" << destination << std::endl;\n    std::cout << \"Departure Time: \" << departureTime << std::endl;\n    std::cout << \"Capacity: \" << capacity << \" seats\" << std::endl;\n}\n\nbool Flight::bookSeat(int seatNumber) {\n    if (seatNumber < 1 || seatNumber > capacity) return false;\n    if (seats[seatNumber - 1].isBooked()) return false;\n    \n    seats[seatNumber - 1].book();\n    return true;\n}\n\nbool Flight::cancelSeat(int seatNumber) {\n    if (seatNumber < 1 || seatNumber > capacity) return false;\n    if (!seats[seatNumber - 1].isBooked()) return false;\n    \n    seats[seatNumber - 1].cancel();\n    return true;\n} "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Flight.hpp",
    "content": "#ifndef FLIGHT_HPP\n#define FLIGHT_HPP\n\n#include <string>\n#include <vector>\n#include \"Seat.hpp\"\n\nclass Flight {\nprivate:\n    std::string flightNumber;\n    std::string origin;\n    std::string destination;\n    std::string departureTime;\n    int capacity;\n    std::vector<Seat> seats;\n\npublic:\n    Flight(std::string flightNumber, std::string origin, std::string destination, \n           std::string departureTime, int capacity);\n    \n    std::string getFlightNumber() const;\n    std::string getOrigin() const;\n    std::string getDestination() const;\n    std::string getDepartureTime() const;\n    int getCapacity() const;\n    std::vector<Seat>& getSeats();\n    \n    void displayFlightInfo() const;\n    bool bookSeat(int seatNumber);\n    bool cancelSeat(int seatNumber);\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Passenger.cpp",
    "content": "#include \"Passenger.hpp\"\n#include <iostream>\n\nPassenger::Passenger(std::string name, std::string passportNumber, std::string contactNumber)\n    : name(name), passportNumber(passportNumber), contactNumber(contactNumber) {}\n\nstd::string Passenger::getName() const { return name; }\nstd::string Passenger::getPassportNumber() const { return passportNumber; }\nstd::string Passenger::getContactNumber() const { return contactNumber; }\n\nvoid Passenger::displayInfo() const {\n    std::cout << \"Passenger Details:\" << std::endl;\n    std::cout << \"Name: \" << name << std::endl;\n    std::cout << \"Passport Number: \" << passportNumber << std::endl;\n    std::cout << \"Contact Number: \" << contactNumber << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Passenger.hpp",
    "content": "#ifndef PASSENGER_HPP\n#define PASSENGER_HPP\n\n#include <string>\n\nclass Passenger {\nprivate:\n    std::string name;\n    std::string passportNumber;\n    std::string contactNumber;\n\npublic:\n    Passenger(std::string name, std::string passportNumber, std::string contactNumber);\n    \n    std::string getName() const;\n    std::string getPassportNumber() const;\n    std::string getContactNumber() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/README.md",
    "content": "# Designing an Airline Management System\n\n## Requirements\n1. The airline management system should allow users to search for flights based on source, destination, and date.\n2. Users should be able to book flights, select seats, and make payments.\n3. The system should manage flight schedules, aircraft assignments, and crew assignments.\n4. The system should handle passenger information, including personal details and baggage information.\n5. The system should support different types of users, such as passengers, airline staff, and administrators.\n6. The system should be able to handle cancellations, refunds, and flight changes.\n7. The system should ensure data consistency and handle concurrent access to shared resources.\n8. The system should be scalable and extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Flight** class represents a flight in the airline management system, with properties such as flight number, source, destination, departure time, arrival time, and available seats.\n2. The **Aircraft** class represents an aircraft, with properties like tail number, model, and total seats.\n3. The **Passenger** class represents a passenger, with properties such as ID, name, email, and phone number.\n4. The **Booking** class represents a booking made by a passenger for a specific flight and seat, with properties such as booking number, flight, passenger, seat, price, and booking status.\n5. The **Seat** class represents a seat on a flight, with properties like seat number, seat type, and seat status.\n6. The **Payment** class represents a payment made for a booking, with properties such as payment ID, payment method, amount, and payment status.\n7. The **FlightSearch** class provides functionality to search for flights based on source, destination, and date.\n8. The **BookingManager** class manages the creation and cancellation of bookings. It follows the Singleton pattern to ensure a single instance of the booking manager.\n9. The **PaymentProcessor** class handles the processing of payments. It follows the Singleton pattern to ensure a single instance of the payment processor.\n10. The **AirlineManagementSystem** class serves as the main entry point of the system, combining all the components and providing methods for flight management, booking, payment processing, and other operations."
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Seat.cpp",
    "content": "#include \"Seat.hpp\"\n\nSeat::Seat(int number, bool isBooked) \n    : seatNumber(number), booked(isBooked) {}\n\nint Seat::getSeatNumber() const { return seatNumber; }\nbool Seat::isBooked() const { return booked; }\nvoid Seat::book() { booked = true; }\nvoid Seat::cancel() { booked = false; } "
  },
  {
    "path": "solutions/cpp/airlinemanagementsystem/Seat.hpp",
    "content": "#ifndef SEAT_HPP\n#define SEAT_HPP\n\nclass Seat {\nprivate:\n    int seatNumber;\n    bool booked;\n\npublic:\n    Seat(int number, bool isBooked = false);\n    \n    int getSeatNumber() const;\n    bool isBooked() const;\n    void book();\n    void cancel();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/atm/ATM.cpp",
    "content": "#include \"ATM.hpp\"\n#include <iostream>\n#include <limits>\n\nATM::ATM() : currentAccount(nullptr), isAuthenticated(false) {}\n\nATM::~ATM() {\n    for (auto account : accounts) {\n        delete account;\n    }\n}\n\nvoid ATM::addAccount(Account* account) {\n    accounts.push_back(account);\n}\n\nbool ATM::authenticate(const std::string& accountNumber, const std::string& pin) {\n    for (auto account : accounts) {\n        if (account->getAccountNumber() == accountNumber && account->validatePin(pin)) {\n            currentAccount = account;\n            isAuthenticated = true;\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid ATM::logout() {\n    currentAccount = nullptr;\n    isAuthenticated = false;\n}\n\nbool ATM::deposit(double amount) {\n    if (!isAuthenticated || !currentAccount) return false;\n    return currentAccount->deposit(amount);\n}\n\nbool ATM::withdraw(double amount) {\n    if (!isAuthenticated || !currentAccount) return false;\n    return currentAccount->withdraw(amount);\n}\n\nvoid ATM::checkBalance() const {\n    if (!isAuthenticated || !currentAccount) return;\n    currentAccount->displayBalance();\n}\n\nvoid ATM::displayMenu() const {\n    std::cout << \"\\nATM Menu:\" << std::endl;\n    std::cout << \"1. Check Balance\" << std::endl;\n    std::cout << \"2. Deposit\" << std::endl;\n    std::cout << \"3. Withdraw\" << std::endl;\n    std::cout << \"4. Logout\" << std::endl;\n    std::cout << \"5. Exit\" << std::endl;\n    std::cout << \"Enter your choice: \";\n}\n\nvoid ATM::start() {\n    std::string accountNumber, pin;\n    int choice;\n    double amount;\n\n    while (true) {\n        if (!isAuthenticated) {\n            std::cout << \"\\nWelcome to ATM\" << std::endl;\n            std::cout << \"Enter account number: \";\n            std::cin >> accountNumber;\n            std::cout << \"Enter PIN: \";\n            std::cin >> pin;\n\n            if (!authenticate(accountNumber, pin)) {\n                std::cout << \"Invalid account number or PIN\" << std::endl;\n                continue;\n            }\n            std::cout << \"Authentication successful!\" << std::endl;\n        }\n\n        displayMenu();\n        std::cin >> choice;\n        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\\n');\n\n        switch (choice) {\n            case 1:\n                checkBalance();\n                break;\n\n            case 2:\n                std::cout << \"Enter amount to deposit: $\";\n                std::cin >> amount;\n                if (deposit(amount)) {\n                    std::cout << \"Deposit successful\" << std::endl;\n                    checkBalance();\n                } else {\n                    std::cout << \"Invalid amount\" << std::endl;\n                }\n                break;\n\n            case 3:\n                std::cout << \"Enter amount to withdraw: $\";\n                std::cin >> amount;\n                if (withdraw(amount)) {\n                    std::cout << \"Withdrawal successful\" << std::endl;\n                    checkBalance();\n                } else {\n                    std::cout << \"Invalid amount or insufficient funds\" << std::endl;\n                }\n                break;\n\n            case 4:\n                logout();\n                std::cout << \"Logged out successfully\" << std::endl;\n                break;\n\n            case 5:\n                std::cout << \"Thank you for using ATM. Goodbye!\" << std::endl;\n                return;\n\n            default:\n                std::cout << \"Invalid choice\" << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/atm/ATM.hpp",
    "content": "#ifndef ATM_HPP\n#define ATM_HPP\n\n#include \"Account.hpp\"\n#include <vector>\n#include <string>\n\nclass ATM {\nprivate:\n    std::vector<Account*> accounts;\n    Account* currentAccount;\n    bool isAuthenticated;\n\npublic:\n    ATM();\n    ~ATM();\n    \n    void addAccount(Account* account);\n    bool authenticate(const std::string& accountNumber, const std::string& pin);\n    void logout();\n    \n    bool deposit(double amount);\n    bool withdraw(double amount);\n    void checkBalance() const;\n    \n    void displayMenu() const;\n    void start();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/atm/ATMDemo.cpp",
    "content": "#include \"ATM.hpp\"\n#include <iostream>\n\nint main() {\n    ATM atm;\n    \n    // Create some test accounts\n    Account* account1 = new Account(\"1234\", \"5678\", 1000.0);\n    Account* account2 = new Account(\"4321\", \"8765\", 2000.0);\n    \n    // Add accounts to ATM\n    atm.addAccount(account1);\n    atm.addAccount(account2);\n    \n    // Start the ATM\n    atm.start();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/atm/Account.cpp",
    "content": "#include \"Account.hpp\"\n#include <iostream>\n#include <iomanip>\n\nAccount::Account(std::string accountNumber, std::string pin, double initialBalance)\n    : accountNumber(accountNumber), pin(pin), balance(initialBalance) {}\n\nstd::string Account::getAccountNumber() const {\n    return accountNumber;\n}\n\nbool Account::validatePin(const std::string& inputPin) const {\n    return pin == inputPin;\n}\n\ndouble Account::getBalance() const {\n    return balance;\n}\n\nbool Account::deposit(double amount) {\n    if (amount <= 0) return false;\n    \n    balance += amount;\n    return true;\n}\n\nbool Account::withdraw(double amount) {\n    if (amount <= 0 || amount > balance) return false;\n    \n    balance -= amount;\n    return true;\n}\n\nvoid Account::displayBalance() const {\n    std::cout << \"Current balance: $\" << std::fixed << std::setprecision(2) << balance << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/atm/Account.hpp",
    "content": "#ifndef ACCOUNT_HPP\n#define ACCOUNT_HPP\n\n#include <string>\n\nclass Account {\nprivate:\n    std::string accountNumber;\n    std::string pin;\n    double balance;\n\npublic:\n    Account(std::string accountNumber, std::string pin, double initialBalance = 0.0);\n    \n    std::string getAccountNumber() const;\n    bool validatePin(const std::string& inputPin) const;\n    double getBalance() const;\n    \n    bool deposit(double amount);\n    bool withdraw(double amount);\n    void displayBalance() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/atm/README.md",
    "content": "# Designing an ATM System\n\n## Requirements\n1. The ATM system should support basic operations such as balance inquiry, cash withdrawal, and cash deposit.\n2. Users should be able to authenticate themselves using a card and a PIN (Personal Identification Number).\n3. The system should interact with a bank's backend system to validate user accounts and perform transactions.\n4. The ATM should have a cash dispenser to dispense cash to users.\n5. The system should handle concurrent access and ensure data consistency.\n6. The ATM should have a user-friendly interface for users to interact with.\n\n## Classes, Interfaces and Enumerations\n1. The **Card** class represents an ATM card with a card number and PIN.\n2. The **Account** class represents a bank account with an account number and balance. It provides methods to debit and credit the account balance.\n3. The **Transaction** class is an abstract base class for different types of transactions, such as withdrawal and deposit. It is extended by WithdrawalTransaction and DepositTransaction classes.\n4. The **BankingService** class manages the bank accounts and processes transactions. It uses a thread-safe ConcurrentHashMap to store and retrieve account information.\n5. The **CashDispenser** class represents the ATM's cash dispenser and handles the dispensing of cash. It uses synchronization to ensure thread safety when dispensing cash.\n6. The **ATM** class serves as the main interface for ATM operations. It interacts with the BankingService and CashDispenser to perform user authentication, balance inquiry, cash withdrawal, and cash deposit.\n7. The **ATMDriver** class demonstrates the usage of the ATM system by creating sample accounts and performing ATM operations."
  },
  {
    "path": "solutions/cpp/carrentalsystem/Car.cpp",
    "content": "#include \"Car.hpp\"\n#include <iostream>\n#include <iomanip>\n\nCar::Car(std::string carId, std::string brand, std::string model, double basePrice)\n    : carId(carId), brand(brand), model(model), basePrice(basePrice), available(true) {}\n\nstd::string Car::getCarId() const { return carId; }\nstd::string Car::getBrand() const { return brand; }\nstd::string Car::getModel() const { return model; }\ndouble Car::getBasePrice() const { return basePrice; }\nbool Car::isAvailable() const { return available; }\n\nvoid Car::setAvailable(bool status) {\n    available = status;\n}\n\nvoid Car::displayInfo() const {\n    std::cout << \"Car ID: \" << carId << std::endl;\n    std::cout << \"Brand: \" << brand << std::endl;\n    std::cout << \"Model: \" << model << std::endl;\n    std::cout << \"Base Price per Day: $\" << std::fixed << std::setprecision(2) << basePrice << std::endl;\n    std::cout << \"Status: \" << (available ? \"Available\" : \"Rented\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/carrentalsystem/Car.hpp",
    "content": "#ifndef CAR_HPP\n#define CAR_HPP\n\n#include <string>\n\nclass Car {\nprivate:\n    std::string carId;\n    std::string brand;\n    std::string model;\n    double basePrice;\n    bool available;\n\npublic:\n    Car(std::string carId, std::string brand, std::string model, double basePrice);\n    \n    std::string getCarId() const;\n    std::string getBrand() const;\n    std::string getModel() const;\n    double getBasePrice() const;\n    bool isAvailable() const;\n    \n    void setAvailable(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/carrentalsystem/CarRentalSystem.cpp",
    "content": "#include \"CarRentalSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nCarRentalSystem::CarRentalSystem() : rentalIdCounter(1) {}\n\nCarRentalSystem::~CarRentalSystem() {\n    for (auto car : cars) delete car;\n    for (auto customer : customers) delete customer;\n    for (auto rental : rentals) delete rental;\n}\n\nvoid CarRentalSystem::addCar(Car* car) {\n    cars.push_back(car);\n}\n\nvoid CarRentalSystem::addCustomer(Customer* customer) {\n    customers.push_back(customer);\n}\n\nstd::string CarRentalSystem::rentCar(Car* car, Customer* customer, \n                                   std::string startDate, int days) {\n    if (!car->isAvailable()) return \"\";\n    \n    std::string rentalId = \"R\" + std::to_string(rentalIdCounter++);\n    Rental* rental = new Rental(rentalId, car, customer, startDate, days);\n    rentals.push_back(rental);\n    car->setAvailable(false);\n    return rentalId;\n}\n\nbool CarRentalSystem::returnCar(std::string rentalId) {\n    Rental* rental = findRental(rentalId);\n    if (!rental) return false;\n    \n    rental->getCar()->setAvailable(true);\n    \n    auto it = std::find(rentals.begin(), rentals.end(), rental);\n    if (it != rentals.end()) {\n        rentals.erase(it);\n        delete rental;\n        return true;\n    }\n    return false;\n}\n\nvoid CarRentalSystem::displayAvailableCars() const {\n    std::cout << \"\\nAvailable Cars:\" << std::endl;\n    for (const auto& car : cars) {\n        if (car->isAvailable()) {\n            car->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid CarRentalSystem::displayRentals() const {\n    std::cout << \"\\nCurrent Rentals:\" << std::endl;\n    for (const auto& rental : rentals) {\n        rental->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid CarRentalSystem::displayCustomers() const {\n    std::cout << \"\\nRegistered Customers:\" << std::endl;\n    for (const auto& customer : customers) {\n        customer->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nCar* CarRentalSystem::findCar(std::string carId) const {\n    for (auto car : cars) {\n        if (car->getCarId() == carId) return car;\n    }\n    return nullptr;\n}\n\nCustomer* CarRentalSystem::findCustomer(std::string customerId) const {\n    for (auto customer : customers) {\n        if (customer->getCustomerId() == customerId) return customer;\n    }\n    return nullptr;\n}\n\nRental* CarRentalSystem::findRental(std::string rentalId) const {\n    for (auto rental : rentals) {\n        if (rental->getRentalId() == rentalId) return rental;\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/carrentalsystem/CarRentalSystem.hpp",
    "content": "#ifndef CAR_RENTAL_SYSTEM_HPP\n#define CAR_RENTAL_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Car.hpp\"\n#include \"Customer.hpp\"\n#include \"Rental.hpp\"\n\nclass CarRentalSystem {\nprivate:\n    std::vector<Car*> cars;\n    std::vector<Customer*> customers;\n    std::vector<Rental*> rentals;\n    int rentalIdCounter;\n\npublic:\n    CarRentalSystem();\n    ~CarRentalSystem();\n    \n    void addCar(Car* car);\n    void addCustomer(Customer* customer);\n    std::string rentCar(Car* car, Customer* customer, std::string startDate, int days);\n    bool returnCar(std::string rentalId);\n    \n    void displayAvailableCars() const;\n    void displayRentals() const;\n    void displayCustomers() const;\n    \n    Car* findCar(std::string carId) const;\n    Customer* findCustomer(std::string customerId) const;\n    Rental* findRental(std::string rentalId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/carrentalsystem/CarRentalSystemDemo.cpp",
    "content": "#include \"CarRentalSystem.hpp\"\n#include <iostream>\n\nint main() {\n    CarRentalSystem rentalSystem;\n    \n    // Add some cars\n    Car* car1 = new Car(\"C001\", \"Toyota\", \"Camry\", 60.0);\n    Car* car2 = new Car(\"C002\", \"Honda\", \"Accord\", 70.0);\n    Car* car3 = new Car(\"C003\", \"BMW\", \"3 Series\", 100.0);\n    \n    rentalSystem.addCar(car1);\n    rentalSystem.addCar(car2);\n    rentalSystem.addCar(car3);\n    \n    // Add some customers\n    Customer* customer1 = new Customer(\"CUST001\", \"John Doe\", \"+1-555-0123\");\n    Customer* customer2 = new Customer(\"CUST002\", \"Jane Smith\", \"+1-555-0124\");\n    \n    rentalSystem.addCustomer(customer1);\n    rentalSystem.addCustomer(customer2);\n    \n    // Display available cars\n    rentalSystem.displayAvailableCars();\n    \n    // Rent some cars\n    std::string rental1 = rentalSystem.rentCar(car1, customer1, \"2024-03-20\", 3);\n    std::string rental2 = rentalSystem.rentCar(car2, customer2, \"2024-03-21\", 5);\n    \n    if (!rental1.empty()) {\n        std::cout << \"\\nRental created successfully: \" << rental1 << std::endl;\n    }\n    if (!rental2.empty()) {\n        std::cout << \"Rental created successfully: \" << rental2 << std::endl;\n    }\n    \n    // Display all rentals\n    rentalSystem.displayRentals();\n    \n    // Display available cars after rentals\n    rentalSystem.displayAvailableCars();\n    \n    // Return a car\n    if (rentalSystem.returnCar(rental1)) {\n        std::cout << \"\\nCar returned successfully for rental: \" << rental1 << std::endl;\n    }\n    \n    // Display available cars after return\n    rentalSystem.displayAvailableCars();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/carrentalsystem/Customer.cpp",
    "content": "#include \"Customer.hpp\"\n#include <iostream>\n\nCustomer::Customer(std::string customerId, std::string name, std::string contactNumber)\n    : customerId(customerId), name(name), contactNumber(contactNumber) {}\n\nstd::string Customer::getCustomerId() const { return customerId; }\nstd::string Customer::getName() const { return name; }\nstd::string Customer::getContactNumber() const { return contactNumber; }\n\nvoid Customer::displayInfo() const {\n    std::cout << \"Customer ID: \" << customerId << std::endl;\n    std::cout << \"Name: \" << name << std::endl;\n    std::cout << \"Contact Number: \" << contactNumber << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/carrentalsystem/Customer.hpp",
    "content": "#ifndef CUSTOMER_HPP\n#define CUSTOMER_HPP\n\n#include <string>\n\nclass Customer {\nprivate:\n    std::string customerId;\n    std::string name;\n    std::string contactNumber;\n\npublic:\n    Customer(std::string customerId, std::string name, std::string contactNumber);\n    \n    std::string getCustomerId() const;\n    std::string getName() const;\n    std::string getContactNumber() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/carrentalsystem/README.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "solutions/cpp/carrentalsystem/Rental.cpp",
    "content": "#include \"Rental.hpp\"\n#include <iostream>\n#include <iomanip>\n\nRental::Rental(std::string rentalId, Car* car, Customer* customer, \n               std::string startDate, int days)\n    : rentalId(rentalId), car(car), customer(customer), \n      startDate(startDate), days(days) {\n    totalPrice = car->getBasePrice() * days;\n}\n\nstd::string Rental::getRentalId() const { return rentalId; }\nCar* Rental::getCar() const { return car; }\nCustomer* Rental::getCustomer() const { return customer; }\nstd::string Rental::getStartDate() const { return startDate; }\nint Rental::getDays() const { return days; }\ndouble Rental::getTotalPrice() const { return totalPrice; }\n\nvoid Rental::displayInfo() const {\n    std::cout << \"\\nRental Details:\" << std::endl;\n    std::cout << \"Rental ID: \" << rentalId << std::endl;\n    std::cout << \"Start Date: \" << startDate << std::endl;\n    std::cout << \"Duration: \" << days << \" days\" << std::endl;\n    std::cout << \"Total Price: $\" << std::fixed << std::setprecision(2) << totalPrice << std::endl;\n    std::cout << \"\\nCustomer Information:\" << std::endl;\n    customer->displayInfo();\n    std::cout << \"\\nCar Information:\" << std::endl;\n    car->displayInfo();\n} "
  },
  {
    "path": "solutions/cpp/carrentalsystem/Rental.hpp",
    "content": "#ifndef RENTAL_HPP\n#define RENTAL_HPP\n\n#include \"Car.hpp\"\n#include \"Customer.hpp\"\n#include <string>\n\nclass Rental {\nprivate:\n    std::string rentalId;\n    Car* car;\n    Customer* customer;\n    std::string startDate;\n    int days;\n    double totalPrice;\n\npublic:\n    Rental(std::string rentalId, Car* car, Customer* customer, \n           std::string startDate, int days);\n    \n    std::string getRentalId() const;\n    Car* getCar() const;\n    Customer* getCustomer() const;\n    std::string getStartDate() const;\n    int getDays() const;\n    double getTotalPrice() const;\n    \n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/Board.hpp",
    "content": "#ifndef BOARD_HPP\n#define BOARD_HPP\n\n#include \"Piece.hpp\"\n#include <vector>\n\nclass Board {\nprivate:\n    Piece* squares[8][8];\n    std::vector<Piece*> capturedPieces;\n\npublic:\n    Board();\n    ~Board();\n    \n    void initialize();\n    bool movePiece(Position from, Position to);\n    Piece* getPiece(Position position) const;\n    void displayBoard() const;\n    \nprivate:\n    void placePiece(Piece* piece);\n    void setupInitialPosition();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/ChessDemo.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n\nint main() {\n    Game chess;\n    std::cout << \"Welcome to Chess!\" << std::endl;\n    chess.start();\n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/Game.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n\nGame::Game() : currentTurn(Color::WHITE), gameOver(false) {\n    board.initialize();\n}\n\nvoid Game::start() {\n    while (!gameOver) {\n        displayBoard();\n        \n        std::cout << (currentTurn == Color::WHITE ? \"White\" : \"Black\") << \"'s turn\" << std::endl;\n        \n        int fromX, fromY, toX, toY;\n        std::cout << \"Enter move (fromX fromY toX toY): \";\n        std::cin >> fromX >> fromY >> toX >> toY;\n        \n        Position from(fromX, fromY);\n        Position to(toX, toY);\n        \n        if (makeMove(from, to)) {\n            switchTurn();\n        } else {\n            std::cout << \"Invalid move! Try again.\" << std::endl;\n        }\n    }\n}\n\nbool Game::makeMove(Position from, Position to) {\n    Piece* piece = board.getPiece(from);\n    if (!piece || piece->getColor() != currentTurn) return false;\n    \n    return board.movePiece(from, to);\n}\n\nvoid Game::switchTurn() {\n    currentTurn = (currentTurn == Color::WHITE) ? Color::BLACK : Color::WHITE;\n}\n\nColor Game::getCurrentTurn() const {\n    return currentTurn;\n}\n\nbool Game::isGameOver() const {\n    return gameOver;\n}\n\nvoid Game::displayBoard() const {\n    board.displayBoard();\n} "
  },
  {
    "path": "solutions/cpp/chessgame/Game.hpp",
    "content": "#ifndef GAME_HPP\n#define GAME_HPP\n\n#include \"Board.hpp\"\n\nclass Game {\nprivate:\n    Board board;\n    Color currentTurn;\n    bool gameOver;\n\npublic:\n    Game();\n    \n    void start();\n    bool makeMove(Position from, Position to);\n    void switchTurn();\n    Color getCurrentTurn() const;\n    bool isGameOver() const;\n    void displayBoard() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/Piece.cpp",
    "content": "#include \"Piece.hpp\"\n#include <cctype>\n\nPiece::Piece(PieceType type, Color color, Position position)\n    : type(type), color(color), position(position), captured(false) {}\n\nPieceType Piece::getType() const { return type; }\nColor Piece::getColor() const { return color; }\nPosition Piece::getPosition() const { return position; }\nbool Piece::isCaptured() const { return captured; }\n\nvoid Piece::setPosition(Position newPosition) { position = newPosition; }\nvoid Piece::setCaptured(bool status) { captured = status; }\n\nstd::string Piece::getSymbol() const {\n    char symbol;\n    switch (type) {\n        case PieceType::KING: symbol = 'K'; break;\n        case PieceType::QUEEN: symbol = 'Q'; break;\n        case PieceType::BISHOP: symbol = 'B'; break;\n        case PieceType::KNIGHT: symbol = 'N'; break;\n        case PieceType::ROOK: symbol = 'R'; break;\n        case PieceType::PAWN: symbol = 'P'; break;\n        default: symbol = '?';\n    }\n    return std::string(1, color == Color::WHITE ? symbol : tolower(symbol));\n} "
  },
  {
    "path": "solutions/cpp/chessgame/Piece.hpp",
    "content": "#ifndef PIECE_HPP\n#define PIECE_HPP\n\n#include <string>\n#include \"Position.hpp\"\n\nenum class PieceType {\n    KING, QUEEN, BISHOP, KNIGHT, ROOK, PAWN\n};\n\nenum class Color {\n    WHITE, BLACK\n};\n\nclass Piece {\nprivate:\n    PieceType type;\n    Color color;\n    Position position;\n    bool captured;\n\npublic:\n    Piece(PieceType type, Color color, Position position)\n        : type(type), color(color), position(position), captured(false) {}\n    \n    virtual ~Piece() = default;\n    \n    PieceType getType() const { return type; }\n    Color getColor() const { return color; }\n    Position getPosition() const { return position; }\n    bool isCaptured() const { return captured; }\n    \n    void setPosition(Position newPosition) { position = newPosition; }\n    void setCaptured(bool status) { captured = status; }\n    \n    virtual bool isValidMove(Position newPosition, Piece* board[8][8]) const = 0;\n    \n    std::string getSymbol() const {\n        char symbol;\n        switch (type) {\n            case PieceType::KING: symbol = 'K'; break;\n            case PieceType::QUEEN: symbol = 'Q'; break;\n            case PieceType::BISHOP: symbol = 'B'; break;\n            case PieceType::KNIGHT: symbol = 'N'; break;\n            case PieceType::ROOK: symbol = 'R'; break;\n            case PieceType::PAWN: symbol = 'P'; break;\n            default: symbol = '?';\n        }\n        return std::string(1, color == Color::WHITE ? symbol : tolower(symbol));\n    }\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/Position.hpp",
    "content": "#ifndef POSITION_HPP\n#define POSITION_HPP\n\nclass Position {\nprivate:\n    int x;\n    int y;\n\npublic:\n    Position(int x, int y);\n    \n    int getX() const;\n    int getY() const;\n    bool isValid() const;\n    bool operator==(const Position& other) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/README.md",
    "content": "# Designing a Chess Game\n\n## Requirements\n1. The chess game should follow the standard rules of chess.\n2. The game should support two players, each controlling their own set of pieces.\n3. The game board should be represented as an 8x8 grid, with alternating black and white squares.\n4. Each player should have 16 pieces: 1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.\n5. The game should validate legal moves for each piece and prevent illegal moves.\n6. The game should detect checkmate and stalemate conditions.\n7. The game should handle player turns and allow players to make moves alternately.\n8. The game should provide a user interface for players to interact with the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Piece** class is an abstract base class representing a chess piece. It contains common attributes such as color, row, and column, and declares an abstract method canMove to be implemented by each specific piece class.\n2. The **King**, **Queen**, **Rook**, **Bishop**, **Knight**, and **Pawn** classes extend the Piece class and implement their respective movement logic in the canMove method.\n3. The **Board** class represents the chess board and manages the placement of pieces. It provides methods to get and set pieces on the board, check the validity of moves, and determine checkmate and stalemate conditions.\n4. The **Player** class represents a player in the game and has a method to make a move on the board.\n5. The Move class represents a move made by a player, containing the piece being moved and the destination coordinates.\n6. The **Game** class orchestrates the overall game flow. It initializes the board, handles player turns, and determines the game result.\n7. The **ChessGame** class is the entry point of the application and starts the game."
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Bishop.cpp",
    "content": "#include \"Bishop.hpp\"\n#include <cstdlib>\n\nBishop::Bishop(Color color, Position position)\n    : Piece(PieceType::BISHOP, color, position) {}\n\nbool Bishop::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int dx = newPosition.getX() - currentPos.getX();\n    int dy = newPosition.getY() - currentPos.getY();\n    \n    // Bishop can only move diagonally\n    if (abs(dx) == abs(dy)) {\n        // Check if path is clear\n        int xStep = dx / abs(dx);\n        int yStep = dy / abs(dy);\n        \n        int x = currentPos.getX() + xStep;\n        int y = currentPos.getY() + yStep;\n        \n        while (x != newPosition.getX()) {\n            if (board[x][y] != nullptr) return false;\n            x += xStep;\n            y += yStep;\n        }\n        \n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return !targetPiece || targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Bishop.hpp",
    "content": "#ifndef BISHOP_HPP\n#define BISHOP_HPP\n\n#include \"../Piece.hpp\"\n\nclass Bishop : public Piece {\npublic:\n    Bishop(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/King.cpp",
    "content": "#include \"King.hpp\"\n#include <cstdlib>\n\nKing::King(Color color, Position position)\n    : Piece(PieceType::KING, color, position) {}\n\nbool King::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int dx = abs(newPosition.getX() - currentPos.getX());\n    int dy = abs(newPosition.getY() - currentPos.getY());\n    \n    // King can move one square in any direction\n    if (dx <= 1 && dy <= 1) {\n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return !targetPiece || targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/King.hpp",
    "content": "#ifndef KING_HPP\n#define KING_HPP\n\n#include \"../Piece.hpp\"\n\nclass King : public Piece {\npublic:\n    King(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Knight.cpp",
    "content": "#include \"Knight.hpp\"\n#include <cstdlib>\n\nKnight::Knight(Color color, Position position)\n    : Piece(PieceType::KNIGHT, color, position) {}\n\nbool Knight::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int dx = abs(newPosition.getX() - currentPos.getX());\n    int dy = abs(newPosition.getY() - currentPos.getY());\n    \n    // Knight moves in L-shape: 2 squares in one direction and 1 square perpendicular\n    if ((dx == 2 && dy == 1) || (dx == 1 && dy == 2)) {\n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return !targetPiece || targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Knight.hpp",
    "content": "#ifndef KNIGHT_HPP\n#define KNIGHT_HPP\n\n#include \"../Piece.hpp\"\n\nclass Knight : public Piece {\npublic:\n    Knight(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Pawn.cpp",
    "content": "#include \"Pawn.hpp\"\n\nPawn::Pawn(Color color, Position position)\n    : Piece(PieceType::PAWN, color, position) {}\n\nbool Pawn::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int direction = (getColor() == Color::WHITE) ? 1 : -1;\n    int dx = newPosition.getX() - currentPos.getX();\n    int dy = newPosition.getY() - currentPos.getY();\n    \n    // Normal move forward\n    if (dy == 0 && dx == direction) {\n        return board[newPosition.getX()][newPosition.getY()] == nullptr;\n    }\n    \n    // Initial two-square move\n    if (dy == 0 && dx == 2 * direction && \n        ((getColor() == Color::WHITE && currentPos.getX() == 1) ||\n         (getColor() == Color::BLACK && currentPos.getX() == 6))) {\n        return board[currentPos.getX() + direction][currentPos.getY()] == nullptr &&\n               board[newPosition.getX()][newPosition.getY()] == nullptr;\n    }\n    \n    // Capture diagonally\n    if (abs(dy) == 1 && dx == direction) {\n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return targetPiece && targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Pawn.hpp",
    "content": "#ifndef PAWN_HPP\n#define PAWN_HPP\n\n#include \"../Piece.hpp\"\n\nclass Pawn : public Piece {\npublic:\n    Pawn(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Queen.cpp",
    "content": "#include \"Queen.hpp\"\n#include <cstdlib>\n\nQueen::Queen(Color color, Position position)\n    : Piece(PieceType::QUEEN, color, position) {}\n\nbool Queen::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int dx = newPosition.getX() - currentPos.getX();\n    int dy = newPosition.getY() - currentPos.getY();\n    \n    // Queen can move diagonally, horizontally, or vertically\n    if (abs(dx) == abs(dy) || dx == 0 || dy == 0) {\n        // Check if path is clear\n        int xStep = (dx == 0) ? 0 : dx / abs(dx);\n        int yStep = (dy == 0) ? 0 : dy / abs(dy);\n        \n        int x = currentPos.getX() + xStep;\n        int y = currentPos.getY() + yStep;\n        \n        while (x != newPosition.getX() || y != newPosition.getY()) {\n            if (board[x][y] != nullptr) return false;\n            x += xStep;\n            y += yStep;\n        }\n        \n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return !targetPiece || targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Queen.hpp",
    "content": "#ifndef QUEEN_HPP\n#define QUEEN_HPP\n\n#include \"../Piece.hpp\"\n\nclass Queen : public Piece {\npublic:\n    Queen(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Rook.cpp",
    "content": "#include \"Rook.hpp\"\n#include <cstdlib>\n\nRook::Rook(Color color, Position position)\n    : Piece(PieceType::ROOK, color, position) {}\n\nbool Rook::isValidMove(Position newPosition, Piece* board[8][8]) const {\n    if (!newPosition.isValid()) return false;\n    \n    Position currentPos = getPosition();\n    int dx = newPosition.getX() - currentPos.getX();\n    int dy = newPosition.getY() - currentPos.getY();\n    \n    // Rook can only move horizontally or vertically\n    if (dx == 0 || dy == 0) {\n        // Check if path is clear\n        int xStep = (dx == 0) ? 0 : dx / abs(dx);\n        int yStep = (dy == 0) ? 0 : dy / abs(dy);\n        \n        int x = currentPos.getX() + xStep;\n        int y = currentPos.getY() + yStep;\n        \n        while (x != newPosition.getX() || y != newPosition.getY()) {\n            if (board[x][y] != nullptr) return false;\n            x += xStep;\n            y += yStep;\n        }\n        \n        Piece* targetPiece = board[newPosition.getX()][newPosition.getY()];\n        return !targetPiece || targetPiece->getColor() != getColor();\n    }\n    \n    return false;\n} "
  },
  {
    "path": "solutions/cpp/chessgame/pieces/Rook.hpp",
    "content": "#ifndef ROOK_HPP\n#define ROOK_HPP\n\n#include \"../Piece.hpp\"\n\nclass Rook : public Piece {\npublic:\n    Rook(Color color, Position position);\n    bool isValidMove(Position newPosition, Piece* board[8][8]) const override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/Coffee.cpp",
    "content": "#include \"Coffee.hpp\"\n\nCoffee::Coffee(CoffeeType type, double price, std::string description)\n    : type(type), price(price), description(description) {}\n\nCoffeeType Coffee::getType() const { return type; }\ndouble Coffee::getPrice() const { return price; }\nstd::string Coffee::getDescription() const { return description; } "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/Coffee.hpp",
    "content": "#ifndef COFFEE_HPP\n#define COFFEE_HPP\n\n#include <string>\n#include \"CoffeeType.hpp\"\n\nclass Coffee {\nprivate:\n    CoffeeType type;\n    double price;\n    std::string description;\n\npublic:\n    Coffee(CoffeeType type, double price, std::string description);\n    \n    CoffeeType getType() const;\n    double getPrice() const;\n    std::string getDescription() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/CoffeeType.hpp",
    "content": "#ifndef COFFEE_TYPE_HPP\n#define COFFEE_TYPE_HPP\n\nenum class CoffeeType {\n    ESPRESSO,\n    LATTE,\n    CAPPUCCINO,\n    AMERICANO\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/CoffeeVendingMachine.cpp",
    "content": "#include \"CoffeeVendingMachine.hpp\"\n#include <iostream>\n#include <iomanip>\n\nCoffeeVendingMachine::CoffeeVendingMachine() : moneyCollected(0.0) {\n    initializeMenu();\n}\n\nvoid CoffeeVendingMachine::initializeMenu() {\n    coffeeMenu.push_back(Coffee(CoffeeType::ESPRESSO, 2.50, \"Strong black coffee\"));\n    coffeeMenu.push_back(Coffee(CoffeeType::LATTE, 3.50, \"Coffee with steamed milk\"));\n    coffeeMenu.push_back(Coffee(CoffeeType::CAPPUCCINO, 3.00, \"Coffee topped with foamy milk\"));\n    coffeeMenu.push_back(Coffee(CoffeeType::AMERICANO, 2.00, \"Diluted espresso\"));\n}\n\nvoid CoffeeVendingMachine::displayMenu() const {\n    std::cout << \"\\nCoffee Menu:\" << std::endl;\n    std::cout << std::fixed << std::setprecision(2);\n    \n    for (const auto& coffee : coffeeMenu) {\n        std::cout << \"Type: \";\n        switch (coffee.getType()) {\n            case CoffeeType::ESPRESSO: std::cout << \"Espresso\"; break;\n            case CoffeeType::LATTE: std::cout << \"Latte\"; break;\n            case CoffeeType::CAPPUCCINO: std::cout << \"Cappuccino\"; break;\n            case CoffeeType::AMERICANO: std::cout << \"Americano\"; break;\n        }\n        std::cout << \" - $\" << coffee.getPrice() << std::endl;\n        std::cout << \"Description: \" << coffee.getDescription() << std::endl;\n        std::cout << \"Available: \" << inventory.getQuantity(coffee.getType()) << std::endl;\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nbool CoffeeVendingMachine::selectCoffee(CoffeeType type, double payment) {\n    Coffee* coffee = findCoffee(type);\n    if (!coffee) {\n        std::cout << \"Invalid coffee selection!\" << std::endl;\n        return false;\n    }\n    \n    if (!inventory.hasItem(type)) {\n        std::cout << \"Sorry, this coffee is out of stock!\" << std::endl;\n        return false;\n    }\n    \n    if (payment < coffee->getPrice()) {\n        std::cout << \"Insufficient payment! Price is $\" << coffee->getPrice() << std::endl;\n        return false;\n    }\n    \n    inventory.deductItem(type);\n    moneyCollected += coffee->getPrice();\n    double change = payment - coffee->getPrice();\n    \n    std::cout << \"\\nDispensing \" << coffee->getDescription() << std::endl;\n    if (change > 0) {\n        std::cout << \"Change: $\" << std::fixed << std::setprecision(2) << change << std::endl;\n    }\n    \n    return true;\n}\n\nvoid CoffeeVendingMachine::refillInventory(CoffeeType type, int quantity) {\n    inventory.addItem(type, quantity);\n    std::cout << \"Inventory refilled successfully!\" << std::endl;\n}\n\ndouble CoffeeVendingMachine::getMoneyCollected() const {\n    return moneyCollected;\n}\n\nvoid CoffeeVendingMachine::displayInventory() const {\n    inventory.display();\n}\n\nCoffee* CoffeeVendingMachine::findCoffee(CoffeeType type) {\n    for (auto& coffee : coffeeMenu) {\n        if (coffee.getType() == type) {\n            return &coffee;\n        }\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/CoffeeVendingMachine.hpp",
    "content": "#ifndef COFFEE_VENDING_MACHINE_HPP\n#define COFFEE_VENDING_MACHINE_HPP\n\n#include <vector>\n#include \"Coffee.hpp\"\n#include \"Inventory.hpp\"\n\nclass CoffeeVendingMachine {\nprivate:\n    std::vector<Coffee> coffeeMenu;\n    Inventory inventory;\n    double moneyCollected;\n\npublic:\n    CoffeeVendingMachine();\n    \n    void initializeMenu();\n    void displayMenu() const;\n    bool selectCoffee(CoffeeType type, double payment);\n    void refillInventory(CoffeeType type, int quantity);\n    double getMoneyCollected() const;\n    void displayInventory() const;\n    \nprivate:\n    Coffee* findCoffee(CoffeeType type);\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/CoffeeVendingMachineDemo.cpp",
    "content": "#include \"CoffeeVendingMachine.hpp\"\n#include <iostream>\n\nint main() {\n    CoffeeVendingMachine machine;\n    \n    // Refill inventory\n    machine.refillInventory(CoffeeType::ESPRESSO, 5);\n    machine.refillInventory(CoffeeType::LATTE, 5);\n    machine.refillInventory(CoffeeType::CAPPUCCINO, 5);\n    machine.refillInventory(CoffeeType::AMERICANO, 5);\n    \n    // Display menu and inventory\n    machine.displayMenu();\n    machine.displayInventory();\n    \n    // Make some purchases\n    std::cout << \"\\nMaking purchases:\" << std::endl;\n    \n    if (machine.selectCoffee(CoffeeType::ESPRESSO, 3.00)) {\n        std::cout << \"Espresso purchased successfully!\" << std::endl;\n    }\n    \n    if (machine.selectCoffee(CoffeeType::LATTE, 3.50)) {\n        std::cout << \"Latte purchased successfully!\" << std::endl;\n    }\n    \n    // Try insufficient payment\n    if (!machine.selectCoffee(CoffeeType::CAPPUCCINO, 2.00)) {\n        std::cout << \"Cappuccino purchase failed - insufficient payment\" << std::endl;\n    }\n    \n    // Display updated inventory and money collected\n    machine.displayInventory();\n    std::cout << \"\\nTotal money collected: $\" << machine.getMoneyCollected() << std::endl;\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/Inventory.cpp",
    "content": "#include \"Inventory.hpp\"\n#include <iostream>\n\nInventory::Inventory() {\n    // Initialize inventory with zero quantity for all coffee types\n    items[CoffeeType::ESPRESSO] = 0;\n    items[CoffeeType::LATTE] = 0;\n    items[CoffeeType::CAPPUCCINO] = 0;\n    items[CoffeeType::AMERICANO] = 0;\n}\n\nvoid Inventory::addItem(CoffeeType type, int quantity) {\n    items[type] += quantity;\n}\n\nbool Inventory::hasItem(CoffeeType type) {\n    return items[type] > 0;\n}\n\nvoid Inventory::deductItem(CoffeeType type) {\n    if (items[type] > 0) {\n        items[type]--;\n    }\n}\n\nint Inventory::getQuantity(CoffeeType type) const {\n    auto it = items.find(type);\n    return it != items.end() ? it->second : 0;\n}\n\nvoid Inventory::display() const {\n    std::cout << \"\\nCurrent Inventory:\" << std::endl;\n    std::cout << \"Espresso: \" << items.at(CoffeeType::ESPRESSO) << std::endl;\n    std::cout << \"Latte: \" << items.at(CoffeeType::LATTE) << std::endl;\n    std::cout << \"Cappuccino: \" << items.at(CoffeeType::CAPPUCCINO) << std::endl;\n    std::cout << \"Americano: \" << items.at(CoffeeType::AMERICANO) << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/Inventory.hpp",
    "content": "#ifndef INVENTORY_HPP\n#define INVENTORY_HPP\n\n#include <map>\n#include \"CoffeeType.hpp\"\n\nclass Inventory {\nprivate:\n    std::map<CoffeeType, int> items;\n\npublic:\n    Inventory();\n    \n    void addItem(CoffeeType type, int quantity);\n    bool hasItem(CoffeeType type);\n    void deductItem(CoffeeType type);\n    int getQuantity(CoffeeType type) const;\n    void display() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/coffeevendingmachine/README.md",
    "content": "# Designing a Coffee Vending Machine\n\n## Requirements\n1. The coffee vending machine should support different types of coffee, such as espresso, cappuccino, and latte.\n2. Each type of coffee should have a specific price and recipe (ingredients and their quantities).\n3. The machine should have a menu to display the available coffee options and their prices.\n4. Users should be able to select a coffee type and make a payment.\n5. The machine should dispense the selected coffee and provide change if necessary.\n6. The machine should track the inventory of ingredients and notify when they are running low.\n7. The machine should handle multiple user requests concurrently and ensure thread safety.\n\n## Classes, Interfaces and Enumerations\n1. The **Coffee** class represents a coffee type with its name, price, and recipe (ingredients and their quantities).\n2. The **Ingredient** class represents an ingredient used in making coffee, with its name and quantity. It provides a synchronized method to update the quantity.\n3. The **Payment** class represents a payment made by a user, with the amount paid.\n4. The **CoffeeMachine** class is the main class that manages the coffee vending machine. It follows the Singleton pattern to ensure a single instance of the machine.\n5. The **CoffeeMachine** class initializes the coffee menu and ingredients in its constructor. It provides methods to display the menu, select a coffee, dispense coffee, and update ingredient quantities.\n6. The hasEnoughIngredients method checks if there are sufficient ingredients to make a selected coffee, while the updateIngredients method updates the ingredient quantities after dispensing a coffee.\n7. The **CoffeeVendingMachine** class is the entry point of the application and demonstrates the usage of the coffee vending machine. It creates an instance of the machine, displays the menu, and simulates concurrent user requests using an ExecutorService."
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Booking.cpp",
    "content": "#include \"Booking.hpp\"\n#include <iostream>\n#include <iomanip>\n\nBooking::Booking(std::string bookingId, std::string customerName, Concert* concert, \n                int seatNumber, double totalPrice)\n    : bookingId(bookingId), customerName(customerName), concert(concert), \n      seatNumber(seatNumber), totalPrice(totalPrice) {}\n\nstd::string Booking::getBookingId() const { return bookingId; }\nstd::string Booking::getCustomerName() const { return customerName; }\nConcert* Booking::getConcert() const { return concert; }\nint Booking::getSeatNumber() const { return seatNumber; }\ndouble Booking::getTotalPrice() const { return totalPrice; }\n\nvoid Booking::displayInfo() const {\n    std::cout << \"\\nBooking Details:\" << std::endl;\n    std::cout << \"Booking ID: \" << bookingId << std::endl;\n    std::cout << \"Customer Name: \" << customerName << std::endl;\n    std::cout << \"Seat Number: \" << seatNumber << std::endl;\n    std::cout << \"Total Price: $\" << std::fixed << std::setprecision(2) << totalPrice << std::endl;\n    std::cout << \"\\nConcert Information:\" << std::endl;\n    concert->displayInfo();\n} "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Booking.hpp",
    "content": "#ifndef BOOKING_HPP\n#define BOOKING_HPP\n\n#include <string>\n#include \"Concert.hpp\"\n\nclass Booking {\nprivate:\n    std::string bookingId;\n    std::string customerName;\n    Concert* concert;\n    int seatNumber;\n    double totalPrice;\n\npublic:\n    Booking(std::string bookingId, std::string customerName, Concert* concert, \n            int seatNumber, double totalPrice);\n    \n    std::string getBookingId() const;\n    std::string getCustomerName() const;\n    Concert* getConcert() const;\n    int getSeatNumber() const;\n    double getTotalPrice() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/BookingSystem.cpp",
    "content": "#include \"BookingSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nBookingSystem::BookingSystem() : bookingIdCounter(1) {}\n\nBookingSystem::~BookingSystem() {\n    for (auto concert : concerts) delete concert;\n    for (auto booking : bookings) delete booking;\n}\n\nvoid BookingSystem::addConcert(Concert* concert) {\n    concerts.push_back(concert);\n}\n\nstd::string BookingSystem::createBooking(std::string customerName, Concert* concert, int seatNumber) {\n    if (!concert->bookSeat(seatNumber)) {\n        std::cout << \"Failed to book seat: Seat \" << seatNumber << \" is not available\" << std::endl;\n        return \"\";\n    }\n    \n    std::string bookingId = \"B\" + std::to_string(bookingIdCounter++);\n    double totalPrice = concert->getBasePrice();  // Could add premium pricing logic here\n    \n    Booking* booking = new Booking(bookingId, customerName, concert, seatNumber, totalPrice);\n    bookings.push_back(booking);\n    return bookingId;\n}\n\nbool BookingSystem::cancelBooking(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking) return false;\n    \n    booking->getConcert()->cancelSeat(booking->getSeatNumber());\n    \n    auto it = std::find(bookings.begin(), bookings.end(), booking);\n    if (it != bookings.end()) {\n        bookings.erase(it);\n        delete booking;\n        return true;\n    }\n    return false;\n}\n\nvoid BookingSystem::displayAllConcerts() const {\n    std::cout << \"\\nAvailable Concerts:\" << std::endl;\n    for (const auto& concert : concerts) {\n        concert->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid BookingSystem::displayAllBookings() const {\n    std::cout << \"\\nCurrent Bookings:\" << std::endl;\n    for (const auto& booking : bookings) {\n        booking->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid BookingSystem::displayAvailableSeats(Concert* concert) const {\n    std::cout << \"\\nAvailable seats for concert \" << concert->getName() << \":\" << std::endl;\n    for (int i = 1; i <= concert->getTotalSeats(); i++) {\n        if (concert->isSeatAvailable(i)) {\n            std::cout << i << \" \";\n        }\n    }\n    std::cout << std::endl;\n}\n\nConcert* BookingSystem::findConcert(std::string concertId) const {\n    for (auto concert : concerts) {\n        if (concert->getConcertId() == concertId) return concert;\n    }\n    return nullptr;\n}\n\nBooking* BookingSystem::findBooking(std::string bookingId) const {\n    for (auto booking : bookings) {\n        if (booking->getBookingId() == bookingId) return booking;\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/BookingSystem.hpp",
    "content": "#ifndef BOOKING_SYSTEM_HPP\n#define BOOKING_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Concert.hpp\"\n#include \"Booking.hpp\"\n\nclass BookingSystem {\nprivate:\n    std::vector<Concert*> concerts;\n    std::vector<Booking*> bookings;\n    int bookingIdCounter;\n\npublic:\n    BookingSystem();\n    ~BookingSystem();\n    \n    void addConcert(Concert* concert);\n    std::string createBooking(std::string customerName, Concert* concert, int seatNumber);\n    bool cancelBooking(std::string bookingId);\n    \n    void displayAllConcerts() const;\n    void displayAllBookings() const;\n    void displayAvailableSeats(Concert* concert) const;\n    \n    Concert* findConcert(std::string concertId) const;\n    Booking* findBooking(std::string bookingId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Concert.cpp",
    "content": "#include \"Concert.hpp\"\n#include <iostream>\n#include <iomanip>\n\nConcert::Concert(std::string concertId, std::string name, std::string venue, \n                std::string date, double basePrice, int totalSeats)\n    : concertId(concertId), name(name), venue(venue), date(date), \n      basePrice(basePrice), totalSeats(totalSeats) {\n    \n    // Initialize seats\n    for (int i = 1; i <= totalSeats; i++) {\n        seats.push_back(Seat(i));\n    }\n}\n\nstd::string Concert::getConcertId() const { return concertId; }\nstd::string Concert::getName() const { return name; }\nstd::string Concert::getVenue() const { return venue; }\nstd::string Concert::getDate() const { return date; }\ndouble Concert::getBasePrice() const { return basePrice; }\nint Concert::getTotalSeats() const { return totalSeats; }\n\nint Concert::getAvailableSeats() const {\n    int available = 0;\n    for (const auto& seat : seats) {\n        if (!seat.isBooked()) available++;\n    }\n    return available;\n}\n\nbool Concert::bookSeat(int seatNumber) {\n    if (seatNumber < 1 || seatNumber > totalSeats) return false;\n    if (seats[seatNumber - 1].isBooked()) return false;\n    \n    seats[seatNumber - 1].book();\n    return true;\n}\n\nbool Concert::cancelSeat(int seatNumber) {\n    if (seatNumber < 1 || seatNumber > totalSeats) return false;\n    if (!seats[seatNumber - 1].isBooked()) return false;\n    \n    seats[seatNumber - 1].cancel();\n    return true;\n}\n\nbool Concert::isSeatAvailable(int seatNumber) const {\n    if (seatNumber < 1 || seatNumber > totalSeats) return false;\n    return !seats[seatNumber - 1].isBooked();\n}\n\nvoid Concert::displayInfo() const {\n    std::cout << \"Concert: \" << name << std::endl;\n    std::cout << \"ID: \" << concertId << std::endl;\n    std::cout << \"Venue: \" << venue << std::endl;\n    std::cout << \"Date: \" << date << std::endl;\n    std::cout << \"Price: $\" << std::fixed << std::setprecision(2) << basePrice << std::endl;\n    std::cout << \"Available Seats: \" << getAvailableSeats() << \"/\" << totalSeats << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Concert.hpp",
    "content": "#ifndef CONCERT_HPP\n#define CONCERT_HPP\n\n#include <string>\n#include <vector>\n#include \"Seat.hpp\"\n\nclass Concert {\nprivate:\n    std::string concertId;\n    std::string name;\n    std::string venue;\n    std::string date;\n    double basePrice;\n    std::vector<Seat> seats;\n    int totalSeats;\n\npublic:\n    Concert(std::string concertId, std::string name, std::string venue, \n            std::string date, double basePrice, int totalSeats);\n    \n    std::string getConcertId() const;\n    std::string getName() const;\n    std::string getVenue() const;\n    std::string getDate() const;\n    double getBasePrice() const;\n    int getTotalSeats() const;\n    int getAvailableSeats() const;\n    \n    bool bookSeat(int seatNumber);\n    bool cancelSeat(int seatNumber);\n    bool isSeatAvailable(int seatNumber) const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/ConcertBookingDemo.cpp",
    "content": "#include \"BookingSystem.hpp\"\n#include <iostream>\n\nint main() {\n    BookingSystem bookingSystem;\n    \n    // Create some concerts\n    Concert* concert1 = new Concert(\"C001\", \"Rock Festival\", \"Stadium A\", \"2024-07-15\", 100.0, 50);\n    Concert* concert2 = new Concert(\"C002\", \"Jazz Night\", \"Hall B\", \"2024-07-20\", 75.0, 30);\n    \n    bookingSystem.addConcert(concert1);\n    bookingSystem.addConcert(concert2);\n    \n    // Display all concerts\n    bookingSystem.displayAllConcerts();\n    \n    // Make some bookings\n    std::string booking1 = bookingSystem.createBooking(\"John Doe\", concert1, 1);\n    std::string booking2 = bookingSystem.createBooking(\"Jane Smith\", concert1, 2);\n    std::string booking3 = bookingSystem.createBooking(\"Alice Johnson\", concert2, 1);\n    \n    if (!booking1.empty()) {\n        std::cout << \"\\nBooking created successfully: \" << booking1 << std::endl;\n    }\n    if (!booking2.empty()) {\n        std::cout << \"Booking created successfully: \" << booking2 << std::endl;\n    }\n    if (!booking3.empty()) {\n        std::cout << \"Booking created successfully: \" << booking3 << std::endl;\n    }\n    \n    // Display all bookings\n    bookingSystem.displayAllBookings();\n    \n    // Display available seats for concert1\n    bookingSystem.displayAvailableSeats(concert1);\n    \n    // Cancel a booking\n    if (bookingSystem.cancelBooking(booking1)) {\n        std::cout << \"\\nBooking \" << booking1 << \" cancelled successfully\" << std::endl;\n    }\n    \n    // Display updated available seats\n    bookingSystem.displayAvailableSeats(concert1);\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/README.md",
    "content": "# Designing a Concert Ticket Booking System\n\n## Requirements\n1. The concert ticket booking system should allow users to view available concerts and their seating arrangements.\n2. Users should be able to search for concerts based on various criteria such as artist, venue, date, and time.\n3. Users should be able to select seats and purchase tickets for a specific concert.\n4. The system should handle concurrent booking requests to avoid double-booking of seats.\n5. The system should ensure fair booking opportunities for all users.\n6. The system should handle payment processing securely.\n7. The system should generate booking confirmations and send them to users via email or SMS.\n8. The system should provide a waiting list functionality for sold-out concerts.\n\n## Classes, Interfaces and Enumerations\n1. The **Concert** class represents a concert event, with properties such as ID, artist, venue, date and time, and a list of seats.\n2. The **Seat** class represents a seat in a concert, with properties like ID, seat number, seat type, price, and status. It provides methods to book and release a seat.\n3. The **SeatType** enum represents the different types of seats available, such as regular, premium, and VIP.\n4. The **SeatStatus** enum represents the status of a seat, which can be available, booked, or reserved.\n5. The **Booking** class represents a booking made by a user for a specific concert and seats. It contains properties such as ID, user, concert, seats, total price, and status. It provides methods to confirm and cancel a booking.\n6. The **BookingStatus** enum represents the status of a booking, which can be pending, confirmed, or cancelled.\n7. The **User** class represents a user of the concert ticket booking system, with properties like ID, name, and email.\n8. The **ConcertTicketBookingSystem** class is the central component of the system. It follows the Singleton pattern to ensure a single instance of the system. It manages concerts, bookings, and provides methods to add concerts, search concerts, book tickets, and cancel bookings.\n9. The **SeatNotAvailableException** is a custom exception used to handle cases where a seat is not available for booking."
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Seat.cpp",
    "content": "#include \"Seat.hpp\"\n\nSeat::Seat(int number) : seatNumber(number), booked(false) {}\n\nint Seat::getSeatNumber() const { return seatNumber; }\nbool Seat::isBooked() const { return booked; }\nvoid Seat::book() { booked = true; }\nvoid Seat::cancel() { booked = false; } "
  },
  {
    "path": "solutions/cpp/concertticketbookingsystem/Seat.hpp",
    "content": "#ifndef SEAT_HPP\n#define SEAT_HPP\n\nclass Seat {\nprivate:\n    int seatNumber;\n    bool booked;\n\npublic:\n    Seat(int number);\n    \n    int getSeatNumber() const;\n    bool isBooked() const;\n    void book();\n    void cancel();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/Course.cpp",
    "content": "#include \"Course.hpp\"\n#include <iostream>\n#include <algorithm>\n\nCourse::Course(std::string courseId, std::string name, int maxCapacity)\n    : courseId(courseId), name(name), maxCapacity(maxCapacity), available(true) {}\n\nstd::string Course::getCourseId() const { return courseId; }\nstd::string Course::getName() const { return name; }\nint Course::getMaxCapacity() const { return maxCapacity; }\nint Course::getCurrentEnrollment() const { return enrolledStudents.size(); }\nbool Course::isAvailable() const { return available; }\n\nbool Course::enrollStudent(Student* student) {\n    if (!available || getCurrentEnrollment() >= maxCapacity) return false;\n    if (hasStudent(student)) return false;\n    \n    enrolledStudents.push_back(student);\n    return true;\n}\n\nbool Course::dropStudent(Student* student) {\n    auto it = std::find(enrolledStudents.begin(), enrolledStudents.end(), student);\n    if (it == enrolledStudents.end()) return false;\n    \n    enrolledStudents.erase(it);\n    return true;\n}\n\nbool Course::hasStudent(Student* student) const {\n    return std::find(enrolledStudents.begin(), enrolledStudents.end(), student) \n           != enrolledStudents.end();\n}\n\nvoid Course::displayInfo() const {\n    std::cout << \"Course: \" << name << \" (ID: \" << courseId << \")\" << std::endl;\n    std::cout << \"Enrollment: \" << getCurrentEnrollment() << \"/\" << maxCapacity << std::endl;\n    std::cout << \"Status: \" << (available ? \"Available\" : \"Closed\") << std::endl;\n}\n\nvoid Course::setAvailable(bool status) {\n    available = status;\n} "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/Course.hpp",
    "content": "#ifndef COURSE_HPP\n#define COURSE_HPP\n\n#include <string>\n#include <vector>\n#include \"Student.hpp\"\n\nclass Course {\nprivate:\n    std::string courseId;\n    std::string name;\n    int maxCapacity;\n    std::vector<Student*> enrolledStudents;\n    bool available;\n\npublic:\n    Course(std::string courseId, std::string name, int maxCapacity);\n    \n    std::string getCourseId() const;\n    std::string getName() const;\n    int getMaxCapacity() const;\n    int getCurrentEnrollment() const;\n    bool isAvailable() const;\n    \n    bool enrollStudent(Student* student);\n    bool dropStudent(Student* student);\n    bool hasStudent(Student* student) const;\n    void displayInfo() const;\n    void setAvailable(bool status);\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/README.md",
    "content": "# Designing a University Course Registration System\n\n## Requirements\n1. The course registration system should allow students to register for courses and view their registered courses.\n2. Each course should have a course code, name, instructor, and maximum enrollment capacity.\n3. Students should be able to search for courses based on course code or name.\n4. The system should prevent students from registering for courses that have reached their maximum enrollment capacity.\n5. The system should handle concurrent registration requests from multiple students.\n6. The system should ensure data consistency and prevent race conditions.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Student** class represents a student in the course registration system, with properties such as ID, name, email, and a list of registered courses.\n2. The **Course** class represents a course offered in the system, with properties such as code, name, instructor, maximum capacity, and the number of enrolled students.\n3. The **Registration** class represents a registration record, associating a student with a course and capturing the registration timestamp.\n4. The **CourseRegistrationSystem** class is the main class that manages the course registration system. It follows the Singleton pattern to ensure only one instance of the system exists.\n5. The CourseRegistrationSystem class provides methods for adding courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student.\n6. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as courses and registrations.\n7. The registerCourse method is synchronized to ensure thread safety when multiple students are registering for courses simultaneously.\n8. The notifyObservers method is a placeholder for notifying observers (e.g., UI components) about updates to course enrollment.\n9. The **CourseRegistrationDemo** class demonstrates the usage of the course registration system by creating courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student."
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/RegistrationSystem.cpp",
    "content": "#include \"RegistrationSystem.hpp\"\n#include <iostream>\n\nRegistrationSystem::RegistrationSystem() {}\n\nRegistrationSystem::~RegistrationSystem() {\n    for (auto course : courses) delete course;\n    for (auto student : students) delete student;\n}\n\nvoid RegistrationSystem::addCourse(Course* course) {\n    courses.push_back(course);\n}\n\nvoid RegistrationSystem::addStudent(Student* student) {\n    students.push_back(student);\n}\n\nbool RegistrationSystem::enrollStudentInCourse(Student* student, Course* course) {\n    if (!student || !course) return false;\n    return student->enrollInCourse(course);\n}\n\nbool RegistrationSystem::dropStudentFromCourse(Student* student, Course* course) {\n    if (!student || !course) return false;\n    return student->dropCourse(course);\n}\n\nvoid RegistrationSystem::displayAllCourses() const {\n    std::cout << \"\\nAll Courses:\" << std::endl;\n    for (const auto& course : courses) {\n        course->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid RegistrationSystem::displayAllStudents() const {\n    std::cout << \"\\nAll Students:\" << std::endl;\n    for (const auto& student : students) {\n        student->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid RegistrationSystem::displayCourseEnrollments(Course* course) const {\n    if (!course) return;\n    \n    std::cout << \"\\nEnrollments for \" << course->getName() << \":\" << std::endl;\n    for (const auto& student : students) {\n        if (student->isEnrolledIn(course)) {\n            std::cout << \"- \" << student->getName() << \" (ID: \" << student->getStudentId() << \")\" << std::endl;\n        }\n    }\n}\n\nvoid RegistrationSystem::displayStudentEnrollments(Student* student) const {\n    if (!student) return;\n    student->displayInfo();\n}\n\nCourse* RegistrationSystem::findCourse(std::string courseId) const {\n    for (auto course : courses) {\n        if (course->getCourseId() == courseId) return course;\n    }\n    return nullptr;\n}\n\nStudent* RegistrationSystem::findStudent(std::string studentId) const {\n    for (auto student : students) {\n        if (student->getStudentId() == studentId) return student;\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/RegistrationSystem.hpp",
    "content": "#ifndef REGISTRATION_SYSTEM_HPP\n#define REGISTRATION_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Course.hpp\"\n#include \"Student.hpp\"\n\nclass RegistrationSystem {\nprivate:\n    std::vector<Course*> courses;\n    std::vector<Student*> students;\n\npublic:\n    RegistrationSystem();\n    ~RegistrationSystem();\n    \n    void addCourse(Course* course);\n    void addStudent(Student* student);\n    bool enrollStudentInCourse(Student* student, Course* course);\n    bool dropStudentFromCourse(Student* student, Course* course);\n    \n    void displayAllCourses() const;\n    void displayAllStudents() const;\n    void displayCourseEnrollments(Course* course) const;\n    void displayStudentEnrollments(Student* student) const;\n    \n    Course* findCourse(std::string courseId) const;\n    Student* findStudent(std::string studentId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/RegistrationSystemDemo.cpp",
    "content": "#include \"RegistrationSystem.hpp\"\n#include <iostream>\n\nint main() {\n    RegistrationSystem system;\n    \n    // Create courses\n    Course* course1 = new Course(\"CS101\", \"Introduction to Programming\", 3);\n    Course* course2 = new Course(\"CS102\", \"Data Structures\", 2);\n    Course* course3 = new Course(\"CS103\", \"Algorithms\", 2);\n    \n    system.addCourse(course1);\n    system.addCourse(course2);\n    system.addCourse(course3);\n    \n    // Create students\n    Student* student1 = new Student(\"S001\", \"John Doe\");\n    Student* student2 = new Student(\"S002\", \"Jane Smith\");\n    Student* student3 = new Student(\"S003\", \"Bob Johnson\");\n    \n    system.addStudent(student1);\n    system.addStudent(student2);\n    system.addStudent(student3);\n    \n    // Display initial state\n    system.displayAllCourses();\n    system.displayAllStudents();\n    \n    // Enroll students in courses\n    if (system.enrollStudentInCourse(student1, course1)) {\n        std::cout << \"Enrolled \" << student1->getName() << \" in \" << course1->getName() << std::endl;\n    }\n    \n    if (system.enrollStudentInCourse(student2, course1)) {\n        std::cout << \"Enrolled \" << student2->getName() << \" in \" << course1->getName() << std::endl;\n    }\n    \n    if (system.enrollStudentInCourse(student1, course2)) {\n        std::cout << \"Enrolled \" << student1->getName() << \" in \" << course2->getName() << std::endl;\n    }\n    \n    // Display enrollments\n    system.displayCourseEnrollments(course1);\n    system.displayStudentEnrollments(student1);\n    \n    // Drop a course\n    if (system.dropStudentFromCourse(student1, course1)) {\n        std::cout << \"\\nDropped \" << student1->getName() << \" from \" << course1->getName() << std::endl;\n    }\n    \n    // Display final state\n    system.displayCourseEnrollments(course1);\n    system.displayStudentEnrollments(student1);\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/Student.cpp",
    "content": "#include \"Student.hpp\"\n#include \"Course.hpp\"\n#include <iostream>\n#include <algorithm>\n\nStudent::Student(std::string studentId, std::string name)\n    : studentId(studentId), name(name) {}\n\nstd::string Student::getStudentId() const { return studentId; }\nstd::string Student::getName() const { return name; }\nconst std::vector<Course*>& Student::getEnrolledCourses() const { return enrolledCourses; }\n\nbool Student::enrollInCourse(Course* course) {\n    if (isEnrolledIn(course)) return false;\n    if (!course->enrollStudent(this)) return false;\n    \n    enrolledCourses.push_back(course);\n    return true;\n}\n\nbool Student::dropCourse(Course* course) {\n    auto it = std::find(enrolledCourses.begin(), enrolledCourses.end(), course);\n    if (it == enrolledCourses.end()) return false;\n    \n    if (!course->dropStudent(this)) return false;\n    enrolledCourses.erase(it);\n    return true;\n}\n\nbool Student::isEnrolledIn(Course* course) const {\n    return std::find(enrolledCourses.begin(), enrolledCourses.end(), course) \n           != enrolledCourses.end();\n}\n\nvoid Student::displayInfo() const {\n    std::cout << \"Student: \" << name << \" (ID: \" << studentId << \")\" << std::endl;\n    std::cout << \"Enrolled Courses:\" << std::endl;\n    for (const auto& course : enrolledCourses) {\n        std::cout << \"- \" << course->getName() << \" (ID: \" << course->getCourseId() << \")\" << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/courseregistrationsystem/Student.hpp",
    "content": "#ifndef STUDENT_HPP\n#define STUDENT_HPP\n\n#include <string>\n#include <vector>\n\nclass Course;  // Forward declaration\n\nclass Student {\nprivate:\n    std::string studentId;\n    std::string name;\n    std::vector<Course*> enrolledCourses;\n\npublic:\n    Student(std::string studentId, std::string name);\n    \n    std::string getStudentId() const;\n    std::string getName() const;\n    const std::vector<Course*>& getEnrolledCourses() const;\n    \n    bool enrollInCourse(Course* course);\n    bool dropCourse(Course* course);\n    bool isEnrolledIn(Course* course) const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/cricinfo/CricInfoDemo.cpp",
    "content": "#include \"CricInfoSystem.hpp\"\n#include <iostream>\n\nint main() {\n    CricInfoSystem system;\n    \n    // Create teams\n    Team* team1 = new Team(\"IND\", \"India\", \"India\");\n    Team* team2 = new Team(\"AUS\", \"Australia\", \"Australia\");\n    \n    // Create players\n    Player* player1 = new Player(\"VK18\", \"Virat Kohli\", \"India\", PlayerType::BATSMAN);\n    Player* player2 = new Player(\"RS45\", \"Rohit Sharma\", \"India\", PlayerType::BATSMAN);\n    Player* player3 = new Player(\"SPD23\", \"Steve Smith\", \"Australia\", PlayerType::BATSMAN);\n    Player* player4 = new Player(\"PCU31\", \"Pat Cummins\", \"Australia\", PlayerType::BOWLER);\n    \n    // Add players to teams\n    team1->addPlayer(player1);\n    team1->addPlayer(player2);\n    team2->addPlayer(player3);\n    team2->addPlayer(player4);\n    \n    // Add teams to system\n    system.addTeam(team1);\n    system.addTeam(team2);\n    \n    // Create a match\n    Match* match1 = new Match(\"M001\", team1, team2, \"MCG\", \"2024-01-01\", \"Test\");\n    \n    // Add player performances\n    PlayerStats kohliStats;\n    kohliStats.runsScored = 100;\n    kohliStats.ballsFaced = 150;\n    match1->addPlayerPerformance(\"VK18\", kohliStats);\n    \n    PlayerStats cumminsStats;\n    cumminsStats.wicketsTaken = 3;\n    cumminsStats.ballsBowled = 120;\n    match1->addPlayerPerformance(\"PCU31\", cumminsStats);\n    \n    // Set match winner\n    match1->setWinner(team1);\n    team1->incrementWins();\n    team2->incrementLosses();\n    \n    // Update player stats\n    match1->updateTeamStats();\n    \n    // Add match to system\n    system.addMatch(match1);\n    \n    // Display information\n    system.displayAllTeams();\n    system.displayAllMatches();\n    system.displayPlayerStats(\"VK18\");\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/cricinfo/CricInfoSystem.cpp",
    "content": "#include \"CricInfoSystem.hpp\"\n#include <iostream>\n\nCricInfoSystem::CricInfoSystem() {}\n\nCricInfoSystem::~CricInfoSystem() {\n    for (auto team : teams) delete team;\n    for (auto match : matches) delete match;\n}\n\nvoid CricInfoSystem::addTeam(Team* team) {\n    teams.push_back(team);\n}\n\nvoid CricInfoSystem::addMatch(Match* match) {\n    matches.push_back(match);\n}\n\nTeam* CricInfoSystem::findTeam(const std::string& teamId) const {\n    for (auto team : teams) {\n        if (team->getTeamId() == teamId) return team;\n    }\n    return nullptr;\n}\n\nMatch* CricInfoSystem::findMatch(const std::string& matchId) const {\n    for (auto match : matches) {\n        if (match->getMatchId() == matchId) return match;\n    }\n    return nullptr;\n}\n\nvoid CricInfoSystem::displayAllTeams() const {\n    std::cout << \"\\nAll Teams:\" << std::endl;\n    for (const auto& team : teams) {\n        team->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid CricInfoSystem::displayAllMatches() const {\n    std::cout << \"\\nAll Matches:\" << std::endl;\n    for (const auto& match : matches) {\n        match->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid CricInfoSystem::displayTeamStats(const std::string& teamId) const {\n    Team* team = findTeam(teamId);\n    if (team) {\n        team->displayInfo();\n        team->displayPlayers();\n    }\n}\n\nvoid CricInfoSystem::displayPlayerStats(const std::string& playerId) const {\n    for (const auto& team : teams) {\n        Player* player = team->findPlayer(playerId);\n        if (player) {\n            player->displayInfo();\n            return;\n        }\n    }\n    std::cout << \"Player not found!\" << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/cricinfo/CricInfoSystem.hpp",
    "content": "#ifndef CRIC_INFO_SYSTEM_HPP\n#define CRIC_INFO_SYSTEM_HPP\n\n#include <vector>\n#include \"Team.hpp\"\n#include \"Match.hpp\"\n\nclass CricInfoSystem {\nprivate:\n    std::vector<Team*> teams;\n    std::vector<Match*> matches;\n\npublic:\n    CricInfoSystem();\n    ~CricInfoSystem();\n    \n    void addTeam(Team* team);\n    void addMatch(Match* match);\n    \n    Team* findTeam(const std::string& teamId) const;\n    Match* findMatch(const std::string& matchId) const;\n    \n    void displayAllTeams() const;\n    void displayAllMatches() const;\n    void displayTeamStats(const std::string& teamId) const;\n    void displayPlayerStats(const std::string& playerId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/cricinfo/Match.cpp",
    "content": "#include \"Match.hpp\"\n#include <iostream>\n\nMatch::Match(std::string matchId, Team* team1, Team* team2, \n             std::string venue, std::string date, std::string matchType)\n    : matchId(matchId), team1(team1), team2(team2), venue(venue), \n      date(date), matchType(matchType), winner(nullptr) {}\n\nstd::string Match::getMatchId() const { return matchId; }\nTeam* Match::getTeam1() const { return team1; }\nTeam* Match::getTeam2() const { return team2; }\nstd::string Match::getVenue() const { return venue; }\nstd::string Match::getDate() const { return date; }\nstd::string Match::getMatchType() const { return matchType; }\nTeam* Match::getWinner() const { return winner; }\n\nvoid Match::setWinner(Team* team) {\n    winner = team;\n}\n\nvoid Match::addPlayerPerformance(const std::string& playerId, const PlayerStats& stats) {\n    playerPerformances[playerId] = stats;\n}\n\nvoid Match::updateTeamStats() {\n    for (const auto& performance : playerPerformances) {\n        Player* player = team1->findPlayer(performance.first);\n        if (!player) {\n            player = team2->findPlayer(performance.first);\n        }\n        if (player) {\n            player->updateStats(performance.second);\n        }\n    }\n}\n\nvoid Match::displayInfo() const {\n    std::cout << \"\\nMatch Details:\" << std::endl;\n    std::cout << \"ID: \" << matchId << std::endl;\n    std::cout << \"Type: \" << matchType << std::endl;\n    std::cout << \"Venue: \" << venue << std::endl;\n    std::cout << \"Date: \" << date << std::endl;\n    std::cout << \"Teams: \" << team1->getName() << \" vs \" << team2->getName() << std::endl;\n    if (winner) {\n        std::cout << \"Winner: \" << winner->getName() << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/cricinfo/Match.hpp",
    "content": "#ifndef MATCH_HPP\n#define MATCH_HPP\n\n#include <string>\n#include <vector>\n#include \"Team.hpp\"\n#include \"PlayerStats.hpp\"\n#include <map>\n\nclass Match {\nprivate:\n    std::string matchId;\n    Team* team1;\n    Team* team2;\n    std::string venue;\n    std::string date;\n    std::string matchType;\n    Team* winner;\n    std::map<std::string, PlayerStats> playerPerformances;\n\npublic:\n    Match(std::string matchId, Team* team1, Team* team2, \n          std::string venue, std::string date, std::string matchType);\n    \n    std::string getMatchId() const;\n    Team* getTeam1() const;\n    Team* getTeam2() const;\n    std::string getVenue() const;\n    std::string getDate() const;\n    std::string getMatchType() const;\n    Team* getWinner() const;\n    \n    void setWinner(Team* team);\n    void addPlayerPerformance(const std::string& playerId, const PlayerStats& stats);\n    void updateTeamStats();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/cricinfo/Player.cpp",
    "content": "#include \"Player.hpp\"\n#include <iostream>\n#include <iomanip>\n\nPlayer::Player(std::string playerId, std::string name, std::string country, PlayerType type)\n    : playerId(playerId), name(name), country(country), type(type) {}\n\nstd::string Player::getPlayerId() const { return playerId; }\nstd::string Player::getName() const { return name; }\nstd::string Player::getCountry() const { return country; }\nPlayerType Player::getType() const { return type; }\nPlayerStats& Player::getStats() { return stats; }\n\nvoid Player::updateStats(const PlayerStats& matchStats) {\n    stats.runsScored += matchStats.runsScored;\n    stats.ballsFaced += matchStats.ballsFaced;\n    stats.wicketsTaken += matchStats.wicketsTaken;\n    stats.ballsBowled += matchStats.ballsBowled;\n    stats.matchesPlayed++;\n}\n\nvoid Player::displayInfo() const {\n    std::cout << \"Player: \" << name << \" (ID: \" << playerId << \")\" << std::endl;\n    std::cout << \"Country: \" << country << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case PlayerType::BATSMAN: std::cout << \"Batsman\"; break;\n        case PlayerType::BOWLER: std::cout << \"Bowler\"; break;\n        case PlayerType::ALL_ROUNDER: std::cout << \"All-Rounder\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Stats:\" << std::endl;\n    std::cout << \"Matches: \" << stats.matchesPlayed << std::endl;\n    std::cout << \"Runs: \" << stats.runsScored << std::endl;\n    std::cout << \"Balls Faced: \" << stats.ballsFaced << std::endl;\n    if (stats.ballsFaced > 0) {\n        double strikeRate = (static_cast<double>(stats.runsScored) / stats.ballsFaced) * 100;\n        std::cout << \"Strike Rate: \" << std::fixed << std::setprecision(2) << strikeRate << std::endl;\n    }\n    std::cout << \"Wickets: \" << stats.wicketsTaken << std::endl;\n    std::cout << \"Balls Bowled: \" << stats.ballsBowled << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/cricinfo/Player.hpp",
    "content": "#ifndef PLAYER_HPP\n#define PLAYER_HPP\n\n#include <string>\n#include \"PlayerStats.hpp\"\n\nenum class PlayerType {\n    BATSMAN,\n    BOWLER,\n    ALL_ROUNDER\n};\n\nclass Player {\nprivate:\n    std::string playerId;\n    std::string name;\n    std::string country;\n    PlayerType type;\n    PlayerStats stats;\n\npublic:\n    Player(std::string playerId, std::string name, std::string country, PlayerType type);\n    \n    std::string getPlayerId() const;\n    std::string getName() const;\n    std::string getCountry() const;\n    PlayerType getType() const;\n    PlayerStats& getStats();\n    \n    void updateStats(const PlayerStats& matchStats);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/cricinfo/PlayerStats.hpp",
    "content": "#ifndef PLAYER_STATS_HPP\n#define PLAYER_STATS_HPP\n\nstruct PlayerStats {\n    int matchesPlayed;\n    int runsScored;\n    int ballsFaced;\n    int wicketsTaken;\n    int ballsBowled;\n    \n    PlayerStats()\n        : matchesPlayed(0), runsScored(0), ballsFaced(0), \n          wicketsTaken(0), ballsBowled(0) {}\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/cricinfo/README.md",
    "content": "# Designing a Cricket Information System like CricInfo\n\n## Requirements\n1. The Cricinfo system should provide information about cricket matches, teams, players, and live scores.\n2. Users should be able to view the schedule of upcoming matches and the results of completed matches.\n3. The system should allow users to search for specific matches, teams, or players.\n4. Users should be able to view detailed information about a particular match, including the scorecard, commentary, and statistics.\n5. The system should support real-time updates of live scores and match information.\n6. The system should handle concurrent access to match data and ensure data consistency.\n7. The system should be scalable and able to handle a large volume of user requests.\n8. The system should be extensible to accommodate new features and enhancements in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **Match** class represents a cricket match, with properties such as ID, title, venue, start time, teams, status, and scorecard.\n2. The **Team** class represents a cricket team, with properties like ID, name, and a list of players.\n3. The **Player** class represents a cricket player, with properties such as ID, name, and role.\n4. The **Scorecard** class represents the scorecard of a match, containing team scores and a list of innings.\n5. The **Innings** class represents an innings in a match, with properties like ID, batting team, bowling team, and a list of overs.\n6. The **Over** class represents an over in an innings, containing a list of balls.\n7. The **Ball** class represents a ball bowled in an over, with properties such as ball number, bowler, batsman, and result.\n8. The **MatchStatus** enum represents the different statuses of a match, such as scheduled, in progress, completed, or abandoned.\n9. The **MatchService** class manages the matches in the system, providing methods to add, retrieve, and update match information. It follows the Singleton pattern to ensure a single instance of the service.\n10. The **ScorecardService** class manages the scorecards of matches, allowing the creation, retrieval, and update of scorecards and their associated data, such as innings and scores. It also follows the Singleton pattern.\n11. The **CricinfoSystem** class serves as the main entry point of the system, integrating the match and scorecard services and providing high-level methods for interacting with the system."
  },
  {
    "path": "solutions/cpp/cricinfo/Team.cpp",
    "content": "#include \"Team.hpp\"\n#include <iostream>\n#include <algorithm>\n\nTeam::Team(std::string teamId, std::string name, std::string country)\n    : teamId(teamId), name(name), country(country), matchesWon(0), matchesLost(0) {}\n\nstd::string Team::getTeamId() const { return teamId; }\nstd::string Team::getName() const { return name; }\nstd::string Team::getCountry() const { return country; }\nint Team::getMatchesWon() const { return matchesWon; }\nint Team::getMatchesLost() const { return matchesLost; }\n\nvoid Team::addPlayer(Player* player) {\n    if (player && player->getCountry() == country) {\n        players.push_back(player);\n    }\n}\n\nvoid Team::removePlayer(Player* player) {\n    auto it = std::find(players.begin(), players.end(), player);\n    if (it != players.end()) {\n        players.erase(it);\n    }\n}\n\nPlayer* Team::findPlayer(const std::string& playerId) const {\n    for (auto player : players) {\n        if (player->getPlayerId() == playerId) return player;\n    }\n    return nullptr;\n}\n\nvoid Team::incrementWins() { matchesWon++; }\nvoid Team::incrementLosses() { matchesLost++; }\n\nvoid Team::displayInfo() const {\n    std::cout << \"\\nTeam: \" << name << \" (ID: \" << teamId << \")\" << std::endl;\n    std::cout << \"Country: \" << country << std::endl;\n    std::cout << \"Matches Won: \" << matchesWon << std::endl;\n    std::cout << \"Matches Lost: \" << matchesLost << std::endl;\n}\n\nvoid Team::displayPlayers() const {\n    std::cout << \"\\nPlayers in \" << name << \":\" << std::endl;\n    for (const auto& player : players) {\n        player->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/cricinfo/Team.hpp",
    "content": "#ifndef TEAM_HPP\n#define TEAM_HPP\n\n#include <string>\n#include <vector>\n#include \"Player.hpp\"\n\nclass Team {\nprivate:\n    std::string teamId;\n    std::string name;\n    std::string country;\n    std::vector<Player*> players;\n    int matchesWon;\n    int matchesLost;\n\npublic:\n    Team(std::string teamId, std::string name, std::string country);\n    \n    std::string getTeamId() const;\n    std::string getName() const;\n    std::string getCountry() const;\n    int getMatchesWon() const;\n    int getMatchesLost() const;\n    \n    void addPlayer(Player* player);\n    void removePlayer(Player* player);\n    Player* findPlayer(const std::string& playerId) const;\n    void incrementWins();\n    void incrementLosses();\n    void displayInfo() const;\n    void displayPlayers() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/README.md",
    "content": "# Designing a Digital Wallet System\n\n## Requirements\n1. The digital wallet should allow users to create an account and manage their personal information.\n2. Users should be able to add and remove payment methods, such as credit cards or bank accounts.\n3. The digital wallet should support fund transfers between users and to external accounts.\n4. The system should handle transaction history and provide a statement of transactions.\n5. The digital wallet should support multiple currencies and perform currency conversions.\n6. The system should ensure the security of user information and transactions.\n7. The digital wallet should handle concurrent transactions and ensure data consistency.\n8. The system should be scalable to handle a large number of users and transactions.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the digital wallet, with properties such as ID, name, email, password, and a list of accounts.\n2. The **Account** class represents a user's account within the digital wallet, with properties like ID, user, account number, currency, balance, and a list of transactions. It provides methods to deposit and withdraw funds.\n3. The **Transaction** class represents a financial transaction between two accounts, containing properties such as ID, source account, destination account, amount, currency, and timestamp.\n4. The **PaymentMethod** class is an abstract base class for different payment methods, such as credit cards and bank accounts. It defines the common properties and methods for processing payments.\n5. The **CreditCard** and **BankAccount** classes are concrete implementations of the PaymentMethod class, representing specific payment methods.\n6. The **Currency** enum represents different currencies supported by the digital wallet.\n7. The **CurrencyConverter** class provides a static method to convert amounts between different currencies based on predefined exchange rates.\n8. The **DigitalWallet** class is the central component of the digital wallet system. It follows the Singleton pattern to ensure only one instance of the digital wallet exists. It provides methods to create users, accounts, add payment methods, transfer funds, and retrieve transaction history. It handles concurrent access to shared resources using synchronization.\n9. The **DigitalWalletDemo** class demonstrates the usage of the digital wallet system by creating users, accounts, adding payment methods, depositing funds, transferring funds, and retrieving transaction history."
  },
  {
    "path": "solutions/cpp/digitalwalletservice/Transaction.cpp",
    "content": "#include \"Transaction.hpp\"\n#include <iostream>\n#include <iomanip>\n\nTransaction::Transaction(std::string transactionId, std::string walletId, \n                       TransactionType type, double amount, std::string timestamp,\n                       std::string description)\n    : transactionId(transactionId), walletId(walletId), type(type), \n      amount(amount), timestamp(timestamp), description(description), status(false) {}\n\nstd::string Transaction::getTransactionId() const { return transactionId; }\nstd::string Transaction::getWalletId() const { return walletId; }\nTransactionType Transaction::getType() const { return type; }\ndouble Transaction::getAmount() const { return amount; }\nstd::string Transaction::getTimestamp() const { return timestamp; }\nstd::string Transaction::getDescription() const { return description; }\nbool Transaction::getStatus() const { return status; }\n\nvoid Transaction::setStatus(bool status) {\n    this->status = status;\n}\n\nvoid Transaction::displayInfo() const {\n    std::cout << \"Transaction ID: \" << transactionId << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case TransactionType::ADD_MONEY: std::cout << \"Add Money\"; break;\n        case TransactionType::WITHDRAW: std::cout << \"Withdraw\"; break;\n        case TransactionType::TRANSFER: std::cout << \"Transfer\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Amount: $\" << std::fixed << std::setprecision(2) << amount << std::endl;\n    std::cout << \"Time: \" << timestamp << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Status: \" << (status ? \"Success\" : \"Pending\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/Transaction.hpp",
    "content": "#ifndef TRANSACTION_HPP\n#define TRANSACTION_HPP\n\n#include <string>\n\nenum class TransactionType {\n    ADD_MONEY,\n    WITHDRAW,\n    TRANSFER\n};\n\nclass Transaction {\nprivate:\n    std::string transactionId;\n    std::string walletId;\n    TransactionType type;\n    double amount;\n    std::string timestamp;\n    std::string description;\n    bool status;\n\npublic:\n    Transaction(std::string transactionId, std::string walletId, \n               TransactionType type, double amount, std::string timestamp,\n               std::string description);\n    \n    std::string getTransactionId() const;\n    std::string getWalletId() const;\n    TransactionType getType() const;\n    double getAmount() const;\n    std::string getTimestamp() const;\n    std::string getDescription() const;\n    bool getStatus() const;\n    \n    void setStatus(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n\nUser::User(std::string userId, std::string name, std::string email, std::string phoneNumber)\n    : userId(userId), name(name), email(email), phoneNumber(phoneNumber) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getName() const { return name; }\nstd::string User::getEmail() const { return email; }\nstd::string User::getPhoneNumber() const { return phoneNumber; }\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << name << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Phone: \" << phoneNumber << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string name;\n    std::string email;\n    std::string phoneNumber;\n\npublic:\n    User(std::string userId, std::string name, std::string email, std::string phoneNumber);\n    \n    std::string getUserId() const;\n    std::string getName() const;\n    std::string getEmail() const;\n    std::string getPhoneNumber() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/Wallet.cpp",
    "content": "#include \"Wallet.hpp\"\n#include <iostream>\n#include <iomanip>\n\nWallet::Wallet(std::string walletId, std::string userId)\n    : walletId(walletId), userId(userId), balance(0.0) {}\n\nWallet::~Wallet() {\n    for (auto transaction : transactions) {\n        delete transaction;\n    }\n}\n\nstd::string Wallet::getWalletId() const { return walletId; }\nstd::string Wallet::getUserId() const { return userId; }\ndouble Wallet::getBalance() const { return balance; }\n\nbool Wallet::addMoney(double amount, std::string source) {\n    if (amount <= 0) return false;\n    \n    balance += amount;\n    return true;\n}\n\nbool Wallet::withdrawMoney(double amount, std::string destination) {\n    if (amount <= 0 || amount > balance) return false;\n    \n    balance -= amount;\n    return true;\n}\n\nvoid Wallet::addTransaction(Transaction* transaction) {\n    transactions.push_back(transaction);\n}\n\nvoid Wallet::displayInfo() const {\n    std::cout << \"Wallet ID: \" << walletId << std::endl;\n    std::cout << \"User ID: \" << userId << std::endl;\n    std::cout << \"Balance: $\" << std::fixed << std::setprecision(2) << balance << std::endl;\n}\n\nvoid Wallet::displayTransactions() const {\n    std::cout << \"\\nTransaction History:\" << std::endl;\n    for (const auto& transaction : transactions) {\n        transaction->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/Wallet.hpp",
    "content": "#ifndef WALLET_HPP\n#define WALLET_HPP\n\n#include <string>\n#include <vector>\n#include \"Transaction.hpp\"\n\nclass Wallet {\nprivate:\n    std::string walletId;\n    std::string userId;\n    double balance;\n    std::vector<Transaction*> transactions;\n\npublic:\n    Wallet(std::string walletId, std::string userId);\n    ~Wallet();\n    \n    std::string getWalletId() const;\n    std::string getUserId() const;\n    double getBalance() const;\n    \n    bool addMoney(double amount, std::string source);\n    bool withdrawMoney(double amount, std::string destination);\n    void addTransaction(Transaction* transaction);\n    void displayInfo() const;\n    void displayTransactions() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/WalletDemo.cpp",
    "content": "#include \"WalletSystem.hpp\"\n#include <iostream>\n\nint main() {\n    WalletSystem system;\n    \n    // Create users\n    User* user1 = new User(\"U001\", \"John Doe\", \"john@example.com\", \"+1-555-0123\");\n    User* user2 = new User(\"U002\", \"Jane Smith\", \"jane@example.com\", \"+1-555-0124\");\n    \n    system.addUser(user1);\n    system.addUser(user2);\n    \n    // Create wallets\n    Wallet* wallet1 = system.createWallet(\"U001\");\n    Wallet* wallet2 = system.createWallet(\"U002\");\n    \n    // Add money to wallets\n    if (system.addMoney(\"WU001\", 1000.0, \"Bank Transfer\")) {\n        std::cout << \"Added $1000 to John's wallet\" << std::endl;\n    }\n    \n    if (system.addMoney(\"WU002\", 500.0, \"Credit Card\")) {\n        std::cout << \"Added $500 to Jane's wallet\" << std::endl;\n    }\n    \n    // Transfer money\n    if (system.transferMoney(\"WU001\", \"WU002\", 300.0)) {\n        std::cout << \"Transferred $300 from John to Jane\" << std::endl;\n    }\n    \n    // Withdraw money\n    if (system.withdrawMoney(\"WU002\", 200.0, \"Bank Account\")) {\n        std::cout << \"Jane withdrew $200\" << std::endl;\n    }\n    \n    // Display information\n    system.displayAllUsers();\n    system.displayAllWallets();\n    \n    // Display detailed user information\n    std::cout << \"\\nDetailed User Information:\" << std::endl;\n    system.displayUserInfo(\"U001\");\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/WalletSystem.cpp",
    "content": "#include \"WalletSystem.hpp\"\n#include <iostream>\n#include <ctime>\n#include <sstream>\n#include <iomanip>\n\nWalletSystem::WalletSystem() : transactionIdCounter(1) {}\n\nWalletSystem::~WalletSystem() {\n    for (auto user : users) delete user;\n    for (auto wallet : wallets) delete wallet;\n}\n\nvoid WalletSystem::addUser(User* user) {\n    users.push_back(user);\n}\n\nWallet* WalletSystem::createWallet(std::string userId) {\n    if (!findUser(userId)) return nullptr;\n    \n    std::string walletId = \"W\" + userId;\n    Wallet* wallet = new Wallet(walletId, userId);\n    wallets.push_back(wallet);\n    return wallet;\n}\n\nbool WalletSystem::addMoney(std::string walletId, double amount, std::string source) {\n    Wallet* wallet = findWallet(walletId);\n    if (!wallet) return false;\n    \n    if (wallet->addMoney(amount, source)) {\n        Transaction* transaction = new Transaction(\n            generateTransactionId(),\n            walletId,\n            TransactionType::ADD_MONEY,\n            amount,\n            getCurrentTimestamp(),\n            \"Added money from \" + source\n        );\n        transaction->setStatus(true);\n        wallet->addTransaction(transaction);\n        return true;\n    }\n    return false;\n}\n\nbool WalletSystem::withdrawMoney(std::string walletId, double amount, std::string destination) {\n    Wallet* wallet = findWallet(walletId);\n    if (!wallet) return false;\n    \n    if (wallet->withdrawMoney(amount, destination)) {\n        Transaction* transaction = new Transaction(\n            generateTransactionId(),\n            walletId,\n            TransactionType::WITHDRAW,\n            amount,\n            getCurrentTimestamp(),\n            \"Withdrawn to \" + destination\n        );\n        transaction->setStatus(true);\n        wallet->addTransaction(transaction);\n        return true;\n    }\n    return false;\n}\n\nbool WalletSystem::transferMoney(std::string fromWalletId, std::string toWalletId, double amount) {\n    Wallet* fromWallet = findWallet(fromWalletId);\n    Wallet* toWallet = findWallet(toWalletId);\n    if (!fromWallet || !toWallet) return false;\n    \n    if (fromWallet->withdrawMoney(amount, \"Transfer to \" + toWalletId) &&\n        toWallet->addMoney(amount, \"Transfer from \" + fromWalletId)) {\n        \n        Transaction* transaction = new Transaction(\n            generateTransactionId(),\n            fromWalletId,\n            TransactionType::TRANSFER,\n            amount,\n            getCurrentTimestamp(),\n            \"Transfer to wallet \" + toWalletId\n        );\n        transaction->setStatus(true);\n        fromWallet->addTransaction(transaction);\n        \n        transaction = new Transaction(\n            generateTransactionId(),\n            toWalletId,\n            TransactionType::TRANSFER,\n            amount,\n            getCurrentTimestamp(),\n            \"Transfer from wallet \" + fromWalletId\n        );\n        transaction->setStatus(true);\n        toWallet->addTransaction(transaction);\n        \n        return true;\n    }\n    return false;\n}\n\nvoid WalletSystem::displayUserInfo(std::string userId) const {\n    User* user = findUser(userId);\n    if (user) {\n        user->displayInfo();\n        for (const auto& wallet : wallets) {\n            if (wallet->getUserId() == userId) {\n                wallet->displayInfo();\n                wallet->displayTransactions();\n            }\n        }\n    }\n}\n\nvoid WalletSystem::displayWalletInfo(std::string walletId) const {\n    Wallet* wallet = findWallet(walletId);\n    if (wallet) {\n        wallet->displayInfo();\n        wallet->displayTransactions();\n    }\n}\n\nvoid WalletSystem::displayAllUsers() const {\n    std::cout << \"\\nAll Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid WalletSystem::displayAllWallets() const {\n    std::cout << \"\\nAll Wallets:\" << std::endl;\n    for (const auto& wallet : wallets) {\n        wallet->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nUser* WalletSystem::findUser(const std::string& userId) const {\n    for (auto user : users) {\n        if (user->getUserId() == userId) return user;\n    }\n    return nullptr;\n}\n\nWallet* WalletSystem::findWallet(const std::string& walletId) const {\n    for (auto wallet : wallets) {\n        if (wallet->getWalletId() == walletId) return wallet;\n    }\n    return nullptr;\n}\n\nstd::string WalletSystem::generateTransactionId() {\n    return \"T\" + std::to_string(transactionIdCounter++);\n}\n\nstd::string WalletSystem::getCurrentTimestamp() const {\n    auto now = std::time(nullptr);\n    auto tm = *std::localtime(&now);\n    std::ostringstream oss;\n    oss << std::put_time(&tm, \"%Y-%m-%d %H:%M:%S\");\n    return oss.str();\n} "
  },
  {
    "path": "solutions/cpp/digitalwalletservice/WalletSystem.hpp",
    "content": "#ifndef WALLET_SYSTEM_HPP\n#define WALLET_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Wallet.hpp\"\n#include \"Transaction.hpp\"\n\nclass WalletSystem {\nprivate:\n    std::vector<User*> users;\n    std::vector<Wallet*> wallets;\n    int transactionIdCounter;\n\npublic:\n    WalletSystem();\n    ~WalletSystem();\n    \n    void addUser(User* user);\n    Wallet* createWallet(std::string userId);\n    \n    bool addMoney(std::string walletId, double amount, std::string source);\n    bool withdrawMoney(std::string walletId, double amount, std::string destination);\n    bool transferMoney(std::string fromWalletId, std::string toWalletId, double amount);\n    \n    void displayUserInfo(std::string userId) const;\n    void displayWalletInfo(std::string walletId) const;\n    void displayAllUsers() const;\n    void displayAllWallets() const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Wallet* findWallet(const std::string& walletId) const;\n    std::string generateTransactionId();\n    std::string getCurrentTimestamp() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/elevatorsystem/Elevator.cpp",
    "content": "#include \"Elevator.hpp\"\n#include <iostream>\n\nElevator::Elevator(int id, int maxFloor, int minFloor)\n    : id(id), currentFloor(minFloor), direction(Direction::IDLE),\n      status(Status::STOPPED), maxFloor(maxFloor), minFloor(minFloor) {\n    floorsToVisit.resize(maxFloor + 1, false);\n}\n\nint Elevator::getId() const { return id; }\nint Elevator::getCurrentFloor() const { return currentFloor; }\nDirection Elevator::getDirection() const { return direction; }\nStatus Elevator::getStatus() const { return status; }\n\nvoid Elevator::setDirection(Direction direction) {\n    this->direction = direction;\n}\n\nvoid Elevator::setStatus(Status status) {\n    this->status = status;\n}\n\nvoid Elevator::addRequest(const Request& request) {\n    requests.push(request);\n    floorsToVisit[request.getDestinationFloor()] = true;\n    \n    if (direction == Direction::IDLE) {\n        if (request.getDestinationFloor() > currentFloor) {\n            direction = Direction::UP;\n        } else if (request.getDestinationFloor() < currentFloor) {\n            direction = Direction::DOWN;\n        }\n    }\n}\n\nvoid Elevator::moveToNextFloor() {\n    if (status != Status::MOVING) return;\n    \n    if (direction == Direction::UP && currentFloor < maxFloor) {\n        currentFloor++;\n    } else if (direction == Direction::DOWN && currentFloor > minFloor) {\n        currentFloor--;\n    }\n    \n    updateDirection();\n}\n\nbool Elevator::hasStopRequest() const {\n    return floorsToVisit[currentFloor];\n}\n\nvoid Elevator::processFloor() {\n    if (floorsToVisit[currentFloor]) {\n        floorsToVisit[currentFloor] = false;\n        status = Status::STOPPED;\n        std::cout << \"Elevator \" << id << \" stopped at floor \" << currentFloor << std::endl;\n        \n        // Remove processed requests\n        while (!requests.empty() && requests.front().getDestinationFloor() == currentFloor) {\n            requests.pop();\n        }\n    }\n}\n\nvoid Elevator::updateDirection() {\n    if (direction == Direction::UP) {\n        bool hasHigherFloorRequest = false;\n        for (int i = currentFloor + 1; i <= maxFloor; i++) {\n            if (floorsToVisit[i]) {\n                hasHigherFloorRequest = true;\n                break;\n            }\n        }\n        if (!hasHigherFloorRequest) {\n            direction = Direction::DOWN;\n        }\n    } else if (direction == Direction::DOWN) {\n        bool hasLowerFloorRequest = false;\n        for (int i = currentFloor - 1; i >= minFloor; i--) {\n            if (floorsToVisit[i]) {\n                hasLowerFloorRequest = true;\n                break;\n            }\n        }\n        if (!hasLowerFloorRequest) {\n            direction = Direction::UP;\n        }\n    }\n    \n    if (!requests.empty()) {\n        status = Status::MOVING;\n    } else {\n        direction = Direction::IDLE;\n        status = Status::STOPPED;\n    }\n}\n\nvoid Elevator::displayInfo() const {\n    std::cout << \"Elevator \" << id << \" - Floor: \" << currentFloor;\n    std::cout << \" - Direction: \";\n    switch (direction) {\n        case Direction::UP: std::cout << \"UP\"; break;\n        case Direction::DOWN: std::cout << \"DOWN\"; break;\n        case Direction::IDLE: std::cout << \"IDLE\"; break;\n    }\n    std::cout << \" - Status: \";\n    switch (status) {\n        case Status::MOVING: std::cout << \"MOVING\"; break;\n        case Status::STOPPED: std::cout << \"STOPPED\"; break;\n        case Status::MAINTENANCE: std::cout << \"MAINTENANCE\"; break;\n    }\n    std::cout << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/elevatorsystem/Elevator.hpp",
    "content": "#ifndef ELEVATOR_HPP\n#define ELEVATOR_HPP\n\n#include <vector>\n#include <queue>\n#include <string>\n#include \"Request.hpp\"\n\nenum class Direction {\n    UP,\n    DOWN,\n    IDLE\n};\n\nenum class Status {\n    MOVING,\n    STOPPED,\n    MAINTENANCE\n};\n\nclass Elevator {\nprivate:\n    int id;\n    int currentFloor;\n    Direction direction;\n    Status status;\n    int maxFloor;\n    int minFloor;\n    std::vector<bool> floorsToVisit;\n    std::queue<Request> requests;\n\npublic:\n    Elevator(int id, int maxFloor, int minFloor = 0);\n    \n    int getId() const;\n    int getCurrentFloor() const;\n    Direction getDirection() const;\n    Status getStatus() const;\n    \n    void setDirection(Direction direction);\n    void setStatus(Status status);\n    \n    void addRequest(const Request& request);\n    void moveToNextFloor();\n    bool hasStopRequest() const;\n    void processFloor();\n    void displayInfo() const;\n    \nprivate:\n    void updateDirection();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/elevatorsystem/ElevatorDemo.cpp",
    "content": "#include \"ElevatorSystem.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    ElevatorSystem system(2, 10); // 2 elevators, 10 floors\n    \n    // Add some requests\n    system.addRequest(0, Request(0, 5));  // Elevator 0: Ground floor to 5th floor\n    system.addRequest(1, Request(2, 7));  // Elevator 1: 2nd floor to 7th floor\n    system.addRequest(0, Request(5, 3));  // Elevator 0: 5th floor to 3rd floor\n    \n    // Simulate elevator movement\n    for (int i = 0; i < 15; i++) {\n        system.displayStatus();\n        system.step();\n        \n        // Wait for a second before next step\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/elevatorsystem/ElevatorSystem.cpp",
    "content": "#include \"ElevatorSystem.hpp\"\n#include <iostream>\n\nElevatorSystem::ElevatorSystem(int numElevators, int maxFloor, int minFloor)\n    : maxFloor(maxFloor), minFloor(minFloor) {\n    for (int i = 0; i < numElevators; i++) {\n        elevators.push_back(new Elevator(i, maxFloor, minFloor));\n    }\n}\n\nElevatorSystem::~ElevatorSystem() {\n    for (auto elevator : elevators) {\n        delete elevator;\n    }\n}\n\nvoid ElevatorSystem::addRequest(int elevatorId, const Request& request) {\n    Elevator* elevator = findElevator(elevatorId);\n    if (elevator) {\n        elevator->addRequest(request);\n        std::cout << \"Added request to elevator \" << elevatorId \n                  << \" from floor \" << request.getSourceFloor() \n                  << \" to floor \" << request.getDestinationFloor() << std::endl;\n    }\n}\n\nvoid ElevatorSystem::step() {\n    for (auto elevator : elevators) {\n        if (elevator->getStatus() == Status::MOVING) {\n            elevator->moveToNextFloor();\n        }\n        if (elevator->hasStopRequest()) {\n            elevator->processFloor();\n        }\n    }\n}\n\nvoid ElevatorSystem::displayStatus() const {\n    std::cout << \"\\nElevator System Status:\" << std::endl;\n    for (const auto& elevator : elevators) {\n        elevator->displayInfo();\n    }\n    std::cout << std::endl;\n}\n\nElevator* ElevatorSystem::findElevator(int elevatorId) const {\n    if (elevatorId >= 0 && elevatorId < elevators.size()) {\n        return elevators[elevatorId];\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/elevatorsystem/ElevatorSystem.hpp",
    "content": "#ifndef ELEVATOR_SYSTEM_HPP\n#define ELEVATOR_SYSTEM_HPP\n\n#include <vector>\n#include \"Elevator.hpp\"\n\nclass ElevatorSystem {\nprivate:\n    std::vector<Elevator*> elevators;\n    int maxFloor;\n    int minFloor;\n\npublic:\n    ElevatorSystem(int numElevators, int maxFloor, int minFloor = 0);\n    ~ElevatorSystem();\n    \n    void addRequest(int elevatorId, const Request& request);\n    void step();\n    void displayStatus() const;\n    \nprivate:\n    Elevator* findElevator(int elevatorId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/elevatorsystem/README.md",
    "content": "# Designing an Elevator System\n\n## Requirements\n1. The elevator system should consist of multiple elevators serving multiple floors.\n2. Each elevator should have a capacity limit and should not exceed it.\n3. Users should be able to request an elevator from any floor and select a destination floor.\n4. The elevator system should efficiently handle user requests and optimize the movement of elevators to minimize waiting time.\n5. The system should prioritize requests based on the direction of travel and the proximity of the elevators to the requested floor.\n6. The elevators should be able to handle multiple requests concurrently and process them in an optimal order.\n7. The system should ensure thread safety and prevent race conditions when multiple threads interact with the elevators.\n\n## Classes, Interfaces and Enumerations\n1. The **Direction** enum represents the possible directions of elevator movement (UP or DOWN).\n2. The **Request** class represents a user request for an elevator, containing the source floor and destination floor.\n3. The **Elevator** class represents an individual elevator in the system. It has a capacity limit and maintains a list of 4. requests. The elevator processes requests concurrently and moves between floors based on the requests.\n4. The **ElevatorController** class manages multiple elevators and handles user requests. It finds the optimal elevator to serve a request based on the proximity of the elevators to the requested floor.\n5. The **ElevatorSystem** class is the entry point of the application and demonstrates the usage of the elevator system."
  },
  {
    "path": "solutions/cpp/elevatorsystem/Request.cpp",
    "content": "#include \"Request.hpp\"\n\nRequest::Request(int sourceFloor, int destinationFloor)\n    : sourceFloor(sourceFloor), destinationFloor(destinationFloor) {\n    isUp = destinationFloor > sourceFloor;\n}\n\nint Request::getSourceFloor() const { return sourceFloor; }\nint Request::getDestinationFloor() const { return destinationFloor; }\nbool Request::getIsUp() const { return isUp; } "
  },
  {
    "path": "solutions/cpp/elevatorsystem/Request.hpp",
    "content": "#ifndef REQUEST_HPP\n#define REQUEST_HPP\n\nclass Request {\nprivate:\n    int sourceFloor;\n    int destinationFloor;\n    bool isUp;\n\npublic:\n    Request(int sourceFloor, int destinationFloor);\n    \n    int getSourceFloor() const;\n    int getDestinationFloor() const;\n    bool getIsUp() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/DeliveryDemo.cpp",
    "content": "#include \"DeliveryService.hpp\"\n#include <iostream>\n\nint main() {\n    DeliveryService service;\n    \n    // Create users\n    User* user1 = new User(\"U001\", \"John Doe\", \"john@example.com\", \n                          \"+1-555-0123\", \"123 Main St\");\n    service.addUser(user1);\n    \n    // Create restaurants\n    Restaurant* restaurant1 = new Restaurant(\"R001\", \"Pizza Palace\", \n                                           \"Italian\", \"456 Oak Ave\");\n    \n    // Add menu items\n    MenuItem* item1 = new MenuItem(\"I001\", \"Margherita Pizza\", \n                                 \"Classic tomato and mozzarella\", 12.99);\n    MenuItem* item2 = new MenuItem(\"I002\", \"Pepperoni Pizza\", \n                                 \"Spicy pepperoni with cheese\", 14.99);\n    restaurant1->addMenuItem(item1);\n    restaurant1->addMenuItem(item2);\n    \n    service.addRestaurant(restaurant1);\n    \n    // Display available restaurants\n    service.displayAllRestaurants();\n    \n    // Create an order\n    Order* order = service.createOrder(\"U001\", \"R001\");\n    if (order) {\n        service.addItemToOrder(order->getOrderId(), \"I001\", 2);  // 2 Margherita pizzas\n        service.addItemToOrder(order->getOrderId(), \"I002\", 1);  // 1 Pepperoni pizza\n        \n        // Display order details\n        service.displayOrderDetails(order->getOrderId());\n        \n        // Update order status\n        service.updateOrderStatus(order->getOrderId(), OrderStatus::PREPARING);\n        service.updateOrderStatus(order->getOrderId(), OrderStatus::OUT_FOR_DELIVERY);\n        service.updateOrderStatus(order->getOrderId(), OrderStatus::DELIVERED);\n        \n        // Display order history\n        std::cout << \"\\nOrder History for John Doe:\" << std::endl;\n        service.displayOrderHistory(\"U001\");\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/DeliveryService.cpp",
    "content": "#include \"DeliveryService.hpp\"\n#include <iostream>\n\nDeliveryService::DeliveryService() : orderIdCounter(1) {}\n\nDeliveryService::~DeliveryService() {\n    for (auto user : users) delete user;\n    for (auto restaurant : restaurants) delete restaurant;\n    for (auto order : orders) delete order;\n}\n\nvoid DeliveryService::addUser(User* user) {\n    users.push_back(user);\n}\n\nvoid DeliveryService::addRestaurant(Restaurant* restaurant) {\n    restaurants.push_back(restaurant);\n}\n\nOrder* DeliveryService::createOrder(std::string userId, std::string restaurantId) {\n    User* user = findUser(userId);\n    Restaurant* restaurant = findRestaurant(restaurantId);\n    \n    if (!user || !restaurant || !restaurant->getIsOpen()) return nullptr;\n    \n    Order* order = new Order(generateOrderId(), user, restaurant);\n    orders.push_back(order);\n    return order;\n}\n\nbool DeliveryService::addItemToOrder(std::string orderId, std::string itemId, int quantity) {\n    Order* order = findOrder(orderId);\n    if (!order || order->getStatus() != OrderStatus::PLACED) return false;\n    \n    MenuItem* item = order->getRestaurant()->findMenuItem(itemId);\n    if (!item || !item->isAvailable()) return false;\n    \n    order->addItem(item, quantity);\n    return true;\n}\n\nbool DeliveryService::updateOrderStatus(std::string orderId, OrderStatus status) {\n    Order* order = findOrder(orderId);\n    if (!order) return false;\n    \n    order->setStatus(status);\n    return true;\n}\n\nvoid DeliveryService::displayAllRestaurants() const {\n    std::cout << \"\\nAvailable Restaurants:\" << std::endl;\n    for (const auto& restaurant : restaurants) {\n        restaurant->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid DeliveryService::displayRestaurantMenu(std::string restaurantId) const {\n    Restaurant* restaurant = findRestaurant(restaurantId);\n    if (restaurant) {\n        restaurant->displayInfo();\n        restaurant->displayMenu();\n    }\n}\n\nvoid DeliveryService::displayOrderHistory(std::string userId) const {\n    for (const auto& order : orders) {\n        if (order->getUser()->getUserId() == userId) {\n            order->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid DeliveryService::displayOrderDetails(std::string orderId) const {\n    Order* order = findOrder(orderId);\n    if (order) {\n        order->displayInfo();\n    }\n}\n\nUser* DeliveryService::findUser(const std::string& userId) const {\n    for (auto user : users) {\n        if (user->getUserId() == userId) return user;\n    }\n    return nullptr;\n}\n\nRestaurant* DeliveryService::findRestaurant(const std::string& restaurantId) const {\n    for (auto restaurant : restaurants) {\n        if (restaurant->getRestaurantId() == restaurantId) return restaurant;\n    }\n    return nullptr;\n}\n\nOrder* DeliveryService::findOrder(const std::string& orderId) const {\n    for (auto order : orders) {\n        if (order->getOrderId() == orderId) return order;\n    }\n    return nullptr;\n}\n\nstd::string DeliveryService::generateOrderId() {\n    return \"ORD\" + std::to_string(orderIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/DeliveryService.hpp",
    "content": "#ifndef DELIVERY_SERVICE_HPP\n#define DELIVERY_SERVICE_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Restaurant.hpp\"\n#include \"Order.hpp\"\n\nclass DeliveryService {\nprivate:\n    std::vector<User*> users;\n    std::vector<Restaurant*> restaurants;\n    std::vector<Order*> orders;\n    int orderIdCounter;\n\npublic:\n    DeliveryService();\n    ~DeliveryService();\n    \n    void addUser(User* user);\n    void addRestaurant(Restaurant* restaurant);\n    \n    Order* createOrder(std::string userId, std::string restaurantId);\n    bool addItemToOrder(std::string orderId, std::string itemId, int quantity);\n    bool updateOrderStatus(std::string orderId, OrderStatus status);\n    \n    void displayAllRestaurants() const;\n    void displayRestaurantMenu(std::string restaurantId) const;\n    void displayOrderHistory(std::string userId) const;\n    void displayOrderDetails(std::string orderId) const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Restaurant* findRestaurant(const std::string& restaurantId) const;\n    Order* findOrder(const std::string& orderId) const;\n    std::string generateOrderId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/MenuItem.cpp",
    "content": "#include \"MenuItem.hpp\"\n#include <iostream>\n#include <iomanip>\n\nMenuItem::MenuItem(std::string itemId, std::string name, \n                  std::string description, double price)\n    : itemId(itemId), name(name), description(description), \n      price(price), available(true) {}\n\nstd::string MenuItem::getItemId() const { return itemId; }\nstd::string MenuItem::getName() const { return name; }\nstd::string MenuItem::getDescription() const { return description; }\ndouble MenuItem::getPrice() const { return price; }\nbool MenuItem::isAvailable() const { return available; }\n\nvoid MenuItem::setAvailable(bool status) {\n    available = status;\n}\n\nvoid MenuItem::displayInfo() const {\n    std::cout << \"Item: \" << name << \" (ID: \" << itemId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Price: $\" << std::fixed << std::setprecision(2) << price << std::endl;\n    std::cout << \"Status: \" << (available ? \"Available\" : \"Not Available\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/MenuItem.hpp",
    "content": "#ifndef MENU_ITEM_HPP\n#define MENU_ITEM_HPP\n\n#include <string>\n\nclass MenuItem {\nprivate:\n    std::string itemId;\n    std::string name;\n    std::string description;\n    double price;\n    bool available;\n\npublic:\n    MenuItem(std::string itemId, std::string name, std::string description, double price);\n    \n    std::string getItemId() const;\n    std::string getName() const;\n    std::string getDescription() const;\n    double getPrice() const;\n    bool isAvailable() const;\n    \n    void setAvailable(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/Order.cpp",
    "content": "#include \"Order.hpp\"\n#include <iostream>\n#include <iomanip>\n\nOrder::Order(std::string orderId, User* user, Restaurant* restaurant)\n    : orderId(orderId), user(user), restaurant(restaurant), \n      status(OrderStatus::PLACED), totalAmount(0.0) {\n    // Get current timestamp\n    auto now = std::time(nullptr);\n    timestamp = std::ctime(&now);\n}\n\nstd::string Order::getOrderId() const { return orderId; }\nUser* Order::getUser() const { return user; }\nRestaurant* Order::getRestaurant() const { return restaurant; }\nOrderStatus Order::getStatus() const { return status; }\ndouble Order::getTotalAmount() const { return totalAmount; }\nstd::string Order::getTimestamp() const { return timestamp; }\n\nvoid Order::addItem(MenuItem* item, int quantity) {\n    if (item && quantity > 0) {\n        items[item] = quantity;\n        calculateTotal();\n    }\n}\n\nvoid Order::setStatus(OrderStatus status) {\n    this->status = status;\n}\n\nvoid Order::calculateTotal() {\n    totalAmount = 0.0;\n    for (const auto& pair : items) {\n        totalAmount += pair.first->getPrice() * pair.second;\n    }\n}\n\nvoid Order::displayInfo() const {\n    std::cout << \"\\nOrder Details:\" << std::endl;\n    std::cout << \"Order ID: \" << orderId << std::endl;\n    std::cout << \"Customer: \" << user->getName() << std::endl;\n    std::cout << \"Restaurant: \" << restaurant->getName() << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case OrderStatus::PLACED: std::cout << \"Placed\"; break;\n        case OrderStatus::PREPARING: std::cout << \"Preparing\"; break;\n        case OrderStatus::OUT_FOR_DELIVERY: std::cout << \"Out for Delivery\"; break;\n        case OrderStatus::DELIVERED: std::cout << \"Delivered\"; break;\n        case OrderStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"\\nOrdered Items:\" << std::endl;\n    for (const auto& pair : items) {\n        std::cout << pair.first->getName() << \" x \" << pair.second \n                  << \" = $\" << std::fixed << std::setprecision(2)\n                  << pair.first->getPrice() * pair.second << std::endl;\n    }\n    \n    std::cout << \"\\nTotal Amount: $\" << std::fixed << std::setprecision(2) \n              << totalAmount << std::endl;\n    std::cout << \"Order Time: \" << timestamp;\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/Order.hpp",
    "content": "#ifndef ORDER_HPP\n#define ORDER_HPP\n\n#include <string>\n#include <vector>\n#include <map>\n#include \"User.hpp\"\n#include \"Restaurant.hpp\"\n#include \"MenuItem.hpp\"\n\nenum class OrderStatus {\n    PLACED,\n    PREPARING,\n    OUT_FOR_DELIVERY,\n    DELIVERED,\n    CANCELLED\n};\n\nclass Order {\nprivate:\n    std::string orderId;\n    User* user;\n    Restaurant* restaurant;\n    std::map<MenuItem*, int> items;  // item and quantity\n    OrderStatus status;\n    double totalAmount;\n    std::string timestamp;\n\npublic:\n    Order(std::string orderId, User* user, Restaurant* restaurant);\n    \n    std::string getOrderId() const;\n    User* getUser() const;\n    Restaurant* getRestaurant() const;\n    OrderStatus getStatus() const;\n    double getTotalAmount() const;\n    std::string getTimestamp() const;\n    \n    void addItem(MenuItem* item, int quantity);\n    void setStatus(OrderStatus status);\n    void calculateTotal();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/README.md",
    "content": "# Designing an Online Food Delivery Service Like Swiggy\n\n## Requirements\n1. The food delivery service should allow customers to browse restaurants, view menus, and place orders.\n2. Restaurants should be able to manage their menus, prices, and availability.\n3. Delivery agents should be able to accept and fulfill orders.\n4. The system should handle order tracking and status updates.\n5. The system should support multiple payment methods.\n6. The system should handle concurrent orders and ensure data consistency.\n7. The system should be scalable and handle a high volume of orders.\n8. The system should provide real-time notifications to customers, restaurants, and delivery agents.\n\n## Classes, Interfaces and Enumerations\n1. The **Customer** class represents a customer who can place orders. It contains customer details such as ID, name, email, and phone number.\n2. The **Restaurant** class represents a restaurant that offers menu items. It contains restaurant details such as ID, name, address, and a list of menu items. It provides methods to add and remove menu items.\n3. The **MenuItem** class represents an item on a restaurant's menu. It contains details such as ID, name, description, price, and availability status.\n4. The **Order** class represents an order placed by a customer. It contains order details such as ID, customer, restaurant, list of order items, status, and assigned delivery agent. It provides methods to add and remove order items, update order status, and assign a delivery agent.\n5. The **OrderItem** class represents an item within an order. It contains the selected menu item and the quantity ordered.\n6. The **OrderStatus** enum represents the different statuses an order can have, such as PENDING, CONFIRMED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.\n7. The **DeliveryAgent** class represents a delivery agent who fulfills orders. It contains details such as ID, name, phone number, and availability status.\n8. The **FoodDeliveryService** class is the main class that manages the food delivery service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register customers, restaurants, and delivery agents, retrieve available restaurants and menus, place orders, update order status, cancel orders, and assign delivery agents to orders. It also handles notifications to customers, restaurants, and delivery agents."
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/Restaurant.cpp",
    "content": "#include \"Restaurant.hpp\"\n#include <iostream>\n#include <algorithm>\n\nRestaurant::Restaurant(std::string restaurantId, std::string name, \n                      std::string cuisine, std::string address)\n    : restaurantId(restaurantId), name(name), cuisine(cuisine), \n      address(address), isOpen(true) {}\n\nRestaurant::~Restaurant() {\n    for (auto item : menu) {\n        delete item;\n    }\n}\n\nstd::string Restaurant::getRestaurantId() const { return restaurantId; }\nstd::string Restaurant::getName() const { return name; }\nstd::string Restaurant::getCuisine() const { return cuisine; }\nstd::string Restaurant::getAddress() const { return address; }\nbool Restaurant::getIsOpen() const { return isOpen; }\n\nvoid Restaurant::addMenuItem(MenuItem* item) {\n    menu.push_back(item);\n}\n\nvoid Restaurant::removeMenuItem(MenuItem* item) {\n    auto it = std::find(menu.begin(), menu.end(), item);\n    if (it != menu.end()) {\n        menu.erase(it);\n    }\n}\n\nMenuItem* Restaurant::findMenuItem(const std::string& itemId) const {\n    for (auto item : menu) {\n        if (item->getItemId() == itemId) return item;\n    }\n    return nullptr;\n}\n\nvoid Restaurant::setOpen(bool status) {\n    isOpen = status;\n}\n\nvoid Restaurant::displayInfo() const {\n    std::cout << \"Restaurant: \" << name << \" (ID: \" << restaurantId << \")\" << std::endl;\n    std::cout << \"Cuisine: \" << cuisine << std::endl;\n    std::cout << \"Address: \" << address << std::endl;\n    std::cout << \"Status: \" << (isOpen ? \"Open\" : \"Closed\") << std::endl;\n}\n\nvoid Restaurant::displayMenu() const {\n    std::cout << \"\\nMenu Items:\" << std::endl;\n    for (const auto& item : menu) {\n        item->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/Restaurant.hpp",
    "content": "#ifndef RESTAURANT_HPP\n#define RESTAURANT_HPP\n\n#include <string>\n#include <vector>\n#include \"MenuItem.hpp\"\n\nclass Restaurant {\nprivate:\n    std::string restaurantId;\n    std::string name;\n    std::string cuisine;\n    std::string address;\n    std::vector<MenuItem*> menu;\n    bool isOpen;\n\npublic:\n    Restaurant(std::string restaurantId, std::string name, \n              std::string cuisine, std::string address);\n    ~Restaurant();\n    \n    std::string getRestaurantId() const;\n    std::string getName() const;\n    std::string getCuisine() const;\n    std::string getAddress() const;\n    bool getIsOpen() const;\n    \n    void addMenuItem(MenuItem* item);\n    void removeMenuItem(MenuItem* item);\n    MenuItem* findMenuItem(const std::string& itemId) const;\n    void setOpen(bool status);\n    void displayInfo() const;\n    void displayMenu() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n\nUser::User(std::string userId, std::string name, std::string email, \n           std::string phone, std::string address)\n    : userId(userId), name(name), email(email), phone(phone), address(address) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getName() const { return name; }\nstd::string User::getEmail() const { return email; }\nstd::string User::getPhone() const { return phone; }\nstd::string User::getAddress() const { return address; }\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << name << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Phone: \" << phone << std::endl;\n    std::cout << \"Address: \" << address << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/fooddeliveryservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string name;\n    std::string email;\n    std::string phone;\n    std::string address;\n\npublic:\n    User(std::string userId, std::string name, std::string email, \n         std::string phone, std::string address);\n    \n    std::string getUserId() const;\n    std::string getName() const;\n    std::string getEmail() const;\n    std::string getPhone() const;\n    std::string getAddress() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Booking.cpp",
    "content": "#include \"Booking.hpp\"\n#include <iostream>\n#include <iomanip>\n\nBooking::Booking(std::string bookingId, Guest* guest, Room* room,\n                std::string checkInDate, std::string checkOutDate, int numberOfNights)\n    : bookingId(bookingId), guest(guest), room(room),\n      checkInDate(checkInDate), checkOutDate(checkOutDate),\n      numberOfNights(numberOfNights), status(BookingStatus::CONFIRMED) {\n    calculateTotalAmount();\n}\n\nstd::string Booking::getBookingId() const { return bookingId; }\nGuest* Booking::getGuest() const { return guest; }\nRoom* Booking::getRoom() const { return room; }\nstd::string Booking::getCheckInDate() const { return checkInDate; }\nstd::string Booking::getCheckOutDate() const { return checkOutDate; }\nint Booking::getNumberOfNights() const { return numberOfNights; }\ndouble Booking::getTotalAmount() const { return totalAmount; }\nBookingStatus Booking::getStatus() const { return status; }\n\nvoid Booking::calculateTotalAmount() {\n    totalAmount = room->getPricePerNight() * numberOfNights;\n}\n\nvoid Booking::setStatus(BookingStatus status) {\n    this->status = status;\n}\n\nvoid Booking::displayInfo() const {\n    std::cout << \"\\nBooking Details:\" << std::endl;\n    std::cout << \"Booking ID: \" << bookingId << std::endl;\n    std::cout << \"Guest: \" << guest->getName() << std::endl;\n    std::cout << \"Room: \" << room->getRoomNumber() << std::endl;\n    std::cout << \"Check-in Date: \" << checkInDate << std::endl;\n    std::cout << \"Check-out Date: \" << checkOutDate << std::endl;\n    std::cout << \"Number of Nights: \" << numberOfNights << std::endl;\n    std::cout << \"Total Amount: $\" << std::fixed << std::setprecision(2) \n              << totalAmount << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case BookingStatus::CONFIRMED: std::cout << \"Confirmed\"; break;\n        case BookingStatus::CHECKED_IN: std::cout << \"Checked In\"; break;\n        case BookingStatus::CHECKED_OUT: std::cout << \"Checked Out\"; break;\n        case BookingStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Booking.hpp",
    "content": "#ifndef BOOKING_HPP\n#define BOOKING_HPP\n\n#include <string>\n#include \"Guest.hpp\"\n#include \"Room.hpp\"\n\nenum class BookingStatus {\n    CONFIRMED,\n    CHECKED_IN,\n    CHECKED_OUT,\n    CANCELLED\n};\n\nclass Booking {\nprivate:\n    std::string bookingId;\n    Guest* guest;\n    Room* room;\n    std::string checkInDate;\n    std::string checkOutDate;\n    int numberOfNights;\n    double totalAmount;\n    BookingStatus status;\n\npublic:\n    Booking(std::string bookingId, Guest* guest, Room* room,\n           std::string checkInDate, std::string checkOutDate, int numberOfNights);\n    \n    std::string getBookingId() const;\n    Guest* getGuest() const;\n    Room* getRoom() const;\n    std::string getCheckInDate() const;\n    std::string getCheckOutDate() const;\n    int getNumberOfNights() const;\n    double getTotalAmount() const;\n    BookingStatus getStatus() const;\n    \n    void calculateTotalAmount();\n    void setStatus(BookingStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Guest.cpp",
    "content": "#include \"Guest.hpp\"\n#include <iostream>\n\nGuest::Guest(std::string guestId, std::string name, std::string email,\n            std::string phone, std::string address)\n    : guestId(guestId), name(name), email(email), phone(phone), address(address) {}\n\nstd::string Guest::getGuestId() const { return guestId; }\nstd::string Guest::getName() const { return name; }\nstd::string Guest::getEmail() const { return email; }\nstd::string Guest::getPhone() const { return phone; }\nstd::string Guest::getAddress() const { return address; }\n\nvoid Guest::displayInfo() const {\n    std::cout << \"Guest: \" << name << \" (ID: \" << guestId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Phone: \" << phone << std::endl;\n    std::cout << \"Address: \" << address << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Guest.hpp",
    "content": "#ifndef GUEST_HPP\n#define GUEST_HPP\n\n#include <string>\n\nclass Guest {\nprivate:\n    std::string guestId;\n    std::string name;\n    std::string email;\n    std::string phone;\n    std::string address;\n\npublic:\n    Guest(std::string guestId, std::string name, std::string email,\n          std::string phone, std::string address);\n    \n    std::string getGuestId() const;\n    std::string getName() const;\n    std::string getEmail() const;\n    std::string getPhone() const;\n    std::string getAddress() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/HotelDemo.cpp",
    "content": "#include \"HotelManager.hpp\"\n#include <iostream>\n\nint main() {\n    HotelManager hotel;\n    \n    // Add rooms\n    Room* room1 = new Room(\"101\", RoomType::STANDARD, 100.0, 2);\n    Room* room2 = new Room(\"201\", RoomType::DELUXE, 150.0, 3);\n    Room* room3 = new Room(\"301\", RoomType::SUITE, 250.0, 4);\n    \n    hotel.addRoom(room1);\n    hotel.addRoom(room2);\n    hotel.addRoom(room3);\n    \n    // Add guests\n    Guest* guest1 = new Guest(\"G001\", \"John Doe\", \"john@example.com\",\n                            \"+1-555-0123\", \"123 Main St\");\n    hotel.addGuest(guest1);\n    \n    // Display available rooms\n    hotel.displayAvailableRooms();\n    \n    // Create a booking\n    Booking* booking = hotel.createBooking(\"G001\", \"101\", \"2024-01-01\",\n                                         \"2024-01-03\", 2);\n    if (booking) {\n        std::cout << \"\\nBooking created successfully!\" << std::endl;\n        booking->displayInfo();\n        \n        // Check in\n        if (hotel.checkIn(booking->getBookingId())) {\n            std::cout << \"\\nChecked in successfully!\" << std::endl;\n        }\n        \n        // Display available rooms after check-in\n        hotel.displayAvailableRooms();\n        \n        // Check out\n        if (hotel.checkOut(booking->getBookingId())) {\n            std::cout << \"\\nChecked out successfully!\" << std::endl;\n        }\n        \n        // Display booking history\n        hotel.displayBookingHistory(\"G001\");\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/HotelManager.cpp",
    "content": "#include \"HotelManager.hpp\"\n#include <iostream>\n\nHotelManager::HotelManager() : bookingIdCounter(1) {}\n\nHotelManager::~HotelManager() {\n    for (auto room : rooms) delete room;\n    for (auto guest : guests) delete guest;\n    for (auto booking : bookings) delete booking;\n}\n\nvoid HotelManager::addRoom(Room* room) {\n    rooms.push_back(room);\n}\n\nvoid HotelManager::addGuest(Guest* guest) {\n    guests.push_back(guest);\n}\n\nBooking* HotelManager::createBooking(std::string guestId, std::string roomNumber,\n                                   std::string checkInDate, std::string checkOutDate,\n                                   int numberOfNights) {\n    Guest* guest = findGuest(guestId);\n    Room* room = findRoom(roomNumber);\n    \n    if (!guest || !room || room->getStatus() != RoomStatus::AVAILABLE) {\n        return nullptr;\n    }\n    \n    Booking* booking = new Booking(generateBookingId(), guest, room,\n                                 checkInDate, checkOutDate, numberOfNights);\n    bookings.push_back(booking);\n    return booking;\n}\n\nbool HotelManager::checkIn(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking || booking->getStatus() != BookingStatus::CONFIRMED) {\n        return false;\n    }\n    \n    booking->setStatus(BookingStatus::CHECKED_IN);\n    booking->getRoom()->setStatus(RoomStatus::OCCUPIED);\n    return true;\n}\n\nbool HotelManager::checkOut(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking || booking->getStatus() != BookingStatus::CHECKED_IN) {\n        return false;\n    }\n    \n    booking->setStatus(BookingStatus::CHECKED_OUT);\n    booking->getRoom()->setStatus(RoomStatus::AVAILABLE);\n    return true;\n}\n\nbool HotelManager::cancelBooking(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking || booking->getStatus() != BookingStatus::CONFIRMED) {\n        return false;\n    }\n    \n    booking->setStatus(BookingStatus::CANCELLED);\n    booking->getRoom()->setStatus(RoomStatus::AVAILABLE);\n    return true;\n}\n\nvoid HotelManager::displayAvailableRooms() const {\n    std::cout << \"\\nAvailable Rooms:\" << std::endl;\n    for (const auto& room : rooms) {\n        if (room->getStatus() == RoomStatus::AVAILABLE) {\n            room->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid HotelManager::displayBookingHistory(std::string guestId) const {\n    std::cout << \"\\nBooking History:\" << std::endl;\n    for (const auto& booking : bookings) {\n        if (booking->getGuest()->getGuestId() == guestId) {\n            booking->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid HotelManager::displayAllGuests() const {\n    std::cout << \"\\nAll Guests:\" << std::endl;\n    for (const auto& guest : guests) {\n        guest->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid HotelManager::displayAllBookings() const {\n    std::cout << \"\\nAll Bookings:\" << std::endl;\n    for (const auto& booking : bookings) {\n        booking->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nRoom* HotelManager::findRoom(const std::string& roomNumber) const {\n    for (auto room : rooms) {\n        if (room->getRoomNumber() == roomNumber) return room;\n    }\n    return nullptr;\n}\n\nGuest* HotelManager::findGuest(const std::string& guestId) const {\n    for (auto guest : guests) {\n        if (guest->getGuestId() == guestId) return guest;\n    }\n    return nullptr;\n}\n\nBooking* HotelManager::findBooking(const std::string& bookingId) const {\n    for (auto booking : bookings) {\n        if (booking->getBookingId() == bookingId) return booking;\n    }\n    return nullptr;\n}\n\nstd::string HotelManager::generateBookingId() {\n    return \"BK\" + std::to_string(bookingIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/HotelManager.hpp",
    "content": "#ifndef HOTEL_MANAGER_HPP\n#define HOTEL_MANAGER_HPP\n\n#include <vector>\n#include <string>\n#include \"Room.hpp\"\n#include \"Guest.hpp\"\n#include \"Booking.hpp\"\n\nclass HotelManager {\nprivate:\n    std::vector<Room*> rooms;\n    std::vector<Guest*> guests;\n    std::vector<Booking*> bookings;\n    int bookingIdCounter;\n\npublic:\n    HotelManager();\n    ~HotelManager();\n    \n    void addRoom(Room* room);\n    void addGuest(Guest* guest);\n    \n    Booking* createBooking(std::string guestId, std::string roomNumber,\n                          std::string checkInDate, std::string checkOutDate,\n                          int numberOfNights);\n    \n    bool checkIn(std::string bookingId);\n    bool checkOut(std::string bookingId);\n    bool cancelBooking(std::string bookingId);\n    \n    void displayAvailableRooms() const;\n    void displayBookingHistory(std::string guestId) const;\n    void displayAllGuests() const;\n    void displayAllBookings() const;\n    \nprivate:\n    Room* findRoom(const std::string& roomNumber) const;\n    Guest* findGuest(const std::string& guestId) const;\n    Booking* findBooking(const std::string& bookingId) const;\n    std::string generateBookingId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/README.md",
    "content": "# Designing a Hotel Management System\n\n## Requirements\n1. The hotel management system should allow guests to book rooms, check-in, and check-out.\n2. The system should manage different types of rooms, such as single, double, deluxe, and suite.\n3. The system should handle room availability and reservation status.\n4. The system should allow the hotel staff to manage guest information, room assignments, and billing.\n5. The system should support multiple payment methods, such as cash, credit card, and online payment.\n6. The system should handle concurrent bookings and ensure data consistency.\n7. The system should provide reporting and analytics features for hotel management.\n8. The system should be scalable and handle a large number of rooms and guests.\n\n## Classes, Interfaces and Enumerations\n1. The **Guest** class represents a guest of the hotel, with properties such as ID, name, email, and phone number.\n2. The **Room** class represents a room in the hotel, with properties like ID, room type, price, and status. It provides methods to book, check-in, and check-out a room.\n3. The **RoomType** enum represents the different types of rooms available in the hotel.\n4. The **RoomStatus** enum represents the status of a room, which can be available, booked, or occupied.\n5. The **Reservation** class represents a reservation made by a guest for a specific room and date range. It contains properties such as ID, guest, room, check-in date, check-out date, and status. It provides a method to cancel a reservation.\n6. The **ReservationStatus** enum represents the status of a reservation, which can be confirmed or cancelled.\n7. The **Payment** interface defines the contract for processing payments. It is implemented by concrete payment classes like CashPayment and CreditCardPayment.\n8. The **HotelManagementSystem** class is the central component of the hotel management system. It follows the Singleton pattern to ensure only one instance of the system exists. It provides methods to add guests and rooms, book rooms, cancel reservations, check-in, check-out, and process payments. It also handles concurrent access to shared resources using synchronization.\n9. The **HotelManagementSystemDemo** class demonstrates the usage of the hotel management system by creating guests, rooms, booking a room, checking in, checking out, and cancelling a reservation."
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Room.cpp",
    "content": "#include \"Room.hpp\"\n#include <iostream>\n#include <iomanip>\n\nRoom::Room(std::string roomNumber, RoomType type, double pricePerNight, int capacity)\n    : roomNumber(roomNumber), type(type), status(RoomStatus::AVAILABLE),\n      pricePerNight(pricePerNight), capacity(capacity) {}\n\nstd::string Room::getRoomNumber() const { return roomNumber; }\nRoomType Room::getType() const { return type; }\nRoomStatus Room::getStatus() const { return status; }\ndouble Room::getPricePerNight() const { return pricePerNight; }\nint Room::getCapacity() const { return capacity; }\n\nvoid Room::setStatus(RoomStatus status) {\n    this->status = status;\n}\n\nvoid Room::displayInfo() const {\n    std::cout << \"Room \" << roomNumber << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case RoomType::STANDARD: std::cout << \"Standard\"; break;\n        case RoomType::DELUXE: std::cout << \"Deluxe\"; break;\n        case RoomType::SUITE: std::cout << \"Suite\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Status: \";\n    switch (status) {\n        case RoomStatus::AVAILABLE: std::cout << \"Available\"; break;\n        case RoomStatus::OCCUPIED: std::cout << \"Occupied\"; break;\n        case RoomStatus::UNDER_MAINTENANCE: std::cout << \"Under Maintenance\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Price per night: $\" << std::fixed << std::setprecision(2) \n              << pricePerNight << std::endl;\n    std::cout << \"Capacity: \" << capacity << \" persons\" << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/hotelmanagementsystem/Room.hpp",
    "content": "#ifndef ROOM_HPP\n#define ROOM_HPP\n\n#include <string>\n\nenum class RoomType {\n    STANDARD,\n    DELUXE,\n    SUITE\n};\n\nenum class RoomStatus {\n    AVAILABLE,\n    OCCUPIED,\n    UNDER_MAINTENANCE\n};\n\nclass Room {\nprivate:\n    std::string roomNumber;\n    RoomType type;\n    RoomStatus status;\n    double pricePerNight;\n    int capacity;\n\npublic:\n    Room(std::string roomNumber, RoomType type, double pricePerNight, int capacity);\n    \n    std::string getRoomNumber() const;\n    RoomType getType() const;\n    RoomStatus getStatus() const;\n    double getPricePerNight() const;\n    int getCapacity() const;\n    \n    void setStatus(RoomStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Book.cpp",
    "content": "#include \"Book.hpp\"\n#include <iostream>\n\nBook::Book(std::string bookId, std::string title, std::string author,\n           std::string publisher, std::string isbn, int publicationYear)\n    : bookId(bookId), title(title), author(author), publisher(publisher),\n      isbn(isbn), status(BookStatus::AVAILABLE), publicationYear(publicationYear) {}\n\nstd::string Book::getBookId() const { return bookId; }\nstd::string Book::getTitle() const { return title; }\nstd::string Book::getAuthor() const { return author; }\nstd::string Book::getPublisher() const { return publisher; }\nstd::string Book::getIsbn() const { return isbn; }\nBookStatus Book::getStatus() const { return status; }\nint Book::getPublicationYear() const { return publicationYear; }\n\nvoid Book::setStatus(BookStatus status) {\n    this->status = status;\n}\n\nvoid Book::displayInfo() const {\n    std::cout << \"Book: \" << title << \" (ID: \" << bookId << \")\" << std::endl;\n    std::cout << \"Author: \" << author << std::endl;\n    std::cout << \"Publisher: \" << publisher << std::endl;\n    std::cout << \"ISBN: \" << isbn << std::endl;\n    std::cout << \"Publication Year: \" << publicationYear << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case BookStatus::AVAILABLE: std::cout << \"Available\"; break;\n        case BookStatus::BORROWED: std::cout << \"Borrowed\"; break;\n        case BookStatus::RESERVED: std::cout << \"Reserved\"; break;\n        case BookStatus::LOST: std::cout << \"Lost\"; break;\n    }\n    std::cout << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Book.hpp",
    "content": "#ifndef BOOK_HPP\n#define BOOK_HPP\n\n#include <string>\n\nenum class BookStatus {\n    AVAILABLE,\n    BORROWED,\n    RESERVED,\n    LOST\n};\n\nclass Book {\nprivate:\n    std::string bookId;\n    std::string title;\n    std::string author;\n    std::string publisher;\n    std::string isbn;\n    BookStatus status;\n    int publicationYear;\n\npublic:\n    Book(std::string bookId, std::string title, std::string author,\n         std::string publisher, std::string isbn, int publicationYear);\n    \n    std::string getBookId() const;\n    std::string getTitle() const;\n    std::string getAuthor() const;\n    std::string getPublisher() const;\n    std::string getIsbn() const;\n    BookStatus getStatus() const;\n    int getPublicationYear() const;\n    \n    void setStatus(BookStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/LibraryDemo.cpp",
    "content": "#include \"LibraryManager.hpp\"\n#include <iostream>\n\nint main() {\n    LibraryManager library;\n    \n    // Add books\n    Book* book1 = new Book(\"B001\", \"The Great Gatsby\", \"F. Scott Fitzgerald\",\n                          \"Scribner\", \"978-0743273565\", 1925);\n    Book* book2 = new Book(\"B002\", \"To Kill a Mockingbird\", \"Harper Lee\",\n                          \"HarperCollins\", \"978-0446310789\", 1960);\n    \n    library.addBook(book1);\n    library.addBook(book2);\n    \n    // Add members\n    Member* member1 = new Member(\"M001\", \"John Doe\", \"john@example.com\",\n                               \"+1-555-0123\");\n    library.addMember(member1);\n    \n    // Display available books\n    library.displayAvailableBooks();\n    \n    // Borrow a book\n    if (library.borrowBook(\"M001\", \"B001\", \"2024-01-01\", \"2024-01-15\")) {\n        std::cout << \"\\nBook borrowed successfully!\" << std::endl;\n    }\n    \n    // Display member's books\n    library.displayMemberBooks(\"M001\");\n    \n    // Return the book\n    if (library.returnBook(\"M001\", \"B001\", \"2024-01-10\")) {\n        std::cout << \"\\nBook returned successfully!\" << std::endl;\n    }\n    \n    // Display transaction history\n    library.displayTransactionHistory();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/LibraryManager.cpp",
    "content": "#include \"LibraryManager.hpp\"\n#include <iostream>\n\nLibraryManager::LibraryManager() : transactionIdCounter(1) {}\n\nLibraryManager::~LibraryManager() {\n    for (auto book : books) delete book;\n    for (auto member : members) delete member;\n    for (auto transaction : transactions) delete transaction;\n}\n\nvoid LibraryManager::addBook(Book* book) {\n    books.push_back(book);\n}\n\nvoid LibraryManager::addMember(Member* member) {\n    members.push_back(member);\n}\n\nbool LibraryManager::borrowBook(std::string memberId, std::string bookId,\n                              std::string issueDate, std::string dueDate) {\n    Member* member = findMember(memberId);\n    Book* book = findBook(bookId);\n    \n    if (!member || !member->isActive() || !book || \n        book->getStatus() != BookStatus::AVAILABLE) {\n        return false;\n    }\n    \n    Transaction* transaction = new Transaction(\n        generateTransactionId(),\n        book,\n        member,\n        TransactionType::BORROW,\n        issueDate,\n        dueDate\n    );\n    \n    transactions.push_back(transaction);\n    book->setStatus(BookStatus::BORROWED);\n    member->addBorrowedBook(book);\n    return true;\n}\n\nbool LibraryManager::returnBook(std::string memberId, std::string bookId,\n                              std::string returnDate) {\n    Member* member = findMember(memberId);\n    Book* book = findBook(bookId);\n    Transaction* transaction = findTransaction(bookId, memberId);\n    \n    if (!member || !book || !transaction || \n        book->getStatus() != BookStatus::BORROWED) {\n        return false;\n    }\n    \n    transaction->setReturnDate(returnDate);\n    book->setStatus(BookStatus::AVAILABLE);\n    member->removeBorrowedBook(book);\n    \n    // Create return transaction\n    Transaction* returnTrans = new Transaction(\n        generateTransactionId(),\n        book,\n        member,\n        TransactionType::RETURN,\n        returnDate,\n        returnDate\n    );\n    transactions.push_back(returnTrans);\n    \n    return true;\n}\n\nbool LibraryManager::reserveBook(std::string memberId, std::string bookId) {\n    Member* member = findMember(memberId);\n    Book* book = findBook(bookId);\n    \n    if (!member || !member->isActive() || !book || \n        book->getStatus() != BookStatus::AVAILABLE) {\n        return false;\n    }\n    \n    book->setStatus(BookStatus::RESERVED);\n    Transaction* transaction = new Transaction(\n        generateTransactionId(),\n        book,\n        member,\n        TransactionType::RESERVE,\n        \"NOW\",  // Should use actual datetime\n        \"NOW\"   // Should use actual datetime\n    );\n    transactions.push_back(transaction);\n    return true;\n}\n\nbool LibraryManager::renewBook(std::string memberId, std::string bookId,\n                             std::string newDueDate) {\n    Member* member = findMember(memberId);\n    Book* book = findBook(bookId);\n    Transaction* transaction = findTransaction(bookId, memberId);\n    \n    if (!member || !book || !transaction || \n        book->getStatus() != BookStatus::BORROWED) {\n        return false;\n    }\n    \n    Transaction* renewTrans = new Transaction(\n        generateTransactionId(),\n        book,\n        member,\n        TransactionType::RENEW,\n        transaction->getDueDate(),\n        newDueDate\n    );\n    transactions.push_back(renewTrans);\n    return true;\n}\n\nvoid LibraryManager::displayAvailableBooks() const {\n    std::cout << \"\\nAvailable Books:\" << std::endl;\n    for (const auto& book : books) {\n        if (book->getStatus() == BookStatus::AVAILABLE) {\n            book->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid LibraryManager::displayMemberBooks(std::string memberId) const {\n    Member* member = findMember(memberId);\n    if (!member) return;\n    \n    std::cout << \"\\nBooks borrowed by \" << member->getName() << \":\" << std::endl;\n    for (const auto& book : member->getBorrowedBooks()) {\n        book->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid LibraryManager::displayAllMembers() const {\n    std::cout << \"\\nAll Members:\" << std::endl;\n    for (const auto& member : members) {\n        member->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid LibraryManager::displayTransactionHistory() const {\n    std::cout << \"\\nTransaction History:\" << std::endl;\n    for (const auto& transaction : transactions) {\n        transaction->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nBook* LibraryManager::findBook(const std::string& bookId) const {\n    for (auto book : books) {\n        if (book->getBookId() == bookId) return book;\n    }\n    return nullptr;\n}\n\nMember* LibraryManager::findMember(const std::string& memberId) const {\n    for (auto member : members) {\n        if (member->getMemberId() == memberId) return member;\n    }\n    return nullptr;\n}\n\nTransaction* LibraryManager::findTransaction(const std::string& bookId,\n                                          const std::string& memberId) const {\n    for (auto transaction : transactions) {\n        if (transaction->getBook()->getBookId() == bookId &&\n            transaction->getMember()->getMemberId() == memberId &&\n            transaction->getType() == TransactionType::BORROW) {\n            return transaction;\n        }\n    }\n    return nullptr;\n}\n\nstd::string LibraryManager::generateTransactionId() {\n    return \"T\" + std::to_string(transactionIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/LibraryManager.hpp",
    "content": "#ifndef LIBRARY_MANAGER_HPP\n#define LIBRARY_MANAGER_HPP\n\n#include <vector>\n#include <string>\n#include \"Book.hpp\"\n#include \"Member.hpp\"\n#include \"Transaction.hpp\"\n\nclass LibraryManager {\nprivate:\n    std::vector<Book*> books;\n    std::vector<Member*> members;\n    std::vector<Transaction*> transactions;\n    int transactionIdCounter;\n\npublic:\n    LibraryManager();\n    ~LibraryManager();\n    \n    void addBook(Book* book);\n    void addMember(Member* member);\n    \n    bool borrowBook(std::string memberId, std::string bookId,\n                   std::string issueDate, std::string dueDate);\n    bool returnBook(std::string memberId, std::string bookId,\n                   std::string returnDate);\n    bool reserveBook(std::string memberId, std::string bookId);\n    bool renewBook(std::string memberId, std::string bookId,\n                  std::string newDueDate);\n    \n    void displayAvailableBooks() const;\n    void displayMemberBooks(std::string memberId) const;\n    void displayAllMembers() const;\n    void displayTransactionHistory() const;\n    \nprivate:\n    Book* findBook(const std::string& bookId) const;\n    Member* findMember(const std::string& memberId) const;\n    Transaction* findTransaction(const std::string& bookId,\n                               const std::string& memberId) const;\n    std::string generateTransactionId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Member.cpp",
    "content": "#include \"Member.hpp\"\n#include <iostream>\n#include <algorithm>\n\nMember::Member(std::string memberId, std::string name, std::string email, std::string phone)\n    : memberId(memberId), name(name), email(email), phone(phone), active(true) {}\n\nstd::string Member::getMemberId() const { return memberId; }\nstd::string Member::getName() const { return name; }\nstd::string Member::getEmail() const { return email; }\nstd::string Member::getPhone() const { return phone; }\nbool Member::isActive() const { return active; }\nconst std::vector<Book*>& Member::getBorrowedBooks() const { return borrowedBooks; }\n\nvoid Member::addBorrowedBook(Book* book) {\n    borrowedBooks.push_back(book);\n}\n\nvoid Member::removeBorrowedBook(Book* book) {\n    auto it = std::find(borrowedBooks.begin(), borrowedBooks.end(), book);\n    if (it != borrowedBooks.end()) {\n        borrowedBooks.erase(it);\n    }\n}\n\nvoid Member::setActive(bool status) {\n    active = status;\n}\n\nvoid Member::displayInfo() const {\n    std::cout << \"Member: \" << name << \" (ID: \" << memberId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Phone: \" << phone << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Borrowed Books: \" << borrowedBooks.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Member.hpp",
    "content": "#ifndef MEMBER_HPP\n#define MEMBER_HPP\n\n#include <string>\n#include <vector>\n#include \"Book.hpp\"\n\nclass Member {\nprivate:\n    std::string memberId;\n    std::string name;\n    std::string email;\n    std::string phone;\n    std::vector<Book*> borrowedBooks;\n    bool active;\n\npublic:\n    Member(std::string memberId, std::string name, std::string email, std::string phone);\n    \n    std::string getMemberId() const;\n    std::string getName() const;\n    std::string getEmail() const;\n    std::string getPhone() const;\n    bool isActive() const;\n    const std::vector<Book*>& getBorrowedBooks() const;\n    \n    void addBorrowedBook(Book* book);\n    void removeBorrowedBook(Book* book);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/README.md",
    "content": "# Designing a Library Management System\n\n## Requirements\n1. The library management system should allow librarians to manage books, members, and borrowing activities.\n2. The system should support adding, updating, and removing books from the library catalog.\n3. Each book should have details such as title, author, ISBN, publication year, and availability status.\n4. The system should allow members to borrow and return books.\n5. Each member should have details such as name, member ID, contact information, and borrowing history.\n6. The system should enforce borrowing rules, such as a maximum number of books that can be borrowed at a time and loan duration.\n7. The system should handle concurrent access to the library catalog and member records.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Book** class represents a book in the library catalog, with properties such as ISBN, title, author, publication year, and availability status.\n2. The **Member** class represents a library member, with properties like member ID, name, contact information, and a list of borrowed books.\n3. The **LibraryManager** class is the core of the library management system and follows the Singleton pattern to ensure a single instance of the library manager.\n4. The LibraryManager class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to the library catalog and member records.\n5. The LibraryManager class provides methods for adding and removing books, registering and unregistering members, borrowing and returning books, and searching for books based on keywords.\n6. The **LibraryManagementSystemDemo** class serves as the entry point of the application and demonstrates the usage of the library management system."
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Transaction.cpp",
    "content": "#include \"Transaction.hpp\"\n#include <iostream>\n#include <iomanip>\n\nTransaction::Transaction(std::string transactionId, Book* book, Member* member,\n                       TransactionType type, std::string issueDate, std::string dueDate)\n    : transactionId(transactionId), book(book), member(member), type(type),\n      issueDate(issueDate), dueDate(dueDate), fine(0.0) {}\n\nstd::string Transaction::getTransactionId() const { return transactionId; }\nBook* Transaction::getBook() const { return book; }\nMember* Transaction::getMember() const { return member; }\nTransactionType Transaction::getType() const { return type; }\nstd::string Transaction::getIssueDate() const { return issueDate; }\nstd::string Transaction::getDueDate() const { return dueDate; }\nstd::string Transaction::getReturnDate() const { return returnDate; }\ndouble Transaction::getFine() const { return fine; }\n\nvoid Transaction::setReturnDate(std::string date) {\n    returnDate = date;\n}\n\nvoid Transaction::setFine(double amount) {\n    fine = amount;\n}\n\nvoid Transaction::displayInfo() const {\n    std::cout << \"\\nTransaction Details:\" << std::endl;\n    std::cout << \"Transaction ID: \" << transactionId << std::endl;\n    std::cout << \"Book: \" << book->getTitle() << std::endl;\n    std::cout << \"Member: \" << member->getName() << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case TransactionType::BORROW: std::cout << \"Borrow\"; break;\n        case TransactionType::RETURN: std::cout << \"Return\"; break;\n        case TransactionType::RESERVE: std::cout << \"Reserve\"; break;\n        case TransactionType::RENEW: std::cout << \"Renew\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Issue Date: \" << issueDate << std::endl;\n    std::cout << \"Due Date: \" << dueDate << std::endl;\n    if (!returnDate.empty()) {\n        std::cout << \"Return Date: \" << returnDate << std::endl;\n    }\n    if (fine > 0) {\n        std::cout << \"Fine: $\" << std::fixed << std::setprecision(2) << fine << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/librarymanagementsystem/Transaction.hpp",
    "content": "#ifndef TRANSACTION_HPP\n#define TRANSACTION_HPP\n\n#include <string>\n#include \"Book.hpp\"\n#include \"Member.hpp\"\n\nenum class TransactionType {\n    BORROW,\n    RETURN,\n    RESERVE,\n    RENEW\n};\n\nclass Transaction {\nprivate:\n    std::string transactionId;\n    Book* book;\n    Member* member;\n    TransactionType type;\n    std::string issueDate;\n    std::string dueDate;\n    std::string returnDate;\n    double fine;\n\npublic:\n    Transaction(std::string transactionId, Book* book, Member* member,\n               TransactionType type, std::string issueDate, std::string dueDate);\n    \n    std::string getTransactionId() const;\n    Book* getBook() const;\n    Member* getMember() const;\n    TransactionType getType() const;\n    std::string getIssueDate() const;\n    std::string getDueDate() const;\n    std::string getReturnDate() const;\n    double getFine() const;\n    \n    void setReturnDate(std::string date);\n    void setFine(double amount);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/linkedin/LinkedInDemo.cpp",
    "content": "#include \"LinkedInManager.hpp\"\n#include <iostream>\n\nint main() {\n    LinkedInManager linkedin;\n    \n    // Create users\n    User* user1 = new User(\"U001\", \"john@example.com\", \"password123\");\n    User* user2 = new User(\"U002\", \"jane@example.com\", \"password456\");\n    \n    // Create profiles\n    Profile* profile1 = new Profile(\"John Doe\", \"Software Engineer\");\n    Profile* profile2 = new Profile(\"Jane Smith\", \"Product Manager\");\n    \n    user1->setProfile(profile1);\n    user2->setProfile(profile2);\n    \n    // Add skills\n    profile1->addSkill(\"C++\");\n    profile1->addSkill(\"Python\");\n    profile2->addSkill(\"Product Management\");\n    profile2->addSkill(\"Agile\");\n    \n    // Add experience\n    Experience exp1{\"Tech Corp\", \"Software Engineer\", \"2020\", \"Present\",\n                   \"Developing enterprise applications\"};\n    profile1->addExperience(exp1);\n    \n    // Add education\n    Education edu1{\"University of Tech\", \"BS\", \"Computer Science\",\n                  \"2016\", \"2020\"};\n    profile1->addEducation(edu1);\n    \n    linkedin.addUser(user1);\n    linkedin.addUser(user2);\n    \n    // Create connection\n    linkedin.addConnection(\"U001\", \"U002\");\n    \n    // Create posts\n    Post* post = linkedin.createPost(\"U001\", \"Hello LinkedIn!\",\n                                   PostType::TEXT, \"2024-01-01\");\n    if (post) {\n        linkedin.likePost(\"U002\", post->getPostId());\n        linkedin.commentOnPost(\"U002\", post->getPostId(),\n                             \"Great to see you here!\");\n    }\n    \n    // Display information\n    std::cout << \"User Profiles:\" << std::endl;\n    linkedin.displayUserProfile(\"U001\");\n    linkedin.displayUserProfile(\"U002\");\n    \n    std::cout << \"\\nUser Connections:\" << std::endl;\n    linkedin.displayUserConnections(\"U001\");\n    \n    std::cout << \"\\nUser Posts:\" << std::endl;\n    linkedin.displayUserPosts(\"U001\");\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/linkedin/LinkedInManager.cpp",
    "content": "#include \"LinkedInManager.hpp\"\n#include <iostream>\n\nLinkedInManager::LinkedInManager() : postIdCounter(1) {}\n\nLinkedInManager::~LinkedInManager() {\n    for (auto user : users) delete user;\n    for (auto post : posts) delete post;\n}\n\nvoid LinkedInManager::addUser(User* user) {\n    users.push_back(user);\n}\n\nPost* LinkedInManager::createPost(std::string userId, std::string content,\n                                PostType type, std::string timestamp) {\n    User* user = findUser(userId);\n    if (!user || !user->isActive()) return nullptr;\n    \n    Post* post = new Post(generatePostId(), user, content, type, timestamp);\n    posts.push_back(post);\n    user->addPost(post);\n    return post;\n}\n\nbool LinkedInManager::addConnection(std::string userId1, std::string userId2) {\n    User* user1 = findUser(userId1);\n    User* user2 = findUser(userId2);\n    \n    if (!user1 || !user2 || !user1->isActive() || !user2->isActive()) {\n        return false;\n    }\n    \n    user1->addConnection(user2);\n    return true;\n}\n\nbool LinkedInManager::removeConnection(std::string userId1, std::string userId2) {\n    User* user1 = findUser(userId1);\n    User* user2 = findUser(userId2);\n    \n    if (!user1 || !user2) return false;\n    \n    user1->removeConnection(user2);\n    return true;\n}\n\nbool LinkedInManager::likePost(std::string userId, std::string postId) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post || !user->isActive()) return false;\n    \n    post->addLike(user);\n    return true;\n}\n\nbool LinkedInManager::unlikePost(std::string userId, std::string postId) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post) return false;\n    \n    post->removeLike(user);\n    return true;\n}\n\nbool LinkedInManager::commentOnPost(std::string userId, std::string postId,\n                                  const std::string& comment) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post || !user->isActive()) return false;\n    \n    post->addComment(comment);\n    return true;\n}\n\nvoid LinkedInManager::displayUserProfile(std::string userId) const {\n    User* user = findUser(userId);\n    if (user) {\n        user->displayInfo();\n    }\n}\n\nvoid LinkedInManager::displayUserConnections(std::string userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nConnections for \" << user->getEmail() << \":\" << std::endl;\n    for (const auto& connection : user->getConnections()) {\n        connection->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid LinkedInManager::displayUserPosts(std::string userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nPosts by \" << user->getEmail() << \":\" << std::endl;\n    for (const auto& post : user->getPosts()) {\n        post->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid LinkedInManager::displayAllUsers() const {\n    std::cout << \"\\nAll Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nUser* LinkedInManager::findUser(const std::string& userId) const {\n    for (auto user : users) {\n        if (user->getUserId() == userId) return user;\n    }\n    return nullptr;\n}\n\nPost* LinkedInManager::findPost(const std::string& postId) const {\n    for (auto post : posts) {\n        if (post->getPostId() == postId) return post;\n    }\n    return nullptr;\n}\n\nstd::string LinkedInManager::generatePostId() {\n    return \"P\" + std::to_string(postIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/linkedin/LinkedInManager.hpp",
    "content": "#ifndef LINKEDIN_MANAGER_HPP\n#define LINKEDIN_MANAGER_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Post.hpp\"\n\nclass LinkedInManager {\nprivate:\n    std::vector<User*> users;\n    std::vector<Post*> posts;\n    int postIdCounter;\n\npublic:\n    LinkedInManager();\n    ~LinkedInManager();\n    \n    void addUser(User* user);\n    Post* createPost(std::string userId, std::string content,\n                    PostType type, std::string timestamp);\n    \n    bool addConnection(std::string userId1, std::string userId2);\n    bool removeConnection(std::string userId1, std::string userId2);\n    \n    bool likePost(std::string userId, std::string postId);\n    bool unlikePost(std::string userId, std::string postId);\n    bool commentOnPost(std::string userId, std::string postId,\n                      const std::string& comment);\n    \n    void displayUserProfile(std::string userId) const;\n    void displayUserConnections(std::string userId) const;\n    void displayUserPosts(std::string userId) const;\n    void displayAllUsers() const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Post* findPost(const std::string& postId) const;\n    std::string generatePostId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/linkedin/Post.cpp",
    "content": "#include \"Post.hpp\"\n#include <iostream>\n#include <algorithm>\n\nPost::Post(std::string postId, User* author, std::string content,\n           PostType type, std::string timestamp)\n    : postId(postId), author(author), content(content),\n      type(type), timestamp(timestamp) {}\n\nstd::string Post::getPostId() const { return postId; }\nUser* Post::getAuthor() const { return author; }\nstd::string Post::getContent() const { return content; }\nPostType Post::getType() const { return type; }\nstd::string Post::getTimestamp() const { return timestamp; }\nconst std::vector<User*>& Post::getLikes() const { return likes; }\nconst std::vector<std::string>& Post::getComments() const { return comments; }\n\nvoid Post::addLike(User* user) {\n    if (user && std::find(likes.begin(), likes.end(), user) == likes.end()) {\n        likes.push_back(user);\n    }\n}\n\nvoid Post::removeLike(User* user) {\n    auto it = std::find(likes.begin(), likes.end(), user);\n    if (it != likes.end()) {\n        likes.erase(it);\n    }\n}\n\nvoid Post::addComment(const std::string& comment) {\n    comments.push_back(comment);\n}\n\nvoid Post::displayInfo() const {\n    std::cout << \"\\nPost Details:\" << std::endl;\n    std::cout << \"ID: \" << postId << std::endl;\n    std::cout << \"Author: \" << author->getProfile()->getName() << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case PostType::TEXT: std::cout << \"Text\"; break;\n        case PostType::IMAGE: std::cout << \"Image\"; break;\n        case PostType::VIDEO: std::cout << \"Video\"; break;\n        case PostType::ARTICLE: std::cout << \"Article\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Content: \" << content << std::endl;\n    std::cout << \"Timestamp: \" << timestamp << std::endl;\n    std::cout << \"Likes: \" << likes.size() << std::endl;\n    std::cout << \"Comments: \" << comments.size() << std::endl;\n    \n    if (!comments.empty()) {\n        std::cout << \"\\nComments:\" << std::endl;\n        for (const auto& comment : comments) {\n            std::cout << \"- \" << comment << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/linkedin/Post.hpp",
    "content": "#ifndef POST_HPP\n#define POST_HPP\n\n#include <string>\n#include <vector>\n#include \"User.hpp\"\n\nenum class PostType {\n    TEXT,\n    IMAGE,\n    VIDEO,\n    ARTICLE\n};\n\nclass Post {\nprivate:\n    std::string postId;\n    User* author;\n    std::string content;\n    PostType type;\n    std::string timestamp;\n    std::vector<User*> likes;\n    std::vector<std::string> comments;\n\npublic:\n    Post(std::string postId, User* author, std::string content, \n         PostType type, std::string timestamp);\n    \n    std::string getPostId() const;\n    User* getAuthor() const;\n    std::string getContent() const;\n    PostType getType() const;\n    std::string getTimestamp() const;\n    const std::vector<User*>& getLikes() const;\n    const std::vector<std::string>& getComments() const;\n    \n    void addLike(User* user);\n    void removeLike(User* user);\n    void addComment(const std::string& comment);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/linkedin/Profile.cpp",
    "content": "#include \"Profile.hpp\"\n#include <iostream>\n\nProfile::Profile(std::string name, std::string headline)\n    : name(name), headline(headline) {}\n\n\nstd::string Profile::getName() const{\n    return name;\n}\n\nvoid Profile::setAbout(const std::string& about) {\n    this->about = about;\n}\n\nvoid Profile::setLocation(const std::string& location) {\n    this->location = location;\n}\n\nvoid Profile::addSkill(const std::string& skill) {\n    skills.push_back(skill);\n}\n\nvoid Profile::addExperience(const Experience& exp) {\n    experiences.push_back(exp);\n}\n\nvoid Profile::addEducation(const Education& edu) {\n    educations.push_back(edu);\n}\n\nvoid Profile::displayInfo() const {\n    std::cout << \"\\nProfile Information:\" << std::endl;\n    std::cout << \"Name: \" << name << std::endl;\n    std::cout << \"Headline: \" << headline << std::endl;\n    if (!about.empty()) {\n        std::cout << \"About: \" << about << std::endl;\n    }\n    if (!location.empty()) {\n        std::cout << \"Location: \" << location << std::endl;\n    }\n    \n    if (!skills.empty()) {\n        std::cout << \"\\nSkills:\" << std::endl;\n        for (const auto& skill : skills) {\n            std::cout << \"- \" << skill << std::endl;\n        }\n    }\n    \n    if (!experiences.empty()) {\n        std::cout << \"\\nExperience:\" << std::endl;\n        for (const auto& exp : experiences) {\n            std::cout << exp.position << \" at \" << exp.company << std::endl;\n            std::cout << exp.startDate << \" - \" << exp.endDate << std::endl;\n            std::cout << exp.description << std::endl;\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n    \n    if (!educations.empty()) {\n        std::cout << \"\\nEducation:\" << std::endl;\n        for (const auto& edu : educations) {\n            std::cout << edu.degree << \" in \" << edu.field << std::endl;\n            std::cout << edu.school << std::endl;\n            std::cout << edu.startDate << \" - \" << edu.endDate << std::endl;\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/linkedin/Profile.hpp",
    "content": "#ifndef PROFILE_HPP\n#define PROFILE_HPP\n\n#include <string>\n#include <vector>\n\nstruct Experience {\n    std::string company;\n    std::string position;\n    std::string startDate;\n    std::string endDate;\n    std::string description;\n};\n\nstruct Education {\n    std::string school;\n    std::string degree;\n    std::string field;\n    std::string startDate;\n    std::string endDate;\n};\n\nclass Profile {\nprivate:\n    std::string name;\n    std::string headline;\n    std::string about;\n    std::string location;\n    std::vector<std::string> skills;\n    std::vector<Experience> experiences;\n    std::vector<Education> educations;\n\npublic:\n    Profile(std::string name, std::string headline);\n\n    std::string getName() const;\n    \n    void setAbout(const std::string& about);\n    void setLocation(const std::string& location);\n    void addSkill(const std::string& skill);\n    void addExperience(const Experience& exp);\n    void addEducation(const Education& edu);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/linkedin/README.md",
    "content": "# Designing a Professional Networking Platform like LinkedIn\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their professional information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their professional information, such as profile picture, headline, summary, experience, education, and skills.\n- Users should be able to update their profile information.\n#### Connections:\n- Users should be able to send connection requests to other users.\n- Users should be able to accept or decline connection requests.\n- Users should be able to view their list of connections.\n#### Messaging:\n- Users should be able to send messages to their connections.\n- Users should be able to view their inbox and sent messages.\n#### Job Postings:\n- Employers should be able to post job listings with details such as title, description, requirements, and location.\n- Users should be able to view and apply for job postings.\n#### Search Functionality:\n- Users should be able to search for other users, companies, and job postings based on relevant criteria.\n- Search results should be ranked based on relevance and user preferences.\n#### Notifications:\n- Users should receive notifications for events such as connection requests, messages, and job postings.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the LinkedIn system, containing properties such as ID, name, email, password, profile, connections, inbox, and sent messages.\n2. The **Profile** class represents a user's profile, containing properties such as profile picture, headline, summary, experiences, educations, and skills.\n3. The **Experience**, **Education**, and **Skill** classes represent different components of a user's profile.\n4. The **Connection** class represents a connection between two users, containing the user and the connection date.\n5. The **Message** class represents a message sent between users, containing properties such as ID, sender, receiver, content, and timestamp.\n6. The **JobPosting** class represents a job listing posted by an employer, containing properties such as ID, title, description, requirements, location, and post date.\n7. The **Notification** class represents a notification generated for a user, containing properties such as ID, user, notification type, content, and timestamp.\n8. The **NotificationType** enum defines the different types of notifications, such as connection request, message, and job posting.\n9. The **LinkedInService** class is the main class that manages the LinkedIn system. It follows the Singleton pattern to ensure only one instance of the service exists.\n10. The **LinkedInService** class provides methods for user registration, login, profile updates, connection requests, job postings, user and job search, messaging, and notifications.\n11. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n12. The **LinkedInDemo** class demonstrates the usage of the LinkedIn system by registering users, logging in, updating profiles, sending connection requests, posting job listings, searching for users and jobs, sending messages, and retrieving notifications."
  },
  {
    "path": "solutions/cpp/linkedin/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <algorithm>\n\nUser::User(std::string userId, std::string email, std::string password)\n    : userId(userId), email(email), password(password), profile(nullptr), active(true) {}\n\nUser::~User() {\n    delete profile;\n    for (auto post : posts) {\n        delete post;\n    }\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getEmail() const { return email; }\nProfile* User::getProfile() const { return profile; }\nbool User::isActive() const { return active; }\nconst std::vector<User*>& User::getConnections() const { return connections; }\nconst std::vector<Post*>& User::getPosts() const { return posts; }\n\nvoid User::setProfile(Profile* profile) {\n    delete this->profile;\n    this->profile = profile;\n}\n\nvoid User::addConnection(User* user) {\n    if (user && std::find(connections.begin(), connections.end(), user) == connections.end()) {\n        connections.push_back(user);\n        user->connections.push_back(this);\n    }\n}\n\nvoid User::removeConnection(User* user) {\n    auto it = std::find(connections.begin(), connections.end(), user);\n    if (it != connections.end()) {\n        connections.erase(it);\n        auto it2 = std::find(user->connections.begin(), user->connections.end(), this);\n        if (it2 != user->connections.end()) {\n            user->connections.erase(it2);\n        }\n    }\n}\n\nvoid User::addPost(Post* post) {\n    posts.push_back(post);\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User ID: \" << userId << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Connections: \" << connections.size() << std::endl;\n    std::cout << \"Posts: \" << posts.size() << std::endl;\n    if (profile) {\n        profile->displayInfo();\n    }\n} "
  },
  {
    "path": "solutions/cpp/linkedin/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include \"Profile.hpp\"\n#include \"Post.hpp\"\n\nclass User {\nprivate:\n    std::string userId;\n    std::string email;\n    std::string password;\n    Profile* profile;\n    std::vector<User*> connections;\n    std::vector<Post*> posts;\n    bool active;\n\npublic:\n    User(std::string userId, std::string email, std::string password);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getEmail() const;\n    Profile* getProfile() const;\n    bool isActive() const;\n    const std::vector<User*>& getConnections() const;\n    const std::vector<Post*>& getPosts() const;\n    \n    void setProfile(Profile* profile);\n    void addConnection(User* user);\n    void removeConnection(User* user);\n    void addPost(Post* post);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/ConsoleAppender.cpp",
    "content": "#include \"ConsoleAppender.hpp\"\n#include <iostream>\n\nvoid ConsoleAppender::append(const LogMessage& message) {\n    std::cout << message.getFormattedMessage() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/loggingframework/ConsoleAppender.hpp",
    "content": "#ifndef CONSOLE_APPENDER_HPP\n#define CONSOLE_APPENDER_HPP\n\n#include \"LogAppender.hpp\"\n\nclass ConsoleAppender : public LogAppender {\npublic:\n    void append(const LogMessage& message) override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/FileAppender.cpp",
    "content": "#include \"FileAppender.hpp\"\n\nFileAppender::FileAppender(const std::string& filename) \n    : filename(filename) {\n    file.open(filename, std::ios::app);\n}\n\nFileAppender::~FileAppender() {\n    if (file.is_open()) {\n        file.close();\n    }\n}\n\nvoid FileAppender::append(const LogMessage& message) {\n    if (file.is_open()) {\n        file << message.getFormattedMessage() << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/loggingframework/FileAppender.hpp",
    "content": "#ifndef FILE_APPENDER_HPP\n#define FILE_APPENDER_HPP\n\n#include <string>\n#include <fstream>\n#include \"LogAppender.hpp\"\n\nclass FileAppender : public LogAppender {\nprivate:\n    std::string filename;\n    std::ofstream file;\n\npublic:\n    FileAppender(const std::string& filename);\n    ~FileAppender();\n    void append(const LogMessage& message) override;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/LogAppender.hpp",
    "content": "#ifndef LOG_APPENDER_HPP\n#define LOG_APPENDER_HPP\n\n#include \"LogMessage.hpp\"\n\nclass LogAppender {\npublic:\n    virtual ~LogAppender() = default;\n    virtual void append(const LogMessage& message) = 0;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/LogLevel.hpp",
    "content": "#ifndef LOG_LEVEL_HPP\n#define LOG_LEVEL_HPP\n\nenum class LogLevel {\n    TRACE,\n    DEBUG,\n    INFO,\n    WARN,\n    ERROR,\n    FATAL\n};\n\n// Helper function to convert LogLevel to string\ninline std::string logLevelToString(LogLevel level) {\n    switch (level) {\n        case LogLevel::TRACE: return \"TRACE\";\n        case LogLevel::DEBUG: return \"DEBUG\";\n        case LogLevel::INFO: return \"INFO\";\n        case LogLevel::WARN: return \"WARN\";\n        case LogLevel::ERROR: return \"ERROR\";\n        case LogLevel::FATAL: return \"FATAL\";\n        default: return \"UNKNOWN\";\n    }\n}\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/LogMessage.cpp",
    "content": "#include \"LogMessage.hpp\"\n#include <sstream>\n#include <iomanip>\n\nLogMessage::LogMessage(LogLevel level, const std::string& message, \n                      const std::string& source)\n    : level(level), message(message), source(source) {\n    // Get current timestamp\n    auto now = std::time(nullptr);\n    auto tm = *std::localtime(&now);\n    std::ostringstream oss;\n    oss << std::put_time(&tm, \"%Y-%m-%d %H:%M:%S\");\n    timestamp = oss.str();\n}\n\nLogLevel LogMessage::getLevel() const { return level; }\nstd::string LogMessage::getMessage() const { return message; }\nstd::string LogMessage::getTimestamp() const { return timestamp; }\nstd::string LogMessage::getSource() const { return source; }\n\nstd::string LogMessage::getFormattedMessage() const {\n    std::ostringstream oss;\n    oss << \"[\" << timestamp << \"] \"\n        << \"[\" << logLevelToString(level) << \"] \"\n        << \"[\" << source << \"] \"\n        << message;\n    return oss.str();\n} "
  },
  {
    "path": "solutions/cpp/loggingframework/LogMessage.hpp",
    "content": "#ifndef LOG_MESSAGE_HPP\n#define LOG_MESSAGE_HPP\n\n#include <string>\n#include <ctime>\n#include \"LogLevel.hpp\"\n\nclass LogMessage {\nprivate:\n    LogLevel level;\n    std::string message;\n    std::string timestamp;\n    std::string source;\n\npublic:\n    LogMessage(LogLevel level, const std::string& message, \n               const std::string& source);\n    \n    LogLevel getLevel() const;\n    std::string getMessage() const;\n    std::string getTimestamp() const;\n    std::string getSource() const;\n    std::string getFormattedMessage() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/Logger.cpp",
    "content": "#include \"Logger.hpp\"\n\nLogger::Logger(const std::string& name, LogLevel minLevel)\n    : name(name), minLevel(minLevel) {}\n\nvoid Logger::addAppender(std::shared_ptr<LogAppender> appender) {\n    appenders.push_back(appender);\n}\n\nvoid Logger::setMinLevel(LogLevel level) {\n    minLevel = level;\n}\n\nbool Logger::isLevelEnabled(LogLevel level) const {\n    return static_cast<int>(level) >= static_cast<int>(minLevel);\n}\n\nvoid Logger::log(LogLevel level, const std::string& message) {\n    if (!isLevelEnabled(level)) return;\n    \n    LogMessage logMessage(level, message, name);\n    for (const auto& appender : appenders) {\n        appender->append(logMessage);\n    }\n}\n\nvoid Logger::trace(const std::string& message) {\n    log(LogLevel::TRACE, message);\n}\n\nvoid Logger::debug(const std::string& message) {\n    log(LogLevel::DEBUG, message);\n}\n\nvoid Logger::info(const std::string& message) {\n    log(LogLevel::INFO, message);\n}\n\nvoid Logger::warn(const std::string& message) {\n    log(LogLevel::WARN, message);\n}\n\nvoid Logger::error(const std::string& message) {\n    log(LogLevel::ERROR, message);\n}\n\nvoid Logger::fatal(const std::string& message) {\n    log(LogLevel::FATAL, message);\n} "
  },
  {
    "path": "solutions/cpp/loggingframework/Logger.hpp",
    "content": "#ifndef LOGGER_HPP\n#define LOGGER_HPP\n\n#include <string>\n#include <vector>\n#include <memory>\n#include \"LogLevel.hpp\"\n#include \"LogMessage.hpp\"\n#include \"LogAppender.hpp\"\n\nclass Logger {\nprivate:\n    std::string name;\n    LogLevel minLevel;\n    std::vector<std::shared_ptr<LogAppender>> appenders;\n\npublic:\n    Logger(const std::string& name, LogLevel minLevel = LogLevel::INFO);\n    \n    void addAppender(std::shared_ptr<LogAppender> appender);\n    void setMinLevel(LogLevel level);\n    \n    void log(LogLevel level, const std::string& message);\n    void trace(const std::string& message);\n    void debug(const std::string& message);\n    void info(const std::string& message);\n    void warn(const std::string& message);\n    void error(const std::string& message);\n    void fatal(const std::string& message);\n\nprivate:\n    bool isLevelEnabled(LogLevel level) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/loggingframework/LoggingDemo.cpp",
    "content": "#include \"Logger.hpp\"\n#include \"ConsoleAppender.hpp\"\n#include \"FileAppender.hpp\"\n#include <memory>\n\nint main() {\n    // Create logger\n    Logger logger(\"MyApp\");\n    \n    // Add console appender\n    auto consoleAppender = std::make_shared<ConsoleAppender>();\n    logger.addAppender(consoleAppender);\n    \n    // Add file appender\n    auto fileAppender = std::make_shared<FileAppender>(\"app.log\");\n    logger.addAppender(fileAppender);\n    \n    // Log messages at different levels\n    logger.trace(\"This is a trace message\");  // Won't be logged (below INFO)\n    logger.debug(\"This is a debug message\");  // Won't be logged (below INFO)\n    logger.info(\"Application started\");\n    logger.warn(\"This is a warning message\");\n    logger.error(\"An error occurred\");\n    logger.fatal(\"Fatal error: application shutting down\");\n    \n    // Change minimum log level\n    logger.setMinLevel(LogLevel::DEBUG);\n    logger.debug(\"Now debug messages will be logged\");\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/loggingframework/README.md",
    "content": "# Designing a Logging Framework\n\n## Requirements\n1. The logging framework should support different log levels, such as DEBUG, INFO, WARNING, ERROR, and FATAL.\n2. It should allow logging messages with a timestamp, log level, and message content.\n3. The framework should support multiple output destinations, such as console, file, and database.\n4. It should provide a configuration mechanism to set the log level and output destination.\n5. The logging framework should be thread-safe to handle concurrent logging from multiple threads.\n6. It should be extensible to accommodate new log levels and output destinations in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **LogLevel** enum defines the different log levels supported by the logging framework.\n2. The **LogMessage** class represents a log message with a timestamp, log level, and message content.\n3. The **LogAppender** interface defines the contract for appending log messages to different output destinations.\n4. The **ConsoleAppender**, **FileAppender**, and **DatabaseAppender** classes are concrete implementations of the LogAppender interface, supporting logging to the console, file, and database, respectively.\n5. The **LoggerConfig** class holds the configuration settings for the logger, including the log level and the selected log appender.\n6. The **Logger** class is a singleton that provides the main logging functionality. It allows setting the configuration, logging messages at different levels, and provides convenience methods for each log level.\n7. The **LoggingExample** class demonstrates the usage of the logging framework, showcasing different log levels, changing the configuration, and logging from multiple threads."
  },
  {
    "path": "solutions/cpp/lrucache/DoublyLinkedList.hpp",
    "content": "#ifndef DOUBLY_LINKED_LIST_HPP\n#define DOUBLY_LINKED_LIST_HPP\n\ntemplate<typename K, typename V>\nstruct Node {\n    K key;\n    V value;\n    Node* prev;\n    Node* next;\n    \n    Node(K key, V value) : key(key), value(value), prev(nullptr), next(nullptr) {}\n};\n\ntemplate<typename K, typename V>\nclass DoublyLinkedList {\nprivate:\n    Node<K,V>* head;\n    Node<K,V>* tail;\n    int size;\n\npublic:\n    DoublyLinkedList() : head(nullptr), tail(nullptr), size(0) {}\n    ~DoublyLinkedList() {\n        while (head) {\n            Node<K,V>* temp = head;\n            head = head->next;\n            delete temp;\n        }\n    }\n    \n    Node<K,V>* addToFront(K key, V value) {\n        Node<K,V>* node = new Node<K,V>(key, value);\n        \n        if (!head) {\n            head = tail = node;\n        } else {\n            node->next = head;\n            head->prev = node;\n            head = node;\n        }\n        \n        size++;\n        return node;\n    }\n    \n    void moveToFront(Node<K,V>* node) {\n        if (node == head) return;\n        \n        if (node == tail) {\n            tail = node->prev;\n            tail->next = nullptr;\n        } else {\n            node->prev->next = node->next;\n            node->next->prev = node->prev;\n        }\n        \n        node->prev = nullptr;\n        node->next = head;\n        head->prev = node;\n        head = node;\n    }\n    \n    void removeNode(Node<K,V>* node) {\n        if (node == head) {\n            head = node->next;\n            if (head) head->prev = nullptr;\n        } else if (node == tail) {\n            tail = node->prev;\n            tail->next = nullptr;\n        } else {\n            node->prev->next = node->next;\n            node->next->prev = node->prev;\n        }\n        \n        delete node;\n        size--;\n        \n        if (size == 0) {\n            head = tail = nullptr;\n        }\n    }\n    \n    Node<K,V>* removeLast() {\n        if (!tail) return nullptr;\n        \n        Node<K,V>* node = tail;\n        tail = tail->prev;\n        if (tail) {\n            tail->next = nullptr;\n        } else {\n            head = nullptr;\n        }\n        \n        size--;\n        return node;\n    }\n    \n    int getSize() const { return size; }\n    bool isEmpty() const { return size == 0; }\n    Node<K,V>* getHead() const { return head; }\n    Node<K,V>* getTail() const { return tail; }\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/lrucache/LRUCache.hpp",
    "content": "#ifndef LRU_CACHE_HPP\n#define LRU_CACHE_HPP\n\n#include <unordered_map>\n#include \"DoublyLinkedList.hpp\"\n\ntemplate<typename K, typename V>\nclass LRUCache {\nprivate:\n    int capacity;\n    DoublyLinkedList<K,V> dll;\n    std::unordered_map<K, Node<K,V>*> cache;\n\npublic:\n    LRUCache(int capacity) : capacity(capacity) {}\n    \n    V get(K key) {\n        auto it = cache.find(key);\n        if (it == cache.end()) {\n            throw std::runtime_error(\"Key not found\");\n        }\n        \n        Node<K,V>* node = it->second;\n        dll.moveToFront(node);\n        return node->value;\n    }\n    \n    void put(K key, V value) {\n        auto it = cache.find(key);\n        if (it != cache.end()) {\n            // Key exists, update value and move to front\n            Node<K,V>* node = it->second;\n            node->value = value;\n            dll.moveToFront(node);\n        } else {\n            // Key doesn't exist, add new entry\n            if (cache.size() >= capacity) {\n                // Remove least recently used item\n                Node<K,V>* lastNode = dll.getTail();\n                cache.erase(lastNode->key);\n                dll.removeNode(lastNode);\n            }\n            \n            // Add new item to front\n            Node<K,V>* newNode = dll.addToFront(key, value);\n            cache[key] = newNode;\n        }\n    }\n    \n    bool contains(K key) const {\n        return cache.find(key) != cache.end();\n    }\n    \n    int getSize() const {\n        return cache.size();\n    }\n    \n    bool isEmpty() const {\n        return cache.empty();\n    }\n    \n    void clear() {\n        while (!dll.isEmpty()) {\n            Node<K,V>* node = dll.removeLast();\n            cache.erase(node->key);\n            delete node;\n        }\n    }\n    \n    void display() const {\n        std::cout << \"\\nLRU Cache Contents:\" << std::endl;\n        Node<K,V>* current = dll.getHead();\n        while (current) {\n            std::cout << current->key << \" -> \" << current->value << std::endl;\n            current = current->next;\n        }\n        std::cout << \"Cache size: \" << cache.size() << \"/\" << capacity << std::endl;\n    }\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/lrucache/LRUCacheDemo.cpp",
    "content": "#include \"LRUCache.hpp\"\n#include <iostream>\n#include <string>\n\nint main() {\n    // Create LRU cache with capacity 3\n    LRUCache<int, std::string> cache(3);\n    \n    // Add some entries\n    std::cout << \"Adding entries to cache...\" << std::endl;\n    cache.put(1, \"One\");\n    cache.put(2, \"Two\");\n    cache.put(3, \"Three\");\n    cache.display();\n    \n    // Try to get an entry\n    std::cout << \"\\nGetting value for key 2...\" << std::endl;\n    std::cout << \"Value: \" << cache.get(2) << std::endl;\n    cache.display();  // 2 should move to front\n    \n    // Add new entry when cache is full\n    std::cout << \"\\nAdding new entry when cache is full...\" << std::endl;\n    cache.put(4, \"Four\");  // Should evict least recently used item\n    cache.display();\n    \n    // Try to access non-existent key\n    std::cout << \"\\nTrying to access non-existent key...\" << std::endl;\n    try {\n        cache.get(1);  // Should throw exception\n    } catch (const std::runtime_error& e) {\n        std::cout << \"Error: \" << e.what() << std::endl;\n    }\n    \n    // Update existing entry\n    std::cout << \"\\nUpdating existing entry...\" << std::endl;\n    cache.put(2, \"Two Updated\");\n    cache.display();\n    \n    // Clear cache\n    std::cout << \"\\nClearing cache...\" << std::endl;\n    cache.clear();\n    cache.display();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/lrucache/README.md",
    "content": "# Designing a LRU Cache\n\n## Requirements\n1. The LRU cache should support the following operations:\n- put(key, value): Insert a key-value pair into the cache. If the cache is at capacity, remove the least recently used item before inserting the new item.\n- get(key): Get the value associated with the given key. If the key exists in the cache, move it to the front of the cache (most recently used) and return its value. If the key does not exist, return -1.\n2. The cache should have a fixed capacity, specified during initialization.\n3. The cache should be thread-safe, allowing concurrent access from multiple threads.\n4. The cache should be efficient in terms of time complexity for both put and get operations, ideally O(1).\n\n## Classes, Interfaces and Enumerations\n1. The **Node** class represents a node in the doubly linked list, containing the key, value, and references to the previous and next nodes.\n2. The **LRUCache** class implements the LRU cache functionality using a combination of a hash map (cache) and a doubly linked list (head and tail).\n3. The get method retrieves the value associated with a given key. If the key exists in the cache, it is moved to the head of the linked list (most recently used) and its value is returned. If the key does not exist, null is returned.\n4. The put method inserts a key-value pair into the cache. If the key already exists, its value is updated, and the node is moved to the head of the linked list. If the key does not exist and the cache is at capacity, the least recently used item (at the tail of the linked list) is removed, and the new item is inserted at the head.\n5. The addToHead, removeNode, moveToHead, and removeTail methods are helper methods to manipulate the doubly linked list.\n6. The synchronized keyword is used on the get and put methods to ensure thread safety, allowing concurrent access from multiple threads.\n7. The **LRUCacheDemo** class demonstrates the usage of the LRU cache by creating an instance of LRUCache with a capacity of 3, performing various put and get operations, and printing the results."
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Booking.cpp",
    "content": "#include \"Booking.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <ctime>\n\nBooking::Booking(std::string bookingId, Show* show, std::string customerName,\n                std::string customerPhone, const std::vector<int>& seatNumbers)\n    : bookingId(bookingId), show(show), customerName(customerName),\n      customerPhone(customerPhone), seatNumbers(seatNumbers),\n      status(BookingStatus::PENDING) {\n    // Get current timestamp\n    auto now = std::time(nullptr);\n    auto tm = *std::localtime(&now);\n    std::ostringstream oss;\n    oss << std::put_time(&tm, \"%Y-%m-%d %H:%M:%S\");\n    timestamp = oss.str();\n    \n    calculateTotalAmount();\n}\n\nstd::string Booking::getBookingId() const { return bookingId; }\nShow* Booking::getShow() const { return show; }\nstd::string Booking::getCustomerName() const { return customerName; }\nstd::string Booking::getCustomerPhone() const { return customerPhone; }\nconst std::vector<int>& Booking::getSeatNumbers() const { return seatNumbers; }\ndouble Booking::getTotalAmount() const { return totalAmount; }\nBookingStatus Booking::getStatus() const { return status; }\nstd::string Booking::getTimestamp() const { return timestamp; }\n\nvoid Booking::calculateTotalAmount() {\n    totalAmount = show->getTicketPrice() * seatNumbers.size();\n}\n\nvoid Booking::setStatus(BookingStatus status) {\n    this->status = status;\n}\n\nvoid Booking::displayInfo() const {\n    std::cout << \"\\nBooking Details:\" << std::endl;\n    std::cout << \"Booking ID: \" << bookingId << std::endl;\n    std::cout << \"Customer Name: \" << customerName << std::endl;\n    std::cout << \"Customer Phone: \" << customerPhone << std::endl;\n    show->displayInfo();\n    std::cout << \"Seats: \";\n    for (int seat : seatNumbers) {\n        std::cout << seat << \" \";\n    }\n    std::cout << std::endl;\n    std::cout << \"Total Amount: $\" << std::fixed << std::setprecision(2) \n              << totalAmount << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case BookingStatus::PENDING: std::cout << \"Pending\"; break;\n        case BookingStatus::CONFIRMED: std::cout << \"Confirmed\"; break;\n        case BookingStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Booking Time: \" << timestamp << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Booking.hpp",
    "content": "#ifndef BOOKING_HPP\n#define BOOKING_HPP\n\n#include <string>\n#include <vector>\n#include \"Show.hpp\"\n\nenum class BookingStatus {\n    PENDING,\n    CONFIRMED,\n    CANCELLED\n};\n\nclass Booking {\nprivate:\n    std::string bookingId;\n    Show* show;\n    std::string customerName;\n    std::string customerPhone;\n    std::vector<int> seatNumbers;\n    double totalAmount;\n    BookingStatus status;\n    std::string timestamp;\n\npublic:\n    Booking(std::string bookingId, Show* show, std::string customerName,\n           std::string customerPhone, const std::vector<int>& seatNumbers);\n    \n    std::string getBookingId() const;\n    Show* getShow() const;\n    std::string getCustomerName() const;\n    std::string getCustomerPhone() const;\n    const std::vector<int>& getSeatNumbers() const;\n    double getTotalAmount() const;\n    BookingStatus getStatus() const;\n    std::string getTimestamp() const;\n    \n    void calculateTotalAmount();\n    void setStatus(BookingStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/BookingDemo.cpp",
    "content": "#include \"BookingSystem.hpp\"\n#include <iostream>\n\nint main() {\n    BookingSystem system;\n    \n    // Create movies\n    Movie* movie1 = new Movie(\"M001\", \"The Matrix\", \"A sci-fi action movie\",\n                             MovieGenre::SCIFI, 136, \"English\");\n    movie1->addCastMember(\"Keanu Reeves\");\n    movie1->addCastMember(\"Laurence Fishburne\");\n    \n    Movie* movie2 = new Movie(\"M002\", \"Inception\", \"A mind-bending thriller\",\n                             MovieGenre::THRILLER, 148, \"English\");\n    movie2->addCastMember(\"Leonardo DiCaprio\");\n    movie2->addCastMember(\"Ellen Page\");\n    \n    system.addMovie(movie1);\n    system.addMovie(movie2);\n    \n    // Create theaters\n    Theater* theater1 = new Theater(\"T001\", \"Cineplex\", \"Downtown\", 100);\n    Theater* theater2 = new Theater(\"T002\", \"MovieMax\", \"Uptown\", 150);\n    \n    system.addTheater(theater1);\n    system.addTheater(theater2);\n    \n    // Create shows\n    Show* show1 = new Show(\"S001\", movie1, \"2024-01-01\", \"18:00\", 12.99, 100);\n    Show* show2 = new Show(\"S002\", movie2, \"2024-01-01\", \"20:00\", 14.99, 150);\n    \n    theater1->addShow(show1);\n    theater2->addShow(show2);\n    \n    // Display available movies and shows\n    system.displayMovies();\n    system.displayShows(\"M001\");\n    \n    // Create a booking\n    std::vector<int> seats = {1, 2, 3};\n    Booking* booking = system.createBooking(\"S001\", \"John Doe\", \"+1-555-0123\", seats);\n    \n    if (booking) {\n        std::cout << \"\\nBooking created successfully!\" << std::endl;\n        system.displayBooking(booking->getBookingId());\n        \n        // Try to book same seats again\n        std::cout << \"\\nTrying to book same seats again...\" << std::endl;\n        Booking* failedBooking = system.createBooking(\"S001\", \"Jane Smith\", \n                                                     \"+1-555-0124\", seats);\n        if (!failedBooking) {\n            std::cout << \"Booking failed: Seats already taken\" << std::endl;\n        }\n        \n        // Cancel booking\n        std::cout << \"\\nCancelling booking...\" << std::endl;\n        if (system.cancelBooking(booking->getBookingId())) {\n            std::cout << \"Booking cancelled successfully!\" << std::endl;\n            system.displayBooking(booking->getBookingId());\n        }\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/BookingSystem.cpp",
    "content": "#include \"BookingSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nBookingSystem::BookingSystem() : bookingIdCounter(1) {}\n\nBookingSystem::~BookingSystem() {\n    for (auto movie : movies) delete movie;\n    for (auto theater : theaters) delete theater;\n    for (auto booking : bookings) delete booking;\n}\n\nvoid BookingSystem::addMovie(Movie* movie) {\n    movies.push_back(movie);\n}\n\nvoid BookingSystem::addTheater(Theater* theater) {\n    theaters.push_back(theater);\n}\n\nBooking* BookingSystem::createBooking(std::string showId, std::string customerName,\n                                    std::string customerPhone, const std::vector<int>& seats) {\n    Show* show = findShow(showId);\n    if (!show || show->getStatus() != ShowStatus::SCHEDULED) {\n        return nullptr;\n    }\n    \n    // Check if all seats are available\n    for (int seatNumber : seats) {\n        if (!show->isSeatAvailable(seatNumber)) {\n            return nullptr;\n        }\n    }\n    \n    // Book all seats\n    for (int seatNumber : seats) {\n        show->bookSeat(seatNumber);\n    }\n    \n    // Create booking\n    Booking* booking = new Booking(generateBookingId(), show, customerName,\n                                 customerPhone, seats);\n    booking->setStatus(BookingStatus::CONFIRMED);\n    bookings.push_back(booking);\n    return booking;\n}\n\nbool BookingSystem::cancelBooking(std::string bookingId) {\n    Booking* booking = findBooking(bookingId);\n    if (!booking || booking->getStatus() == BookingStatus::CANCELLED) {\n        return false;\n    }\n    \n    // Cancel seat bookings\n    Show* show = booking->getShow();\n    for (int seatNumber : booking->getSeatNumbers()) {\n        show->cancelSeatBooking(seatNumber);\n    }\n    \n    booking->setStatus(BookingStatus::CANCELLED);\n    return true;\n}\n\nvoid BookingSystem::displayMovies() const {\n    std::cout << \"\\nAvailable Movies:\" << std::endl;\n    for (const auto& movie : movies) {\n        if (movie->isActive()) {\n            movie->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid BookingSystem::displayTheaters() const {\n    std::cout << \"\\nTheaters:\" << std::endl;\n    for (const auto& theater : theaters) {\n        if (theater->isActive()) {\n            theater->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid BookingSystem::displayShows(std::string movieId) const {\n    std::cout << \"\\nShows for Movie ID \" << movieId << \":\" << std::endl;\n    for (const auto& theater : theaters) {\n        for (const auto& show : theater->getShows()) {\n            if (show->getMovie()->getMovieId() == movieId) {\n                show->displayInfo();\n                std::cout << \"------------------------\" << std::endl;\n            }\n        }\n    }\n}\n\nvoid BookingSystem::displayBooking(std::string bookingId) const {\n    Booking* booking = findBooking(bookingId);\n    if (booking) {\n        booking->displayInfo();\n    }\n}\n\nShow* BookingSystem::findShow(const std::string& showId) const {\n    for (const auto& theater : theaters) {\n        for (const auto& show : theater->getShows()) {\n            if (show->getShowId() == showId) {\n                return show;\n            }\n        }\n    }\n    return nullptr;\n}\n\nBooking* BookingSystem::findBooking(const std::string& bookingId) const {\n    for (auto booking : bookings) {\n        if (booking->getBookingId() == bookingId) {\n            return booking;\n        }\n    }\n    return nullptr;\n}\n\nstd::string BookingSystem::generateBookingId() {\n    return \"B\" + std::to_string(bookingIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/BookingSystem.hpp",
    "content": "#ifndef BOOKING_SYSTEM_HPP\n#define BOOKING_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Movie.hpp\"\n#include \"Theater.hpp\"\n#include \"Show.hpp\"\n#include \"Booking.hpp\"\n\nclass BookingSystem {\nprivate:\n    std::vector<Movie*> movies;\n    std::vector<Theater*> theaters;\n    std::vector<Booking*> bookings;\n    int bookingIdCounter;\n\npublic:\n    BookingSystem();\n    ~BookingSystem();\n    \n    void addMovie(Movie* movie);\n    void addTheater(Theater* theater);\n    \n    Booking* createBooking(std::string showId, std::string customerName,\n                          std::string customerPhone, const std::vector<int>& seats);\n    bool cancelBooking(std::string bookingId);\n    \n    void displayMovies() const;\n    void displayTheaters() const;\n    void displayShows(std::string movieId) const;\n    void displayBooking(std::string bookingId) const;\n    \nprivate:\n    Show* findShow(const std::string& showId) const;\n    Booking* findBooking(const std::string& bookingId) const;\n    std::string generateBookingId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Movie.cpp",
    "content": "#include \"Movie.hpp\"\n#include <iostream>\n\nMovie::Movie(std::string movieId, std::string title, std::string description,\n             MovieGenre genre, int durationMinutes, std::string language)\n    : movieId(movieId), title(title), description(description),\n      genre(genre), durationMinutes(durationMinutes), language(language),\n      active(true) {}\n\nstd::string Movie::getMovieId() const { return movieId; }\nstd::string Movie::getTitle() const { return title; }\nstd::string Movie::getDescription() const { return description; }\nMovieGenre Movie::getGenre() const { return genre; }\nint Movie::getDurationMinutes() const { return durationMinutes; }\nstd::string Movie::getLanguage() const { return language; }\nbool Movie::isActive() const { return active; }\nconst std::vector<std::string>& Movie::getCast() const { return cast; }\n\nvoid Movie::addCastMember(const std::string& actor) {\n    cast.push_back(actor);\n}\n\nvoid Movie::setActive(bool status) {\n    active = status;\n}\n\nvoid Movie::displayInfo() const {\n    std::cout << \"Movie: \" << title << \" (ID: \" << movieId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Genre: \";\n    switch (genre) {\n        case MovieGenre::ACTION: std::cout << \"Action\"; break;\n        case MovieGenre::COMEDY: std::cout << \"Comedy\"; break;\n        case MovieGenre::DRAMA: std::cout << \"Drama\"; break;\n        case MovieGenre::HORROR: std::cout << \"Horror\"; break;\n        case MovieGenre::SCIFI: std::cout << \"Sci-Fi\"; break;\n        case MovieGenre::THRILLER: std::cout << \"Thriller\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Duration: \" << durationMinutes << \" minutes\" << std::endl;\n    std::cout << \"Language: \" << language << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    \n    if (!cast.empty()) {\n        std::cout << \"Cast:\" << std::endl;\n        for (const auto& actor : cast) {\n            std::cout << \"- \" << actor << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Movie.hpp",
    "content": "#ifndef MOVIE_HPP\n#define MOVIE_HPP\n\n#include <string>\n#include <vector>\n\nenum class MovieGenre {\n    ACTION,\n    COMEDY,\n    DRAMA,\n    HORROR,\n    SCIFI,\n    THRILLER\n};\n\nclass Movie {\nprivate:\n    std::string movieId;\n    std::string title;\n    std::string description;\n    MovieGenre genre;\n    int durationMinutes;\n    std::string language;\n    std::vector<std::string> cast;\n    bool active;\n\npublic:\n    Movie(std::string movieId, std::string title, std::string description,\n          MovieGenre genre, int durationMinutes, std::string language);\n    \n    std::string getMovieId() const;\n    std::string getTitle() const;\n    std::string getDescription() const;\n    MovieGenre getGenre() const;\n    int getDurationMinutes() const;\n    std::string getLanguage() const;\n    bool isActive() const;\n    const std::vector<std::string>& getCast() const;\n    \n    void addCastMember(const std::string& actor);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/README.md",
    "content": "# Designing a Movie Ticket Booking System like BookMyShow\n\n## Requirements\n1. The system should allow users to view the list of movies playing in different theaters.\n2. Users should be able to select a movie, theater, and show timing to book tickets.\n3. The system should display the seating arrangement of the selected show and allow users to choose seats.\n4. Users should be able to make payments and confirm their booking.\n5. The system should handle concurrent bookings and ensure seat availability is updated in real-time.\n6. The system should support different types of seats (e.g., normal, premium) and pricing.\n7. The system should allow theater administrators to add, update, and remove movies, shows, and seating arrangements.\n8. The system should be scalable to handle a large number of concurrent users and bookings.\n\n## Classes, Interfaces and Enumerations\n1. The **Movie** class represents a movie with properties such as ID, title, description, and duration.\n2. The **Theater** class represents a theater with properties such as ID, name, location, and a list of shows.\n3. The **Show** class represents a movie show in a theater, with properties such as ID, movie, theater, start time, end time, and a map of seats.\n4. The **Seat** class represents a seat in a show, with properties such as ID, row, column, type, price, and status.\n5. The **SeatType** enum defines the different types of seats (normal or premium).\n6. The **SeatStatus** enum defines the different statuses of a seat (available or booked).\n7. The **Booking** class represents a booking made by a user, with properties such as ID, user, show, selected seats, total price, and status.\n8. The **BookingStatus** enum defines the different statuses of a booking (pending, confirmed, or cancelled).\n9. The **User** class represents a user of the booking system, with properties such as ID, name, and email.\n10. The **MovieTicketBookingSystem** class is the main class that manages the movie ticket booking system. It follows the Singleton pattern to ensure only one instance of the system exists.\n11. The MovieTicketBookingSystem class provides methods for adding movies, theaters, and shows, as well as booking tickets, confirming bookings, and cancelling bookings.\n12. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap to handle concurrent access to shared resources like shows and bookings.\n13. The **MovieTicketBookingDemo** class demonstrates the usage of the movie ticket booking system by adding movies, theaters, shows, booking tickets, and confirming or cancelling bookings."
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Show.cpp",
    "content": "#include \"Show.hpp\"\n#include <iostream>\n#include <iomanip>\n\nShow::Show(std::string showId, Movie* movie, std::string date,\n           std::string startTime, double ticketPrice, int totalSeats)\n    : showId(showId), movie(movie), date(date), startTime(startTime),\n      ticketPrice(ticketPrice), seats(totalSeats, false),\n      status(ShowStatus::SCHEDULED) {}\n\nstd::string Show::getShowId() const { return showId; }\nMovie* Show::getMovie() const { return movie; }\nstd::string Show::getDate() const { return date; }\nstd::string Show::getStartTime() const { return startTime; }\ndouble Show::getTicketPrice() const { return ticketPrice; }\nShowStatus Show::getStatus() const { return status; }\n\nbool Show::isSeatAvailable(int seatNumber) const {\n    if (seatNumber < 1 || seatNumber > seats.size()) return false;\n    return !seats[seatNumber - 1];\n}\n\nbool Show::bookSeat(int seatNumber) {\n    if (!isSeatAvailable(seatNumber)) return false;\n    seats[seatNumber - 1] = true;\n    return true;\n}\n\nvoid Show::cancelSeatBooking(int seatNumber) {\n    if (seatNumber >= 1 && seatNumber <= seats.size()) {\n        seats[seatNumber - 1] = false;\n    }\n}\n\nvoid Show::setStatus(ShowStatus status) {\n    this->status = status;\n}\n\nint Show::getAvailableSeats() const {\n    int count = 0;\n    for (bool seat : seats) {\n        if (!seat) count++;\n    }\n    return count;\n}\n\nvoid Show::displayInfo() const {\n    std::cout << \"\\nShow Details:\" << std::endl;\n    std::cout << \"Show ID: \" << showId << std::endl;\n    movie->displayInfo();\n    std::cout << \"Date: \" << date << std::endl;\n    std::cout << \"Start Time: \" << startTime << std::endl;\n    std::cout << \"Ticket Price: $\" << std::fixed << std::setprecision(2) \n              << ticketPrice << std::endl;\n    std::cout << \"Available Seats: \" << getAvailableSeats() \n              << \"/\" << seats.size() << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case ShowStatus::SCHEDULED: std::cout << \"Scheduled\"; break;\n        case ShowStatus::RUNNING: std::cout << \"Running\"; break;\n        case ShowStatus::COMPLETED: std::cout << \"Completed\"; break;\n        case ShowStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Show.hpp",
    "content": "#ifndef SHOW_HPP\n#define SHOW_HPP\n\n#include <string>\n#include <vector>\n#include \"Movie.hpp\"\n\nenum class ShowStatus {\n    SCHEDULED,\n    RUNNING,\n    COMPLETED,\n    CANCELLED\n};\n\nclass Show {\nprivate:\n    std::string showId;\n    Movie* movie;\n    std::string date;\n    std::string startTime;\n    double ticketPrice;\n    std::vector<bool> seats;  // true if seat is booked\n    ShowStatus status;\n\npublic:\n    Show(std::string showId, Movie* movie, std::string date,\n         std::string startTime, double ticketPrice, int totalSeats);\n    \n    std::string getShowId() const;\n    Movie* getMovie() const;\n    std::string getDate() const;\n    std::string getStartTime() const;\n    double getTicketPrice() const;\n    ShowStatus getStatus() const;\n    \n    bool isSeatAvailable(int seatNumber) const;\n    bool bookSeat(int seatNumber);\n    void cancelSeatBooking(int seatNumber);\n    void setStatus(ShowStatus status);\n    int getAvailableSeats() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Theater.cpp",
    "content": "#include \"Theater.hpp\"\n#include <iostream>\n#include <algorithm>\n\nTheater::Theater(std::string theaterId, std::string name, std::string location,\n                int totalSeats)\n    : theaterId(theaterId), name(name), location(location),\n      totalSeats(totalSeats), active(true) {}\n\nTheater::~Theater() {\n    for (auto show : shows) {\n        delete show;\n    }\n}\n\nstd::string Theater::getTheaterId() const { return theaterId; }\nstd::string Theater::getName() const { return name; }\nstd::string Theater::getLocation() const { return location; }\nint Theater::getTotalSeats() const { return totalSeats; }\nbool Theater::isActive() const { return active; }\nconst std::vector<Show*>& Theater::getShows() const { return shows; }\n\nvoid Theater::addShow(Show* show) {\n    shows.push_back(show);\n}\n\nvoid Theater::removeShow(Show* show) {\n    auto it = std::find(shows.begin(), shows.end(), show);\n    if (it != shows.end()) {\n        shows.erase(it);\n    }\n}\n\nvoid Theater::setActive(bool status) {\n    active = status;\n}\n\nvoid Theater::displayInfo() const {\n    std::cout << \"Theater: \" << name << \" (ID: \" << theaterId << \")\" << std::endl;\n    std::cout << \"Location: \" << location << std::endl;\n    std::cout << \"Total Seats: \" << totalSeats << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Number of Shows: \" << shows.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/movieticketbookingsystem/Theater.hpp",
    "content": "#ifndef THEATER_HPP\n#define THEATER_HPP\n\n#include <string>\n#include <vector>\n#include \"Show.hpp\"\n\nclass Theater {\nprivate:\n    std::string theaterId;\n    std::string name;\n    std::string location;\n    int totalSeats;\n    std::vector<Show*> shows;\n    bool active;\n\npublic:\n    Theater(std::string theaterId, std::string name, std::string location,\n           int totalSeats);\n    ~Theater();\n    \n    std::string getTheaterId() const;\n    std::string getName() const;\n    std::string getLocation() const;\n    int getTotalSeats() const;\n    bool isActive() const;\n    const std::vector<Show*>& getShows() const;\n    \n    void addShow(Show* show);\n    void removeShow(Show* show);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Artist.cpp",
    "content": "#include \"Artist.hpp\"\n#include <iostream>\n#include <algorithm>\n\nArtist::Artist(std::string artistId, std::string name, std::string bio)\n    : artistId(artistId), name(name), bio(bio), active(true) {}\n\nArtist::~Artist() {\n    for (auto song : songs) {\n        delete song;\n    }\n}\n\nstd::string Artist::getArtistId() const { return artistId; }\nstd::string Artist::getName() const { return name; }\nstd::string Artist::getBio() const { return bio; }\nbool Artist::isActive() const { return active; }\nconst std::vector<Song*>& Artist::getSongs() const { return songs; }\n\nvoid Artist::addSong(Song* song) {\n    songs.push_back(song);\n}\n\nvoid Artist::removeSong(Song* song) {\n    auto it = std::find(songs.begin(), songs.end(), song);\n    if (it != songs.end()) {\n        delete *it;\n        songs.erase(it);\n    }\n}\n\nvoid Artist::setActive(bool status) {\n    active = status;\n}\n\nvoid Artist::displayInfo() const {\n    std::cout << \"Artist: \" << name << \" (ID: \" << artistId << \")\" << std::endl;\n    std::cout << \"Bio: \" << bio << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Number of Songs: \" << songs.size() << std::endl;\n    \n    if (!songs.empty()) {\n        std::cout << \"\\nSongs:\" << std::endl;\n        for (const auto& song : songs) {\n            std::cout << \"- \" << song->getTitle() << \" (\" << song->getAlbum() << \")\" << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Artist.hpp",
    "content": "#ifndef ARTIST_HPP\n#define ARTIST_HPP\n\n#include <string>\n#include <vector>\n#include \"Song.hpp\"\n\nclass Artist {\nprivate:\n    std::string artistId;\n    std::string name;\n    std::string bio;\n    std::vector<Song*> songs;\n    bool active;\n\npublic:\n    Artist(std::string artistId, std::string name, std::string bio);\n    ~Artist();\n    \n    std::string getArtistId() const;\n    std::string getName() const;\n    std::string getBio() const;\n    bool isActive() const;\n    const std::vector<Song*>& getSongs() const;\n    \n    void addSong(Song* song);\n    void removeSong(Song* song);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/MusicStreamingDemo.cpp",
    "content": "#include \"MusicStreamingService.hpp\"\n#include <iostream>\n\nint main() {\n    MusicStreamingService service;\n    \n    // Create users\n    User* user1 = new User(\"U001\", \"john_doe\", \"john@email.com\");\n    User* user2 = new User(\"U002\", \"jane_smith\", \"jane@email.com\", UserType::PREMIUM);\n    service.addUser(user1);\n    service.addUser(user2);\n    \n    // Create artists\n    Artist* artist1 = new Artist(\"A001\", \"The Beatles\", \"Legendary British rock band\");\n    Artist* artist2 = new Artist(\"A002\", \"Queen\", \"Iconic rock band led by Freddie Mercury\");\n    service.addArtist(artist1);\n    service.addArtist(artist2);\n    \n    // Add songs\n    Song* song1 = new Song(\"S001\", \"Hey Jude\", \"The Beatles\", \"The Beatles\", \n                          Genre::ROCK, 431, \"path/to/hey_jude.mp3\");\n    Song* song2 = new Song(\"S002\", \"Let It Be\", \"The Beatles\", \"Let It Be\",\n                          Genre::ROCK, 243, \"path/to/let_it_be.mp3\");\n    Song* song3 = new Song(\"S003\", \"Bohemian Rhapsody\", \"Queen\", \"A Night at the Opera\",\n                          Genre::ROCK, 354, \"path/to/bohemian_rhapsody.mp3\");\n    \n    service.addSong(song1, \"A001\");\n    service.addSong(song2, \"A001\");\n    service.addSong(song3, \"A002\");\n    \n    // Display all songs and artists\n    std::cout << \"Initial catalog:\" << std::endl;\n    service.displayAllSongs();\n    service.displayAllArtists();\n    \n    // Create playlists\n    Playlist* playlist1 = service.createPlaylist(\"U001\", \"Rock Classics\",\n                                               \"Best rock songs of all time\");\n    if (playlist1) {\n        service.addSongToPlaylist(playlist1->getPlaylistId(), \"S001\");\n        service.addSongToPlaylist(playlist1->getPlaylistId(), \"S003\");\n    }\n    \n    Playlist* playlist2 = service.createPlaylist(\"U002\", \"Beatles Only\",\n                                               \"Beatles songs collection\", false);\n    if (playlist2) {\n        service.addSongToPlaylist(playlist2->getPlaylistId(), \"S001\");\n        service.addSongToPlaylist(playlist2->getPlaylistId(), \"S002\");\n    }\n    \n    // Display user playlists\n    std::cout << \"\\nUser Playlists:\" << std::endl;\n    service.displayUserPlaylists(\"U001\");\n    service.displayUserPlaylists(\"U002\");\n    \n    // Search functionality\n    std::cout << \"\\nSearching for 'Beatles':\" << std::endl;\n    auto songResults = service.searchSongs(\"Beatles\");\n    for (const auto& song : songResults) {\n        song->displayInfo();\n    }\n    \n    // Remove song from playlist\n    std::cout << \"\\nRemoving 'Hey Jude' from Rock Classics playlist...\" << std::endl;\n    if (service.removeSongFromPlaylist(playlist1->getPlaylistId(), \"S001\")) {\n        std::cout << \"Song removed successfully\" << std::endl;\n        service.displayUserPlaylists(\"U001\");\n    }\n    \n    // Upgrade user to premium\n    std::cout << \"\\nUpgrading user john_doe to premium...\" << std::endl;\n    user1->upgradeToPremuim();\n    user1->displayInfo();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/MusicStreamingService.cpp",
    "content": "#include \"MusicStreamingService.hpp\"\n#include <iostream>\n#include <algorithm>\n\nMusicStreamingService::MusicStreamingService() : playlistIdCounter(1) {}\n\nMusicStreamingService::~MusicStreamingService() {\n    for (auto user : users) delete user;\n    for (auto artist : artists) delete artist;\n    for (auto song : songs) delete song;\n}\n\nvoid MusicStreamingService::addUser(User* user) {\n    users.push_back(user);\n}\n\nvoid MusicStreamingService::addArtist(Artist* artist) {\n    artists.push_back(artist);\n}\n\nvoid MusicStreamingService::addSong(Song* song, std::string artistId) {\n    Artist* artist = findArtist(artistId);\n    if (artist && artist->isActive()) {\n        songs.push_back(song);\n        artist->addSong(song);\n    }\n}\n\nPlaylist* MusicStreamingService::createPlaylist(std::string userId, std::string name,\n                                              std::string description, bool isPublic) {\n    User* user = findUser(userId);\n    if (!user || !user->isActive()) return nullptr;\n    \n    Playlist* playlist = new Playlist(generatePlaylistId(), name, description, isPublic);\n    user->addPlaylist(playlist);\n    return playlist;\n}\n\nbool MusicStreamingService::addSongToPlaylist(std::string playlistId, std::string songId) {\n    Playlist* playlist = findPlaylist(playlistId);\n    Song* song = findSong(songId);\n    \n    if (playlist && song && song->isActive()) {\n        playlist->addSong(song);\n        return true;\n    }\n    return false;\n}\n\nbool MusicStreamingService::removeSongFromPlaylist(std::string playlistId, std::string songId) {\n    Playlist* playlist = findPlaylist(playlistId);\n    Song* song = findSong(songId);\n    \n    if (playlist && song) {\n        playlist->removeSong(song);\n        return true;\n    }\n    return false;\n}\n\nstd::vector<Song*> MusicStreamingService::searchSongs(const std::string& query) const {\n    std::vector<Song*> results;\n    for (auto song : songs) {\n        if (song->isActive() && \n            (song->getTitle().find(query) != std::string::npos ||\n             song->getArtist().find(query) != std::string::npos ||\n             song->getAlbum().find(query) != std::string::npos)) {\n            results.push_back(song);\n        }\n    }\n    return results;\n}\n\nstd::vector<Artist*> MusicStreamingService::searchArtists(const std::string& query) const {\n    std::vector<Artist*> results;\n    for (auto artist : artists) {\n        if (artist->isActive() && \n            (artist->getName().find(query) != std::string::npos ||\n             artist->getBio().find(query) != std::string::npos)) {\n            results.push_back(artist);\n        }\n    }\n    return results;\n}\n\nstd::vector<Playlist*> MusicStreamingService::searchPlaylists(const std::string& query) const {\n    std::vector<Playlist*> results;\n    for (auto user : users) {\n        for (auto playlist : user->getPlaylists()) {\n            if (playlist->getIsPublic() && \n                (playlist->getName().find(query) != std::string::npos ||\n                 playlist->getDescription().find(query) != std::string::npos)) {\n                results.push_back(playlist);\n            }\n        }\n    }\n    return results;\n}\n\nvoid MusicStreamingService::displayAllSongs() const {\n    std::cout << \"\\nAll Songs:\" << std::endl;\n    for (const auto& song : songs) {\n        if (song->isActive()) {\n            song->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid MusicStreamingService::displayAllArtists() const {\n    std::cout << \"\\nAll Artists:\" << std::endl;\n    for (const auto& artist : artists) {\n        if (artist->isActive()) {\n            artist->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid MusicStreamingService::displayUserPlaylists(std::string userId) const {\n    User* user = findUser(userId);\n    if (user && user->isActive()) {\n        std::cout << \"\\nPlaylists for user \" << user->getUsername() << \":\" << std::endl;\n        for (const auto& playlist : user->getPlaylists()) {\n            playlist->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nvoid MusicStreamingService::displayArtistSongs(std::string artistId) const {\n    Artist* artist = findArtist(artistId);\n    if (artist && artist->isActive()) {\n        artist->displayInfo();\n    }\n}\n\nUser* MusicStreamingService::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [&userId](const User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nArtist* MusicStreamingService::findArtist(const std::string& artistId) const {\n    auto it = std::find_if(artists.begin(), artists.end(),\n        [&artistId](const Artist* artist) { return artist->getArtistId() == artistId; });\n    return it != artists.end() ? *it : nullptr;\n}\n\nSong* MusicStreamingService::findSong(const std::string& songId) const {\n    auto it = std::find_if(songs.begin(), songs.end(),\n        [&songId](const Song* song) { return song->getSongId() == songId; });\n    return it != songs.end() ? *it : nullptr;\n}\n\nPlaylist* MusicStreamingService::findPlaylist(const std::string& playlistId) const {\n    for (const auto& user : users) {\n        for (const auto& playlist : user->getPlaylists()) {\n            if (playlist->getPlaylistId() == playlistId) {\n                return playlist;\n            }\n        }\n    }\n    return nullptr;\n}\n\nstd::string MusicStreamingService::generatePlaylistId() {\n    return \"P\" + std::to_string(playlistIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/MusicStreamingService.hpp",
    "content": "#ifndef MUSIC_STREAMING_SERVICE_HPP\n#define MUSIC_STREAMING_SERVICE_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Artist.hpp\"\n#include \"Song.hpp\"\n#include \"Playlist.hpp\"\n\nclass MusicStreamingService {\nprivate:\n    std::vector<User*> users;\n    std::vector<Artist*> artists;\n    std::vector<Song*> songs;\n    int playlistIdCounter;\n\npublic:\n    MusicStreamingService();\n    ~MusicStreamingService();\n    \n    void addUser(User* user);\n    void addArtist(Artist* artist);\n    void addSong(Song* song, std::string artistId);\n    \n    Playlist* createPlaylist(std::string userId, std::string name,\n                           std::string description, bool isPublic = true);\n    bool addSongToPlaylist(std::string playlistId, std::string songId);\n    bool removeSongFromPlaylist(std::string playlistId, std::string songId);\n    \n    std::vector<Song*> searchSongs(const std::string& query) const;\n    std::vector<Artist*> searchArtists(const std::string& query) const;\n    std::vector<Playlist*> searchPlaylists(const std::string& query) const;\n    \n    void displayAllSongs() const;\n    void displayAllArtists() const;\n    void displayUserPlaylists(std::string userId) const;\n    void displayArtistSongs(std::string artistId) const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Artist* findArtist(const std::string& artistId) const;\n    Song* findSong(const std::string& songId) const;\n    Playlist* findPlaylist(const std::string& playlistId) const;\n    std::string generatePlaylistId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Playlist.cpp",
    "content": "#include \"Playlist.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <algorithm>\n\nPlaylist::Playlist(std::string playlistId, std::string name, std::string description,\n                  bool isPublic)\n    : playlistId(playlistId), name(name), description(description),\n      isPublic(isPublic) {}\n\nstd::string Playlist::getPlaylistId() const { return playlistId; }\nstd::string Playlist::getName() const { return name; }\nstd::string Playlist::getDescription() const { return description; }\nbool Playlist::getIsPublic() const { return isPublic; }\nconst std::vector<Song*>& Playlist::getSongs() const { return songs; }\n\nvoid Playlist::addSong(Song* song) {\n    if (song && song->isActive()) {\n        songs.push_back(song);\n    }\n}\n\nvoid Playlist::removeSong(Song* song) {\n    auto it = std::find(songs.begin(), songs.end(), song);\n    if (it != songs.end()) {\n        songs.erase(it);\n    }\n}\n\nvoid Playlist::setPublic(bool isPublic) {\n    this->isPublic = isPublic;\n}\n\nint Playlist::getTotalDuration() const {\n    int total = 0;\n    for (const auto& song : songs) {\n        total += song->getDurationSeconds();\n    }\n    return total;\n}\n\nvoid Playlist::displayInfo() const {\n    std::cout << \"\\nPlaylist: \" << name << \" (ID: \" << playlistId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Visibility: \" << (isPublic ? \"Public\" : \"Private\") << std::endl;\n    std::cout << \"Number of Songs: \" << songs.size() << std::endl;\n    \n    int totalDuration = getTotalDuration();\n    int minutes = totalDuration / 60;\n    int seconds = totalDuration % 60;\n    std::cout << \"Total Duration: \" << minutes << \":\" \n              << std::setfill('0') << std::setw(2) << seconds << std::endl;\n    \n    if (!songs.empty()) {\n        std::cout << \"\\nSongs:\" << std::endl;\n        for (const auto& song : songs) {\n            std::cout << \"- \" << song->getTitle() << \" by \" << song->getArtist() << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Playlist.hpp",
    "content": "#ifndef PLAYLIST_HPP\n#define PLAYLIST_HPP\n\n#include <string>\n#include <vector>\n#include \"Song.hpp\"\n\nclass Playlist {\nprivate:\n    std::string playlistId;\n    std::string name;\n    std::string description;\n    std::vector<Song*> songs;\n    bool isPublic;\n\npublic:\n    Playlist(std::string playlistId, std::string name, std::string description,\n            bool isPublic = true);\n    \n    std::string getPlaylistId() const;\n    std::string getName() const;\n    std::string getDescription() const;\n    bool getIsPublic() const;\n    const std::vector<Song*>& getSongs() const;\n    \n    void addSong(Song* song);\n    void removeSong(Song* song);\n    void setPublic(bool isPublic);\n    int getTotalDuration() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/README.md",
    "content": "# Designing an Online Music Streaming Service Like Spotify\n\n## Requirements\n1. The music streaming service should allow users to browse and search for songs, albums, and artists.\n2. Users should be able to create and manage playlists.\n3. The system should support user authentication and authorization.\n4. Users should be able to play, pause, skip, and seek within songs.\n5. The system should recommend songs and playlists based on user preferences and listening history.\n6. The system should handle concurrent requests and ensure smooth streaming experience for multiple users.\n7. The system should be scalable and handle a large volume of songs and users.\n8. The system should be extensible to support additional features such as social sharing and offline playback.\n\n## Classes, Interfaces and Enumerations\n1. The **Song**, **Album**, and **Artist** classes represent the basic entities in the music streaming service, with properties such as ID, title, artist, album, duration, and relationships between them.\n2. The **User** class represents a user of the music streaming service, with properties like ID, username, password, and a list of playlists.\n3. The **Playlist** class represents a user-created playlist, containing a list of songs.\n4. The **MusicLibrary** class serves as a central repository for storing and managing songs, albums, and artists. It follows the Singleton pattern to ensure a single instance of the music library.\n5. The **UserManager** class handles user registration, login, and other user-related operations. It also follows the Singleton pattern.\n6. The **MusicPlayer** class represents the music playback functionality, allowing users to play, pause, skip, and seek within songs.\n7. The **MusicRecommender** class generates song recommendations based on user preferences and listening history. It follows the Singleton pattern.\n8. The **MusicStreamingService** class is the main entry point of the music streaming service. It initializes the necessary components, handles user requests, and manages the overall functionality of the service."
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Song.cpp",
    "content": "#include \"Song.hpp\"\n#include <iostream>\n#include <iomanip>\n\nSong::Song(std::string songId, std::string title, std::string artist,\n           std::string album, Genre genre, int durationSeconds,\n           std::string filePath)\n    : songId(songId), title(title), artist(artist), album(album),\n      genre(genre), durationSeconds(durationSeconds), filePath(filePath),\n      active(true) {}\n\nstd::string Song::getSongId() const { return songId; }\nstd::string Song::getTitle() const { return title; }\nstd::string Song::getArtist() const { return artist; }\nstd::string Song::getAlbum() const { return album; }\nGenre Song::getGenre() const { return genre; }\nint Song::getDurationSeconds() const { return durationSeconds; }\nstd::string Song::getFilePath() const { return filePath; }\nbool Song::isActive() const { return active; }\n\nvoid Song::setActive(bool status) {\n    active = status;\n}\n\nvoid Song::displayInfo() const {\n    std::cout << \"Song: \" << title << \" (ID: \" << songId << \")\" << std::endl;\n    std::cout << \"Artist: \" << artist << std::endl;\n    std::cout << \"Album: \" << album << std::endl;\n    std::cout << \"Genre: \";\n    switch (genre) {\n        case Genre::POP: std::cout << \"Pop\"; break;\n        case Genre::ROCK: std::cout << \"Rock\"; break;\n        case Genre::JAZZ: std::cout << \"Jazz\"; break;\n        case Genre::CLASSICAL: std::cout << \"Classical\"; break;\n        case Genre::HIPHOP: std::cout << \"Hip Hop\"; break;\n        case Genre::ELECTRONIC: std::cout << \"Electronic\"; break;\n    }\n    std::cout << std::endl;\n    \n    int minutes = durationSeconds / 60;\n    int seconds = durationSeconds % 60;\n    std::cout << \"Duration: \" << minutes << \":\" \n              << std::setfill('0') << std::setw(2) << seconds << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/Song.hpp",
    "content": "#ifndef SONG_HPP\n#define SONG_HPP\n\n#include <string>\n#include <vector>\n\nenum class Genre {\n    POP,\n    ROCK,\n    JAZZ,\n    CLASSICAL,\n    HIPHOP,\n    ELECTRONIC\n};\n\nclass Song {\nprivate:\n    std::string songId;\n    std::string title;\n    std::string artist;\n    std::string album;\n    Genre genre;\n    int durationSeconds;\n    std::string filePath;\n    bool active;\n\npublic:\n    Song(std::string songId, std::string title, std::string artist,\n         std::string album, Genre genre, int durationSeconds,\n         std::string filePath);\n    \n    std::string getSongId() const;\n    std::string getTitle() const;\n    std::string getArtist() const;\n    std::string getAlbum() const;\n    Genre getGenre() const;\n    int getDurationSeconds() const;\n    std::string getFilePath() const;\n    bool isActive() const;\n    \n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <algorithm>\n\nUser::User(std::string userId, std::string username, std::string email,\n           UserType type)\n    : userId(userId), username(username), email(email), type(type),\n      active(true) {}\n\nUser::~User() {\n    for (auto playlist : playlists) {\n        delete playlist;\n    }\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\nUserType User::getType() const { return type; }\nbool User::isActive() const { return active; }\nconst std::vector<Playlist*>& User::getPlaylists() const { return playlists; }\n\nvoid User::addPlaylist(Playlist* playlist) {\n    playlists.push_back(playlist);\n}\n\nvoid User::removePlaylist(Playlist* playlist) {\n    auto it = std::find(playlists.begin(), playlists.end(), playlist);\n    if (it != playlists.end()) {\n        delete *it;\n        playlists.erase(it);\n    }\n}\n\nvoid User::upgradeToPremuim() {\n    type = UserType::PREMIUM;\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Type: \" << (type == UserType::PREMIUM ? \"Premium\" : \"Free\") << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Number of Playlists: \" << playlists.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/musicstreamingservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include \"Playlist.hpp\"\n\nenum class UserType {\n    FREE,\n    PREMIUM\n};\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    UserType type;\n    std::vector<Playlist*> playlists;\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email,\n         UserType type = UserType::FREE);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    UserType getType() const;\n    bool isActive() const;\n    const std::vector<Playlist*>& getPlaylists() const;\n    \n    void addPlaylist(Playlist* playlist);\n    void removePlaylist(Playlist* playlist);\n    void upgradeToPremuim();\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/Auction.cpp",
    "content": "#include \"Auction.hpp\"\n#include <iostream>\n#include <iomanip>\n\nAuction::Auction(std::string auctionId, Item* item, std::time_t startTime,\n                std::time_t endTime)\n    : auctionId(auctionId), item(item), startTime(startTime), endTime(endTime),\n      currentPrice(item->getStartingPrice()), status(AuctionStatus::PENDING) {}\n\nstd::string Auction::getAuctionId() const { return auctionId; }\nItem* Auction::getItem() const { return item; }\nstd::time_t Auction::getStartTime() const { return startTime; }\nstd::time_t Auction::getEndTime() const { return endTime; }\ndouble Auction::getCurrentPrice() const { return currentPrice; }\nAuctionStatus Auction::getStatus() const { return status; }\nstd::string Auction::getWinnerId() const { return winnerId; }\nconst std::vector<Bid>& Auction::getBids() const { return bids; }\n\nbool Auction::placeBid(const std::string& bidderId, double amount) {\n    if (status != AuctionStatus::ACTIVE || amount <= currentPrice) {\n        return false;\n    }\n    \n    bids.emplace_back(bidderId, amount);\n    currentPrice = amount;\n    winnerId = bidderId;\n    return true;\n}\n\nvoid Auction::start() {\n    if (status == AuctionStatus::PENDING) {\n        status = AuctionStatus::ACTIVE;\n        item->setStatus(ItemStatus::IN_AUCTION);\n    }\n}\n\nvoid Auction::end() {\n    if (status == AuctionStatus::ACTIVE) {\n        status = AuctionStatus::ENDED;\n        item->setStatus(ItemStatus::SOLD);\n    }\n}\n\nvoid Auction::cancel() {\n    status = AuctionStatus::CANCELLED;\n    item->setStatus(ItemStatus::AVAILABLE);\n    winnerId.clear();\n}\n\nbool Auction::isActive() const {\n    return status == AuctionStatus::ACTIVE;\n}\n\nvoid Auction::displayInfo() const {\n    std::cout << \"\\nAuction Details:\" << std::endl;\n    std::cout << \"Auction ID: \" << auctionId << std::endl;\n    item->displayInfo();\n    \n    std::cout << \"Start Time: \" << std::ctime(&startTime);\n    std::cout << \"End Time: \" << std::ctime(&endTime);\n    std::cout << \"Current Price: $\" << std::fixed << std::setprecision(2) \n              << currentPrice << std::endl;\n    \n    std::cout << \"Status: \";\n    switch (status) {\n        case AuctionStatus::PENDING: std::cout << \"Pending\"; break;\n        case AuctionStatus::ACTIVE: std::cout << \"Active\"; break;\n        case AuctionStatus::ENDED: std::cout << \"Ended\"; break;\n        case AuctionStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n    \n    if (!bids.empty()) {\n        std::cout << \"\\nBid History:\" << std::endl;\n        for (const auto& bid : bids) {\n            std::cout << \"Bidder: \" << bid.bidderId \n                      << \", Amount: $\" << std::fixed << std::setprecision(2) \n                      << bid.amount \n                      << \", Time: \" << std::ctime(&bid.timestamp);\n        }\n    }\n    \n    if (!winnerId.empty()) {\n        std::cout << \"Winner ID: \" << winnerId << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/Auction.hpp",
    "content": "#ifndef AUCTION_HPP\n#define AUCTION_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n#include \"Item.hpp\"\n#include \"User.hpp\"\n\nstruct Bid {\n    std::string bidderId;\n    double amount;\n    std::time_t timestamp;\n    \n    Bid(std::string bidderId, double amount)\n        : bidderId(bidderId), amount(amount), timestamp(std::time(nullptr)) {}\n};\n\nenum class AuctionStatus {\n    PENDING,\n    ACTIVE,\n    ENDED,\n    CANCELLED\n};\n\nclass Auction {\nprivate:\n    std::string auctionId;\n    Item* item;\n    std::time_t startTime;\n    std::time_t endTime;\n    double currentPrice;\n    std::vector<Bid> bids;\n    AuctionStatus status;\n    std::string winnerId;\n\npublic:\n    Auction(std::string auctionId, Item* item, std::time_t startTime,\n           std::time_t endTime);\n    \n    std::string getAuctionId() const;\n    Item* getItem() const;\n    std::time_t getStartTime() const;\n    std::time_t getEndTime() const;\n    double getCurrentPrice() const;\n    AuctionStatus getStatus() const;\n    std::string getWinnerId() const;\n    const std::vector<Bid>& getBids() const;\n    \n    bool placeBid(const std::string& bidderId, double amount);\n    void start();\n    void end();\n    void cancel();\n    bool isActive() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/AuctionSystem.cpp",
    "content": "#include \"AuctionSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nAuctionSystem::AuctionSystem() : itemIdCounter(1), auctionIdCounter(1) {}\n\nAuctionSystem::~AuctionSystem() {\n    for (auto user : users) delete user;\n    for (auto item : items) delete item;\n    for (auto auction : auctions) delete auction;\n}\n\nUser* AuctionSystem::registerUser(std::string username, std::string email) {\n    std::string userId = \"U\" + std::to_string(users.size() + 1);\n    User* user = new User(userId, username, email);\n    users.push_back(user);\n    return user;\n}\n\nItem* AuctionSystem::createItem(std::string sellerId, std::string name, std::string description,\n                              ItemCategory category, double startingPrice) {\n    User* seller = findUser(sellerId);\n    if (!seller || !seller->isActive()) return nullptr;\n    \n    Item* item = new Item(generateItemId(), name, description, category,\n                         startingPrice, sellerId);\n    items.push_back(item);\n    seller->addListedItem(item);\n    return item;\n}\n\nAuction* AuctionSystem::createAuction(std::string itemId, std::time_t startTime,\n                                    std::time_t endTime) {\n    Item* item = findItem(itemId);\n    if (!item || item->getStatus() != ItemStatus::AVAILABLE) return nullptr;\n    \n    Auction* auction = new Auction(generateAuctionId(), item, startTime, endTime);\n    auctions.push_back(auction);\n    return auction;\n}\n\nbool AuctionSystem::placeBid(std::string auctionId, std::string bidderId, double amount) {\n    Auction* auction = findAuction(auctionId);\n    User* bidder = findUser(bidderId);\n    \n    if (!auction || !bidder || !bidder->isActive() || !auction->isActive() ||\n        bidder->getBalance() < amount) {\n        return false;\n    }\n    \n    if (auction->placeBid(bidderId, amount)) {\n        bidder->deductBalance(amount);\n        return true;\n    }\n    return false;\n}\n\nbool AuctionSystem::addUserBalance(std::string userId, double amount) {\n    User* user = findUser(userId);\n    if (user && user->isActive()) {\n        user->addBalance(amount);\n        return true;\n    }\n    return false;\n}\n\nvoid AuctionSystem::startAuction(std::string auctionId) {\n    Auction* auction = findAuction(auctionId);\n    if (auction) auction->start();\n}\n\nvoid AuctionSystem::endAuction(std::string auctionId) {\n    Auction* auction = findAuction(auctionId);\n    if (auction) {\n        auction->end();\n        if (!auction->getWinnerId().empty()) {\n            User* winner = findUser(auction->getWinnerId());\n            if (winner) {\n                winner->addPurchasedItem(auction->getItem());\n            }\n        }\n    }\n}\n\nvoid AuctionSystem::cancelAuction(std::string auctionId) {\n    Auction* auction = findAuction(auctionId);\n    if (auction) auction->cancel();\n}\n\nstd::vector<Auction*> AuctionSystem::getActiveAuctions() const {\n    std::vector<Auction*> activeAuctions;\n    for (auto auction : auctions) {\n        if (auction->isActive()) {\n            activeAuctions.push_back(auction);\n        }\n    }\n    return activeAuctions;\n}\n\nstd::vector<Item*> AuctionSystem::searchItems(const std::string& query) const {\n    std::vector<Item*> results;\n    for (auto item : items) {\n        if (item->getStatus() == ItemStatus::AVAILABLE &&\n            (item->getName().find(query) != std::string::npos ||\n             item->getDescription().find(query) != std::string::npos)) {\n            results.push_back(item);\n        }\n    }\n    return results;\n}\n\nvoid AuctionSystem::displayUserInfo(std::string userId) const {\n    User* user = findUser(userId);\n    if (user) user->displayInfo();\n}\n\nvoid AuctionSystem::displayItemInfo(std::string itemId) const {\n    Item* item = findItem(itemId);\n    if (item) item->displayInfo();\n}\n\nvoid AuctionSystem::displayAuctionInfo(std::string auctionId) const {\n    Auction* auction = findAuction(auctionId);\n    if (auction) auction->displayInfo();\n}\n\nvoid AuctionSystem::displayAllAuctions() const {\n    std::cout << \"\\nAll Auctions:\" << std::endl;\n    for (const auto& auction : auctions) {\n        auction->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nUser* AuctionSystem::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [&userId](const User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nItem* AuctionSystem::findItem(const std::string& itemId) const {\n    auto it = std::find_if(items.begin(), items.end(),\n        [&itemId](const Item* item) { return item->getItemId() == itemId; });\n    return it != items.end() ? *it : nullptr;\n}\n\nAuction* AuctionSystem::findAuction(const std::string& auctionId) const {\n    auto it = std::find_if(auctions.begin(), auctions.end(),\n        [&auctionId](const Auction* auction) { return auction->getAuctionId() == auctionId; });\n    return it != auctions.end() ? *it : nullptr;\n}\n\nstd::string AuctionSystem::generateItemId() {\n    return \"I\" + std::to_string(itemIdCounter++);\n}\n\nstd::string AuctionSystem::generateAuctionId() {\n    return \"A\" + std::to_string(auctionIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/AuctionSystem.hpp",
    "content": "#ifndef AUCTION_SYSTEM_HPP\n#define AUCTION_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Item.hpp\"\n#include \"Auction.hpp\"\n\nclass AuctionSystem {\nprivate:\n    std::vector<User*> users;\n    std::vector<Item*> items;\n    std::vector<Auction*> auctions;\n    int itemIdCounter;\n    int auctionIdCounter;\n\npublic:\n    AuctionSystem();\n    ~AuctionSystem();\n    \n    User* registerUser(std::string username, std::string email);\n    Item* createItem(std::string sellerId, std::string name, std::string description,\n                    ItemCategory category, double startingPrice);\n    Auction* createAuction(std::string itemId, std::time_t startTime, std::time_t endTime);\n    \n    bool placeBid(std::string auctionId, std::string bidderId, double amount);\n    bool addUserBalance(std::string userId, double amount);\n    void startAuction(std::string auctionId);\n    void endAuction(std::string auctionId);\n    void cancelAuction(std::string auctionId);\n    \n    std::vector<Auction*> getActiveAuctions() const;\n    std::vector<Item*> searchItems(const std::string& query) const;\n    \n    void displayUserInfo(std::string userId) const;\n    void displayItemInfo(std::string itemId) const;\n    void displayAuctionInfo(std::string auctionId) const;\n    void displayAllAuctions() const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Item* findItem(const std::string& itemId) const;\n    Auction* findAuction(const std::string& auctionId) const;\n    std::string generateItemId();\n    std::string generateAuctionId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/AuctionSystemDemo.cpp",
    "content": "#include \"AuctionSystem.hpp\"\n#include <iostream>\n#include <ctime>\n\nint main() {\n    AuctionSystem system;\n    \n    // Register users\n    User* seller = system.registerUser(\"john_seller\", \"john@email.com\");\n    User* bidder1 = system.registerUser(\"alice_bidder\", \"alice@email.com\");\n    User* bidder2 = system.registerUser(\"bob_bidder\", \"bob@email.com\");\n    \n    // Add balance to bidders\n    system.addUserBalance(bidder1->getUserId(), 1000.0);\n    system.addUserBalance(bidder2->getUserId(), 1500.0);\n    \n    std::cout << \"Initial user balances:\" << std::endl;\n    system.displayUserInfo(bidder1->getUserId());\n    system.displayUserInfo(bidder2->getUserId());\n    \n    // Create items\n    Item* phone = system.createItem(seller->getUserId(), \"Smartphone\", \n                                  \"Latest model smartphone\", \n                                  ItemCategory::ELECTRONICS, 500.0);\n    Item* watch = system.createItem(seller->getUserId(), \"Luxury Watch\",\n                                  \"Vintage luxury timepiece\",\n                                  ItemCategory::FASHION, 1000.0);\n    \n    if (phone && watch) {\n        std::cout << \"\\nCreated items:\" << std::endl;\n        system.displayItemInfo(phone->getItemId());\n        system.displayItemInfo(watch->getItemId());\n        \n        // Create auctions\n        std::time_t now = std::time(nullptr);\n        std::time_t oneHourLater = now + 3600;\n        \n        Auction* phoneAuction = system.createAuction(phone->getItemId(), now, oneHourLater);\n        Auction* watchAuction = system.createAuction(watch->getItemId(), now, oneHourLater);\n        \n        if (phoneAuction && watchAuction) {\n            // Start auctions\n            system.startAuction(phoneAuction->getAuctionId());\n            system.startAuction(watchAuction->getAuctionId());\n            \n            std::cout << \"\\nActive auctions:\" << std::endl;\n            system.displayAllAuctions();\n            \n            // Place bids\n            std::cout << \"\\nPlacing bids...\" << std::endl;\n            if (system.placeBid(phoneAuction->getAuctionId(), \n                              bidder1->getUserId(), 600.0)) {\n                std::cout << \"Bid placed successfully by \" \n                         << bidder1->getUsername() << std::endl;\n            }\n            \n            if (system.placeBid(phoneAuction->getAuctionId(), \n                              bidder2->getUserId(), 700.0)) {\n                std::cout << \"Bid placed successfully by \" \n                         << bidder2->getUsername() << std::endl;\n            }\n            \n            if (system.placeBid(watchAuction->getAuctionId(), \n                              bidder2->getUserId(), 1200.0)) {\n                std::cout << \"Bid placed successfully by \" \n                         << bidder2->getUsername() << std::endl;\n            }\n            \n            // Display auction status\n            std::cout << \"\\nCurrent auction status:\" << std::endl;\n            system.displayAuctionInfo(phoneAuction->getAuctionId());\n            system.displayAuctionInfo(watchAuction->getAuctionId());\n            \n            // End auctions\n            std::cout << \"\\nEnding auctions...\" << std::endl;\n            system.endAuction(phoneAuction->getAuctionId());\n            system.endAuction(watchAuction->getAuctionId());\n            \n            // Display final results\n            std::cout << \"\\nFinal auction results:\" << std::endl;\n            system.displayAuctionInfo(phoneAuction->getAuctionId());\n            system.displayAuctionInfo(watchAuction->getAuctionId());\n            \n            // Display updated user balances\n            std::cout << \"\\nFinal user balances:\" << std::endl;\n            system.displayUserInfo(bidder1->getUserId());\n            system.displayUserInfo(bidder2->getUserId());\n        }\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/Item.cpp",
    "content": "#include \"Item.hpp\"\n#include <iostream>\n#include <iomanip>\n\nItem::Item(std::string itemId, std::string name, std::string description,\n           ItemCategory category, double startingPrice, std::string sellerId)\n    : itemId(itemId), name(name), description(description), category(category),\n      startingPrice(startingPrice), sellerId(sellerId), status(ItemStatus::AVAILABLE) {}\n\nstd::string Item::getItemId() const { return itemId; }\nstd::string Item::getName() const { return name; }\nstd::string Item::getDescription() const { return description; }\nItemCategory Item::getCategory() const { return category; }\ndouble Item::getStartingPrice() const { return startingPrice; }\nItemStatus Item::getStatus() const { return status; }\nstd::string Item::getSellerId() const { return sellerId; }\n\nvoid Item::setStatus(ItemStatus status) {\n    this->status = status;\n}\n\nvoid Item::displayInfo() const {\n    std::cout << \"Item: \" << name << \" (ID: \" << itemId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Category: \";\n    switch (category) {\n        case ItemCategory::ELECTRONICS: std::cout << \"Electronics\"; break;\n        case ItemCategory::FASHION: std::cout << \"Fashion\"; break;\n        case ItemCategory::HOME: std::cout << \"Home\"; break;\n        case ItemCategory::SPORTS: std::cout << \"Sports\"; break;\n        case ItemCategory::BOOKS: std::cout << \"Books\"; break;\n        case ItemCategory::COLLECTIBLES: std::cout << \"Collectibles\"; break;\n        case ItemCategory::OTHER: std::cout << \"Other\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Starting Price: $\" << std::fixed << std::setprecision(2) \n              << startingPrice << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case ItemStatus::AVAILABLE: std::cout << \"Available\"; break;\n        case ItemStatus::IN_AUCTION: std::cout << \"In Auction\"; break;\n        case ItemStatus::SOLD: std::cout << \"Sold\"; break;\n        case ItemStatus::WITHDRAWN: std::cout << \"Withdrawn\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Seller ID: \" << sellerId << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/Item.hpp",
    "content": "#ifndef ITEM_HPP\n#define ITEM_HPP\n\n#include <string>\n\nenum class ItemCategory {\n    ELECTRONICS,\n    FASHION,\n    HOME,\n    SPORTS,\n    BOOKS,\n    COLLECTIBLES,\n    OTHER\n};\n\nenum class ItemStatus {\n    AVAILABLE,\n    IN_AUCTION,\n    SOLD,\n    WITHDRAWN\n};\n\nclass Item {\nprivate:\n    std::string itemId;\n    std::string name;\n    std::string description;\n    ItemCategory category;\n    double startingPrice;\n    ItemStatus status;\n    std::string sellerId;\n\npublic:\n    Item(std::string itemId, std::string name, std::string description,\n         ItemCategory category, double startingPrice, std::string sellerId);\n    \n    std::string getItemId() const;\n    std::string getName() const;\n    std::string getDescription() const;\n    ItemCategory getCategory() const;\n    double getStartingPrice() const;\n    ItemStatus getStatus() const;\n    std::string getSellerId() const;\n    \n    void setStatus(ItemStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/README.md",
    "content": "# Designing an Online Auction System\nIn this article, we delve into the object-oriented design and implementation of an Online Auction System using Java. \n\nThis system allows for the creation and management of auctions, user participation in bidding, and handling transactions.\n\n## Requirements\n1. The online auction system should allow users to register and log in to their accounts.\n2. Users should be able to create new auction listings with details such as item name, description, starting price, and auction duration.\n3. Users should be able to browse and search for auction listings based on various criteria (e.g., item name, category, price range).\n4. Users should be able to place bids on active auction listings.\n5. The system should automatically update the current highest bid and notify the bidders accordingly.\n6. The auction should end when the specified duration is reached, and the highest bidder should be declared the winner.\n7. The system should handle concurrent access to auction listings and ensure data consistency.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online auction system, with properties such as id, username, and email.\n2. The **AuctionStatus** enum defines the possible states of an auction listing, such as active and closed.\n3. The **AuctionListing** class represents an auction listing in the system, with properties like id, item name, description, starting price, duration, seller, current highest bid, and a list of bids.\n4. The **Bid** class represents a bid placed by a user on an auction listing, with properties such as id, bidder, amount, and timestamp.\n5. The **AuctionSystem** class is the core of the online auction system and follows the Singleton pattern to ensure a single instance of the auction system.\n6. The AuctionSystem class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to auction listings and ensure thread safety.\n7. The AuctionSystem class provides methods for registering users, creating auction listings, searching auction listings, and placing bids.\n8. The **AuctionSystemDemo** class serves as the entry point of the application and demonstrates the usage of the online auction system."
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <iomanip>\n\nUser::User(std::string userId, std::string username, std::string email)\n    : userId(userId), username(username), email(email), balance(0.0), active(true) {}\n\nUser::~User() {\n    // Note: Items are managed by the auction system\n    listedItems.clear();\n    purchasedItems.clear();\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\ndouble User::getBalance() const { return balance; }\nbool User::isActive() const { return active; }\nconst std::vector<Item*>& User::getListedItems() const { return listedItems; }\nconst std::vector<Item*>& User::getPurchasedItems() const { return purchasedItems; }\n\nvoid User::addBalance(double amount) {\n    if (amount > 0) {\n        balance += amount;\n    }\n}\n\nbool User::deductBalance(double amount) {\n    if (amount > 0 && balance >= amount) {\n        balance -= amount;\n        return true;\n    }\n    return false;\n}\n\nvoid User::addListedItem(Item* item) {\n    listedItems.push_back(item);\n}\n\nvoid User::addPurchasedItem(Item* item) {\n    purchasedItems.push_back(item);\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Balance: $\" << std::fixed << std::setprecision(2) << balance << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Listed Items: \" << listedItems.size() << std::endl;\n    std::cout << \"Purchased Items: \" << purchasedItems.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineauctionsystem/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include \"Item.hpp\"\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    double balance;\n    std::vector<Item*> listedItems;\n    std::vector<Item*> purchasedItems;\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    double getBalance() const;\n    bool isActive() const;\n    const std::vector<Item*>& getListedItems() const;\n    const std::vector<Item*>& getPurchasedItems() const;\n    \n    void addBalance(double amount);\n    bool deductBalance(double amount);\n    void addListedItem(Item* item);\n    void addPurchasedItem(Item* item);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Cart.cpp",
    "content": "#include \"Cart.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <algorithm>\n\nCart::Cart(User* user) : user(user), total(0.0) {}\n\nCart::~Cart() {\n    clear();\n}\n\nUser* Cart::getUser() const { return user; }\nconst std::vector<CartItem*>& Cart::getItems() const { return items; }\ndouble Cart::getTotal() const { return total; }\n\nbool Cart::addItem(Product* product, int quantity) {\n    if (!product->isAvailable() || quantity <= 0 || \n        quantity > product->getStockQuantity()) {\n        return false;\n    }\n\n    // Check if product already exists in cart\n    for (auto item : items) {\n        if (item->getProduct() == product) {\n            return updateItemQuantity(product, item->getQuantity() + quantity);\n        }\n    }\n\n    items.push_back(new CartItem(product, quantity));\n    calculateTotal();\n    return true;\n}\n\nbool Cart::updateItemQuantity(Product* product, int quantity) {\n    if (quantity <= 0 || quantity > product->getStockQuantity()) {\n        return false;\n    }\n\n    for (auto item : items) {\n        if (item->getProduct() == product) {\n            item->setQuantity(quantity);\n            calculateTotal();\n            return true;\n        }\n    }\n    return false;\n}\n\nbool Cart::removeItem(Product* product) {\n    auto it = std::find_if(items.begin(), items.end(),\n        [product](CartItem* item) { return item->getProduct() == product; });\n    \n    if (it != items.end()) {\n        delete *it;\n        items.erase(it);\n        calculateTotal();\n        return true;\n    }\n    return false;\n}\n\nvoid Cart::clear() {\n    for (auto item : items) {\n        delete item;\n    }\n    items.clear();\n    total = 0.0;\n}\n\nvoid Cart::calculateTotal() {\n    total = 0.0;\n    for (const auto& item : items) {\n        total += item->getSubtotal();\n    }\n}\n\nvoid Cart::displayInfo() const {\n    std::cout << \"\\nShopping Cart for \" << user->getUsername() << \":\" << std::endl;\n    std::cout << \"Items:\" << std::endl;\n    for (const auto& item : items) {\n        item->displayInfo();\n    }\n    std::cout << \"------------------------\" << std::endl;\n    std::cout << \"Total: $\" << std::fixed << std::setprecision(2) << total << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Cart.hpp",
    "content": "#ifndef CART_HPP\n#define CART_HPP\n\n#include <vector>\n#include \"CartItem.hpp\"\n#include \"User.hpp\"\n\nclass Cart {\nprivate:\n    User* user;\n    std::vector<CartItem*> items;\n    double total;\n\npublic:\n    Cart(User* user);\n    ~Cart();\n    \n    User* getUser() const;\n    const std::vector<CartItem*>& getItems() const;\n    double getTotal() const;\n    \n    bool addItem(Product* product, int quantity);\n    bool updateItemQuantity(Product* product, int quantity);\n    bool removeItem(Product* product);\n    void clear();\n    void calculateTotal();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/CartItem.cpp",
    "content": "#include \"CartItem.hpp\"\n#include <iostream>\n#include <iomanip>\n\nCartItem::CartItem(Product* product, int quantity)\n    : product(product), quantity(quantity) {}\n\nProduct* CartItem::getProduct() const { return product; }\nint CartItem::getQuantity() const { return quantity; }\n\ndouble CartItem::getSubtotal() const {\n    return product->getPrice() * quantity;\n}\n\nvoid CartItem::setQuantity(int quantity) {\n    if (quantity > 0) {\n        this->quantity = quantity;\n    }\n}\n\nvoid CartItem::displayInfo() const {\n    std::cout << product->getName() << \" x \" << quantity \n              << \" = $\" << std::fixed << std::setprecision(2) \n              << getSubtotal() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/CartItem.hpp",
    "content": "#ifndef CART_ITEM_HPP\n#define CART_ITEM_HPP\n\n#include \"Product.hpp\"\n\nclass CartItem {\nprivate:\n    Product* product;\n    int quantity;\n\npublic:\n    CartItem(Product* product, int quantity);\n    \n    Product* getProduct() const;\n    int getQuantity() const;\n    double getSubtotal() const;\n    \n    void setQuantity(int quantity);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Order.cpp",
    "content": "#include \"Order.hpp\"\n#include <iostream>\n#include <iomanip>\n\nOrder::Order(std::string orderId, User* user, const std::vector<CartItem*>& cartItems)\n    : orderId(orderId), user(user), status(OrderStatus::PENDING), totalAmount(0.0) {\n    \n    // Deep copy cart items\n    for (const auto& cartItem : cartItems) {\n        items.push_back(new CartItem(cartItem->getProduct(), cartItem->getQuantity()));\n        totalAmount += cartItem->getSubtotal();\n    }\n    \n    // Set order date to current time\n    orderDate = std::time(nullptr);\n}\n\nOrder::~Order() {\n    for (auto item : items) {\n        delete item;\n    }\n}\n\nstd::string Order::getOrderId() const { return orderId; }\nUser* Order::getUser() const { return user; }\nconst std::vector<CartItem*>& Order::getItems() const { return items; }\ndouble Order::getTotalAmount() const { return totalAmount; }\nstd::time_t Order::getOrderDate() const { return orderDate; }\nOrderStatus Order::getStatus() const { return status; }\n\nvoid Order::setStatus(OrderStatus status) {\n    this->status = status;\n}\n\nvoid Order::displayInfo() const {\n    std::cout << \"\\nOrder Details:\" << std::endl;\n    std::cout << \"Order ID: \" << orderId << std::endl;\n    std::cout << \"Customer: \" << user->getUsername() << std::endl;\n    std::cout << \"Date: \" << std::ctime(&orderDate);\n    std::cout << \"Status: \";\n    switch (status) {\n        case OrderStatus::PENDING: std::cout << \"Pending\"; break;\n        case OrderStatus::CONFIRMED: std::cout << \"Confirmed\"; break;\n        case OrderStatus::SHIPPED: std::cout << \"Shipped\"; break;\n        case OrderStatus::DELIVERED: std::cout << \"Delivered\"; break;\n        case OrderStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"\\nItems:\" << std::endl;\n    for (const auto& item : items) {\n        item->displayInfo();\n    }\n    std::cout << \"------------------------\" << std::endl;\n    std::cout << \"Total Amount: $\" << std::fixed << std::setprecision(2) << totalAmount << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Order.hpp",
    "content": "#ifndef ORDER_HPP\n#define ORDER_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n#include \"CartItem.hpp\"\n\nenum class OrderStatus {\n    PENDING,\n    CONFIRMED,\n    SHIPPED,\n    DELIVERED,\n    CANCELLED\n};\n\nclass Order {\nprivate:\n    std::string orderId;\n    User* user;\n    std::vector<CartItem*> items;\n    double totalAmount;\n    std::time_t orderDate;\n    OrderStatus status;\n\npublic:\n    Order(std::string orderId, User* user, const std::vector<CartItem*>& items);\n    ~Order();\n    \n    std::string getOrderId() const;\n    User* getUser() const;\n    const std::vector<CartItem*>& getItems() const;\n    double getTotalAmount() const;\n    std::time_t getOrderDate() const;\n    OrderStatus getStatus() const;\n    \n    void setStatus(OrderStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Product.cpp",
    "content": "#include \"Product.hpp\"\n#include <iostream>\n#include <iomanip>\n\nProduct::Product(std::string productId, std::string name, std::string description, \n                double price, int stockQuantity)\n    : productId(productId), name(name), description(description), \n      price(price), stockQuantity(stockQuantity), available(true) {}\n\nstd::string Product::getProductId() const { return productId; }\nstd::string Product::getName() const { return name; }\nstd::string Product::getDescription() const { return description; }\ndouble Product::getPrice() const { return price; }\nint Product::getStockQuantity() const { return stockQuantity; }\nbool Product::isAvailable() const { return available; }\n\nvoid Product::setPrice(double newPrice) {\n    if (newPrice >= 0) {\n        price = newPrice;\n    }\n}\n\nvoid Product::setStockQuantity(int quantity) {\n    if (quantity >= 0) {\n        stockQuantity = quantity;\n        available = (quantity > 0);\n    }\n}\n\nvoid Product::setAvailable(bool status) {\n    available = status;\n}\n\nbool Product::updateStock(int quantity) {\n    if (stockQuantity + quantity >= 0) {\n        stockQuantity += quantity;\n        available = (stockQuantity > 0);\n        return true;\n    }\n    return false;\n}\n\nvoid Product::displayInfo() const {\n    std::cout << \"Product: \" << name << \" (ID: \" << productId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Price: $\" << std::fixed << std::setprecision(2) << price << std::endl;\n    std::cout << \"Stock: \" << stockQuantity << std::endl;\n    std::cout << \"Status: \" << (available ? \"Available\" : \"Out of Stock\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/Product.hpp",
    "content": "#ifndef PRODUCT_HPP\n#define PRODUCT_HPP\n\n#include <string>\n\nclass Product {\nprivate:\n    std::string productId;\n    std::string name;\n    std::string description;\n    double price;\n    int stockQuantity;\n    bool available;\n\npublic:\n    Product(std::string productId, std::string name, std::string description, \n            double price, int stockQuantity);\n    \n    std::string getProductId() const;\n    std::string getName() const;\n    std::string getDescription() const;\n    double getPrice() const;\n    int getStockQuantity() const;\n    bool isAvailable() const;\n    \n    void setPrice(double newPrice);\n    void setStockQuantity(int quantity);\n    void setAvailable(bool status);\n    bool updateStock(int quantity);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/README.md",
    "content": "# Designing an Online Shopping System Like Amazon\n\n## Requirements\n1. The online shopping service should allow users to browse products, add them to the shopping cart, and place orders.\n2. The system should support multiple product categories and provide search functionality.\n3. Users should be able to manage their profiles, view order history, and track order status.\n4. The system should handle inventory management and update product availability accordingly.\n5. The system should support multiple payment methods and ensure secure transactions.\n6. The system should handle concurrent user requests and ensure data consistency.\n7. The system should be scalable to handle a large number of products and users.\n8. The system should provide a user-friendly interface for a seamless shopping experience.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online shopping service, with properties such as ID, name, email, password, and a list of orders.\n2. The **Product** class represents a product available for purchase, with properties like ID, name, description, price, and quantity. It provides methods to update the quantity and check product availability.\n3. The **Order** class represents an order placed by a user, containing properties such as ID, user, order items, total amount, and order status. It calculates the total amount based on the order items.\n4. The **OrderItem** class represents an item within an order, consisting of the product and the quantity ordered.\n5. The **OrderStatus** enum represents the different statuses an order can have, such as pending, processing, shipped, delivered, or cancelled.\n6. The **ShoppingCart** class represents the user's shopping cart, allowing them to add, remove, and update item quantities. It maintains a map of product IDs and order items.\n7. The **Payment** interface defines the contract for processing payments, with a concrete implementation CreditCardPayment.\n8. The **OnlineShoppingService** class is the central component of the online shopping service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register users, add products, search products, place orders, and retrieve order information. It handles concurrent access to shared resources using synchronization.\n9. The **OnlineShoppingServiceDemo** class demonstrates the usage of the online shopping service by registering users, adding products, searching for products, placing orders, and viewing order history."
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/ShoppingDemo.cpp",
    "content": "#include \"ShoppingSystem.hpp\"\n#include <iostream>\n\nint main() {\n    ShoppingSystem shop;\n    \n    // Add products\n    Product* laptop = shop.addProduct(\"Laptop\", \"High-performance laptop\", 999.99, 10);\n    Product* phone = shop.addProduct(\"Smartphone\", \"Latest model smartphone\", 599.99, 20);\n    Product* tablet = shop.addProduct(\"Tablet\", \"10-inch tablet\", 299.99, 15);\n    \n    std::cout << \"Initial Products:\" << std::endl;\n    shop.displayProducts();\n    \n    // Register users\n    User* user1 = shop.registerUser(\"john_doe\", \"john@email.com\", \"123 Main St\");\n    User* user2 = shop.registerUser(\"jane_smith\", \"jane@email.com\", \"456 Oak Ave\");\n    \n    std::cout << \"\\nRegistered Users:\" << std::endl;\n    shop.displayUsers();\n    \n    // Add items to cart\n    std::cout << \"\\nAdding items to John's cart...\" << std::endl;\n    shop.addToCart(user1->getUserId(), laptop->getProductId(), 1);\n    shop.addToCart(user1->getUserId(), phone->getProductId(), 2);\n    shop.displayCart(user1->getUserId());\n    \n    // Update cart\n    std::cout << \"\\nUpdating phone quantity...\" << std::endl;\n    shop.updateCartItem(user1->getUserId(), phone->getProductId(), 1);\n    shop.displayCart(user1->getUserId());\n    \n    // Place order\n    std::cout << \"\\nPlacing order...\" << std::endl;\n    Order* order = shop.placeOrder(user1->getUserId());\n    if (order) {\n        std::cout << \"Order placed successfully!\" << std::endl;\n        order->displayInfo();\n        \n        // Update order status\n        shop.updateOrderStatus(order->getOrderId(), OrderStatus::CONFIRMED);\n        shop.updateOrderStatus(order->getOrderId(), OrderStatus::SHIPPED);\n        \n        std::cout << \"\\nUpdated order status:\" << std::endl;\n        order->displayInfo();\n    }\n    \n    // Check updated product stock\n    std::cout << \"\\nUpdated product stock:\" << std::endl;\n    shop.displayProducts();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/ShoppingSystem.cpp",
    "content": "#include \"ShoppingSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nShoppingSystem::ShoppingSystem() : orderIdCounter(1) {}\n\nShoppingSystem::~ShoppingSystem() {\n    for (auto user : users) delete user;\n    for (auto product : products) delete product;\n    for (auto order : orders) delete order;\n    for (auto& pair : userCarts) delete pair.second;\n}\n\nUser* ShoppingSystem::registerUser(const std::string& username, const std::string& email, \n                                 const std::string& address) {\n    std::string userId = \"U\" + std::to_string(users.size() + 1);\n    User* user = new User(userId, username, email, address);\n    users.push_back(user);\n    return user;\n}\n\nvoid ShoppingSystem::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        delete *it;\n        users.erase(it);\n        \n        // Remove user's cart\n        auto cartIt = userCarts.find(userId);\n        if (cartIt != userCarts.end()) {\n            delete cartIt->second;\n            userCarts.erase(cartIt);\n        }\n    }\n}\n\nProduct* ShoppingSystem::addProduct(const std::string& name, const std::string& description,\n                                  double price, int stockQuantity) {\n    std::string productId = \"P\" + std::to_string(products.size() + 1);\n    Product* product = new Product(productId, name, description, price, stockQuantity);\n    products.push_back(product);\n    return product;\n}\n\nvoid ShoppingSystem::removeProduct(const std::string& productId) {\n    auto it = std::find_if(products.begin(), products.end(),\n        [productId](Product* product) { return product->getProductId() == productId; });\n    \n    if (it != products.end()) {\n        delete *it;\n        products.erase(it);\n    }\n}\n\nvoid ShoppingSystem::updateProductStock(const std::string& productId, int quantity) {\n    if (Product* product = findProduct(productId)) {\n        product->updateStock(quantity);\n    }\n}\n\nbool ShoppingSystem::addToCart(const std::string& userId, const std::string& productId, int quantity) {\n    User* user = findUser(userId);\n    Product* product = findProduct(productId);\n    \n    if (!user || !product) return false;\n    \n    Cart* cart = getCart(userId);\n    return cart->addItem(product, quantity);\n}\n\nbool ShoppingSystem::updateCartItem(const std::string& userId, const std::string& productId, int quantity) {\n    User* user = findUser(userId);\n    Product* product = findProduct(productId);\n    \n    if (!user || !product) return false;\n    \n    Cart* cart = getCart(userId);\n    return cart->updateItemQuantity(product, quantity);\n}\n\nbool ShoppingSystem::removeFromCart(const std::string& userId, const std::string& productId) {\n    User* user = findUser(userId);\n    Product* product = findProduct(productId);\n    \n    if (!user || !product) return false;\n    \n    Cart* cart = getCart(userId);\n    return cart->removeItem(product);\n}\n\nvoid ShoppingSystem::clearCart(const std::string& userId) {\n    if (Cart* cart = getCart(userId)) {\n        cart->clear();\n    }\n}\n\nOrder* ShoppingSystem::placeOrder(const std::string& userId) {\n    User* user = findUser(userId);\n    Cart* cart = getCart(userId);\n    \n    if (!user || !cart || cart->getItems().empty()) return nullptr;\n    \n    // Check stock availability and update stock\n    for (const auto& item : cart->getItems()) {\n        Product* product = item->getProduct();\n        if (!product->updateStock(-item->getQuantity())) {\n            return nullptr;\n        }\n    }\n    \n    // Create order\n    std::string orderId = generateOrderId();\n    Order* order = new Order(orderId, user, cart->getItems());\n    orders.push_back(order);\n    user->addOrder(order);\n    \n    // Clear cart after successful order\n    cart->clear();\n    \n    return order;\n}\n\nbool ShoppingSystem::updateOrderStatus(const std::string& orderId, OrderStatus status) {\n    if (Order* order = findOrder(orderId)) {\n        order->setStatus(status);\n        return true;\n    }\n    return false;\n}\n\nvoid ShoppingSystem::displayProducts() const {\n    std::cout << \"\\nAvailable Products:\" << std::endl;\n    for (const auto& product : products) {\n        product->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid ShoppingSystem::displayUsers() const {\n    std::cout << \"\\nRegistered Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid ShoppingSystem::displayCart(const std::string& userId) const {\n    auto it = userCarts.find(userId);\n    if (it != userCarts.end()) {\n        it->second->displayInfo();\n    }\n}\n\nvoid ShoppingSystem::displayOrders(const std::string& userId) const {\n    if (User* user = findUser(userId)) {\n        user->displayOrders();\n    }\n}\n\nvoid ShoppingSystem::displayAllOrders() const {\n    std::cout << \"\\nAll Orders:\" << std::endl;\n    for (const auto& order : orders) {\n        order->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nUser* ShoppingSystem::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nProduct* ShoppingSystem::findProduct(const std::string& productId) const {\n    auto it = std::find_if(products.begin(), products.end(),\n        [productId](Product* product) { return product->getProductId() == productId; });\n    return it != products.end() ? *it : nullptr;\n}\n\nOrder* ShoppingSystem::findOrder(const std::string& orderId) const {\n    auto it = std::find_if(orders.begin(), orders.end(),\n        [orderId](Order* order) { return order->getOrderId() == orderId; });\n    return it != orders.end() ? *it : nullptr;\n}\n\nCart* ShoppingSystem::getCart(const std::string& userId) {\n    auto it = userCarts.find(userId);\n    if (it == userCarts.end()) {\n        User* user = findUser(userId);\n        if (!user) return nullptr;\n        \n        Cart* cart = new Cart(user);\n        userCarts[userId] = cart;\n        return cart;\n    }\n    return it->second;\n}\n\nstd::string ShoppingSystem::generateOrderId() {\n    return \"O\" + std::to_string(orderIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/ShoppingSystem.hpp",
    "content": "#ifndef SHOPPING_SYSTEM_HPP\n#define SHOPPING_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include <map>\n#include \"User.hpp\"\n#include \"Product.hpp\"\n#include \"Cart.hpp\"\n#include \"Order.hpp\"\n\nclass ShoppingSystem {\nprivate:\n    std::vector<User*> users;\n    std::vector<Product*> products;\n    std::vector<Order*> orders;\n    std::map<std::string, Cart*> userCarts;\n    int orderIdCounter;\n\npublic:\n    ShoppingSystem();\n    ~ShoppingSystem();\n    \n    // User management\n    User* registerUser(const std::string& username, const std::string& email, \n                      const std::string& address);\n    void removeUser(const std::string& userId);\n    \n    // Product management\n    Product* addProduct(const std::string& name, const std::string& description,\n                       double price, int stockQuantity);\n    void removeProduct(const std::string& productId);\n    void updateProductStock(const std::string& productId, int quantity);\n    \n    // Cart operations\n    bool addToCart(const std::string& userId, const std::string& productId, int quantity);\n    bool updateCartItem(const std::string& userId, const std::string& productId, int quantity);\n    bool removeFromCart(const std::string& userId, const std::string& productId);\n    void clearCart(const std::string& userId);\n    \n    // Order operations\n    Order* placeOrder(const std::string& userId);\n    bool updateOrderStatus(const std::string& orderId, OrderStatus status);\n    \n    // Display functions\n    void displayProducts() const;\n    void displayUsers() const;\n    void displayCart(const std::string& userId) const;\n    void displayOrders(const std::string& userId) const;\n    void displayAllOrders() const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Product* findProduct(const std::string& productId) const;\n    Order* findOrder(const std::string& orderId) const;\n    Cart* getCart(const std::string& userId);\n    std::string generateOrderId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n\nUser::User(std::string userId, std::string username, std::string email, std::string address)\n    : userId(userId), username(username), email(email), address(address), active(true) {}\n\nUser::~User() {\n    for (auto order : orders) {\n        delete order;\n    }\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\nstd::string User::getAddress() const { return address; }\nbool User::isActive() const { return active; }\nconst std::vector<Order*>& User::getOrders() const { return orders; }\n\nvoid User::addOrder(Order* order) {\n    orders.push_back(order);\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Address: \" << address << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Total Orders: \" << orders.size() << std::endl;\n}\n\nvoid User::displayOrders() const {\n    std::cout << \"\\nOrder History for \" << username << \":\" << std::endl;\n    for (const auto& order : orders) {\n        order->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/onlineshoppingservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include \"Order.hpp\"\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    std::string address;\n    std::vector<Order*> orders;\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email, std::string address);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    std::string getAddress() const;\n    bool isActive() const;\n    const std::vector<Order*>& getOrders() const;\n    \n    void addOrder(Order* order);\n    void setActive(bool status);\n    void displayInfo() const;\n    void displayOrders() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/BrokerageDemo.cpp",
    "content": "#include \"BrokerageSystem.hpp\"\n#include <iostream>\n\nint main() {\n    BrokerageSystem brokerage;\n    \n    // Add stocks\n    Stock* apple = brokerage.addStock(\"AAPL\", \"Apple Inc.\", 150.0, 1000);\n    Stock* google = brokerage.addStock(\"GOOGL\", \"Alphabet Inc.\", 2800.0, 500);\n    Stock* amazon = brokerage.addStock(\"AMZN\", \"Amazon.com Inc.\", 3300.0, 300);\n    \n    std::cout << \"Initial Stocks:\" << std::endl;\n    brokerage.displayStocks();\n    \n    // Register users\n    User* user1 = brokerage.registerUser(\"john_trader\", \"john@email.com\");\n    User* user2 = brokerage.registerUser(\"jane_investor\", \"jane@email.com\");\n    \n    // Deposit funds\n    brokerage.deposit(user1->getUserId(), 10000.0);\n    brokerage.deposit(user2->getUserId(), 15000.0);\n    \n    std::cout << \"\\nUsers after deposit:\" << std::endl;\n    brokerage.displayUsers();\n    \n    // Perform transactions\n    Transaction* trans1 = brokerage.buyStock(user1->getUserId(), \"AAPL\", 10);\n    if (trans1) {\n        std::cout << \"\\nBuy Transaction:\" << std::endl;\n        trans1->displayInfo();\n    }\n    \n    // Update stock price\n    brokerage.updateStockPrice(\"AAPL\", 155.0);\n    \n    Transaction* trans2 = brokerage.sellStock(user1->getUserId(), \"AAPL\", 5);\n    if (trans2) {\n        std::cout << \"\\nSell Transaction:\" << std::endl;\n        trans2->displayInfo();\n    }\n    \n    // Display final state\n    std::cout << \"\\nFinal Portfolio for John:\" << std::endl;\n    brokerage.displayUserPortfolio(user1->getUserId());\n    \n    std::cout << \"\\nTransaction History for John:\" << std::endl;\n    brokerage.displayTransactionHistory(user1->getUserId());\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/BrokerageSystem.cpp",
    "content": "#include \"BrokerageSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nBrokerageSystem::BrokerageSystem() : transactionIdCounter(1) {}\n\nBrokerageSystem::~BrokerageSystem() {\n    for (auto user : users) delete user;\n    for (auto& pair : stocks) delete pair.second;\n    for (auto transaction : transactions) delete transaction;\n}\n\nUser* BrokerageSystem::registerUser(const std::string& username, const std::string& email) {\n    std::string userId = \"U\" + std::to_string(users.size() + 1);\n    User* user = new User(userId, username, email);\n    users.push_back(user);\n    return user;\n}\n\nvoid BrokerageSystem::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        delete *it;\n        users.erase(it);\n    }\n}\n\nStock* BrokerageSystem::addStock(const std::string& symbol, const std::string& companyName,\n                                double price, int shares) {\n    Stock* stock = new Stock(symbol, companyName, price, shares);\n    stocks[symbol] = stock;\n    return stock;\n}\n\nvoid BrokerageSystem::updateStockPrice(const std::string& symbol, double newPrice) {\n    if (Stock* stock = findStock(symbol)) {\n        stock->setCurrentPrice(newPrice);\n        updatePortfolioValues();\n    }\n}\n\nbool BrokerageSystem::deposit(const std::string& userId, double amount) {\n    if (User* user = findUser(userId)) {\n        return user->deposit(amount);\n    }\n    return false;\n}\n\nbool BrokerageSystem::withdraw(const std::string& userId, double amount) {\n    if (User* user = findUser(userId)) {\n        return user->withdraw(amount);\n    }\n    return false;\n}\n\nTransaction* BrokerageSystem::buyStock(const std::string& userId, const std::string& symbol, int quantity) {\n    User* user = findUser(userId);\n    Stock* stock = findStock(symbol);\n    \n    if (!user || !stock || !stock->isActive()) return nullptr;\n    \n    double totalCost = stock->getCurrentPrice() * quantity;\n    if (user->getBalance() < totalCost || stock->getAvailableShares() < quantity) {\n        return nullptr;\n    }\n    \n    // Process transaction\n    user->withdraw(totalCost);\n    stock->updateShares(-quantity);\n    user->getPortfolio()->addShares(symbol, quantity);\n    \n    // Create transaction record\n    Transaction* transaction = new Transaction(generateTransactionId(), user, stock,\n                                            TransactionType::BUY, quantity,\n                                            stock->getCurrentPrice());\n    transactions.push_back(transaction);\n    \n    updatePortfolioValues();\n    return transaction;\n}\n\nTransaction* BrokerageSystem::sellStock(const std::string& userId, const std::string& symbol, int quantity) {\n    User* user = findUser(userId);\n    Stock* stock = findStock(symbol);\n    \n    if (!user || !stock || !stock->isActive()) return nullptr;\n    \n    Portfolio* portfolio = user->getPortfolio();\n    if (portfolio->getShareQuantity(symbol) < quantity) {\n        return nullptr;\n    }\n    \n    // Process transaction\n    double totalAmount = stock->getCurrentPrice() * quantity;\n    user->deposit(totalAmount);\n    stock->updateShares(quantity);\n    portfolio->removeShares(symbol, quantity);\n    \n    // Create transaction record\n    Transaction* transaction = new Transaction(generateTransactionId(), user, stock,\n                                            TransactionType::SELL, quantity,\n                                            stock->getCurrentPrice());\n    transactions.push_back(transaction);\n    \n    updatePortfolioValues();\n    return transaction;\n}\n\nvoid BrokerageSystem::displayStocks() const {\n    std::cout << \"\\nAvailable Stocks:\" << std::endl;\n    for (const auto& pair : stocks) {\n        pair.second->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid BrokerageSystem::displayUsers() const {\n    std::cout << \"\\nRegistered Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid BrokerageSystem::displayUserPortfolio(const std::string& userId) const {\n    if (User* user = findUser(userId)) {\n        user->getPortfolio()->displayInfo();\n    }\n}\n\nvoid BrokerageSystem::displayTransactionHistory(const std::string& userId) const {\n    std::cout << \"\\nTransaction History:\" << std::endl;\n    for (const auto& transaction : transactions) {\n        if (transaction->getUser()->getUserId() == userId) {\n            transaction->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nUser* BrokerageSystem::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nStock* BrokerageSystem::findStock(const std::string& symbol) const {\n    auto it = stocks.find(symbol);\n    return it != stocks.end() ? it->second : nullptr;\n}\n\nvoid BrokerageSystem::updatePortfolioValues() {\n    for (auto user : users) {\n        user->getPortfolio()->updateTotalValue(stocks);\n    }\n}\n\nstd::string BrokerageSystem::generateTransactionId() {\n    return \"T\" + std::to_string(transactionIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/BrokerageSystem.hpp",
    "content": "#ifndef BROKERAGE_SYSTEM_HPP\n#define BROKERAGE_SYSTEM_HPP\n\n#include <vector>\n#include <map>\n#include <string>\n#include \"User.hpp\"\n#include \"Stock.hpp\"\n#include \"Transaction.hpp\"\n\nclass BrokerageSystem {\nprivate:\n    std::vector<User*> users;\n    std::map<std::string, Stock*> stocks;  // symbol -> Stock*\n    std::vector<Transaction*> transactions;\n    int transactionIdCounter;\n\npublic:\n    BrokerageSystem();\n    ~BrokerageSystem();\n    \n    // User management\n    User* registerUser(const std::string& username, const std::string& email);\n    void removeUser(const std::string& userId);\n    \n    // Stock management\n    Stock* addStock(const std::string& symbol, const std::string& companyName,\n                   double price, int shares);\n    void updateStockPrice(const std::string& symbol, double newPrice);\n    \n    // Trading operations\n    bool deposit(const std::string& userId, double amount);\n    bool withdraw(const std::string& userId, double amount);\n    Transaction* buyStock(const std::string& userId, const std::string& symbol, int quantity);\n    Transaction* sellStock(const std::string& userId, const std::string& symbol, int quantity);\n    \n    // Display functions\n    void displayStocks() const;\n    void displayUsers() const;\n    void displayUserPortfolio(const std::string& userId) const;\n    void displayTransactionHistory(const std::string& userId) const;\n    \nprivate:\n    User* findUser(const std::string& userId) const;\n    Stock* findStock(const std::string& symbol) const;\n    void updatePortfolioValues();\n    std::string generateTransactionId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Portfolio.cpp",
    "content": "#include \"Portfolio.hpp\"\n#include <iostream>\n#include <iomanip>\n\nPortfolio::Portfolio(std::string userId) : userId(userId), totalValue(0.0) {}\n\nstd::string Portfolio::getUserId() const { return userId; }\nconst std::map<std::string, int>& Portfolio::getHoldings() const { return holdings; }\ndouble Portfolio::getTotalValue() const { return totalValue; }\n\nint Portfolio::getShareQuantity(const std::string& symbol) const {\n    auto it = holdings.find(symbol);\n    return it != holdings.end() ? it->second : 0;\n}\n\nvoid Portfolio::addShares(const std::string& symbol, int quantity) {\n    if (quantity > 0) {\n        holdings[symbol] += quantity;\n    }\n}\n\nbool Portfolio::removeShares(const std::string& symbol, int quantity) {\n    auto it = holdings.find(symbol);\n    if (it != holdings.end() && it->second >= quantity) {\n        it->second -= quantity;\n        if (it->second == 0) {\n            holdings.erase(it);\n        }\n        return true;\n    }\n    return false;\n}\n\nvoid Portfolio::updateTotalValue(const std::map<std::string, Stock*>& stocks) {\n    totalValue = 0.0;\n    for (const auto& holding : holdings) {\n        auto stockIt = stocks.find(holding.first);\n        if (stockIt != stocks.end()) {\n            totalValue += stockIt->second->getCurrentPrice() * holding.second;\n        }\n    }\n}\n\nvoid Portfolio::displayInfo() const {\n    std::cout << \"\\nPortfolio Holdings:\" << std::endl;\n    if (holdings.empty()) {\n        std::cout << \"No holdings\" << std::endl;\n    } else {\n        for (const auto& holding : holdings) {\n            std::cout << holding.first << \": \" << holding.second << \" shares\" << std::endl;\n        }\n    }\n    std::cout << \"Total Value: $\" << std::fixed << std::setprecision(2) << totalValue << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Portfolio.hpp",
    "content": "#ifndef PORTFOLIO_HPP\n#define PORTFOLIO_HPP\n\n#include <string>\n#include <map>\n#include \"Stock.hpp\"\n\nclass Portfolio {\nprivate:\n    std::string userId;\n    std::map<std::string, int> holdings;  // symbol -> quantity\n    double totalValue;\n\npublic:\n    Portfolio(std::string userId);\n    \n    std::string getUserId() const;\n    const std::map<std::string, int>& getHoldings() const;\n    double getTotalValue() const;\n    int getShareQuantity(const std::string& symbol) const;\n    \n    void addShares(const std::string& symbol, int quantity);\n    bool removeShares(const std::string& symbol, int quantity);\n    void updateTotalValue(const std::map<std::string, Stock*>& stocks);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/README.md",
    "content": "# Designing an Online Stock Brokerage System\n\n## Requirements\n1. The online stock brokerage system should allow users to create and manage their trading accounts.\n2. Users should be able to buy and sell stocks, as well as view their portfolio and transaction history.\n3. The system should provide real-time stock quotes and market data to users.\n4. The system should handle order placement, execution, and settlement processes.\n5. The system should enforce various business rules and validations, such as checking account balances and stock availability.\n6. The system should handle concurrent user requests and ensure data consistency and integrity.\n7. The system should be scalable and able to handle a large number of users and transactions.\n8. The system should be secure and protect sensitive user information.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the stock brokerage system, with properties such as user ID, name, and email.\n2. The **Account** class represents a user's trading account, with properties like account ID, associated user, and balance. It provides methods for depositing and withdrawing funds.\n3. The **Stock** class represents a stock that can be traded, with properties such as symbol, name, and price. It provides a method for updating the stock price.\n4. The **Order** class is an abstract base class representing an order placed by a user. It contains common properties such as order ID, associated account, stock, quantity, price, and order status. The execute() method is declared as abstract, to be implemented by concrete order classes.\n5. The **BuyOrder** and **SellOrder** classes are concrete implementations of the Order class, representing buy and sell orders respectively. They provide the implementation for the execute() method specific to each order type.\n6. The **OrderStatus** enum represents the possible statuses of an order, such as PENDING, EXECUTED, or REJECTED.\n7. The **Portfolio** class represents a user's portfolio, which holds the stocks owned by the user. It provides methods for adding and removing stocks from the portfolio.\n8. The **StockBroker** class is the central component of the stock brokerage system. It follows the Singleton pattern to ensure a single instance of the stock broker. It manages user accounts, stocks, and order processing. It provides methods for creating accounts, adding stocks, placing orders, and processing orders.\n9. The **InsufficientFundsException** and **InsufficientStockException** classes are custom exceptions used to handle insufficient funds and insufficient stock scenarios respectively.\n10. The **StockBrokerageSystem** class serves as the entry point of the application and demonstrates the usage of the stock brokerage system."
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Stock.cpp",
    "content": "#include \"Stock.hpp\"\n#include <iostream>\n#include <iomanip>\n\nStock::Stock(std::string symbol, std::string companyName, double currentPrice, int availableShares)\n    : symbol(symbol), companyName(companyName), currentPrice(currentPrice), \n      availableShares(availableShares), active(true) {}\n\nstd::string Stock::getSymbol() const { return symbol; }\nstd::string Stock::getCompanyName() const { return companyName; }\ndouble Stock::getCurrentPrice() const { return currentPrice; }\nint Stock::getAvailableShares() const { return availableShares; }\nbool Stock::isActive() const { return active; }\n\nvoid Stock::setCurrentPrice(double price) {\n    if (price > 0) {\n        currentPrice = price;\n    }\n}\n\nvoid Stock::updateShares(int quantity) {\n    if (availableShares + quantity >= 0) {\n        availableShares += quantity;\n        active = (availableShares > 0);\n    }\n}\n\nvoid Stock::setActive(bool status) {\n    active = status;\n}\n\nvoid Stock::displayInfo() const {\n    std::cout << \"Stock: \" << companyName << \" (\" << symbol << \")\" << std::endl;\n    std::cout << \"Current Price: $\" << std::fixed << std::setprecision(2) << currentPrice << std::endl;\n    std::cout << \"Available Shares: \" << availableShares << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Stock.hpp",
    "content": "#ifndef STOCK_HPP\n#define STOCK_HPP\n\n#include <string>\n\nclass Stock {\nprivate:\n    std::string symbol;\n    std::string companyName;\n    double currentPrice;\n    int availableShares;\n    bool active;\n\npublic:\n    Stock(std::string symbol, std::string companyName, double currentPrice, int availableShares);\n    \n    std::string getSymbol() const;\n    std::string getCompanyName() const;\n    double getCurrentPrice() const;\n    int getAvailableShares() const;\n    bool isActive() const;\n    \n    void setCurrentPrice(double price);\n    void updateShares(int quantity);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Transaction.cpp",
    "content": "#include \"Transaction.hpp\"\n#include <iostream>\n#include <iomanip>\n\nTransaction::Transaction(std::string transactionId, User* user, Stock* stock,\n                       TransactionType type, int quantity, double pricePerShare)\n    : transactionId(transactionId), user(user), stock(stock), type(type),\n      quantity(quantity), pricePerShare(pricePerShare) {\n    totalAmount = quantity * pricePerShare;\n    timestamp = std::time(nullptr);\n}\n\nstd::string Transaction::getTransactionId() const { return transactionId; }\nUser* Transaction::getUser() const { return user; }\nStock* Transaction::getStock() const { return stock; }\nTransactionType Transaction::getType() const { return type; }\nint Transaction::getQuantity() const { return quantity; }\ndouble Transaction::getPricePerShare() const { return pricePerShare; }\ndouble Transaction::getTotalAmount() const { return totalAmount; }\nstd::time_t Transaction::getTimestamp() const { return timestamp; }\n\nvoid Transaction::displayInfo() const {\n    std::cout << \"\\nTransaction Details:\" << std::endl;\n    std::cout << \"ID: \" << transactionId << std::endl;\n    std::cout << \"Type: \" << (type == TransactionType::BUY ? \"Buy\" : \"Sell\") << std::endl;\n    std::cout << \"Stock: \" << stock->getSymbol() << std::endl;\n    std::cout << \"Quantity: \" << quantity << std::endl;\n    std::cout << \"Price per Share: $\" << std::fixed << std::setprecision(2) << pricePerShare << std::endl;\n    std::cout << \"Total Amount: $\" << std::fixed << std::setprecision(2) << totalAmount << std::endl;\n    std::cout << \"Time: \" << std::ctime(&timestamp);\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/Transaction.hpp",
    "content": "#ifndef TRANSACTION_HPP\n#define TRANSACTION_HPP\n\n#include <string>\n#include <ctime>\n#include \"Stock.hpp\"\n#include \"User.hpp\"\n\nenum class TransactionType {\n    BUY,\n    SELL\n};\n\nclass Transaction {\nprivate:\n    std::string transactionId;\n    User* user;\n    Stock* stock;\n    TransactionType type;\n    int quantity;\n    double pricePerShare;\n    double totalAmount;\n    std::time_t timestamp;\n\npublic:\n    Transaction(std::string transactionId, User* user, Stock* stock,\n               TransactionType type, int quantity, double pricePerShare);\n    \n    std::string getTransactionId() const;\n    User* getUser() const;\n    Stock* getStock() const;\n    TransactionType getType() const;\n    int getQuantity() const;\n    double getPricePerShare() const;\n    double getTotalAmount() const;\n    std::time_t getTimestamp() const;\n    \n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <iomanip>\n\nUser::User(std::string userId, std::string username, std::string email)\n    : userId(userId), username(username), email(email), balance(0.0), active(true) {\n    portfolio = new Portfolio(userId);\n}\n\nUser::~User() {\n    delete portfolio;\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\ndouble User::getBalance() const { return balance; }\nPortfolio* User::getPortfolio() const { return portfolio; }\nbool User::isActive() const { return active; }\n\nbool User::deposit(double amount) {\n    if (amount > 0) {\n        balance += amount;\n        return true;\n    }\n    return false;\n}\n\nbool User::withdraw(double amount) {\n    if (amount > 0 && amount <= balance) {\n        balance -= amount;\n        return true;\n    }\n    return false;\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Balance: $\" << std::fixed << std::setprecision(2) << balance << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    portfolio->displayInfo();\n} "
  },
  {
    "path": "solutions/cpp/onlinestockbrokeragesystem/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include \"Portfolio.hpp\"\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    double balance;\n    Portfolio* portfolio;\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    double getBalance() const;\n    Portfolio* getPortfolio() const;\n    bool isActive() const;\n    \n    bool deposit(double amount);\n    bool withdraw(double amount);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/parkinglot/ParkingLot.cpp",
    "content": "#include \"ParkingLot.hpp\"\n#include <iostream>\n\nParkingLot::ParkingLot(int numCompact, int numRegular, int numLarge) \n    : capacity(numCompact + numRegular + numLarge), availableSpots(capacity) {\n    \n    int spotNumber = 1;\n    \n    // Create compact spots\n    for (int i = 0; i < numCompact; i++) {\n        spots.push_back(new ParkingSpot(spotNumber++, SpotType::COMPACT));\n    }\n    \n    // Create regular spots\n    for (int i = 0; i < numRegular; i++) {\n        spots.push_back(new ParkingSpot(spotNumber++, SpotType::REGULAR));\n    }\n    \n    // Create large spots\n    for (int i = 0; i < numLarge; i++) {\n        spots.push_back(new ParkingSpot(spotNumber++, SpotType::LARGE));\n    }\n}\n\nParkingLot::~ParkingLot() {\n    for (auto spot : spots) {\n        delete spot;\n    }\n}\n\nint ParkingLot::getCapacity() const { return capacity; }\nint ParkingLot::getAvailableSpots() const { return availableSpots; }\n\nbool ParkingLot::parkVehicle(Vehicle* vehicle) {\n    if (!vehicle) return false;\n    \n    // Check if vehicle is already parked\n    if (occupiedSpots.find(vehicle->getLicensePlate()) != occupiedSpots.end()) {\n        return false;\n    }\n    \n    ParkingSpot* spot = findAvailableSpot(vehicle);\n    if (!spot) return false;\n    \n    if (spot->parkVehicle(vehicle)) {\n        occupiedSpots[vehicle->getLicensePlate()] = spot;\n        availableSpots--;\n        return true;\n    }\n    return false;\n}\n\nVehicle* ParkingLot::removeVehicle(const std::string& licensePlate) {\n    auto it = occupiedSpots.find(licensePlate);\n    if (it == occupiedSpots.end()) return nullptr;\n    \n    ParkingSpot* spot = it->second;\n    Vehicle* vehicle = spot->removeVehicle();\n    if (vehicle) {\n        occupiedSpots.erase(it);\n        availableSpots++;\n    }\n    return vehicle;\n}\n\nParkingSpot* ParkingLot::findVehicle(const std::string& licensePlate) const {\n    auto it = occupiedSpots.find(licensePlate);\n    return it != occupiedSpots.end() ? it->second : nullptr;\n}\n\nvoid ParkingLot::displayInfo() const {\n    std::cout << \"\\nParking Lot Status:\" << std::endl;\n    std::cout << \"Total Capacity: \" << capacity << std::endl;\n    std::cout << \"Available Spots: \" << availableSpots << std::endl;\n    std::cout << \"Occupied Spots: \" << (capacity - availableSpots) << std::endl;\n}\n\nvoid ParkingLot::displayOccupancy() const {\n    std::cout << \"\\nDetailed Occupancy:\" << std::endl;\n    for (const auto& spot : spots) {\n        spot->displayInfo();\n    }\n}\n\nParkingSpot* ParkingLot::findAvailableSpot(const Vehicle* vehicle) const {\n    for (auto spot : spots) {\n        if (spot->isAvailable() && spot->canFitVehicle(vehicle)) {\n            return spot;\n        }\n    }\n    return nullptr;\n} "
  },
  {
    "path": "solutions/cpp/parkinglot/ParkingLot.hpp",
    "content": "#ifndef PARKING_LOT_HPP\n#define PARKING_LOT_HPP\n\n#include <vector>\n#include <map>\n#include <string>\n#include \"ParkingSpot.hpp\"\n\nclass ParkingLot {\nprivate:\n    std::vector<ParkingSpot*> spots;\n    std::map<std::string, ParkingSpot*> occupiedSpots;  // licensePlate -> spot\n    int capacity;\n    int availableSpots;\n\npublic:\n    ParkingLot(int numCompact, int numRegular, int numLarge);\n    ~ParkingLot();\n    \n    int getCapacity() const;\n    int getAvailableSpots() const;\n    \n    bool parkVehicle(Vehicle* vehicle);\n    Vehicle* removeVehicle(const std::string& licensePlate);\n    ParkingSpot* findVehicle(const std::string& licensePlate) const;\n    \n    void displayInfo() const;\n    void displayOccupancy() const;\n\nprivate:\n    ParkingSpot* findAvailableSpot(const Vehicle* vehicle) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/parkinglot/ParkingLotDemo.cpp",
    "content": "#include \"ParkingLot.hpp\"\n#include <iostream>\n\nint main() {\n    // Create parking lot with different types of spots\n    ParkingLot parkingLot(2, 3, 2);  // 2 compact, 3 regular, 2 large spots\n    \n    std::cout << \"Initial parking lot status:\" << std::endl;\n    parkingLot.displayInfo();\n    \n    // Create vehicles\n    Vehicle* car1 = new Vehicle(\"CAR001\", VehicleType::CAR, \"Red\");\n    Vehicle* car2 = new Vehicle(\"CAR002\", VehicleType::CAR, \"Blue\");\n    Vehicle* motorcycle = new Vehicle(\"MOTO001\", VehicleType::MOTORCYCLE, \"Black\");\n    Vehicle* truck = new Vehicle(\"TRUCK001\", VehicleType::TRUCK, \"White\");\n    \n    // Park vehicles\n    std::cout << \"\\nParking vehicles...\" << std::endl;\n    \n    if (parkingLot.parkVehicle(car1)) {\n        std::cout << \"Parked successfully: \";\n        car1->displayInfo();\n    }\n    \n    if (parkingLot.parkVehicle(motorcycle)) {\n        std::cout << \"Parked successfully: \";\n        motorcycle->displayInfo();\n    }\n    \n    if (parkingLot.parkVehicle(truck)) {\n        std::cout << \"Parked successfully: \";\n        truck->displayInfo();\n    }\n    \n    // Display current status\n    parkingLot.displayInfo();\n    parkingLot.displayOccupancy();\n    \n    // Remove a vehicle\n    std::cout << \"\\nRemoving vehicle CAR001...\" << std::endl;\n    Vehicle* removed = parkingLot.removeVehicle(\"CAR001\");\n    if (removed) {\n        std::cout << \"Removed successfully: \";\n        removed->displayInfo();\n        delete removed;\n    }\n    \n    // Try to park another car\n    if (parkingLot.parkVehicle(car2)) {\n        std::cout << \"Parked successfully: \";\n        car2->displayInfo();\n    }\n    \n    // Final status\n    std::cout << \"\\nFinal parking lot status:\" << std::endl;\n    parkingLot.displayInfo();\n    parkingLot.displayOccupancy();\n    \n    // Cleanup remaining vehicles\n    delete car2;\n    delete motorcycle;\n    delete truck;\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/parkinglot/ParkingSpot.cpp",
    "content": "#include \"ParkingSpot.hpp\"\n#include <iostream>\n\nParkingSpot::ParkingSpot(int spotNumber, SpotType type)\n    : spotNumber(spotNumber), type(type), vehicle(nullptr), available(true) {}\n\nint ParkingSpot::getSpotNumber() const { return spotNumber; }\nSpotType ParkingSpot::getType() const { return type; }\nVehicle* ParkingSpot::getVehicle() const { return vehicle; }\nbool ParkingSpot::isAvailable() const { return available; }\n\nbool ParkingSpot::canFitVehicle(const Vehicle* vehicle) const {\n    if (!vehicle) return false;\n    \n    switch (vehicle->getType()) {\n        case VehicleType::MOTORCYCLE:\n            return true;  // Can park in any spot\n            \n        case VehicleType::CAR:\n            return type != SpotType::COMPACT;\n            \n        case VehicleType::TRUCK:\n        case VehicleType::BUS:\n            return type == SpotType::LARGE;\n    }\n    return false;\n}\n\nbool ParkingSpot::parkVehicle(Vehicle* vehicle) {\n    if (!available || !canFitVehicle(vehicle)) return false;\n    \n    this->vehicle = vehicle;\n    available = false;\n    return true;\n}\n\nVehicle* ParkingSpot::removeVehicle() {\n    if (!vehicle) return nullptr;\n    \n    Vehicle* removedVehicle = vehicle;\n    vehicle = nullptr;\n    available = true;\n    return removedVehicle;\n}\n\nvoid ParkingSpot::displayInfo() const {\n    std::cout << \"Spot \" << spotNumber << \" (\";\n    switch (type) {\n        case SpotType::COMPACT: std::cout << \"Compact\"; break;\n        case SpotType::REGULAR: std::cout << \"Regular\"; break;\n        case SpotType::LARGE: std::cout << \"Large\"; break;\n    }\n    std::cout << \"): \" << (available ? \"Available\" : \"Occupied\");\n    if (vehicle) {\n        std::cout << \" by \";\n        vehicle->displayInfo();\n    } else {\n        std::cout << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/parkinglot/ParkingSpot.hpp",
    "content": "#ifndef PARKING_SPOT_HPP\n#define PARKING_SPOT_HPP\n\n#include \"Vehicle.hpp\"\n\nenum class SpotType {\n    COMPACT,\n    REGULAR,\n    LARGE\n};\n\nclass ParkingSpot {\nprivate:\n    int spotNumber;\n    SpotType type;\n    Vehicle* vehicle;\n    bool available;\n\npublic:\n    ParkingSpot(int spotNumber, SpotType type);\n    \n    int getSpotNumber() const;\n    SpotType getType() const;\n    Vehicle* getVehicle() const;\n    bool isAvailable() const;\n    \n    bool canFitVehicle(const Vehicle* vehicle) const;\n    bool parkVehicle(Vehicle* vehicle);\n    Vehicle* removeVehicle();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/parkinglot/README.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot should have multiple levels, each level with a certain number of parking spots.\n2. The parking lot should support different types of vehicles, such as cars, motorcycles, and trucks.\n3. Each parking spot should be able to accommodate a specific type of vehicle.\n4. The system should assign a parking spot to a vehicle upon entry and release it when the vehicle exits.\n5. The system should track the availability of parking spots and provide real-time information to customers.\n6. The system should handle multiple entry and exit points and support concurrent access.\n\n## Classes, Interfaces and Enumerations\n1. The **ParkingLot** class follows the Singleton pattern to ensure only one instance of the parking lot exists. It maintains a list of levels and provides methods to park and unpark vehicles.\n2. The **Level** class represents a level in the parking lot and contains a list of parking spots. It handles parking and unparking of vehicles within the level.\n3. The **ParkingSpot** class represents an individual parking spot and tracks the availability and the parked vehicle.\n4. The **Vehicle** class is an abstract base class for different types of vehicles. It is extended by Car, Motorcycle, and Truck classes.\n5. The **VehicleType** enum defines the different types of vehicles supported by the parking lot.\n6. Multi-threading is achieved through the use of synchronized keyword on critical sections to ensure thread safety.\n7. The **Main** class demonstrates the usage of the parking lot system.\n\n## Design Patterns Used:\n1. Singleton Pattern: Ensures only one instance of the ParkingLot class.\n2. Factory Pattern (optional extension): Could be used for creating vehicles based on input.\n3. Observer Pattern (optional extension): Could notify customers about available spots."
  },
  {
    "path": "solutions/cpp/parkinglot/Vehicle.cpp",
    "content": "#include \"Vehicle.hpp\"\n#include <iostream>\n\nVehicle::Vehicle(std::string licensePlate, VehicleType type, std::string color)\n    : licensePlate(licensePlate), type(type), color(color) {}\n\nstd::string Vehicle::getLicensePlate() const { return licensePlate; }\nVehicleType Vehicle::getType() const { return type; }\nstd::string Vehicle::getColor() const { return color; }\n\nvoid Vehicle::displayInfo() const {\n    std::cout << \"Vehicle: \" << color << \" \";\n    switch (type) {\n        case VehicleType::CAR: std::cout << \"Car\"; break;\n        case VehicleType::MOTORCYCLE: std::cout << \"Motorcycle\"; break;\n        case VehicleType::TRUCK: std::cout << \"Truck\"; break;\n        case VehicleType::BUS: std::cout << \"Bus\"; break;\n    }\n    std::cout << \" (License: \" << licensePlate << \")\" << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/parkinglot/Vehicle.hpp",
    "content": "#ifndef VEHICLE_HPP\n#define VEHICLE_HPP\n\n#include <string>\n\nenum class VehicleType {\n    CAR,\n    MOTORCYCLE,\n    TRUCK,\n    BUS\n};\n\nclass Vehicle {\nprivate:\n    std::string licensePlate;\n    VehicleType type;\n    std::string color;\n\npublic:\n    Vehicle(std::string licensePlate, VehicleType type, std::string color);\n    \n    std::string getLicensePlate() const;\n    VehicleType getType() const;\n    std::string getColor() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/pubsubsystem/Message.cpp",
    "content": "#include \"Message.hpp\"\n#include <iostream>\n\nMessage::Message(std::string topic, std::string content)\n    : topic(topic), content(content) {\n    timestamp = std::time(nullptr);\n}\n\nstd::string Message::getTopic() const { return topic; }\nstd::string Message::getContent() const { return content; }\nstd::time_t Message::getTimestamp() const { return timestamp; }\n\nvoid Message::displayInfo() const {\n    std::cout << \"Topic: \" << topic << std::endl;\n    std::cout << \"Content: \" << content << std::endl;\n    std::cout << \"Time: \" << std::ctime(&timestamp);\n} "
  },
  {
    "path": "solutions/cpp/pubsubsystem/Message.hpp",
    "content": "#ifndef MESSAGE_HPP\n#define MESSAGE_HPP\n\n#include <string>\n#include <ctime>\n\nclass Message {\nprivate:\n    std::string topic;\n    std::string content;\n    std::time_t timestamp;\n\npublic:\n    Message(std::string topic, std::string content);\n    \n    std::string getTopic() const;\n    std::string getContent() const;\n    std::time_t getTimestamp() const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/pubsubsystem/PubSubDemo.cpp",
    "content": "#include \"PubSubSystem.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    PubSubSystem system;\n    \n    // Create topics\n    Topic* tech = system.createTopic(\"Technology\", \"Tech news and updates\");\n    Topic* sports = system.createTopic(\"Sports\", \"Sports news and scores\");\n    Topic* weather = system.createTopic(\"Weather\", \"Weather updates\");\n    \n    std::cout << \"Initial topics:\" << std::endl;\n    system.displayTopics();\n    \n    // Add subscribers\n    Subscriber* sub1 = system.addSubscriber(\"John\");\n    Subscriber* sub2 = system.addSubscriber(\"Alice\");\n    Subscriber* sub3 = system.addSubscriber(\"Bob\");\n    \n    // Subscribe to topics\n    system.subscribe(sub1->getId(), \"Technology\");\n    system.subscribe(sub1->getId(), \"Weather\");\n    system.subscribe(sub2->getId(), \"Sports\");\n    system.subscribe(sub3->getId(), \"Technology\");\n    system.subscribe(sub3->getId(), \"Sports\");\n    \n    // Publish messages\n    std::cout << \"\\nPublishing messages...\" << std::endl;\n    \n    system.publish(\"Technology\", \"New AI breakthrough!\");\n    system.publish(\"Sports\", \"Team A wins championship!\");\n    system.publish(\"Weather\", \"Sunny weather expected\");\n    \n    // Small delay to simulate time passing\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    \n    // Display messages for each subscriber\n    std::cout << \"\\nChecking messages for subscribers:\" << std::endl;\n    system.displaySubscriberMessages(sub1->getId());\n    system.displaySubscriberMessages(sub2->getId());\n    system.displaySubscriberMessages(sub3->getId());\n    \n    // Unsubscribe and test\n    std::cout << \"\\nUnsubscribing John from Weather...\" << std::endl;\n    system.unsubscribe(sub1->getId(), \"Weather\");\n    \n    system.publish(\"Weather\", \"Storm warning!\");\n    \n    std::cout << \"\\nJohn's updated messages:\" << std::endl;\n    system.displaySubscriberMessages(sub1->getId());\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/pubsubsystem/PubSubSystem.cpp",
    "content": "#include \"PubSubSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nPubSubSystem::PubSubSystem() : subscriberIdCounter(1) {}\n\nPubSubSystem::~PubSubSystem() {\n    for (auto topic : topics) delete topic;\n    for (auto subscriber : subscribers) delete subscriber;\n}\n\nTopic* PubSubSystem::createTopic(const std::string& name, const std::string& description) {\n    if (findTopic(name)) return nullptr;\n    \n    Topic* topic = new Topic(name, description);\n    topics.push_back(topic);\n    return topic;\n}\n\nvoid PubSubSystem::removeTopic(const std::string& topicName) {\n    auto it = std::find_if(topics.begin(), topics.end(),\n        [topicName](Topic* topic) { return topic->getName() == topicName; });\n    \n    if (it != topics.end()) {\n        delete *it;\n        topics.erase(it);\n    }\n}\n\nSubscriber* PubSubSystem::addSubscriber(const std::string& name) {\n    std::string id = generateSubscriberId();\n    Subscriber* subscriber = new Subscriber(id, name);\n    subscribers.push_back(subscriber);\n    return subscriber;\n}\n\nvoid PubSubSystem::removeSubscriber(const std::string& subscriberId) {\n    // Remove from all topics first\n    for (auto topic : topics) {\n        topic->removeSubscriber(subscriberId);\n    }\n    \n    // Remove from subscribers list\n    auto it = std::find_if(subscribers.begin(), subscribers.end(),\n        [subscriberId](Subscriber* sub) { return sub->getId() == subscriberId; });\n    \n    if (it != subscribers.end()) {\n        delete *it;\n        subscribers.erase(it);\n    }\n}\n\nbool PubSubSystem::subscribe(const std::string& subscriberId, const std::string& topicName) {\n    Topic* topic = findTopic(topicName);\n    Subscriber* subscriber = findSubscriber(subscriberId);\n    \n    if (!topic || !subscriber) return false;\n    \n    topic->addSubscriber(subscriber);\n    return true;\n}\n\nbool PubSubSystem::unsubscribe(const std::string& subscriberId, const std::string& topicName) {\n    Topic* topic = findTopic(topicName);\n    if (!topic) return false;\n    \n    topic->removeSubscriber(subscriberId);\n    return true;\n}\n\nbool PubSubSystem::publish(const std::string& topicName, const std::string& content) {\n    Topic* topic = findTopic(topicName);\n    if (!topic || !topic->isActive()) return false;\n    \n    Message message(topicName, content);\n    topic->publishMessage(message);\n    return true;\n}\n\nvoid PubSubSystem::displayTopics() const {\n    std::cout << \"\\nAvailable Topics:\" << std::endl;\n    for (const auto& topic : topics) {\n        topic->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid PubSubSystem::displaySubscribers() const {\n    std::cout << \"\\nRegistered Subscribers:\" << std::endl;\n    for (const auto& subscriber : subscribers) {\n        subscriber->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid PubSubSystem::displaySubscriberMessages(const std::string& subscriberId) const {\n    if (Subscriber* subscriber = findSubscriber(subscriberId)) {\n        subscriber->displayMessages();\n    }\n}\n\nTopic* PubSubSystem::findTopic(const std::string& topicName) const {\n    auto it = std::find_if(topics.begin(), topics.end(),\n        [topicName](Topic* topic) { return topic->getName() == topicName; });\n    return it != topics.end() ? *it : nullptr;\n}\n\nSubscriber* PubSubSystem::findSubscriber(const std::string& subscriberId) const {\n    auto it = std::find_if(subscribers.begin(), subscribers.end(),\n        [subscriberId](Subscriber* sub) { return sub->getId() == subscriberId; });\n    return it != subscribers.end() ? *it : nullptr;\n}\n\nstd::string PubSubSystem::generateSubscriberId() {\n    return \"SUB\" + std::to_string(subscriberIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/pubsubsystem/PubSubSystem.hpp",
    "content": "#ifndef PUB_SUB_SYSTEM_HPP\n#define PUB_SUB_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Topic.hpp\"\n#include \"Subscriber.hpp\"\n\nclass PubSubSystem {\nprivate:\n    std::vector<Topic*> topics;\n    std::vector<Subscriber*> subscribers;\n    int subscriberIdCounter;\n\npublic:\n    PubSubSystem();\n    ~PubSubSystem();\n    \n    Topic* createTopic(const std::string& name, const std::string& description);\n    void removeTopic(const std::string& topicName);\n    \n    Subscriber* addSubscriber(const std::string& name);\n    void removeSubscriber(const std::string& subscriberId);\n    \n    bool subscribe(const std::string& subscriberId, const std::string& topicName);\n    bool unsubscribe(const std::string& subscriberId, const std::string& topicName);\n    bool publish(const std::string& topicName, const std::string& content);\n    \n    void displayTopics() const;\n    void displaySubscribers() const;\n    void displaySubscriberMessages(const std::string& subscriberId) const;\n\nprivate:\n    Topic* findTopic(const std::string& topicName) const;\n    Subscriber* findSubscriber(const std::string& subscriberId) const;\n    std::string generateSubscriberId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/pubsubsystem/README.md",
    "content": "# Designing a Pub-Sub System in Java\n\n## Requirements\n1. The Pub-Sub system should allow publishers to publish messages to specific topics.\n2. Subscribers should be able to subscribe to topics of interest and receive messages published to those topics.\n3. The system should support multiple publishers and subscribers.\n4. Messages should be delivered to all subscribers of a topic in real-time.\n5. The system should handle concurrent access and ensure thread safety.\n6. The Pub-Sub system should be scalable and efficient in terms of message delivery.\n\n## Classes, Interfaces and Enumerations\n1. The **Message** class represents a message that can be published and received by subscribers. It contains the message content.\n2. The **Topic** class represents a topic to which messages can be published. It maintains a set of subscribers and provides methods to add and remove subscribers, as well as publish messages to all subscribers.\n3. The **Subscriber** interface defines the contract for subscribers. It declares the onMessage method that is invoked when a subscriber receives a message.\n4. The **PrintSubscriber** class is a concrete implementation of the Subscriber interface. It receives messages and prints them to the console.\n5. The **Publisher** class represents a publisher that publishes messages to a specific topic.\n6. The **PubSubSystem** class is the main class that manages topics, subscribers, and message publishing. It uses a ConcurrentHashMap to store topics and an ExecutorService to handle concurrent message publishing.\n7. The **PubSubDemo** class demonstrates the usage of the Pub-Sub system by creating topics, subscribers, and publishers, and publishing messages."
  },
  {
    "path": "solutions/cpp/pubsubsystem/Subscriber.cpp",
    "content": "#include \"Subscriber.hpp\"\n#include <iostream>\n\nSubscriber::Subscriber(std::string id, std::string name)\n    : id(id), name(name), active(true) {}\n\nstd::string Subscriber::getId() const { return id; }\nstd::string Subscriber::getName() const { return name; }\nbool Subscriber::isActive() const { return active; }\nconst std::vector<Message>& Subscriber::getMessageQueue() const { return messageQueue; }\n\nvoid Subscriber::receiveMessage(const Message& message) {\n    if (active) {\n        messageQueue.push_back(message);\n    }\n}\n\nvoid Subscriber::displayMessages() const {\n    std::cout << \"\\nMessages for \" << name << \":\" << std::endl;\n    if (messageQueue.empty()) {\n        std::cout << \"No messages\" << std::endl;\n        return;\n    }\n    \n    for (const auto& message : messageQueue) {\n        message.displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid Subscriber::clearMessages() {\n    messageQueue.clear();\n}\n\nvoid Subscriber::setActive(bool status) {\n    active = status;\n}\n\nvoid Subscriber::displayInfo() const {\n    std::cout << \"Subscriber: \" << name << \" (ID: \" << id << \")\" << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Pending Messages: \" << messageQueue.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/pubsubsystem/Subscriber.hpp",
    "content": "#ifndef SUBSCRIBER_HPP\n#define SUBSCRIBER_HPP\n\n#include <string>\n#include <vector>\n#include \"Message.hpp\"\n\nclass Subscriber {\nprivate:\n    std::string id;\n    std::string name;\n    std::vector<Message> messageQueue;\n    bool active;\n\npublic:\n    Subscriber(std::string id, std::string name);\n    \n    std::string getId() const;\n    std::string getName() const;\n    bool isActive() const;\n    const std::vector<Message>& getMessageQueue() const;\n    \n    void receiveMessage(const Message& message);\n    void displayMessages() const;\n    void clearMessages();\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/pubsubsystem/Topic.cpp",
    "content": "#include \"Topic.hpp\"\n#include <iostream>\n#include <algorithm>\n\nTopic::Topic(std::string name, std::string description)\n    : name(name), description(description), active(true) {}\n\nstd::string Topic::getName() const { return name; }\nstd::string Topic::getDescription() const { return description; }\nbool Topic::isActive() const { return active; }\nconst std::vector<Subscriber*>& Topic::getSubscribers() const { return subscribers; }\n\nvoid Topic::addSubscriber(Subscriber* subscriber) {\n    if (!subscriber) return;\n    \n    auto it = std::find(subscribers.begin(), subscribers.end(), subscriber);\n    if (it == subscribers.end()) {\n        subscribers.push_back(subscriber);\n    }\n}\n\nvoid Topic::removeSubscriber(const std::string& subscriberId) {\n    auto it = std::find_if(subscribers.begin(), subscribers.end(),\n        [subscriberId](Subscriber* sub) { return sub->getId() == subscriberId; });\n    \n    if (it != subscribers.end()) {\n        subscribers.erase(it);\n    }\n}\n\nvoid Topic::publishMessage(const Message& message) {\n    if (!active) return;\n    \n    for (auto subscriber : subscribers) {\n        subscriber->receiveMessage(message);\n    }\n}\n\nvoid Topic::setActive(bool status) {\n    active = status;\n}\n\nvoid Topic::displayInfo() const {\n    std::cout << \"Topic: \" << name << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Subscribers: \" << subscribers.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/pubsubsystem/Topic.hpp",
    "content": "#ifndef TOPIC_HPP\n#define TOPIC_HPP\n\n#include <string>\n#include <vector>\n#include \"Subscriber.hpp\"\n\nclass Topic {\nprivate:\n    std::string name;\n    std::string description;\n    std::vector<Subscriber*> subscribers;\n    bool active;\n\npublic:\n    Topic(std::string name, std::string description);\n    \n    std::string getName() const;\n    std::string getDescription() const;\n    bool isActive() const;\n    const std::vector<Subscriber*>& getSubscribers() const;\n    \n    void addSubscriber(Subscriber* subscriber);\n    void removeSubscriber(const std::string& subscriberId);\n    void publishMessage(const Message& message);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/MenuItem.cpp",
    "content": "#include \"MenuItem.hpp\"\n#include <iostream>\n#include <iomanip>\n\nMenuItem::MenuItem(std::string itemId, std::string name, std::string description,\n                  double price, Category category)\n    : itemId(itemId), name(name), description(description),\n      price(price), category(category), available(true) {}\n\nstd::string MenuItem::getItemId() const { return itemId; }\nstd::string MenuItem::getName() const { return name; }\nstd::string MenuItem::getDescription() const { return description; }\ndouble MenuItem::getPrice() const { return price; }\nCategory MenuItem::getCategory() const { return category; }\nbool MenuItem::isAvailable() const { return available; }\n\nvoid MenuItem::setPrice(double price) {\n    if (price > 0) {\n        this->price = price;\n    }\n}\n\nvoid MenuItem::setAvailable(bool status) {\n    available = status;\n}\n\nvoid MenuItem::displayInfo() const {\n    std::cout << name << \" (ID: \" << itemId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Price: $\" << std::fixed << std::setprecision(2) << price << std::endl;\n    std::cout << \"Category: \";\n    switch (category) {\n        case Category::APPETIZER: std::cout << \"Appetizer\"; break;\n        case Category::MAIN_COURSE: std::cout << \"Main Course\"; break;\n        case Category::DESSERT: std::cout << \"Dessert\"; break;\n        case Category::BEVERAGE: std::cout << \"Beverage\"; break;\n    }\n    std::cout << std::endl;\n    std::cout << \"Status: \" << (available ? \"Available\" : \"Not Available\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/MenuItem.hpp",
    "content": "#ifndef MENU_ITEM_HPP\n#define MENU_ITEM_HPP\n\n#include <string>\n\nenum class Category {\n    APPETIZER,\n    MAIN_COURSE,\n    DESSERT,\n    BEVERAGE\n};\n\nclass MenuItem {\nprivate:\n    std::string itemId;\n    std::string name;\n    std::string description;\n    double price;\n    Category category;\n    bool available;\n\npublic:\n    MenuItem(std::string itemId, std::string name, std::string description,\n            double price, Category category);\n    \n    std::string getItemId() const;\n    std::string getName() const;\n    std::string getDescription() const;\n    double getPrice() const;\n    Category getCategory() const;\n    bool isAvailable() const;\n    \n    void setPrice(double price);\n    void setAvailable(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/Order.cpp",
    "content": "#include \"Order.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <algorithm>\n\nOrder::Order(std::string orderId, Table* table)\n    : orderId(orderId), table(table), totalAmount(0.0), status(OrderStatus::PENDING) {\n    orderTime = std::time(nullptr);\n}\n\nOrder::~Order() {\n    for (auto item : items) {\n        delete item;\n    }\n}\n\nstd::string Order::getOrderId() const { return orderId; }\nTable* Order::getTable() const { return table; }\nconst std::vector<OrderItem*>& Order::getItems() const { return items; }\ndouble Order::getTotalAmount() const { return totalAmount; }\nstd::time_t Order::getOrderTime() const { return orderTime; }\nOrderStatus Order::getStatus() const { return status; }\n\nvoid Order::addItem(MenuItem* menuItem, int quantity) {\n    if (!menuItem || !menuItem->isAvailable()) return;\n    \n    // Check if item already exists\n    auto it = std::find_if(items.begin(), items.end(),\n        [menuItem](OrderItem* item) { return item->getMenuItem() == menuItem; });\n    \n    if (it != items.end()) {\n        (*it)->updateQuantity((*it)->getQuantity() + quantity);\n    } else {\n        items.push_back(new OrderItem(menuItem, quantity));\n    }\n    \n    calculateTotal();\n}\n\nvoid Order::removeItem(const std::string& itemId) {\n    auto it = std::find_if(items.begin(), items.end(),\n        [itemId](OrderItem* item) { return item->getMenuItem()->getItemId() == itemId; });\n    \n    if (it != items.end()) {\n        delete *it;\n        items.erase(it);\n        calculateTotal();\n    }\n}\n\nvoid Order::updateItemQuantity(const std::string& itemId, int quantity) {\n    auto it = std::find_if(items.begin(), items.end(),\n        [itemId](OrderItem* item) { return item->getMenuItem()->getItemId() == itemId; });\n    \n    if (it != items.end()) {\n        if (quantity <= 0) {\n            removeItem(itemId);\n        } else {\n            (*it)->updateQuantity(quantity);\n            calculateTotal();\n        }\n    }\n}\n\nvoid Order::setStatus(OrderStatus status) {\n    this->status = status;\n}\n\nvoid Order::calculateTotal() {\n    totalAmount = 0.0;\n    for (const auto& item : items) {\n        totalAmount += item->getSubtotal();\n    }\n}\n\nvoid Order::displayInfo() const {\n    std::cout << \"\\nOrder Details:\" << std::endl;\n    std::cout << \"Order ID: \" << orderId << std::endl;\n    std::cout << \"Table: \" << table->getTableNumber() << std::endl;\n    std::cout << \"Time: \" << std::ctime(&orderTime);\n    std::cout << \"Status: \";\n    switch (status) {\n        case OrderStatus::PENDING: std::cout << \"Pending\"; break;\n        case OrderStatus::PREPARING: std::cout << \"Preparing\"; break;\n        case OrderStatus::READY: std::cout << \"Ready\"; break;\n        case OrderStatus::SERVED: std::cout << \"Served\"; break;\n        case OrderStatus::PAID: std::cout << \"Paid\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"\\nItems:\" << std::endl;\n    for (const auto& item : items) {\n        item->displayInfo();\n    }\n    std::cout << \"------------------------\" << std::endl;\n    std::cout << \"Total Amount: $\" << std::fixed << std::setprecision(2) << totalAmount << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/Order.hpp",
    "content": "#ifndef ORDER_HPP\n#define ORDER_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n#include \"Table.hpp\"\n#include \"OrderItem.hpp\"\n\nenum class OrderStatus {\n    PENDING,\n    PREPARING,\n    READY,\n    SERVED,\n    PAID\n};\n\nclass Order {\nprivate:\n    std::string orderId;\n    Table* table;\n    std::vector<OrderItem*> items;\n    double totalAmount;\n    std::time_t orderTime;\n    OrderStatus status;\n\npublic:\n    Order(std::string orderId, Table* table);\n    ~Order();\n    \n    std::string getOrderId() const;\n    Table* getTable() const;\n    const std::vector<OrderItem*>& getItems() const;\n    double getTotalAmount() const;\n    std::time_t getOrderTime() const;\n    OrderStatus getStatus() const;\n    \n    void addItem(MenuItem* menuItem, int quantity);\n    void removeItem(const std::string& itemId);\n    void updateItemQuantity(const std::string& itemId, int quantity);\n    void setStatus(OrderStatus status);\n    void calculateTotal();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/OrderItem.cpp",
    "content": "#include \"OrderItem.hpp\"\n#include <iostream>\n#include <iomanip>\n\nOrderItem::OrderItem(MenuItem* menuItem, int quantity)\n    : menuItem(menuItem), quantity(quantity) {\n    subtotal = menuItem->getPrice() * quantity;\n}\n\nMenuItem* OrderItem::getMenuItem() const { return menuItem; }\nint OrderItem::getQuantity() const { return quantity; }\ndouble OrderItem::getSubtotal() const { return subtotal; }\n\nvoid OrderItem::updateQuantity(int quantity) {\n    if (quantity > 0) {\n        this->quantity = quantity;\n        subtotal = menuItem->getPrice() * quantity;\n    }\n}\n\nvoid OrderItem::displayInfo() const {\n    std::cout << menuItem->getName() << \" x \" << quantity \n              << \" = $\" << std::fixed << std::setprecision(2) << subtotal << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/OrderItem.hpp",
    "content": "#ifndef ORDER_ITEM_HPP\n#define ORDER_ITEM_HPP\n\n#include \"MenuItem.hpp\"\n\nclass OrderItem {\nprivate:\n    MenuItem* menuItem;\n    int quantity;\n    double subtotal;\n\npublic:\n    OrderItem(MenuItem* menuItem, int quantity);\n    \n    MenuItem* getMenuItem() const;\n    int getQuantity() const;\n    double getSubtotal() const;\n    \n    void updateQuantity(int quantity);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/README.md",
    "content": "# Designing Restaurant Management System\n\n## Requirements\n1. The restaurant management system should allow customers to place orders, view the menu, and make reservations.\n2. The system should manage the restaurant's inventory, including ingredients and menu items.\n3. The system should handle order processing, including order preparation, billing, and payment.\n4. The system should support multiple payment methods, such as cash, credit card, and mobile payments.\n5. The system should manage staff information, including roles, schedules, and performance tracking.\n6. The system should generate reports and analytics for management, such as sales reports and inventory analysis.\n7. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **MenuItem** class represents a menu item in the restaurant, with properties such as ID, name, description, price, and availability.\n2. The **Order** class represents an order placed by a customer, with properties such as ID, list of menu items, total amount, order status, and timestamp.\n3. The **OrderStatus** enum represents the different statuses an order can have, such as pending, preparing, ready, completed, or cancelled.\n4. The **Reservation** class represents a reservation made by a customer, with properties such as ID, customer name, contact number, party size, and reservation time.\n5. The **Payment** class represents a payment made for an order, with properties such as ID, amount, payment method, and payment status.\n6. The **PaymentMethod** enum represents the different payment methods supported by the restaurant, such as cash, credit card, or mobile payment.\n7. The **PaymentStatus** enum represents the status of a payment, which can be pending, completed, or failed.\n8. The Staff class represents a staff member of the restaurant, with properties such as ID, name, role, and contact number.\n9. The **Restaurant** class is the main class that manages the restaurant operations. It follows the Singleton pattern to ensure only one instance of the restaurant exists.\n10. The Restaurant class provides methods for managing menu items, placing orders, updating order status, making reservations, processing payments, and managing staff.\n11. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as orders and reservations.\n12. The notifyKitchen and notifyStaff methods are placeholders for notifying relevant staff about order updates and status changes.\n13. The **RestaurantManagementDemo** class demonstrates the usage of the restaurant management system by adding menu items, placing an order, making a reservation, processing a payment, updating order status, adding staff, and retrieving the menu."
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/RestaurantDemo.cpp",
    "content": "#include \"RestaurantSystem.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    RestaurantSystem restaurant;\n    \n    // Add menu items\n    MenuItem* burger = restaurant.addMenuItem(\"Burger\", \"Classic beef burger\", 12.99, Category::MAIN_COURSE);\n    MenuItem* fries = restaurant.addMenuItem(\"Fries\", \"Crispy french fries\", 4.99, Category::APPETIZER);\n    MenuItem* salad = restaurant.addMenuItem(\"Salad\", \"Fresh garden salad\", 8.99, Category::APPETIZER);\n    MenuItem* soda = restaurant.addMenuItem(\"Soda\", \"Carbonated drink\", 2.99, Category::BEVERAGE);\n    MenuItem* cake = restaurant.addMenuItem(\"Cake\", \"Chocolate cake\", 6.99, Category::DESSERT);\n    \n    // Add tables\n    restaurant.addTable(2);  // Table 1: 2 seats\n    restaurant.addTable(4);  // Table 2: 4 seats\n    restaurant.addTable(6);  // Table 3: 6 seats\n    \n    std::cout << \"Initial restaurant status:\" << std::endl;\n    restaurant.displayMenu();\n    restaurant.displayTables();\n    \n    // Create an order\n    Order* order1 = restaurant.createOrder(1);  // Order for table 1\n    if (order1) {\n        std::cout << \"\\nCreated new order: \" << order1->getOrderId() << std::endl;\n        \n        // Add items to order\n        restaurant.addToOrder(order1->getOrderId(), burger->getItemId(), 2);\n        restaurant.addToOrder(order1->getOrderId(), fries->getItemId(), 1);\n        restaurant.addToOrder(order1->getOrderId(), soda->getItemId(), 2);\n        \n        // Display order\n        restaurant.displayOrder(order1->getOrderId());\n        \n        // Update order status\n        std::cout << \"\\nUpdating order status...\" << std::endl;\n        restaurant.updateOrderStatus(order1->getOrderId(), OrderStatus::PREPARING);\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n        \n        restaurant.updateOrderStatus(order1->getOrderId(), OrderStatus::READY);\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n        \n        restaurant.updateOrderStatus(order1->getOrderId(), OrderStatus::SERVED);\n        \n        // Update order items\n        std::cout << \"\\nAdding dessert to order...\" << std::endl;\n        restaurant.addToOrder(order1->getOrderId(), cake->getItemId(), 2);\n        \n        // Display final order\n        restaurant.displayOrder(order1->getOrderId());\n        \n        // Complete order\n        std::cout << \"\\nCompleting order...\" << std::endl;\n        restaurant.updateOrderStatus(order1->getOrderId(), OrderStatus::PAID);\n    }\n    \n    // Display final restaurant status\n    std::cout << \"\\nFinal restaurant status:\" << std::endl;\n    restaurant.displayTables();\n    restaurant.displayOrders();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/RestaurantSystem.cpp",
    "content": "#include \"RestaurantSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nRestaurantSystem::RestaurantSystem() : orderIdCounter(1) {}\n\nRestaurantSystem::~RestaurantSystem() {\n    for (auto item : menu) delete item;\n    for (auto table : tables) delete table;\n    for (auto order : orders) delete order;\n}\n\nMenuItem* RestaurantSystem::addMenuItem(const std::string& name, const std::string& description,\n                                      double price, Category category) {\n    std::string itemId = \"ITEM\" + std::to_string(menu.size() + 1);\n    MenuItem* item = new MenuItem(itemId, name, description, price, category);\n    menu.push_back(item);\n    return item;\n}\n\nvoid RestaurantSystem::removeMenuItem(const std::string& itemId) {\n    auto it = std::find_if(menu.begin(), menu.end(),\n        [itemId](MenuItem* item) { return item->getItemId() == itemId; });\n    \n    if (it != menu.end()) {\n        delete *it;\n        menu.erase(it);\n    }\n}\n\nvoid RestaurantSystem::updateItemAvailability(const std::string& itemId, bool available) {\n    if (MenuItem* item = findMenuItem(itemId)) {\n        item->setAvailable(available);\n    }\n}\n\nTable* RestaurantSystem::addTable(int capacity) {\n    int tableNumber = tables.size() + 1;\n    Table* table = new Table(tableNumber, capacity);\n    tables.push_back(table);\n    return table;\n}\n\nvoid RestaurantSystem::updateTableStatus(int tableNumber, TableStatus status) {\n    if (Table* table = findTable(tableNumber)) {\n        table->setStatus(status);\n    }\n}\n\nOrder* RestaurantSystem::createOrder(int tableNumber) {\n    Table* table = findTable(tableNumber);\n    if (!table || table->getStatus() != TableStatus::AVAILABLE) return nullptr;\n    \n    std::string orderId = generateOrderId();\n    Order* order = new Order(orderId, table);\n    orders.push_back(order);\n    table->setStatus(TableStatus::OCCUPIED);\n    return order;\n}\n\nbool RestaurantSystem::addToOrder(const std::string& orderId, const std::string& itemId, int quantity) {\n    Order* order = findOrder(orderId);\n    MenuItem* item = findMenuItem(itemId);\n    \n    if (!order || !item) return false;\n    \n    order->addItem(item, quantity);\n    return true;\n}\n\nbool RestaurantSystem::updateOrderItem(const std::string& orderId, const std::string& itemId, int quantity) {\n    Order* order = findOrder(orderId);\n    if (!order) return false;\n    \n    order->updateItemQuantity(itemId, quantity);\n    return true;\n}\n\nbool RestaurantSystem::updateOrderStatus(const std::string& orderId, OrderStatus status) {\n    Order* order = findOrder(orderId);\n    if (!order) return false;\n    \n    order->setStatus(status);\n    if (status == OrderStatus::PAID) {\n        order->getTable()->setStatus(TableStatus::AVAILABLE);\n    }\n    return true;\n}\n\nvoid RestaurantSystem::displayMenu() const {\n    std::cout << \"\\n=== Restaurant Menu ===\" << std::endl;\n    for (const auto& item : menu) {\n        item->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid RestaurantSystem::displayTables() const {\n    std::cout << \"\\n=== Tables Status ===\" << std::endl;\n    for (const auto& table : tables) {\n        table->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid RestaurantSystem::displayOrders() const {\n    std::cout << \"\\n=== Current Orders ===\" << std::endl;\n    for (const auto& order : orders) {\n        order->displayInfo();\n    }\n}\n\nvoid RestaurantSystem::displayOrder(const std::string& orderId) const {\n    if (Order* order = findOrder(orderId)) {\n        order->displayInfo();\n    }\n}\n\nMenuItem* RestaurantSystem::findMenuItem(const std::string& itemId) const {\n    auto it = std::find_if(menu.begin(), menu.end(),\n        [itemId](MenuItem* item) { return item->getItemId() == itemId; });\n    return it != menu.end() ? *it : nullptr;\n}\n\nTable* RestaurantSystem::findTable(int tableNumber) const {\n    auto it = std::find_if(tables.begin(), tables.end(),\n        [tableNumber](Table* table) { return table->getTableNumber() == tableNumber; });\n    return it != tables.end() ? *it : nullptr;\n}\n\nOrder* RestaurantSystem::findOrder(const std::string& orderId) const {\n    auto it = std::find_if(orders.begin(), orders.end(),\n        [orderId](Order* order) { return order->getOrderId() == orderId; });\n    return it != orders.end() ? *it : nullptr;\n}\n\nstd::string RestaurantSystem::generateOrderId() {\n    return \"ORD\" + std::to_string(orderIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/RestaurantSystem.hpp",
    "content": "#ifndef RESTAURANT_SYSTEM_HPP\n#define RESTAURANT_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"MenuItem.hpp\"\n#include \"Table.hpp\"\n#include \"Order.hpp\"\n\nclass RestaurantSystem {\nprivate:\n    std::vector<MenuItem*> menu;\n    std::vector<Table*> tables;\n    std::vector<Order*> orders;\n    int orderIdCounter;\n\npublic:\n    RestaurantSystem();\n    ~RestaurantSystem();\n    \n    // Menu management\n    MenuItem* addMenuItem(const std::string& name, const std::string& description,\n                        double price, Category category);\n    void removeMenuItem(const std::string& itemId);\n    void updateItemAvailability(const std::string& itemId, bool available);\n    \n    // Table management\n    Table* addTable(int capacity);\n    void updateTableStatus(int tableNumber, TableStatus status);\n    \n    // Order management\n    Order* createOrder(int tableNumber);\n    bool addToOrder(const std::string& orderId, const std::string& itemId, int quantity);\n    bool updateOrderItem(const std::string& orderId, const std::string& itemId, int quantity);\n    bool updateOrderStatus(const std::string& orderId, OrderStatus status);\n    \n    // Display functions\n    void displayMenu() const;\n    void displayTables() const;\n    void displayOrders() const;\n    void displayOrder(const std::string& orderId) const;\n\nprivate:\n    MenuItem* findMenuItem(const std::string& itemId) const;\n    Table* findTable(int tableNumber) const;\n    Order* findOrder(const std::string& orderId) const;\n    std::string generateOrderId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/Table.cpp",
    "content": "#include \"Table.hpp\"\n#include <iostream>\n\nTable::Table(int tableNumber, int capacity)\n    : tableNumber(tableNumber), capacity(capacity), status(TableStatus::AVAILABLE) {}\n\nint Table::getTableNumber() const { return tableNumber; }\nint Table::getCapacity() const { return capacity; }\nTableStatus Table::getStatus() const { return status; }\n\nvoid Table::setStatus(TableStatus status) {\n    this->status = status;\n}\n\nvoid Table::displayInfo() const {\n    std::cout << \"Table \" << tableNumber << std::endl;\n    std::cout << \"Capacity: \" << capacity << \" persons\" << std::endl;\n    std::cout << \"Status: \";\n    switch (status) {\n        case TableStatus::AVAILABLE: std::cout << \"Available\"; break;\n        case TableStatus::OCCUPIED: std::cout << \"Occupied\"; break;\n        case TableStatus::RESERVED: std::cout << \"Reserved\"; break;\n    }\n    std::cout << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/restaurantmanagementsystem/Table.hpp",
    "content": "#ifndef TABLE_HPP\n#define TABLE_HPP\n\nenum class TableStatus {\n    AVAILABLE,\n    OCCUPIED,\n    RESERVED\n};\n\nclass Table {\nprivate:\n    int tableNumber;\n    int capacity;\n    TableStatus status;\n\npublic:\n    Table(int tableNumber, int capacity);\n    \n    int getTableNumber() const;\n    int getCapacity() const;\n    TableStatus getStatus() const;\n    \n    void setStatus(TableStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/ridesharingservice/Location.cpp",
    "content": "#include \"Location.hpp\"\n#include <iostream>\n#include <cmath>\n\nLocation::Location(double latitude, double longitude, std::string address)\n    : latitude(latitude), longitude(longitude), address(address) {}\n\ndouble Location::getLatitude() const { return latitude; }\ndouble Location::getLongitude() const { return longitude; }\nstd::string Location::getAddress() const { return address; }\n\ndouble Location::calculateDistance(const Location& other) const {\n    // Simple Euclidean distance for demonstration\n    double dx = latitude - other.latitude;\n    double dy = longitude - other.longitude;\n    return std::sqrt(dx * dx + dy * dy);\n}\n\nvoid Location::displayInfo() const {\n    std::cout << \"Location: \" << address << std::endl;\n    std::cout << \"Coordinates: (\" << latitude << \", \" << longitude << \")\" << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/ridesharingservice/Location.hpp",
    "content": "#ifndef LOCATION_HPP\n#define LOCATION_HPP\n\n#include <string>\n\nclass Location {\nprivate:\n    double latitude;\n    double longitude;\n    std::string address;\n\npublic:\n    Location(double latitude, double longitude, std::string address);\n    \n    double getLatitude() const;\n    double getLongitude() const;\n    std::string getAddress() const;\n    \n    double calculateDistance(const Location& other) const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/ridesharingservice/README.md",
    "content": "# Designing a Ride-Sharing Service Like Uber\n\n## Requirements\n1. The ride sharing service should allow passengers to request rides and drivers to accept and fulfill those ride requests.\n2. Passengers should be able to specify their pickup location, destination, and desired ride type (e.g., regular, premium).\n3. Drivers should be able to see available ride requests and choose to accept or decline them.\n4. The system should match ride requests with available drivers based on proximity and other factors.\n5. The system should calculate the fare for each ride based on distance, time, and ride type.\n6. The system should handle payments and process transactions between passengers and drivers.\n7. The system should provide real-time tracking of ongoing rides and notify passengers and drivers about ride status updates.\n8. The system should handle concurrent requests and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Passenger** class represents a passenger in the ride sharing service, with properties such as ID, name, contact information, and location.\n2. The **Driver** class represents a driver in the ride sharing service, with properties such as ID, name, contact information, license plate, location, and status (available or busy).\n3. The **Ride** class represents a ride requested by a passenger and accepted by a driver, with properties such as ID, passenger, driver, source location, destination location, status, and fare.\n4. The **Location** class represents a geographical location with latitude and longitude coordinates.\n5. The **Payment** class represents a payment made for a ride, with properties such as ID, ride, amount, and payment status.\n6. The **RideService** class is the main class that manages the ride sharing service. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The RideService class provides methods for adding passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides.\n8. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and ConcurrentLinkedQueue) to handle concurrent access to shared data, such as ride requests and driver availability.\n9. The notifyDrivers, notifyPassenger, and notifyDriver methods are placeholders for notifying relevant parties about ride status updates.\n10. The calculateFare and processPayment methods are placeholders for calculating ride fares and processing payments, respectively.\n11. The **RideSharingDemo** class demonstrates the usage of the ride sharing service by creating passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides."
  },
  {
    "path": "solutions/cpp/ridesharingservice/Ride.cpp",
    "content": "#include \"Ride.hpp\"\n#include <iostream>\n#include <iomanip>\n\nRide::Ride(std::string rideId, User* rider, Location* pickup, Location* dropoff)\n    : rideId(rideId), rider(rider), driver(nullptr), pickup(pickup), dropoff(dropoff),\n      distance(0.0), fare(0.0), status(RideStatus::REQUESTED) {\n    requestTime = std::time(nullptr);\n    completionTime = 0;\n    distance = pickup->calculateDistance(*dropoff);\n}\n\nRide::~Ride() {\n    delete pickup;\n    delete dropoff;\n}\n\nstd::string Ride::getRideId() const { return rideId; }\nUser* Ride::getRider() const { return rider; }\nUser* Ride::getDriver() const { return driver; }\nLocation* Ride::getPickup() const { return pickup; }\nLocation* Ride::getDropoff() const { return dropoff; }\ndouble Ride::getDistance() const { return distance; }\ndouble Ride::getFare() const { return fare; }\nstd::time_t Ride::getRequestTime() const { return requestTime; }\nstd::time_t Ride::getCompletionTime() const { return completionTime; }\nRideStatus Ride::getStatus() const { return status; }\n\nvoid Ride::assignDriver(User* driver) {\n    if (driver && driver->getType() == UserType::DRIVER) {\n        this->driver = driver;\n        status = RideStatus::ACCEPTED;\n    }\n}\n\nvoid Ride::calculateFare() {\n    // Simple fare calculation: base fare + distance-based fare\n    const double BASE_FARE = 5.0;\n    const double RATE_PER_KM = 2.0;\n    fare = BASE_FARE + (distance * RATE_PER_KM);\n}\n\nvoid Ride::updateStatus(RideStatus status) {\n    this->status = status;\n    if (status == RideStatus::COMPLETED) {\n        completionTime = std::time(nullptr);\n        calculateFare();\n    }\n}\n\nvoid Ride::displayInfo() const {\n    std::cout << \"\\nRide Details:\" << std::endl;\n    std::cout << \"ID: \" << rideId << std::endl;\n    std::cout << \"Rider: \" << rider->getName() << std::endl;\n    if (driver) {\n        std::cout << \"Driver: \" << driver->getName() << std::endl;\n    }\n    std::cout << \"Status: \";\n    switch (status) {\n        case RideStatus::REQUESTED: std::cout << \"Requested\"; break;\n        case RideStatus::ACCEPTED: std::cout << \"Accepted\"; break;\n        case RideStatus::IN_PROGRESS: std::cout << \"In Progress\"; break;\n        case RideStatus::COMPLETED: std::cout << \"Completed\"; break;\n        case RideStatus::CANCELLED: std::cout << \"Cancelled\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Pickup: \" << pickup->getAddress() << std::endl;\n    std::cout << \"Dropoff: \" << dropoff->getAddress() << std::endl;\n    std::cout << \"Distance: \" << std::fixed << std::setprecision(2) << distance << \" km\" << std::endl;\n    \n    if (status == RideStatus::COMPLETED) {\n        std::cout << \"Fare: $\" << std::fixed << std::setprecision(2) << fare << std::endl;\n        std::cout << \"Request Time: \" << std::ctime(&requestTime);\n        std::cout << \"Completion Time: \" << std::ctime(&completionTime);\n    }\n} "
  },
  {
    "path": "solutions/cpp/ridesharingservice/Ride.hpp",
    "content": "#ifndef RIDE_HPP\n#define RIDE_HPP\n\n#include <string>\n#include <ctime>\n#include \"User.hpp\"\n#include \"Location.hpp\"\n\nenum class RideStatus {\n    REQUESTED,\n    ACCEPTED,\n    IN_PROGRESS,\n    COMPLETED,\n    CANCELLED\n};\n\nclass Ride {\nprivate:\n    std::string rideId;\n    User* rider;\n    User* driver;\n    Location* pickup;\n    Location* dropoff;\n    double distance;\n    double fare;\n    std::time_t requestTime;\n    std::time_t completionTime;\n    RideStatus status;\n\npublic:\n    Ride(std::string rideId, User* rider, Location* pickup, Location* dropoff);\n    ~Ride();\n    \n    std::string getRideId() const;\n    User* getRider() const;\n    User* getDriver() const;\n    Location* getPickup() const;\n    Location* getDropoff() const;\n    double getDistance() const;\n    double getFare() const;\n    std::time_t getRequestTime() const;\n    std::time_t getCompletionTime() const;\n    RideStatus getStatus() const;\n    \n    void assignDriver(User* driver);\n    void calculateFare();\n    void updateStatus(RideStatus status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/ridesharingservice/RideDemo.cpp",
    "content": "#include \"RideService.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    RideService service;\n    \n    // Register users\n    User* rider1 = service.registerUser(\"John\", \"123-456-7890\", UserType::RIDER,\n        new Location(40.7128, -74.0060, \"New York City\"));\n    \n    User* rider2 = service.registerUser(\"Alice\", \"123-456-7891\", UserType::RIDER,\n        new Location(34.0522, -118.2437, \"Los Angeles\"));\n    \n    User* driver1 = service.registerUser(\"Bob\", \"123-456-7892\", UserType::DRIVER,\n        new Location(40.7300, -74.0100, \"Near NYC\"));\n    \n    User* driver2 = service.registerUser(\"Carol\", \"123-456-7893\", UserType::DRIVER,\n        new Location(34.0500, -118.2400, \"Near LA\"));\n    \n    std::cout << \"Initial users:\" << std::endl;\n    service.displayUsers();\n    \n    // Request rides\n    Location* pickup1 = new Location(40.7128, -74.0060, \"NYC Downtown\");\n    Location* dropoff1 = new Location(40.7589, -73.9851, \"Central Park\");\n    \n    std::cout << \"\\nRequesting ride...\" << std::endl;\n    Ride* ride1 = service.requestRide(rider1->getUserId(), pickup1, dropoff1);\n    \n    if (ride1) {\n        std::cout << \"Ride requested successfully:\" << std::endl;\n        ride1->displayInfo();\n        \n        // Update ride status\n        std::cout << \"\\nUpdating ride status...\" << std::endl;\n        service.updateRideStatus(ride1->getRideId(), RideStatus::IN_PROGRESS);\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n        \n        service.updateRideStatus(ride1->getRideId(), RideStatus::COMPLETED);\n        \n        // Rate users\n        std::cout << \"\\nRating users...\" << std::endl;\n        service.rateUser(ride1->getDriver()->getUserId(), 5.0);  // Rate driver\n        service.rateUser(ride1->getRider()->getUserId(), 4.5);   // Rate rider\n    }\n    \n    // Display final status\n    std::cout << \"\\nFinal user status:\" << std::endl;\n    service.displayUsers();\n    \n    std::cout << \"\\nRide history:\" << std::endl;\n    service.displayRides();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/ridesharingservice/RideService.cpp",
    "content": "#include \"RideService.hpp\"\n#include <iostream>\n#include <algorithm>\n\nRideService::RideService() : userIdCounter(1), rideIdCounter(1) {}\n\nRideService::~RideService() {\n    for (auto user : users) delete user;\n    for (auto ride : rides) delete ride;\n}\n\nUser* RideService::registerUser(const std::string& name, const std::string& phone,\n                              UserType type, Location* location) {\n    std::string userId = generateUserId();\n    User* user = new User(userId, name, phone, type, location);\n    users.push_back(user);\n    return user;\n}\n\nvoid RideService::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        delete *it;\n        users.erase(it);\n    }\n}\n\nRide* RideService::requestRide(const std::string& riderId, Location* pickup, Location* dropoff) {\n    User* rider = findUser(riderId);\n    if (!rider || rider->getType() != UserType::RIDER) return nullptr;\n    \n    std::string rideId = generateRideId();\n    Ride* ride = new Ride(rideId, rider, pickup, dropoff);\n    rides.push_back(ride);\n    \n    // Try to find and assign nearest driver\n    User* driver = findNearestDriver(*pickup);\n    if (driver) {\n        ride->assignDriver(driver);\n    }\n    \n    return ride;\n}\n\nbool RideService::assignDriver(const std::string& rideId, const std::string& driverId) {\n    Ride* ride = findRide(rideId);\n    User* driver = findUser(driverId);\n    \n    if (!ride || !driver || driver->getType() != UserType::DRIVER) return false;\n    \n    ride->assignDriver(driver);\n    return true;\n}\n\nbool RideService::updateRideStatus(const std::string& rideId, RideStatus status) {\n    Ride* ride = findRide(rideId);\n    if (!ride) return false;\n    \n    ride->updateStatus(status);\n    return true;\n}\n\nbool RideService::rateUser(const std::string& userId, double rating) {\n    User* user = findUser(userId);\n    if (!user) return false;\n    \n    user->updateRating(rating);\n    return true;\n}\n\nvoid RideService::displayUsers() const {\n    std::cout << \"\\n=== Registered Users ===\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid RideService::displayRides() const {\n    std::cout << \"\\n=== All Rides ===\" << std::endl;\n    for (const auto& ride : rides) {\n        ride->displayInfo();\n    }\n}\n\nvoid RideService::displayUserHistory(const std::string& userId) const {\n    std::cout << \"\\n=== Ride History for User \" << userId << \" ===\" << std::endl;\n    for (const auto& ride : rides) {\n        if ((ride->getRider()->getUserId() == userId) ||\n            (ride->getDriver() && ride->getDriver()->getUserId() == userId)) {\n            ride->displayInfo();\n        }\n    }\n}\n\nUser* RideService::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nRide* RideService::findRide(const std::string& rideId) const {\n    auto it = std::find_if(rides.begin(), rides.end(),\n        [rideId](Ride* ride) { return ride->getRideId() == rideId; });\n    return it != rides.end() ? *it : nullptr;\n}\n\nUser* RideService::findNearestDriver(const Location& pickup) const {\n    User* nearestDriver = nullptr;\n    double minDistance = std::numeric_limits<double>::max();\n    \n    for (auto user : users) {\n        if (user->getType() == UserType::DRIVER && user->isActive()) {\n            double distance = pickup.calculateDistance(*user->getCurrentLocation());\n            if (distance < minDistance) {\n                minDistance = distance;\n                nearestDriver = user;\n            }\n        }\n    }\n    \n    return nearestDriver;\n}\n\nstd::string RideService::generateUserId() {\n    return \"U\" + std::to_string(userIdCounter++);\n}\n\nstd::string RideService::generateRideId() {\n    return \"R\" + std::to_string(rideIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/ridesharingservice/RideService.hpp",
    "content": "#ifndef RIDE_SERVICE_HPP\n#define RIDE_SERVICE_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Ride.hpp\"\n\nclass RideService {\nprivate:\n    std::vector<User*> users;\n    std::vector<Ride*> rides;\n    int userIdCounter;\n    int rideIdCounter;\n\npublic:\n    RideService();\n    ~RideService();\n    \n    User* registerUser(const std::string& name, const std::string& phone,\n                      UserType type, Location* location);\n    void removeUser(const std::string& userId);\n    \n    Ride* requestRide(const std::string& riderId, Location* pickup, Location* dropoff);\n    bool assignDriver(const std::string& rideId, const std::string& driverId);\n    bool updateRideStatus(const std::string& rideId, RideStatus status);\n    bool rateUser(const std::string& userId, double rating);\n    \n    void displayUsers() const;\n    void displayRides() const;\n    void displayUserHistory(const std::string& userId) const;\n\nprivate:\n    User* findUser(const std::string& userId) const;\n    Ride* findRide(const std::string& rideId) const;\n    User* findNearestDriver(const Location& pickup) const;\n    std::string generateUserId();\n    std::string generateRideId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/ridesharingservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <iomanip>\n\nUser::User(std::string userId, std::string name, std::string phone, UserType type,\n           Location* location)\n    : userId(userId), name(name), phone(phone), type(type),\n      currentLocation(location), active(true), rating(5.0), totalRatings(0) {}\n\nUser::~User() {\n    delete currentLocation;\n}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getName() const { return name; }\nstd::string User::getPhone() const { return phone; }\nUserType User::getType() const { return type; }\nLocation* User::getCurrentLocation() const { return currentLocation; }\nbool User::isActive() const { return active; }\ndouble User::getRating() const { return rating; }\n\nvoid User::updateLocation(Location* location) {\n    delete currentLocation;\n    currentLocation = location;\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::updateRating(double newRating) {\n    if (newRating >= 1.0 && newRating <= 5.0) {\n        rating = ((rating * totalRatings) + newRating) / (totalRatings + 1);\n        totalRatings++;\n    }\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << name << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Type: \" << (type == UserType::RIDER ? \"Rider\" : \"Driver\") << std::endl;\n    std::cout << \"Phone: \" << phone << std::endl;\n    std::cout << \"Rating: \" << std::fixed << std::setprecision(1) << rating << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    if (currentLocation) {\n        currentLocation->displayInfo();\n    }\n} "
  },
  {
    "path": "solutions/cpp/ridesharingservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include \"Location.hpp\"\n\nenum class UserType {\n    RIDER,\n    DRIVER\n};\n\nclass User {\nprivate:\n    std::string userId;\n    std::string name;\n    std::string phone;\n    UserType type;\n    Location* currentLocation;\n    bool active;\n    double rating;\n    int totalRatings;\n\npublic:\n    User(std::string userId, std::string name, std::string phone, UserType type,\n         Location* location);\n    ~User();\n    \n    std::string getUserId() const;\n    std::string getName() const;\n    std::string getPhone() const;\n    UserType getType() const;\n    Location* getCurrentLocation() const;\n    bool isActive() const;\n    double getRating() const;\n    \n    void updateLocation(Location* location);\n    void setActive(bool status);\n    void updateRating(double newRating);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Board.cpp",
    "content": "#include \"Board.hpp\"\n#include <iostream>\n\nBoard::Board(int size) : size(size) {}\n\nint Board::getSize() const { return size; }\n\nvoid Board::addSnake(int start, int end) {\n    if (start > end && start < size) {\n        snakes[start] = end;\n    }\n}\n\nvoid Board::addLadder(int start, int end) {\n    if (end > start && end <= size) {\n        ladders[start] = end;\n    }\n}\n\nint Board::getNextPosition(int currentPos) const {\n    // Check for snakes\n    auto snakeIt = snakes.find(currentPos);\n    if (snakeIt != snakes.end()) {\n        std::cout << \"Oops! Snake at position \" << currentPos \n                  << \". Moving down to \" << snakeIt->second << std::endl;\n        return snakeIt->second;\n    }\n    \n    // Check for ladders\n    auto ladderIt = ladders.find(currentPos);\n    if (ladderIt != ladders.end()) {\n        std::cout << \"Yay! Ladder at position \" << currentPos \n                  << \". Moving up to \" << ladderIt->second << std::endl;\n        return ladderIt->second;\n    }\n    \n    return currentPos;\n}\n\nvoid Board::displayInfo() const {\n    std::cout << \"\\nBoard Information:\" << std::endl;\n    std::cout << \"Size: \" << size << \" squares\" << std::endl;\n    \n    std::cout << \"\\nSnakes:\" << std::endl;\n    for (const auto& snake : snakes) {\n        std::cout << \"From \" << snake.first << \" to \" << snake.second << std::endl;\n    }\n    \n    std::cout << \"\\nLadders:\" << std::endl;\n    for (const auto& ladder : ladders) {\n        std::cout << \"From \" << ladder.first << \" to \" << ladder.second << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Board.hpp",
    "content": "#ifndef BOARD_HPP\n#define BOARD_HPP\n\n#include <map>\n\nclass Board {\nprivate:\n    int size;\n    std::map<int, int> snakes;    // start -> end\n    std::map<int, int> ladders;   // start -> end\n\npublic:\n    Board(int size = 100);\n    \n    int getSize() const;\n    void addSnake(int start, int end);\n    void addLadder(int start, int end);\n    int getNextPosition(int currentPos) const;\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Dice.cpp",
    "content": "#include \"Dice.hpp\"\n#include <random>\n#include <ctime>\n\nDice::Dice(int sides) : sides(sides) {\n    std::srand(static_cast<unsigned int>(std::time(nullptr)));\n}\n\nint Dice::roll() const {\n    return (std::rand() % sides) + 1;\n} "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Dice.hpp",
    "content": "#ifndef DICE_HPP\n#define DICE_HPP\n\nclass Dice {\nprivate:\n    int sides;\n\npublic:\n    Dice(int sides = 6);\n    int roll() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Game.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nGame::Game(int boardSize) : board(boardSize), currentPlayerIndex(0), gameOver(false) {}\n\nGame::~Game() {\n    for (auto player : players) {\n        delete player;\n    }\n}\n\nvoid Game::addPlayer(const std::string& name) {\n    players.push_back(new Player(name));\n}\n\nvoid Game::setupBoard() {\n    // Add snakes\n    board.addSnake(99, 10);\n    board.addSnake(95, 75);\n    board.addSnake(92, 88);\n    board.addSnake(89, 68);\n    board.addSnake(74, 53);\n    board.addSnake(62, 19);\n    board.addSnake(46, 25);\n    board.addSnake(49, 11);\n    \n    // Add ladders\n    board.addLadder(2, 38);\n    board.addLadder(7, 14);\n    board.addLadder(8, 31);\n    board.addLadder(15, 26);\n    board.addLadder(21, 42);\n    board.addLadder(28, 84);\n    board.addLadder(36, 44);\n    board.addLadder(51, 67);\n    board.addLadder(71, 91);\n    board.addLadder(78, 98);\n    \n    board.displayInfo();\n}\n\nbool Game::makeMove() {\n    if (gameOver || players.empty()) return false;\n    \n    Player* currentPlayer = getCurrentPlayer();\n    std::cout << \"\\n\" << currentPlayer->getName() << \"'s turn\" << std::endl;\n    \n    int roll = dice.roll();\n    std::cout << \"Rolled: \" << roll << std::endl;\n    \n    movePlayer(currentPlayer, roll);\n    \n    if (checkWin(currentPlayer)) {\n        currentPlayer->setWinner(true);\n        gameOver = true;\n        std::cout << \"\\nCongratulations! \" << currentPlayer->getName() << \" wins!\" << std::endl;\n        return false;\n    }\n    \n    currentPlayerIndex = (currentPlayerIndex + 1) % players.size();\n    return true;\n}\n\nvoid Game::play() {\n    if (players.empty()) {\n        std::cout << \"No players in the game!\" << std::endl;\n        return;\n    }\n    \n    std::cout << \"\\nStarting the game...\" << std::endl;\n    while (makeMove()) {\n        displayStatus();\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n    }\n}\n\nvoid Game::displayStatus() const {\n    std::cout << \"\\nCurrent Game Status:\" << std::endl;\n    for (const auto& player : players) {\n        std::cout << player->getName() << \" at position \" << player->getPosition() << std::endl;\n    }\n}\n\nvoid Game::movePlayer(Player* player, int steps) {\n    int newPosition = player->getPosition() + steps;\n    \n    if (newPosition > board.getSize()) {\n        std::cout << \"Cannot move, need exact number to finish\" << std::endl;\n        return;\n    }\n    \n    newPosition = board.getNextPosition(newPosition);\n    player->setPosition(newPosition);\n    \n    std::cout << player->getName() << \" moved to position \" << newPosition << std::endl;\n}\n\nbool Game::checkWin(Player* player) const {\n    return player->getPosition() == board.getSize();\n}\n\nPlayer* Game::getCurrentPlayer() const {\n    return players[currentPlayerIndex];\n} "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Game.hpp",
    "content": "#ifndef GAME_HPP\n#define GAME_HPP\n\n#include <vector>\n#include \"Board.hpp\"\n#include \"Player.hpp\"\n#include \"Dice.hpp\"\n\nclass Game {\nprivate:\n    Board board;\n    std::vector<Player*> players;\n    Dice dice;\n    int currentPlayerIndex;\n    bool gameOver;\n\npublic:\n    Game(int boardSize = 100);\n    ~Game();\n    \n    void addPlayer(const std::string& name);\n    void setupBoard();\n    bool makeMove();\n    void play();\n    void displayStatus() const;\n    \nprivate:\n    void movePlayer(Player* player, int steps);\n    bool checkWin(Player* player) const;\n    Player* getCurrentPlayer() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/GameDemo.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n\nint main() {\n    Game game;\n    \n    // Add players\n    game.addPlayer(\"Player 1\");\n    game.addPlayer(\"Player 2\");\n    game.addPlayer(\"Player 3\");\n    \n    // Setup board with snakes and ladders\n    game.setupBoard();\n    \n    // Start the game\n    game.play();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Player.cpp",
    "content": "#include \"Player.hpp\"\n#include <iostream>\n\nPlayer::Player(std::string name)\n    : name(name), position(0), winner(false) {}\n\nstd::string Player::getName() const { return name; }\nint Player::getPosition() const { return position; }\nbool Player::isWinner() const { return winner; }\n\nvoid Player::setPosition(int position) {\n    this->position = position;\n}\n\nvoid Player::setWinner(bool status) {\n    winner = status;\n}\n\nvoid Player::displayInfo() const {\n    std::cout << \"Player: \" << name << std::endl;\n    std::cout << \"Position: \" << position << std::endl;\n    std::cout << \"Status: \" << (winner ? \"Winner!\" : \"Playing\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/Player.hpp",
    "content": "#ifndef PLAYER_HPP\n#define PLAYER_HPP\n\n#include <string>\n\nclass Player {\nprivate:\n    std::string name;\n    int position;\n    bool winner;\n\npublic:\n    Player(std::string name);\n    \n    std::string getName() const;\n    int getPosition() const;\n    bool isWinner() const;\n    \n    void setPosition(int position);\n    void setWinner(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/snakeandladdergame/README.md",
    "content": "# Designing Snake and Ladder Game\n\n## Requirements\n1. The game should be played on a board with numbered cells, typically with 100 cells.\n2. The board should have a predefined set of snakes and ladders, connecting certain cells.\n3. The game should support multiple players, each represented by a unique game piece.\n4. Players should take turns rolling a dice to determine the number of cells to move forward.\n5. If a player lands on a cell with the head of a snake, they should slide down to the cell with the tail of the snake.\n6. If a player lands on a cell with the base of a ladder, they should climb up to the cell at the top of the ladder.\n7. The game should continue until one of the players reaches the final cell on the board.\n8. The game should handle multiple game sessions concurrently, allowing different groups of players to play independently.\n\n## Classes, Interfaces and Enumerations\n1. The **Board** class represents the game board with a fixed size (e.g., 100 cells). It contains the positions of snakes and ladders and provides methods to initialize them and retrieve the new position after encountering a snake or ladder.\n2. The **Player** class represents a player in the game, with properties such as name and current position on the board.\n3. The **Snake** class represents a snake on the board, with properties for the start and end positions.\n4. The **Ladder** class represents a ladder on the board, with properties for the start and end positions.\n5. The **Dice** class represents a dice used in the game, with a method to roll the dice and return a random value between 1 and 6.\n6. The **SnakeAndLadderGame** class represents a single game session. It initializes the game with a board, a list of players, and a dice. The play method handles the game loop, where players take turns rolling the dice and moving their positions on the board. It checks for snakes and ladders and updates the player's position accordingly. The game continues until a player reaches the final position on the board.\n7. The **GameManager** class is a singleton that manages multiple game sessions. It maintains a list of active games and provides a method to start a new game with a list of player names. Each game is started in a separate thread to allow concurrent game sessions.\n8. The **SnakeAndLadderDemo** class demonstrates the usage of the game by creating an instance of the GameManager and starting two separate game sessions with different sets of players."
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/Post.cpp",
    "content": "#include \"Post.hpp\"\n#include <iostream>\n#include <algorithm>\n\nPost::Post(std::string postId, std::string userId, std::string content)\n    : postId(postId), userId(userId), content(content) {\n    timestamp = std::time(nullptr);\n}\n\nstd::string Post::getPostId() const { return postId; }\nstd::string Post::getUserId() const { return userId; }\nstd::string Post::getContent() const { return content; }\nstd::time_t Post::getTimestamp() const { return timestamp; }\nconst std::vector<std::string>& Post::getLikes() const { return likes; }\nconst std::vector<std::string>& Post::getComments() const { return comments; }\n\nvoid Post::addLike(const std::string& userId) {\n    if (std::find(likes.begin(), likes.end(), userId) == likes.end()) {\n        likes.push_back(userId);\n    }\n}\n\nvoid Post::removeLike(const std::string& userId) {\n    auto it = std::find(likes.begin(), likes.end(), userId);\n    if (it != likes.end()) {\n        likes.erase(it);\n    }\n}\n\nvoid Post::addComment(const std::string& comment) {\n    comments.push_back(comment);\n}\n\nvoid Post::displayInfo() const {\n    std::cout << \"\\nPost ID: \" << postId << std::endl;\n    std::cout << \"Content: \" << content << std::endl;\n    std::cout << \"Time: \" << std::ctime(&timestamp);\n    std::cout << \"Likes: \" << likes.size() << std::endl;\n    \n    if (!comments.empty()) {\n        std::cout << \"Comments:\" << std::endl;\n        for (const auto& comment : comments) {\n            std::cout << \"- \" << comment << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/Post.hpp",
    "content": "#ifndef POST_HPP\n#define POST_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n\nclass Post {\nprivate:\n    std::string postId;\n    std::string userId;\n    std::string content;\n    std::time_t timestamp;\n    std::vector<std::string> likes;  // Vector of userIds who liked\n    std::vector<std::string> comments;\n\npublic:\n    Post(std::string postId, std::string userId, std::string content);\n    \n    std::string getPostId() const;\n    std::string getUserId() const;\n    std::string getContent() const;\n    std::time_t getTimestamp() const;\n    const std::vector<std::string>& getLikes() const;\n    const std::vector<std::string>& getComments() const;\n    \n    void addLike(const std::string& userId);\n    void removeLike(const std::string& userId);\n    void addComment(const std::string& comment);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/README.md",
    "content": "# Designing a Social Network Like Facebook\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their personal information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their information, such as profile picture, bio, and interests.\n- Users should be able to update their profile information.\n#### Friend Connections:\n- Users should be able to send friend requests to other users.\n- Users should be able to accept or decline friend requests.\n- Users should be able to view their list of friends.\n#### Posts and Newsfeed:\n- Users should be able to create posts with text, images, or videos.\n- Users should be able to view a newsfeed consisting of posts from their friends and their own posts.\n- The newsfeed should be sorted in reverse chronological order.\n#### Likes and Comments:\n- Users should be able to like and comment on posts.\n- Users should be able to view the list of likes and comments on a post.\n#### Privacy and Security:\n- Users should be able to control the visibility of their posts and profile information.\n- The system should enforce secure access control to ensure data privacy.\n#### Notifications:\n- Users should receive notifications for events such as friend requests, likes, comments, and mentions.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the social networking system, containing properties such as ID, name, email, password, profile picture, bio, list of friends, and list of posts.\n2. The **Post** class represents a post created by a user, containing properties such as ID, user ID, content, image URLs, video URLs, timestamp, likes, and comments.\n3. The **Comment** class represents a comment made by a user on a post, containing properties such as ID, user ID, post ID, content, and timestamp.\n4. The **Notification** class represents a notification generated for a user, containing properties such as ID, user ID, notification type, content, and timestamp.\n5. The **NotificationType** enum defines the different types of notifications, such as friend request, friend request accepted, like, comment, and mention.\n6. The **SocialNetworkingService** class is the main class that manages the social networking system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SocialNetworkingService class provides methods for user registration, login, profile updates, friend requests, post creation, newsfeed generation, likes, comments, and notifications.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SocialNetworkingDemo** class demonstrates the usage of the social networking system by registering users, logging in, sending friend requests, creating posts, liking posts, commenting on posts, and retrieving newsfeed and notifications."
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/SocialNetwork.cpp",
    "content": "#include \"SocialNetwork.hpp\"\n#include <iostream>\n#include <algorithm>\n\nSocialNetwork::SocialNetwork() : userIdCounter(1), postIdCounter(1) {}\n\nSocialNetwork::~SocialNetwork() {\n    for (auto user : users) delete user;\n    for (auto post : posts) delete post;\n}\n\nUser* SocialNetwork::registerUser(const std::string& username, const std::string& email) {\n    std::string userId = generateUserId();\n    User* user = new User(userId, username, email);\n    users.push_back(user);\n    return user;\n}\n\nvoid SocialNetwork::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        // Remove user from friends lists\n        for (auto user : users) {\n            user->removeFriend(userId);\n        }\n        \n        // Remove user's posts\n        posts.erase(\n            std::remove_if(posts.begin(), posts.end(),\n                [userId](Post* post) { return post->getUserId() == userId; }),\n            posts.end()\n        );\n        \n        delete *it;\n        users.erase(it);\n    }\n}\n\nbool SocialNetwork::addFriend(const std::string& userId1, const std::string& userId2) {\n    User* user1 = findUser(userId1);\n    User* user2 = findUser(userId2);\n    \n    if (!user1 || !user2 || userId1 == userId2) return false;\n    \n    user1->addFriend(userId2);\n    user2->addFriend(userId1);\n    return true;\n}\n\nbool SocialNetwork::removeFriend(const std::string& userId1, const std::string& userId2) {\n    User* user1 = findUser(userId1);\n    User* user2 = findUser(userId2);\n    \n    if (!user1 || !user2) return false;\n    \n    user1->removeFriend(userId2);\n    user2->removeFriend(userId1);\n    return true;\n}\n\nPost* SocialNetwork::createPost(const std::string& userId, const std::string& content) {\n    if (!findUser(userId)) return nullptr;\n    \n    std::string postId = generatePostId();\n    Post* post = new Post(postId, userId, content);\n    posts.push_back(post);\n    return post;\n}\n\nbool SocialNetwork::likePost(const std::string& userId, const std::string& postId) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post) return false;\n    \n    post->addLike(userId);\n    return true;\n}\n\nbool SocialNetwork::unlikePost(const std::string& userId, const std::string& postId) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post) return false;\n    \n    post->removeLike(userId);\n    return true;\n}\n\nbool SocialNetwork::addComment(const std::string& postId, const std::string& comment) {\n    Post* post = findPost(postId);\n    if (!post) return false;\n    \n    post->addComment(comment);\n    return true;\n}\n\nvoid SocialNetwork::displayUserProfile(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (user) {\n        std::cout << \"\\nUser Profile:\" << std::endl;\n        user->displayInfo();\n    }\n}\n\nvoid SocialNetwork::displayUserFriends(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nFriends of \" << user->getUsername() << \":\" << std::endl;\n    for (const auto& friendId : user->getFriends()) {\n        if (User* friend_ = findUser(friendId)) {\n            std::cout << \"- \" << friend_->getUsername() << std::endl;\n        }\n    }\n}\n\nvoid SocialNetwork::displayUserPosts(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nPosts by \" << user->getUsername() << \":\" << std::endl;\n    for (const auto& post : posts) {\n        if (post->getUserId() == userId) {\n            post->displayInfo();\n        }\n    }\n}\n\nvoid SocialNetwork::displayAllUsers() const {\n    std::cout << \"\\nAll Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid SocialNetwork::displayAllPosts() const {\n    std::cout << \"\\nAll Posts:\" << std::endl;\n    for (const auto& post : posts) {\n        post->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nUser* SocialNetwork::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nPost* SocialNetwork::findPost(const std::string& postId) const {\n    auto it = std::find_if(posts.begin(), posts.end(),\n        [postId](Post* post) { return post->getPostId() == postId; });\n    return it != posts.end() ? *it : nullptr;\n}\n\nstd::string SocialNetwork::generateUserId() {\n    return \"U\" + std::to_string(userIdCounter++);\n}\n\nstd::string SocialNetwork::generatePostId() {\n    return \"P\" + std::to_string(postIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/SocialNetwork.hpp",
    "content": "#ifndef SOCIAL_NETWORK_HPP\n#define SOCIAL_NETWORK_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Post.hpp\"\n\nclass SocialNetwork {\nprivate:\n    std::vector<User*> users;\n    std::vector<Post*> posts;\n    int userIdCounter;\n    int postIdCounter;\n\npublic:\n    SocialNetwork();\n    ~SocialNetwork();\n    \n    // User management\n    User* registerUser(const std::string& username, const std::string& email);\n    void removeUser(const std::string& userId);\n    bool addFriend(const std::string& userId1, const std::string& userId2);\n    bool removeFriend(const std::string& userId1, const std::string& userId2);\n    \n    // Post management\n    Post* createPost(const std::string& userId, const std::string& content);\n    bool likePost(const std::string& userId, const std::string& postId);\n    bool unlikePost(const std::string& userId, const std::string& postId);\n    bool addComment(const std::string& postId, const std::string& comment);\n    \n    // Display functions\n    void displayUserProfile(const std::string& userId) const;\n    void displayUserFriends(const std::string& userId) const;\n    void displayUserPosts(const std::string& userId) const;\n    void displayAllUsers() const;\n    void displayAllPosts() const;\n\nprivate:\n    User* findUser(const std::string& userId) const;\n    Post* findPost(const std::string& postId) const;\n    std::string generateUserId();\n    std::string generatePostId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/SocialNetworkDemo.cpp",
    "content": "#include \"SocialNetwork.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    SocialNetwork network;\n    \n    // Register users\n    User* user1 = network.registerUser(\"john_doe\", \"john@email.com\");\n    User* user2 = network.registerUser(\"jane_smith\", \"jane@email.com\");\n    User* user3 = network.registerUser(\"bob_wilson\", \"bob@email.com\");\n    \n    std::cout << \"Initial users:\" << std::endl;\n    network.displayAllUsers();\n    \n    // Add friends\n    network.addFriend(user1->getUserId(), user2->getUserId());\n    network.addFriend(user2->getUserId(), user3->getUserId());\n    \n    // Create posts\n    Post* post1 = network.createPost(user1->getUserId(), \"Hello, world!\");\n    Post* post2 = network.createPost(user2->getUserId(), \"Having a great day!\");\n    \n    // Like and comment on posts\n    network.likePost(user2->getUserId(), post1->getPostId());\n    network.likePost(user3->getUserId(), post1->getPostId());\n    network.addComment(post1->getPostId(), \"Great post!\");\n    \n    network.likePost(user1->getUserId(), post2->getPostId());\n    network.addComment(post2->getPostId(), \"Glad to hear that!\");\n    \n    // Display user profiles and posts\n    std::cout << \"\\nUser Profiles and Posts:\" << std::endl;\n    network.displayUserProfile(user1->getUserId());\n    network.displayUserFriends(user1->getUserId());\n    network.displayUserPosts(user1->getUserId());\n    \n    network.displayUserProfile(user2->getUserId());\n    network.displayUserFriends(user2->getUserId());\n    network.displayUserPosts(user2->getUserId());\n    \n    // Remove a friend and display updated info\n    network.removeFriend(user1->getUserId(), user2->getUserId());\n    std::cout << \"\\nAfter removing friendship:\" << std::endl;\n    network.displayUserFriends(user1->getUserId());\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n\nUser::User(std::string userId, std::string username, std::string email)\n    : userId(userId), username(username), email(email), active(true) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\nconst std::set<std::string>& User::getFriends() const { return friends; }\nbool User::isActive() const { return active; }\n\nvoid User::addFriend(const std::string& friendId) {\n    friends.insert(friendId);\n}\n\nvoid User::removeFriend(const std::string& friendId) {\n    friends.erase(friendId);\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Friends: \" << friends.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/socialnetworkingservice/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n#include <set>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    std::set<std::string> friends;  // Set of friend userIds\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email);\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    const std::set<std::string>& getFriends() const;\n    bool isActive() const;\n    \n    void addFriend(const std::string& friendId);\n    void removeFriend(const std::string& friendId);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/splitwise/Expense.cpp",
    "content": "#include \"Expense.hpp\"\n#include <iostream>\n#include <iomanip>\n\nExpense::Expense(std::string expenseId, std::string description, double totalAmount,\n                std::string paidBy, const std::vector<std::string>& participants,\n                ExpenseType type)\n    : expenseId(expenseId), description(description), totalAmount(totalAmount),\n      paidBy(paidBy), participants(participants), type(type) {\n    timestamp = std::time(nullptr);\n    if (type == ExpenseType::EQUAL) {\n        calculateEqualShares();\n    }\n}\n\nstd::string Expense::getExpenseId() const { return expenseId; }\nstd::string Expense::getDescription() const { return description; }\ndouble Expense::getTotalAmount() const { return totalAmount; }\nstd::string Expense::getPaidBy() const { return paidBy; }\nconst std::vector<std::string>& Expense::getParticipants() const { return participants; }\nconst std::map<std::string, double>& Expense::getShares() const { return shares; }\nExpenseType Expense::getType() const { return type; }\nstd::time_t Expense::getTimestamp() const { return timestamp; }\n\nvoid Expense::setShares(const std::map<std::string, double>& shares) {\n    this->shares = shares;\n}\n\nvoid Expense::calculateEqualShares() {\n    double equalShare = totalAmount / participants.size();\n    for (const auto& participant : participants) {\n        shares[participant] = equalShare;\n    }\n}\n\nvoid Expense::displayInfo() const {\n    std::cout << \"\\nExpense Details:\" << std::endl;\n    std::cout << \"ID: \" << expenseId << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Amount: $\" << std::fixed << std::setprecision(2) << totalAmount << std::endl;\n    std::cout << \"Paid by: \" << paidBy << std::endl;\n    std::cout << \"Type: \";\n    switch (type) {\n        case ExpenseType::EQUAL: std::cout << \"Equal\"; break;\n        case ExpenseType::EXACT: std::cout << \"Exact\"; break;\n        case ExpenseType::PERCENT: std::cout << \"Percent\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Shares:\" << std::endl;\n    for (const auto& share : shares) {\n        std::cout << share.first << \": $\" << std::fixed << std::setprecision(2)\n                  << share.second << std::endl;\n    }\n    \n    std::cout << \"Time: \" << std::ctime(&timestamp);\n} "
  },
  {
    "path": "solutions/cpp/splitwise/Expense.hpp",
    "content": "#ifndef EXPENSE_HPP\n#define EXPENSE_HPP\n\n#include <string>\n#include <vector>\n#include <map>\n#include <ctime>\n\nenum class ExpenseType {\n    EQUAL,\n    EXACT,\n    PERCENT\n};\n\nclass Expense {\nprivate:\n    std::string expenseId;\n    std::string description;\n    double totalAmount;\n    std::string paidBy;\n    std::vector<std::string> participants;\n    std::map<std::string, double> shares;  // userId -> share amount\n    ExpenseType type;\n    std::time_t timestamp;\n\npublic:\n    Expense(std::string expenseId, std::string description, double totalAmount,\n           std::string paidBy, const std::vector<std::string>& participants,\n           ExpenseType type);\n    \n    std::string getExpenseId() const;\n    std::string getDescription() const;\n    double getTotalAmount() const;\n    std::string getPaidBy() const;\n    const std::vector<std::string>& getParticipants() const;\n    const std::map<std::string, double>& getShares() const;\n    ExpenseType getType() const;\n    std::time_t getTimestamp() const;\n    \n    void setShares(const std::map<std::string, double>& shares);\n    void calculateEqualShares();\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/splitwise/README.md",
    "content": "# Designing Splitwise\n\n## Requirements\n1. The system should allow users to create accounts and manage their profile information.\n2. Users should be able to create groups and add other users to the groups.\n3. Users should be able to add expenses within a group, specifying the amount, description, and participants.\n4. The system should automatically split the expenses among the participants based on their share.\n5. Users should be able to view their individual balances with other users and settle up the balances.\n6. The system should support different split methods, such as equal split, percentage split, and exact amounts.\n7. Users should be able to view their transaction history and group expenses.\n8. The system should handle concurrent transactions and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the Splitwise system, with properties such as ID, name, email, and a map to store balances with other users.\n2. The **Group** class represents a group in Splitwise, containing a list of member users and a list of expenses.\n3. The **Expense** class represents an expense within a group, with properties such as ID, amount, description, the user who paid, and a list of splits.\n4. The **Split** class is an abstract class representing the split of an expense. It is extended by EqualSplit, PercentSplit, and ExactSplit classes to handle different split methods.\n5. The **Transaction** class represents a transaction between two users, with properties such as ID, sender, receiver, and amount.\n6. The **SplitwiseService** class is the main class that manages the Splitwise system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SplitwiseService class provides methods for adding users, groups, and expenses, splitting expenses, updating balances, settling balances, and creating transactions.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SplitwiseDemo** class demonstrates the usage of the Splitwise system by creating users, a group, adding an expense, settling balances, and printing user balances."
  },
  {
    "path": "solutions/cpp/splitwise/SplitwiseDemo.cpp",
    "content": "#include \"SplitwiseSystem.hpp\"\n#include <iostream>\n\nint main() {\n    SplitwiseSystem splitwise;\n    \n    // Register users\n    User* user1 = splitwise.registerUser(\"John\", \"john@email.com\");\n    User* user2 = splitwise.registerUser(\"Alice\", \"alice@email.com\");\n    User* user3 = splitwise.registerUser(\"Bob\", \"bob@email.com\");\n    \n    std::cout << \"Initial users:\" << std::endl;\n    splitwise.displayUsers();\n    \n    // Add expenses\n    std::vector<std::string> participants = {\n        user1->getUserId(), user2->getUserId(), user3->getUserId()\n    };\n    \n    // Equal split expense\n    Expense* dinner = splitwise.addExpense(\"Dinner\", 300.0, user1->getUserId(), participants);\n    \n    // Custom split expense\n    std::vector<std::string> movieParticipants = {\n        user1->getUserId(), user2->getUserId()\n    };\n    Expense* movie = splitwise.addExpense(\"Movie\", 100.0, user2->getUserId(),\n                                        movieParticipants, ExpenseType::EXACT);\n    \n    std::map<std::string, double> movieShares = {\n        {user1->getUserId(), 60.0},\n        {user2->getUserId(), 40.0}\n    };\n    splitwise.setExpenseShares(movie->getExpenseId(), movieShares);\n    \n    // Display expenses\n    std::cout << \"\\nAll expenses:\" << std::endl;\n    splitwise.displayExpenses();\n    \n    // Show balances\n    std::cout << \"\\nBalances after expenses:\" << std::endl;\n    splitwise.showAllBalances();\n    \n    // Show individual expenses\n    std::cout << \"\\nJohn's expenses:\" << std::endl;\n    splitwise.displayUserExpenses(user1->getUserId());\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/splitwise/SplitwiseSystem.cpp",
    "content": "#include \"SplitwiseSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n#include <numeric>\n\nSplitwiseSystem::SplitwiseSystem() : userIdCounter(1), expenseIdCounter(1) {}\n\nSplitwiseSystem::~SplitwiseSystem() {\n    for (auto user : users) delete user;\n    for (auto expense : expenses) delete expense;\n}\n\nUser* SplitwiseSystem::registerUser(const std::string& name, const std::string& email) {\n    std::string userId = generateUserId();\n    User* user = new User(userId, name, email);\n    users.push_back(user);\n    return user;\n}\n\nvoid SplitwiseSystem::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        delete *it;\n        users.erase(it);\n    }\n}\n\nExpense* SplitwiseSystem::addExpense(const std::string& description, double amount,\n                                   const std::string& paidBy,\n                                   const std::vector<std::string>& participants,\n                                   ExpenseType type) {\n    if (!findUser(paidBy)) return nullptr;\n    \n    std::string expenseId = generateExpenseId();\n    Expense* expense = new Expense(expenseId, description, amount, paidBy, participants, type);\n    expenses.push_back(expense);\n    \n    if (type == ExpenseType::EQUAL) {\n        settleExpense(expenseId);\n    }\n    \n    return expense;\n}\n\nbool SplitwiseSystem::setExpenseShares(const std::string& expenseId,\n                                     const std::map<std::string, double>& shares) {\n    Expense* expense = findExpense(expenseId);\n    if (!expense) return false;\n    \n    // Validate total shares equals expense amount\n    double totalShares = std::accumulate(shares.begin(), shares.end(), 0.0,\n        [](double sum, const auto& pair) { return sum + pair.second; });\n    \n    if (std::abs(totalShares - expense->getTotalAmount()) > 0.01) return false;\n    \n    expense->setShares(shares);\n    settleExpense(expenseId);\n    return true;\n}\n\nvoid SplitwiseSystem::settleExpense(const std::string& expenseId) {\n    Expense* expense = findExpense(expenseId);\n    if (!expense) return;\n    \n    const std::string& paidBy = expense->getPaidBy();\n    const auto& shares = expense->getShares();\n    \n    for (const auto& share : shares) {\n        if (share.first != paidBy) {\n            // Update balances for both users\n            User* payer = findUser(paidBy);\n            User* participant = findUser(share.first);\n            \n            if (payer && participant) {\n                payer->updateBalance(share.first, share.second);\n                participant->updateBalance(paidBy, -share.second);\n            }\n        }\n    }\n}\n\nvoid SplitwiseSystem::showBalance(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    user->displayBalances();\n}\n\nvoid SplitwiseSystem::showAllBalances() const {\n    std::cout << \"\\nAll Balances:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayBalances();\n    }\n}\n\nvoid SplitwiseSystem::displayUsers() const {\n    std::cout << \"\\nRegistered Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid SplitwiseSystem::displayExpenses() const {\n    std::cout << \"\\nAll Expenses:\" << std::endl;\n    for (const auto& expense : expenses) {\n        expense->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid SplitwiseSystem::displayUserExpenses(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nExpenses for \" << user->getName() << \":\" << std::endl;\n    for (const auto& expense : expenses) {\n        if (expense->getPaidBy() == userId ||\n            std::find(expense->getParticipants().begin(),\n                     expense->getParticipants().end(),\n                     userId) != expense->getParticipants().end()) {\n            expense->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nUser* SplitwiseSystem::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nExpense* SplitwiseSystem::findExpense(const std::string& expenseId) const {\n    auto it = std::find_if(expenses.begin(), expenses.end(),\n        [expenseId](Expense* expense) { return expense->getExpenseId() == expenseId; });\n    return it != expenses.end() ? *it : nullptr;\n}\n\nstd::string SplitwiseSystem::generateUserId() {\n    return \"U\" + std::to_string(userIdCounter++);\n}\n\nstd::string SplitwiseSystem::generateExpenseId() {\n    return \"E\" + std::to_string(expenseIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/splitwise/SplitwiseSystem.hpp",
    "content": "#ifndef SPLITWISE_SYSTEM_HPP\n#define SPLITWISE_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Expense.hpp\"\n\nclass SplitwiseSystem {\nprivate:\n    std::vector<User*> users;\n    std::vector<Expense*> expenses;\n    int userIdCounter;\n    int expenseIdCounter;\n\npublic:\n    SplitwiseSystem();\n    ~SplitwiseSystem();\n    \n    // User management\n    User* registerUser(const std::string& name, const std::string& email);\n    void removeUser(const std::string& userId);\n    \n    // Expense management\n    Expense* addExpense(const std::string& description, double amount,\n                       const std::string& paidBy,\n                       const std::vector<std::string>& participants,\n                       ExpenseType type = ExpenseType::EQUAL);\n    bool setExpenseShares(const std::string& expenseId,\n                         const std::map<std::string, double>& shares);\n    \n    // Balance management\n    void settleExpense(const std::string& expenseId);\n    void showBalance(const std::string& userId) const;\n    void showAllBalances() const;\n    \n    // Display functions\n    void displayUsers() const;\n    void displayExpenses() const;\n    void displayUserExpenses(const std::string& userId) const;\n\nprivate:\n    User* findUser(const std::string& userId) const;\n    Expense* findExpense(const std::string& expenseId) const;\n    void updateBalances(Expense* expense);\n    std::string generateUserId();\n    std::string generateExpenseId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/splitwise/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <iomanip>\n\nUser::User(std::string userId, std::string name, std::string email)\n    : userId(userId), name(name), email(email), active(true) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getName() const { return name; }\nstd::string User::getEmail() const { return email; }\nbool User::isActive() const { return active; }\ndouble User::getBalanceWith(const std::string& userId) const {\n    auto it = balances.find(userId);\n    return it != balances.end() ? it->second : 0.0;\n}\nconst std::map<std::string, double>& User::getBalances() const { return balances; }\n\nvoid User::updateBalance(const std::string& userId, double amount) {\n    balances[userId] += amount;\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << name << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n}\n\nvoid User::displayBalances() const {\n    std::cout << \"\\nBalances for \" << name << \":\" << std::endl;\n    for (const auto& balance : balances) {\n        std::cout << \"With \" << balance.first << \": $\"\n                  << std::fixed << std::setprecision(2) << balance.second << std::endl;\n    }\n} "
  },
  {
    "path": "solutions/cpp/splitwise/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <map>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string name;\n    std::string email;\n    std::map<std::string, double> balances;  // userId -> amount\n    bool active;\n\npublic:\n    User(std::string userId, std::string name, std::string email);\n    \n    std::string getUserId() const;\n    std::string getName() const;\n    std::string getEmail() const;\n    bool isActive() const;\n    double getBalanceWith(const std::string& userId) const;\n    const std::map<std::string, double>& getBalances() const;\n    \n    void updateBalance(const std::string& userId, double amount);\n    void setActive(bool status);\n    void displayInfo() const;\n    void displayBalances() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/stackoverflow/Comment.cpp",
    "content": "#include \"Comment.hpp\"\n#include <iostream>\n\nComment::Comment(std::string commentId, std::string userId, std::string content)\n    : commentId(commentId), userId(userId), content(content) {\n    timestamp = std::time(nullptr);\n}\n\nstd::string Comment::getCommentId() const { return commentId; }\nstd::string Comment::getUserId() const { return userId; }\nstd::string Comment::getContent() const { return content; }\nstd::time_t Comment::getTimestamp() const { return timestamp; }\n\nvoid Comment::displayInfo() const {\n    std::cout << \"- \" << content << \" (by User \" << userId << \")\" << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/stackoverflow/Comment.hpp",
    "content": "#ifndef COMMENT_HPP\n#define COMMENT_HPP\n\n#include <string>\n#include <ctime>\n\nclass Comment {\nprivate:\n    std::string commentId;\n    std::string userId;\n    std::string content;\n    std::time_t timestamp;\n\npublic:\n    Comment(std::string commentId, std::string userId, std::string content);\n    \n    std::string getCommentId() const;\n    std::string getUserId() const;\n    std::string getContent() const;\n    std::time_t getTimestamp() const;\n    \n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/stackoverflow/Post.cpp",
    "content": "#include \"Post.hpp\"\n#include <iostream>\n#include <algorithm>\n\nPost::Post(std::string postId, std::string userId, std::string content,\n           const std::vector<std::string>& tags, PostType type)\n    : postId(postId), userId(userId), content(content), tags(tags),\n      score(0), accepted(false), type(type) {\n    timestamp = std::time(nullptr);\n}\n\nPost::~Post() {\n    for (auto comment : comments) {\n        delete comment;\n    }\n}\n\nstd::string Post::getPostId() const { return postId; }\nstd::string Post::getUserId() const { return userId; }\nstd::string Post::getContent() const { return content; }\nconst std::vector<std::string>& Post::getTags() const { return tags; }\nconst std::vector<Comment*>& Post::getComments() const { return comments; }\nint Post::getScore() const { return score; }\nbool Post::isAccepted() const { return accepted; }\nPostType Post::getType() const { return type; }\nstd::time_t Post::getTimestamp() const { return timestamp; }\n\nvoid Post::addComment(Comment* comment) {\n    comments.push_back(comment);\n}\n\nbool Post::addVote(const std::string& userId) {\n    if (std::find(votes.begin(), votes.end(), userId) == votes.end()) {\n        votes.push_back(userId);\n        score++;\n        return true;\n    }\n    return false;\n}\n\nbool Post::removeVote(const std::string& userId) {\n    auto it = std::find(votes.begin(), votes.end(), userId);\n    if (it != votes.end()) {\n        votes.erase(it);\n        score--;\n        return true;\n    }\n    return false;\n}\n\nvoid Post::setAccepted(bool status) {\n    accepted = status;\n}\n\nvoid Post::displayInfo() const {\n    std::cout << \"\\nPost ID: \" << postId << std::endl;\n    std::cout << \"Type: \" << (type == PostType::QUESTION ? \"Question\" : \"Answer\") << std::endl;\n    std::cout << \"Content: \" << content << std::endl;\n    std::cout << \"Score: \" << score << std::endl;\n    std::cout << \"Status: \" << (accepted ? \"Accepted\" : \"Not Accepted\") << std::endl;\n    \n    if (!tags.empty()) {\n        std::cout << \"Tags: \";\n        for (const auto& tag : tags) {\n            std::cout << tag << \" \";\n        }\n        std::cout << std::endl;\n    }\n    \n    if (!comments.empty()) {\n        std::cout << \"Comments:\" << std::endl;\n        for (const auto& comment : comments) {\n            comment->displayInfo();\n        }\n    }\n    \n    std::cout << \"Time: \" << std::ctime(&timestamp);\n} "
  },
  {
    "path": "solutions/cpp/stackoverflow/Post.hpp",
    "content": "#ifndef POST_HPP\n#define POST_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n#include \"Comment.hpp\"\n\nenum class PostType {\n    QUESTION,\n    ANSWER\n};\n\nclass Post {\nprivate:\n    std::string postId;\n    std::string userId;\n    std::string content;\n    std::vector<std::string> tags;\n    std::vector<Comment*> comments;\n    std::vector<std::string> votes;  // userIds who voted\n    int score;\n    bool accepted;\n    PostType type;\n    std::time_t timestamp;\n\npublic:\n    Post(std::string postId, std::string userId, std::string content,\n         const std::vector<std::string>& tags, PostType type);\n    ~Post();\n    \n    std::string getPostId() const;\n    std::string getUserId() const;\n    std::string getContent() const;\n    const std::vector<std::string>& getTags() const;\n    const std::vector<Comment*>& getComments() const;\n    int getScore() const;\n    bool isAccepted() const;\n    PostType getType() const;\n    std::time_t getTimestamp() const;\n    \n    void addComment(Comment* comment);\n    bool addVote(const std::string& userId);\n    bool removeVote(const std::string& userId);\n    void setAccepted(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/stackoverflow/README.md",
    "content": "# Designing Stack Overflow\n\n## Requirements\n1. Users can post questions, answer questions, and comment on questions and answers.\n2. Users can vote on questions and answers.\n3. Questions should have tags associated with them.\n4. Users can search for questions based on keywords, tags, or user profiles.\n5. The system should assign reputation score to users based on their activity and the quality of their contributions.\n6. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the Stack Overflow system, with properties such as id, username, email, and reputation.\n2. The **Question** class represents a question posted by a user, with properties such as id, title, content, author, answers, comments, tags, votes and creation date.\n3. The **Answer** class represents an answer to a question, with properties such as id, content, author, associated question, comments, votes and creation date.\n4. The **Comment** class represents a comment on a question or an answer, with properties such as id, content, author, and creation date.\n5. The **Tag** class represents a tag associated with a question, with properties such as id and name.\n6. The **Vote** class represents vote associated with a question/answer.\n7. The **StackOverflow** class is the main class that manages the Stack Overflow system. It provides methods for creating user, posting questions, answers, and comments, voting on questions and answers, searching for questions, and retrieving questions by tags and users.\n8.  The **StackOverflowDemo** class demonstrates the usage of the Stack Overflow system by creating users, posting questions and answers, voting, searching for questions, and retrieving questions by tags and users."
  },
  {
    "path": "solutions/cpp/stackoverflow/StackOverflow.cpp",
    "content": "#include \"StackOverflow.hpp\"\n#include <iostream>\n#include <algorithm>\n\nStackOverflow::StackOverflow() : userIdCounter(1), postIdCounter(1), commentIdCounter(1) {}\n\nStackOverflow::~StackOverflow() {\n    for (auto user : users) delete user;\n    for (auto post : posts) delete post;\n}\n\nUser* StackOverflow::registerUser(const std::string& username, const std::string& email) {\n    std::string userId = generateUserId();\n    User* user = new User(userId, username, email);\n    users.push_back(user);\n    return user;\n}\n\nvoid StackOverflow::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        delete *it;\n        users.erase(it);\n    }\n}\n\nPost* StackOverflow::addQuestion(const std::string& userId, const std::string& content,\n                                const std::vector<std::string>& tags) {\n    if (!findUser(userId)) return nullptr;\n    \n    std::string postId = generatePostId();\n    Post* question = new Post(postId, userId, content, tags, PostType::QUESTION);\n    posts.push_back(question);\n    return question;\n}\n\nPost* StackOverflow::addAnswer(const std::string& userId, const std::string& questionId,\n                              const std::string& content) {\n    if (!findUser(userId)) return nullptr;\n    \n    Post* question = findPost(questionId);\n    if (!question || question->getType() != PostType::QUESTION) return nullptr;\n    \n    std::string postId = generatePostId();\n    Post* answer = new Post(postId, userId, content, std::vector<std::string>(), PostType::ANSWER);\n    posts.push_back(answer);\n    return answer;\n}\n\nComment* StackOverflow::addComment(const std::string& userId, const std::string& postId,\n                                 const std::string& content) {\n    if (!findUser(userId)) return nullptr;\n    \n    Post* post = findPost(postId);\n    if (!post) return nullptr;\n    \n    std::string commentId = generateCommentId();\n    Comment* comment = new Comment(commentId, userId, content);\n    post->addComment(comment);\n    return comment;\n}\n\nbool StackOverflow::votePost(const std::string& userId, const std::string& postId) {\n    User* user = findUser(userId);\n    Post* post = findPost(postId);\n    \n    if (!user || !post || userId == post->getUserId()) return false;\n    \n    if (post->addVote(userId)) {\n        updateUserReputation(post->getUserId(), 10);  // +10 for upvote\n        return true;\n    }\n    return false;\n}\n\nbool StackOverflow::unvotePost(const std::string& userId, const std::string& postId) {\n    Post* post = findPost(postId);\n    if (!post) return false;\n    \n    if (post->removeVote(userId)) {\n        updateUserReputation(post->getUserId(), -10);  // -10 for removed upvote\n        return true;\n    }\n    return false;\n}\n\nbool StackOverflow::acceptAnswer(const std::string& userId, const std::string& answerId) {\n    Post* answer = findPost(answerId);\n    if (!answer || answer->getType() != PostType::ANSWER) return false;\n    \n    answer->setAccepted(true);\n    updateUserReputation(answer->getUserId(), 15);  // +15 for accepted answer\n    return true;\n}\n\nstd::vector<Post*> StackOverflow::searchQuestions(const std::string& tag) const {\n    std::vector<Post*> results;\n    for (const auto& post : posts) {\n        if (post->getType() == PostType::QUESTION) {\n            const auto& tags = post->getTags();\n            if (std::find(tags.begin(), tags.end(), tag) != tags.end()) {\n                results.push_back(post);\n            }\n        }\n    }\n    return results;\n}\n\nvoid StackOverflow::displayUserProfile(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    user->displayInfo();\n    \n    std::cout << \"\\nPosts by \" << user->getUsername() << \":\" << std::endl;\n    for (const auto& post : posts) {\n        if (post->getUserId() == userId) {\n            post->displayInfo();\n        }\n    }\n}\n\nvoid StackOverflow::displayQuestion(const std::string& questionId) const {\n    Post* question = findPost(questionId);\n    if (!question || question->getType() != PostType::QUESTION) return;\n    \n    question->displayInfo();\n    \n    std::cout << \"\\nAnswers:\" << std::endl;\n    for (const auto& post : posts) {\n        if (post->getType() == PostType::ANSWER) {\n            post->displayInfo();\n        }\n    }\n}\n\nvoid StackOverflow::displayAllQuestions() const {\n    std::cout << \"\\nAll Questions:\" << std::endl;\n    for (const auto& post : posts) {\n        if (post->getType() == PostType::QUESTION) {\n            post->displayInfo();\n            std::cout << \"------------------------\" << std::endl;\n        }\n    }\n}\n\nUser* StackOverflow::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nPost* StackOverflow::findPost(const std::string& postId) const {\n    auto it = std::find_if(posts.begin(), posts.end(),\n        [postId](Post* post) { return post->getPostId() == postId; });\n    return it != posts.end() ? *it : nullptr;\n}\n\nvoid StackOverflow::updateUserReputation(const std::string& userId, int points) {\n    if (User* user = findUser(userId)) {\n        user->updateReputation(points);\n    }\n}\n\nstd::string StackOverflow::generateUserId() {\n    return \"U\" + std::to_string(userIdCounter++);\n}\n\nstd::string StackOverflow::generatePostId() {\n    return \"P\" + std::to_string(postIdCounter++);\n}\n\nstd::string StackOverflow::generateCommentId() {\n    return \"C\" + std::to_string(commentIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/stackoverflow/StackOverflow.hpp",
    "content": "#ifndef STACK_OVERFLOW_HPP\n#define STACK_OVERFLOW_HPP\n\n#include <vector>\n#include <string>\n#include \"User.hpp\"\n#include \"Post.hpp\"\n#include \"Comment.hpp\"\n\nclass StackOverflow {\nprivate:\n    std::vector<User*> users;\n    std::vector<Post*> posts;\n    int userIdCounter;\n    int postIdCounter;\n    int commentIdCounter;\n\npublic:\n    StackOverflow();\n    ~StackOverflow();\n    \n    // User management\n    User* registerUser(const std::string& username, const std::string& email);\n    void removeUser(const std::string& userId);\n    \n    // Post management\n    Post* addQuestion(const std::string& userId, const std::string& content,\n                     const std::vector<std::string>& tags);\n    Post* addAnswer(const std::string& userId, const std::string& questionId,\n                   const std::string& content);\n    Comment* addComment(const std::string& userId, const std::string& postId,\n                       const std::string& content);\n    \n    // Voting and acceptance\n    bool votePost(const std::string& userId, const std::string& postId);\n    bool unvotePost(const std::string& userId, const std::string& postId);\n    bool acceptAnswer(const std::string& userId, const std::string& answerId);\n    \n    // Search and display\n    std::vector<Post*> searchQuestions(const std::string& tag) const;\n    void displayUserProfile(const std::string& userId) const;\n    void displayQuestion(const std::string& questionId) const;\n    void displayAllQuestions() const;\n\nprivate:\n    User* findUser(const std::string& userId) const;\n    Post* findPost(const std::string& postId) const;\n    void updateUserReputation(const std::string& userId, int points);\n    std::string generateUserId();\n    std::string generatePostId();\n    std::string generateCommentId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/stackoverflow/StackOverflowDemo.cpp",
    "content": "#include \"StackOverflow.hpp\"\n#include <iostream>\n\nint main() {\n    StackOverflow stackoverflow;\n    \n    // Register users\n    User* user1 = stackoverflow.registerUser(\"john_doe\", \"john@email.com\");\n    User* user2 = stackoverflow.registerUser(\"alice_smith\", \"alice@email.com\");\n    User* user3 = stackoverflow.registerUser(\"bob_wilson\", \"bob@email.com\");\n    \n    std::cout << \"Initial users:\" << std::endl;\n    stackoverflow.displayUserProfile(user1->getUserId());\n    \n    // Add questions\n    std::vector<std::string> tags = {\"c++\", \"programming\"};\n    Post* question1 = stackoverflow.addQuestion(\n        user1->getUserId(),\n        \"How do I use smart pointers in C++?\",\n        tags\n    );\n    \n    // Add answers\n    Post* answer1 = stackoverflow.addAnswer(\n        user2->getUserId(),\n        question1->getPostId(),\n        \"Smart pointers automatically manage memory for you...\"\n    );\n    \n    Post* answer2 = stackoverflow.addAnswer(\n        user3->getUserId(),\n        question1->getPostId(),\n        \"There are three main types of smart pointers...\"\n    );\n    \n    // Add comments\n    stackoverflow.addComment(\n        user1->getUserId(),\n        answer1->getPostId(),\n        \"Thanks, that's helpful!\"\n    );\n    \n    // Vote on posts\n    stackoverflow.votePost(user2->getUserId(), question1->getPostId());\n    stackoverflow.votePost(user3->getUserId(), answer1->getPostId());\n    stackoverflow.votePost(user1->getUserId(), answer2->getPostId());\n    \n    // Accept answer\n    stackoverflow.acceptAnswer(user1->getUserId(), answer1->getPostId());\n    \n    // Display results\n    std::cout << \"\\nQuestion with answers:\" << std::endl;\n    stackoverflow.displayQuestion(question1->getPostId());\n    \n    std::cout << \"\\nUser profiles after activity:\" << std::endl;\n    stackoverflow.displayUserProfile(user1->getUserId());\n    stackoverflow.displayUserProfile(user2->getUserId());\n    \n    // Search questions\n    std::cout << \"\\nSearching for C++ questions:\" << std::endl;\n    auto results = stackoverflow.searchQuestions(\"c++\");\n    for (const auto& question : results) {\n        question->displayInfo();\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/stackoverflow/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n\nUser::User(std::string userId, std::string username, std::string email)\n    : userId(userId), username(username), email(email), reputation(1), active(true) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\nint User::getReputation() const { return reputation; }\nconst std::vector<std::string>& User::getBadges() const { return badges; }\nbool User::isActive() const { return active; }\n\nvoid User::updateReputation(int points) {\n    reputation += points;\n}\n\nvoid User::addBadge(const std::string& badge) {\n    badges.push_back(badge);\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Reputation: \" << reputation << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    \n    if (!badges.empty()) {\n        std::cout << \"Badges:\" << std::endl;\n        for (const auto& badge : badges) {\n            std::cout << \"- \" << badge << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/stackoverflow/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    int reputation;\n    std::vector<std::string> badges;\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email);\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    int getReputation() const;\n    const std::vector<std::string>& getBadges() const;\n    bool isActive() const;\n    \n    void updateReputation(int points);\n    void addBadge(const std::string& badge);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/README.md",
    "content": "# Designing a Task Management System\n\n## Requirements\n1. The task management system should allow users to create, update, and delete tasks.\n2. Each task should have a title, description, due date, priority, and status (e.g., pending, in progress, completed).\n3. Users should be able to assign tasks to other users and set reminders for tasks.\n4. The system should support searching and filtering tasks based on various criteria (e.g., priority, due date, assigned user).\n5. Users should be able to mark tasks as completed and view their task history.\n6. The system should handle concurrent access to tasks and ensure data consistency.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the task management system, with properties such as id, name, and email.\n2. The **TaskStatus** enum defines the possible states of a task, such as pending, in progress, and completed.\n3. The **Task** class represents a task in the system, with properties like id, title, description, due date, priority, status, and assigned user.\n4. The **TaskManager** class is the core of the task management system and follows the Singleton pattern to ensure a single instance of the task manager.\n5. The TaskManager class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to tasks and ensure thread safety.\n6. The TaskManager class provides methods for creating, updating, deleting, searching, and filtering tasks, as well as marking tasks as completed and retrieving task history for a user.\n7. The **TaskManagementSystem** class serves as the entry point of the application and demonstrates the usage of the task management system."
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/Task.cpp",
    "content": "#include \"Task.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <algorithm>\n\nTask::Task(std::string taskId, std::string title, std::string description,\n           TaskPriority priority)\n    : taskId(taskId), title(title), description(description),\n      status(TaskStatus::TODO), priority(priority) {\n    dueDate = 0;  // No due date set\n}\n\nstd::string Task::getTaskId() const { return taskId; }\nstd::string Task::getTitle() const { return title; }\nstd::string Task::getDescription() const { return description; }\nstd::string Task::getAssignedTo() const { return assignedTo; }\nTaskStatus Task::getStatus() const { return status; }\nTaskPriority Task::getPriority() const { return priority; }\nstd::time_t Task::getDueDate() const { return dueDate; }\nconst std::vector<std::string>& Task::getDependencies() const { return dependencies; }\nconst std::vector<std::string>& Task::getComments() const { return comments; }\n\nvoid Task::setAssignedTo(const std::string& userId) {\n    assignedTo = userId;\n}\n\nvoid Task::setStatus(TaskStatus status) {\n    this->status = status;\n}\n\nvoid Task::setPriority(TaskPriority priority) {\n    this->priority = priority;\n}\n\nvoid Task::setDueDate(std::time_t dueDate) {\n    this->dueDate = dueDate;\n}\n\nvoid Task::addDependency(const std::string& taskId) {\n    if (std::find(dependencies.begin(), dependencies.end(), taskId) == dependencies.end()) {\n        dependencies.push_back(taskId);\n    }\n}\n\nvoid Task::removeDependency(const std::string& taskId) {\n    auto it = std::find(dependencies.begin(), dependencies.end(), taskId);\n    if (it != dependencies.end()) {\n        dependencies.erase(it);\n    }\n}\n\nvoid Task::addComment(const std::string& comment) {\n    comments.push_back(comment);\n}\n\nvoid Task::displayInfo() const {\n    std::cout << \"\\nTask: \" << title << \" (ID: \" << taskId << \")\" << std::endl;\n    std::cout << \"Description: \" << description << std::endl;\n    std::cout << \"Assigned to: \" << (assignedTo.empty() ? \"Unassigned\" : assignedTo) << std::endl;\n    \n    std::cout << \"Status: \";\n    switch (status) {\n        case TaskStatus::TODO: std::cout << \"To Do\"; break;\n        case TaskStatus::IN_PROGRESS: std::cout << \"In Progress\"; break;\n        case TaskStatus::COMPLETED: std::cout << \"Completed\"; break;\n        case TaskStatus::BLOCKED: std::cout << \"Blocked\"; break;\n    }\n    std::cout << std::endl;\n    \n    std::cout << \"Priority: \";\n    switch (priority) {\n        case TaskPriority::LOW: std::cout << \"Low\"; break;\n        case TaskPriority::MEDIUM: std::cout << \"Medium\"; break;\n        case TaskPriority::HIGH: std::cout << \"High\"; break;\n        case TaskPriority::URGENT: std::cout << \"Urgent\"; break;\n    }\n    std::cout << std::endl;\n    \n    if (dueDate != 0) {\n        std::cout << \"Due Date: \" << std::ctime(&dueDate);\n    }\n    \n    if (!dependencies.empty()) {\n        std::cout << \"Dependencies: \";\n        for (const auto& dep : dependencies) {\n            std::cout << dep << \" \";\n        }\n        std::cout << std::endl;\n    }\n    \n    if (!comments.empty()) {\n        std::cout << \"Comments:\" << std::endl;\n        for (const auto& comment : comments) {\n            std::cout << \"- \" << comment << std::endl;\n        }\n    }\n} "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/Task.hpp",
    "content": "#ifndef TASK_HPP\n#define TASK_HPP\n\n#include <string>\n#include <vector>\n#include <ctime>\n\nenum class TaskStatus {\n    TODO,\n    IN_PROGRESS,\n    COMPLETED,\n    BLOCKED\n};\n\nenum class TaskPriority {\n    LOW,\n    MEDIUM,\n    HIGH,\n    URGENT\n};\n\nclass Task {\nprivate:\n    std::string taskId;\n    std::string title;\n    std::string description;\n    std::string assignedTo;\n    TaskStatus status;\n    TaskPriority priority;\n    std::time_t dueDate;\n    std::vector<std::string> dependencies;  // Task IDs\n    std::vector<std::string> comments;\n\npublic:\n    Task(std::string taskId, std::string title, std::string description,\n         TaskPriority priority = TaskPriority::MEDIUM);\n    \n    std::string getTaskId() const;\n    std::string getTitle() const;\n    std::string getDescription() const;\n    std::string getAssignedTo() const;\n    TaskStatus getStatus() const;\n    TaskPriority getPriority() const;\n    std::time_t getDueDate() const;\n    const std::vector<std::string>& getDependencies() const;\n    const std::vector<std::string>& getComments() const;\n    \n    void setAssignedTo(const std::string& userId);\n    void setStatus(TaskStatus status);\n    void setPriority(TaskPriority priority);\n    void setDueDate(std::time_t dueDate);\n    void addDependency(const std::string& taskId);\n    void removeDependency(const std::string& taskId);\n    void addComment(const std::string& comment);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/TaskManager.cpp",
    "content": "#include \"TaskManager.hpp\"\n#include <iostream>\n#include <algorithm>\n\nTaskManager::TaskManager() : taskIdCounter(1), userIdCounter(1) {}\n\nTaskManager::~TaskManager() {\n    for (auto user : users) delete user;\n    for (auto task : tasks) delete task;\n}\n\nUser* TaskManager::registerUser(const std::string& username, const std::string& email) {\n    std::string userId = generateUserId();\n    User* user = new User(userId, username, email);\n    users.push_back(user);\n    return user;\n}\n\nvoid TaskManager::removeUser(const std::string& userId) {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    \n    if (it != users.end()) {\n        // Unassign all tasks from this user\n        for (auto task : tasks) {\n            if (task->getAssignedTo() == userId) {\n                task->setAssignedTo(\"\");\n            }\n        }\n        delete *it;\n        users.erase(it);\n    }\n}\n\nTask* TaskManager::createTask(const std::string& title, const std::string& description,\n                            TaskPriority priority) {\n    std::string taskId = generateTaskId();\n    Task* task = new Task(taskId, title, description, priority);\n    tasks.push_back(task);\n    return task;\n}\n\nvoid TaskManager::removeTask(const std::string& taskId) {\n    auto it = std::find_if(tasks.begin(), tasks.end(),\n        [taskId](Task* task) { return task->getTaskId() == taskId; });\n    \n    if (it != tasks.end()) {\n        // Remove task from user's assigned tasks\n        if (!(*it)->getAssignedTo().empty()) {\n            if (User* user = findUser((*it)->getAssignedTo())) {\n                user->removeTask(taskId);\n            }\n        }\n        \n        // Remove task from dependencies\n        for (auto task : tasks) {\n            task->removeDependency(taskId);\n        }\n        \n        delete *it;\n        tasks.erase(it);\n    }\n}\n\nbool TaskManager::assignTask(const std::string& taskId, const std::string& userId) {\n    Task* task = findTask(taskId);\n    User* user = findUser(userId);\n    \n    if (!task || !user) return false;\n    \n    // Remove task from previous assignee\n    if (!task->getAssignedTo().empty()) {\n        if (User* prevUser = findUser(task->getAssignedTo())) {\n            prevUser->removeTask(taskId);\n        }\n    }\n    \n    task->setAssignedTo(userId);\n    user->addTask(taskId);\n    return true;\n}\n\nbool TaskManager::updateTaskStatus(const std::string& taskId, TaskStatus status) {\n    Task* task = findTask(taskId);\n    if (!task) return false;\n    \n    if (status == TaskStatus::IN_PROGRESS && !checkDependenciesMet(task)) {\n        std::cout << \"Cannot start task: dependencies not met\" << std::endl;\n        return false;\n    }\n    \n    task->setStatus(status);\n    return true;\n}\n\nbool TaskManager::addTaskDependency(const std::string& taskId, const std::string& dependencyId) {\n    Task* task = findTask(taskId);\n    Task* dependency = findTask(dependencyId);\n    \n    if (!task || !dependency || taskId == dependencyId) return false;\n    \n    task->addDependency(dependencyId);\n    return true;\n}\n\nbool TaskManager::addTaskComment(const std::string& taskId, const std::string& comment) {\n    Task* task = findTask(taskId);\n    if (!task) return false;\n    \n    task->addComment(comment);\n    return true;\n}\n\nvoid TaskManager::displayUserTasks(const std::string& userId) const {\n    User* user = findUser(userId);\n    if (!user) return;\n    \n    std::cout << \"\\nTasks assigned to \" << user->getUsername() << \":\" << std::endl;\n    for (const auto& taskId : user->getAssignedTasks()) {\n        if (Task* task = findTask(taskId)) {\n            task->displayInfo();\n        }\n    }\n}\n\nvoid TaskManager::displayAllTasks() const {\n    std::cout << \"\\nAll Tasks:\" << std::endl;\n    for (const auto& task : tasks) {\n        task->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid TaskManager::displayAllUsers() const {\n    std::cout << \"\\nAll Users:\" << std::endl;\n    for (const auto& user : users) {\n        user->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nstd::vector<Task*> TaskManager::getTasksByStatus(TaskStatus status) const {\n    std::vector<Task*> result;\n    std::copy_if(tasks.begin(), tasks.end(), std::back_inserter(result),\n        [status](Task* task) { return task->getStatus() == status; });\n    return result;\n}\n\nstd::vector<Task*> TaskManager::getTasksByPriority(TaskPriority priority) const {\n    std::vector<Task*> result;\n    std::copy_if(tasks.begin(), tasks.end(), std::back_inserter(result),\n        [priority](Task* task) { return task->getPriority() == priority; });\n    return result;\n}\n\nUser* TaskManager::findUser(const std::string& userId) const {\n    auto it = std::find_if(users.begin(), users.end(),\n        [userId](User* user) { return user->getUserId() == userId; });\n    return it != users.end() ? *it : nullptr;\n}\n\nTask* TaskManager::findTask(const std::string& taskId) const {\n    auto it = std::find_if(tasks.begin(), tasks.end(),\n        [taskId](Task* task) { return task->getTaskId() == taskId; });\n    return it != tasks.end() ? *it : nullptr;\n}\n\nbool TaskManager::checkDependenciesMet(const Task* task) const {\n    for (const auto& depId : task->getDependencies()) {\n        Task* dependency = findTask(depId);\n        if (!dependency || dependency->getStatus() != TaskStatus::COMPLETED) {\n            return false;\n        }\n    }\n    return true;\n}\n\nstd::string TaskManager::generateTaskId() {\n    return \"T\" + std::to_string(taskIdCounter++);\n}\n\nstd::string TaskManager::generateUserId() {\n    return \"U\" + std::to_string(userIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/TaskManager.hpp",
    "content": "#ifndef TASK_MANAGER_HPP\n#define TASK_MANAGER_HPP\n\n#include <vector>\n#include <string>\n#include \"Task.hpp\"\n#include \"User.hpp\"\n\nclass TaskManager {\nprivate:\n    std::vector<Task*> tasks;\n    std::vector<User*> users;\n    int taskIdCounter;\n    int userIdCounter;\n\npublic:\n    TaskManager();\n    ~TaskManager();\n    \n    // User management\n    User* registerUser(const std::string& username, const std::string& email);\n    void removeUser(const std::string& userId);\n    \n    // Task management\n    Task* createTask(const std::string& title, const std::string& description,\n                    TaskPriority priority = TaskPriority::MEDIUM);\n    void removeTask(const std::string& taskId);\n    bool assignTask(const std::string& taskId, const std::string& userId);\n    bool updateTaskStatus(const std::string& taskId, TaskStatus status);\n    bool addTaskDependency(const std::string& taskId, const std::string& dependencyId);\n    bool addTaskComment(const std::string& taskId, const std::string& comment);\n    \n    // Display functions\n    void displayUserTasks(const std::string& userId) const;\n    void displayAllTasks() const;\n    void displayAllUsers() const;\n    std::vector<Task*> getTasksByStatus(TaskStatus status) const;\n    std::vector<Task*> getTasksByPriority(TaskPriority priority) const;\n\nprivate:\n    User* findUser(const std::string& userId) const;\n    Task* findTask(const std::string& taskId) const;\n    bool checkDependenciesMet(const Task* task) const;\n    std::string generateTaskId();\n    std::string generateUserId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/TaskManagerDemo.cpp",
    "content": "#include \"TaskManager.hpp\"\n#include <iostream>\n\nint main() {\n    TaskManager manager;\n    \n    // Register users\n    User* user1 = manager.registerUser(\"john_doe\", \"john@email.com\");\n    User* user2 = manager.registerUser(\"alice_smith\", \"alice@email.com\");\n    \n    std::cout << \"Initial users:\" << std::endl;\n    manager.displayAllUsers();\n    \n    // Create tasks\n    Task* task1 = manager.createTask(\"Design Database\", \"Create database schema\", TaskPriority::HIGH);\n    Task* task2 = manager.createTask(\"Implement API\", \"Develop REST API endpoints\", TaskPriority::MEDIUM);\n    Task* task3 = manager.createTask(\"Write Tests\", \"Create unit tests\", TaskPriority::MEDIUM);\n    \n    // Add dependencies\n    manager.addTaskDependency(task2->getTaskId(), task1->getTaskId());  // API depends on DB\n    manager.addTaskDependency(task3->getTaskId(), task2->getTaskId());  // Tests depend on API\n    \n    // Assign tasks\n    manager.assignTask(task1->getTaskId(), user1->getUserId());\n    manager.assignTask(task2->getTaskId(), user2->getUserId());\n    manager.assignTask(task3->getTaskId(), user2->getUserId());\n    \n    // Update task status\n    manager.updateTaskStatus(task1->getTaskId(), TaskStatus::IN_PROGRESS);\n    manager.addTaskComment(task1->getTaskId(), \"Started working on schema design\");\n    \n    // Try to start dependent task (should fail)\n    manager.updateTaskStatus(task2->getTaskId(), TaskStatus::IN_PROGRESS);\n    \n    // Complete first task\n    manager.updateTaskStatus(task1->getTaskId(), TaskStatus::COMPLETED);\n    manager.addTaskComment(task1->getTaskId(), \"Database schema completed\");\n    \n    // Now can start dependent task\n    manager.updateTaskStatus(task2->getTaskId(), TaskStatus::IN_PROGRESS);\n    \n    // Display current state\n    std::cout << \"\\nAll tasks:\" << std::endl;\n    manager.displayAllTasks();\n    \n    std::cout << \"\\nTasks by user:\" << std::endl;\n    manager.displayUserTasks(user1->getUserId());\n    manager.displayUserTasks(user2->getUserId());\n    \n    // Display tasks by status\n    std::cout << \"\\nIn Progress Tasks:\" << std::endl;\n    auto inProgressTasks = manager.getTasksByStatus(TaskStatus::IN_PROGRESS);\n    for (const auto& task : inProgressTasks) {\n        task->displayInfo();\n    }\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/User.cpp",
    "content": "#include \"User.hpp\"\n#include <iostream>\n#include <algorithm>\n\nUser::User(std::string userId, std::string username, std::string email)\n    : userId(userId), username(username), email(email), active(true) {}\n\nstd::string User::getUserId() const { return userId; }\nstd::string User::getUsername() const { return username; }\nstd::string User::getEmail() const { return email; }\nconst std::vector<std::string>& User::getAssignedTasks() const { return assignedTasks; }\nbool User::isActive() const { return active; }\n\nvoid User::addTask(const std::string& taskId) {\n    if (std::find(assignedTasks.begin(), assignedTasks.end(), taskId) == assignedTasks.end()) {\n        assignedTasks.push_back(taskId);\n    }\n}\n\nvoid User::removeTask(const std::string& taskId) {\n    auto it = std::find(assignedTasks.begin(), assignedTasks.end(), taskId);\n    if (it != assignedTasks.end()) {\n        assignedTasks.erase(it);\n    }\n}\n\nvoid User::setActive(bool status) {\n    active = status;\n}\n\nvoid User::displayInfo() const {\n    std::cout << \"User: \" << username << \" (ID: \" << userId << \")\" << std::endl;\n    std::cout << \"Email: \" << email << std::endl;\n    std::cout << \"Status: \" << (active ? \"Active\" : \"Inactive\") << std::endl;\n    std::cout << \"Assigned Tasks: \" << assignedTasks.size() << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/taskmanagementsystem/User.hpp",
    "content": "#ifndef USER_HPP\n#define USER_HPP\n\n#include <string>\n#include <vector>\n\nclass User {\nprivate:\n    std::string userId;\n    std::string username;\n    std::string email;\n    std::vector<std::string> assignedTasks;  // Task IDs\n    bool active;\n\npublic:\n    User(std::string userId, std::string username, std::string email);\n    \n    std::string getUserId() const;\n    std::string getUsername() const;\n    std::string getEmail() const;\n    const std::vector<std::string>& getAssignedTasks() const;\n    bool isActive() const;\n    \n    void addTask(const std::string& taskId);\n    void removeTask(const std::string& taskId);\n    void setActive(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/tictactoe/Board.cpp",
    "content": "#include \"Board.hpp\"\n#include <iostream>\n#include <iomanip>\n\nBoard::Board(int size) : size(size), EMPTY('-') {\n    reset();\n}\n\nint Board::getSize() const { return size; }\n\nchar Board::getCell(int row, int col) const {\n    return grid[row][col];\n}\n\nbool Board::isEmpty(int row, int col) const {\n    return grid[row][col] == EMPTY;\n}\n\nbool Board::isValidPosition(int row, int col) const {\n    return row >= 0 && row < size && col >= 0 && col < size;\n}\n\nbool Board::makeMove(int row, int col, char symbol) {\n    if (!isValidPosition(row, col) || !isEmpty(row, col)) {\n        return false;\n    }\n    grid[row][col] = symbol;\n    return true;\n}\n\nbool Board::isFull() const {\n    for (int i = 0; i < size; i++) {\n        for (int j = 0; j < size; j++) {\n            if (isEmpty(i, j)) return false;\n        }\n    }\n    return true;\n}\n\nbool Board::checkWin(char symbol) const {\n    return checkRows(symbol) || checkColumns(symbol) || checkDiagonals(symbol);\n}\n\nvoid Board::display() const {\n    std::cout << \"\\nCurrent Board:\" << std::endl;\n    for (int i = 0; i < size; i++) {\n        for (int j = 0; j < size; j++) {\n            std::cout << std::setw(3) << grid[i][j];\n        }\n        std::cout << std::endl;\n    }\n    std::cout << std::endl;\n}\n\nvoid Board::reset() {\n    grid.resize(size, std::vector<char>(size, EMPTY));\n}\n\nbool Board::checkRows(char symbol) const {\n    for (int i = 0; i < size; i++) {\n        bool win = true;\n        for (int j = 0; j < size; j++) {\n            if (grid[i][j] != symbol) {\n                win = false;\n                break;\n            }\n        }\n        if (win) return true;\n    }\n    return false;\n}\n\nbool Board::checkColumns(char symbol) const {\n    for (int j = 0; j < size; j++) {\n        bool win = true;\n        for (int i = 0; i < size; i++) {\n            if (grid[i][j] != symbol) {\n                win = false;\n                break;\n            }\n        }\n        if (win) return true;\n    }\n    return false;\n}\n\nbool Board::checkDiagonals(char symbol) const {\n    // Check main diagonal\n    bool win = true;\n    for (int i = 0; i < size; i++) {\n        if (grid[i][i] != symbol) {\n            win = false;\n            break;\n        }\n    }\n    if (win) return true;\n    \n    // Check other diagonal\n    win = true;\n    for (int i = 0; i < size; i++) {\n        if (grid[i][size-1-i] != symbol) {\n            win = false;\n            break;\n        }\n    }\n    return win;\n} "
  },
  {
    "path": "solutions/cpp/tictactoe/Board.hpp",
    "content": "#ifndef BOARD_HPP\n#define BOARD_HPP\n\n#include <vector>\n#include <string>\n\nclass Board {\nprivate:\n    std::vector<std::vector<char>> grid;\n    const int size;\n    const char EMPTY;\n\npublic:\n    Board(int size = 3);\n    \n    int getSize() const;\n    char getCell(int row, int col) const;\n    bool isEmpty(int row, int col) const;\n    bool isValidPosition(int row, int col) const;\n    bool makeMove(int row, int col, char symbol);\n    bool isFull() const;\n    bool checkWin(char symbol) const;\n    void display() const;\n    void reset();\n\nprivate:\n    bool checkRows(char symbol) const;\n    bool checkColumns(char symbol) const;\n    bool checkDiagonals(char symbol) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/tictactoe/Game.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n#include <limits>\n#include <cstdlib>\n#include <ctime>\n\nGame::Game(int boardSize) : board(boardSize), gameOver(false) {\n    player1 = nullptr;\n    player2 = nullptr;\n    currentPlayer = nullptr;\n    std::srand(static_cast<unsigned int>(std::time(nullptr)));\n}\n\nGame::~Game() {\n    delete player1;\n    delete player2;\n}\n\nvoid Game::initializePlayers(const std::string& p1Name, const std::string& p2Name) {\n    player1 = new Player(p1Name, 'X');\n    player2 = new Player(p2Name, 'O', false);  // Computer player\n    currentPlayer = player1;\n}\n\nvoid Game::play() {\n    while (!gameOver) {\n        board.display();\n        \n        if (currentPlayer->isHumanPlayer()) {\n            int row, col;\n            std::cout << currentPlayer->getName() << \"'s turn (symbol: \"\n                      << currentPlayer->getSymbol() << \")\" << std::endl;\n            std::cout << \"Enter row (0-\" << board.getSize()-1 << \"): \";\n            std::cin >> row;\n            std::cout << \"Enter column (0-\" << board.getSize()-1 << \"): \";\n            std::cin >> col;\n            \n            makeMove(row, col);\n        } else {\n            std::cout << \"Computer's turn...\" << std::endl;\n            computerMove();\n        }\n    }\n    \n    displayResult();\n}\n\nvoid Game::makeMove(int row, int col) {\n    if (!board.isValidPosition(row, col)) {\n        std::cout << \"Invalid position!\" << std::endl;\n        return;\n    }\n    \n    if (!board.isEmpty(row, col)) {\n        std::cout << \"Position already taken!\" << std::endl;\n        return;\n    }\n    \n    board.makeMove(row, col, currentPlayer->getSymbol());\n    \n    if (board.checkWin(currentPlayer->getSymbol())) {\n        gameOver = true;\n        return;\n    }\n    \n    if (board.isFull()) {\n        gameOver = true;\n        currentPlayer = nullptr;\n        return;\n    }\n    \n    switchPlayer();\n}\n\nvoid Game::switchPlayer() {\n    currentPlayer = (currentPlayer == player1) ? player2 : player1;\n}\n\nvoid Game::displayResult() const {\n    board.display();\n    if (currentPlayer) {\n        std::cout << currentPlayer->getName() << \" wins!\" << std::endl;\n    } else {\n        std::cout << \"It's a draw!\" << std::endl;\n    }\n}\n\nbool Game::isGameOver() const {\n    return gameOver;\n}\n\nPlayer* Game::getCurrentPlayer() const {\n    return currentPlayer;\n}\n\nvoid Game::computerMove() {\n    auto [row, col] = findBestMove();\n    makeMove(row, col);\n}\n\nstd::pair<int, int> Game::findBestMove() const {\n    int bestScore = std::numeric_limits<int>::min();\n    std::pair<int, int> bestMove = {0, 0};\n    \n    for (int i = 0; i < board.getSize(); i++) {\n        for (int j = 0; j < board.getSize(); j++) {\n            if (board.isEmpty(i, j)) {\n                Board tempBoard = board;  // Create a copy\n                tempBoard.makeMove(i, j, player2->getSymbol());\n                \n                int score = minimax(false, 0);\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestMove = {i, j};\n                }\n            }\n        }\n    }\n    \n    return bestMove;\n}\n\nint Game::minimax(bool isMax, int depth) const {\n    if (board.checkWin(player2->getSymbol())) return 10 - depth;\n    if (board.checkWin(player1->getSymbol())) return depth - 10;\n    if (board.isFull()) return 0;\n    \n    int bestScore = isMax ? std::numeric_limits<int>::min() : std::numeric_limits<int>::max();\n    \n    for (int i = 0; i < board.getSize(); i++) {\n        for (int j = 0; j < board.getSize(); j++) {\n            if (board.isEmpty(i, j)) {\n                Board tempBoard = board;  // Create a copy\n                tempBoard.makeMove(i, j, isMax ? player2->getSymbol() : player1->getSymbol());\n                \n                int score = minimax(!isMax, depth + 1);\n                bestScore = isMax ? std::max(score, bestScore) : std::min(score, bestScore);\n            }\n        }\n    }\n    \n    return bestScore;\n} "
  },
  {
    "path": "solutions/cpp/tictactoe/Game.hpp",
    "content": "#ifndef GAME_HPP\n#define GAME_HPP\n\n#include \"Board.hpp\"\n#include \"Player.hpp\"\n\nclass Game {\nprivate:\n    Board board;\n    Player* player1;\n    Player* player2;\n    Player* currentPlayer;\n    bool gameOver;\n\npublic:\n    Game(int boardSize = 3);\n    ~Game();\n    \n    void initializePlayers(const std::string& p1Name, const std::string& p2Name);\n    void play();\n    void makeMove(int row, int col);\n    void switchPlayer();\n    void displayResult() const;\n    bool isGameOver() const;\n    Player* getCurrentPlayer() const;\n\nprivate:\n    void computerMove();\n    std::pair<int, int> findBestMove() const;\n    int minimax(bool isMax, int depth) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/tictactoe/Player.cpp",
    "content": "#include \"Player.hpp\"\n\nPlayer::Player(std::string name, char symbol, bool isHuman)\n    : name(name), symbol(symbol), isHuman(isHuman) {}\n\nstd::string Player::getName() const { return name; }\nchar Player::getSymbol() const { return symbol; }\nbool Player::isHumanPlayer() const { return isHuman; } "
  },
  {
    "path": "solutions/cpp/tictactoe/Player.hpp",
    "content": "#ifndef PLAYER_HPP\n#define PLAYER_HPP\n\n#include <string>\n\nclass Player {\nprivate:\n    std::string name;\n    char symbol;\n    bool isHuman;\n\npublic:\n    Player(std::string name, char symbol, bool isHuman = true);\n    \n    std::string getName() const;\n    char getSymbol() const;\n    bool isHumanPlayer() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/tictactoe/README.md",
    "content": "# Designing a Tic Tac Toe Game\n\n## Requirements\n1. The Tic-Tac-Toe game should be played on a 3x3 grid.\n2. Two players take turns marking their symbols (X or O) on the grid.\n3. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game.\n4. If all the cells on the grid are filled and no player has won, the game ends in a draw.\n5. The game should have a user interface to display the grid and allow players to make their moves.\n6. The game should handle player turns and validate moves to ensure they are legal.\n7. The game should detect and announce the winner or a draw at the end of the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Player** class represents a player in the game, with a name and a symbol (X or O).\n2. The **Board** class represents the game board, which is a 3x3 grid. It provides methods to make moves, check for a winner, and check if the board is full.\n3. The **Game** class manages the game flow and player interactions. It handles player turns, validates moves, and determines the winner or a draw.\n4. The **TicTacToe** class is the entry point of the application and creates instances of the players and the game."
  },
  {
    "path": "solutions/cpp/tictactoe/TicTacToeDemo.cpp",
    "content": "#include \"Game.hpp\"\n#include <iostream>\n\nint main() {\n    std::cout << \"Welcome to Tic Tac Toe!\" << std::endl;\n    \n    Game game;\n    game.initializePlayers(\"Human\", \"Computer\");\n    game.play();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/Intersection.cpp",
    "content": "#include \"Intersection.hpp\"\n#include <iostream>\n#include <algorithm>\n\nIntersection::Intersection(std::string intersectionId)\n    : intersectionId(intersectionId), isOperational(true) {}\n\nIntersection::~Intersection() {\n    for (auto signal : signals) {\n        delete signal;\n    }\n}\n\nstd::string Intersection::getIntersectionId() const { return intersectionId; }\nbool Intersection::isWorking() const { return isOperational; }\n\nvoid Intersection::addSignal(Signal* signal) {\n    signals.push_back(signal);\n}\n\nvoid Intersection::removeSignal(const std::string& signalId) {\n    auto it = std::find_if(signals.begin(), signals.end(),\n        [signalId](Signal* signal) { return signal->getSignalId() == signalId; });\n    \n    if (it != signals.end()) {\n        delete *it;\n        signals.erase(it);\n    }\n}\n\nvoid Intersection::updateSignals(int timeElapsed) {\n    if (!isOperational) return;\n    \n    for (auto signal : signals) {\n        signal->updateSignal(timeElapsed);\n    }\n}\n\nvoid Intersection::setOperational(bool status) {\n    isOperational = status;\n    for (auto signal : signals) {\n        signal->setWorking(status);\n    }\n}\n\nvoid Intersection::synchronizeSignals() {\n    for (auto signal : signals) {\n        signal->reset();\n    }\n}\n\nvoid Intersection::displayStatus() const {\n    std::cout << \"\\nIntersection \" << intersectionId << \" Status:\" << std::endl;\n    std::cout << \"Operational: \" << (isOperational ? \"Yes\" : \"No\") << std::endl;\n    std::cout << \"Signals:\" << std::endl;\n    for (const auto& signal : signals) {\n        signal->displayStatus();\n    }\n}\n\nSignal* Intersection::findSignal(const std::string& signalId) const {\n    auto it = std::find_if(signals.begin(), signals.end(),\n        [signalId](Signal* signal) { return signal->getSignalId() == signalId; });\n    return it != signals.end() ? *it : nullptr;\n} "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/Intersection.hpp",
    "content": "#ifndef INTERSECTION_HPP\n#define INTERSECTION_HPP\n\n#include <vector>\n#include <string>\n#include \"Signal.hpp\"\n\nclass Intersection {\nprivate:\n    std::string intersectionId;\n    std::vector<Signal*> signals;\n    bool isOperational;\n\npublic:\n    Intersection(std::string intersectionId);\n    ~Intersection();\n    \n    std::string getIntersectionId() const;\n    bool isWorking() const;\n    \n    void addSignal(Signal* signal);\n    void removeSignal(const std::string& signalId);\n    void updateSignals(int timeElapsed);\n    void setOperational(bool status);\n    void synchronizeSignals();\n    void displayStatus() const;\n\nprivate:\n    Signal* findSignal(const std::string& signalId) const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/README.md",
    "content": "# Designing a Traffic Signal Control System\n\n## Requirements\n1. The traffic signal system should control the flow of traffic at an intersection with multiple roads.\n2. The system should support different types of signals, such as red, yellow, and green.\n3. The duration of each signal should be configurable and adjustable based on traffic conditions.\n4. The system should handle the transition between signals smoothly, ensuring safe and efficient traffic flow.\n5. The system should be able to detect and handle emergency situations, such as an ambulance or fire truck approaching the intersection.\n6. The system should be scalable and extensible to support additional features and functionality.\n\n## Classes, Interfaces and Enumerations\n1. The **Signal** enum represents the different states of a traffic light: red, yellow, and green.\n2. The **Road** class represents a road in the traffic signal system, with properties such as ID, name, and an associated traffic light.\n3. The **TrafficLight** class represents a traffic light, with properties such as ID, current signal, and durations for each signal state. It provides methods to change the signal and notify observers (e.g., roads) about signal changes.\n4. The **TrafficController** class serves as the central controller for the traffic signal system. It follows the Singleton pattern to ensure a single instance of the controller. It manages the roads and their associated traffic lights, starts the traffic control process, and handles emergency situations.\n5. The **TrafficSignalSystemDemo** class is the main entry point of the application. It demonstrates the usage of the traffic signal system by creating roads, traffic lights, assigning traffic lights to roads, and starting the traffic control process."
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/Signal.cpp",
    "content": "#include \"Signal.hpp\"\n#include <iostream>\n\nSignal::Signal(std::string signalId, int greenDuration, int yellowDuration, int redDuration)\n    : signalId(signalId), currentColor(SignalColor::RED),\n      greenDuration(greenDuration), yellowDuration(yellowDuration), redDuration(redDuration),\n      isWorking(true) {\n    reset();\n}\n\nstd::string Signal::getSignalId() const { return signalId; }\nSignalColor Signal::getCurrentColor() const { return currentColor; }\nint Signal::getTimeRemaining() const { return timeRemaining; }\nbool Signal::isOperational() const { return isWorking; }\n\nvoid Signal::setDurations(int green, int yellow, int red) {\n    greenDuration = green;\n    yellowDuration = yellow;\n    redDuration = red;\n    reset();\n}\n\nvoid Signal::updateSignal(int timeElapsed) {\n    if (!isWorking) return;\n    \n    timeRemaining -= timeElapsed;\n    if (timeRemaining <= 0) {\n        switchColor();\n    }\n}\n\nvoid Signal::switchColor() {\n    switch (currentColor) {\n        case SignalColor::RED:\n            currentColor = SignalColor::GREEN;\n            timeRemaining = greenDuration;\n            break;\n        case SignalColor::GREEN:\n            currentColor = SignalColor::YELLOW;\n            timeRemaining = yellowDuration;\n            break;\n        case SignalColor::YELLOW:\n            currentColor = SignalColor::RED;\n            timeRemaining = redDuration;\n            break;\n    }\n}\n\nvoid Signal::setWorking(bool status) {\n    isWorking = status;\n}\n\nvoid Signal::reset() {\n    currentColor = SignalColor::RED;\n    timeRemaining = redDuration;\n}\n\nvoid Signal::displayStatus() const {\n    std::cout << \"Signal \" << signalId << \": \";\n    std::cout << \"Color = \";\n    switch (currentColor) {\n        case SignalColor::RED: std::cout << \"RED\"; break;\n        case SignalColor::YELLOW: std::cout << \"YELLOW\"; break;\n        case SignalColor::GREEN: std::cout << \"GREEN\"; break;\n    }\n    std::cout << \", Time Remaining: \" << timeRemaining << \"s\";\n    std::cout << \", Status: \" << (isWorking ? \"Working\" : \"Not Working\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/Signal.hpp",
    "content": "#ifndef SIGNAL_HPP\n#define SIGNAL_HPP\n\n#include <string>\n\nenum class SignalColor {\n    RED,\n    YELLOW,\n    GREEN\n};\n\nclass Signal {\nprivate:\n    std::string signalId;\n    SignalColor currentColor;\n    int greenDuration;\n    int yellowDuration;\n    int redDuration;\n    int timeRemaining;\n    bool isWorking;\n\npublic:\n    Signal(std::string signalId, int greenDuration = 30, int yellowDuration = 5, int redDuration = 30);\n    \n    std::string getSignalId() const;\n    SignalColor getCurrentColor() const;\n    int getTimeRemaining() const;\n    bool isOperational() const;\n    \n    void setDurations(int green, int yellow, int red);\n    void updateSignal(int timeElapsed);\n    void switchColor();\n    void setWorking(bool status);\n    void reset();\n    void displayStatus() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/TrafficSystem.cpp",
    "content": "#include \"TrafficSystem.hpp\"\n#include <iostream>\n#include <algorithm>\n\nTrafficSystem::TrafficSystem() : intersectionIdCounter(1), signalIdCounter(1) {}\n\nTrafficSystem::~TrafficSystem() {\n    for (auto intersection : intersections) {\n        delete intersection;\n    }\n}\n\nIntersection* TrafficSystem::createIntersection() {\n    std::string intersectionId = generateIntersectionId();\n    Intersection* intersection = new Intersection(intersectionId);\n    intersections.push_back(intersection);\n    return intersection;\n}\n\nvoid TrafficSystem::removeIntersection(const std::string& intersectionId) {\n    auto it = std::find_if(intersections.begin(), intersections.end(),\n        [intersectionId](Intersection* intersection) {\n            return intersection->getIntersectionId() == intersectionId;\n        });\n    \n    if (it != intersections.end()) {\n        delete *it;\n        intersections.erase(it);\n    }\n}\n\nSignal* TrafficSystem::addSignal(const std::string& intersectionId,\n                               int greenDuration, int yellowDuration, int redDuration) {\n    Intersection* intersection = findIntersection(intersectionId);\n    if (!intersection) return nullptr;\n    \n    std::string signalId = generateSignalId();\n    Signal* signal = new Signal(signalId, greenDuration, yellowDuration, redDuration);\n    intersection->addSignal(signal);\n    return signal;\n}\n\nvoid TrafficSystem::removeSignal(const std::string& intersectionId, const std::string& signalId) {\n    if (Intersection* intersection = findIntersection(intersectionId)) {\n        intersection->removeSignal(signalId);\n    }\n}\n\nvoid TrafficSystem::updateSystem(int timeElapsed) {\n    for (auto intersection : intersections) {\n        intersection->updateSignals(timeElapsed);\n    }\n}\n\nvoid TrafficSystem::setIntersectionStatus(const std::string& intersectionId, bool operational) {\n    if (Intersection* intersection = findIntersection(intersectionId)) {\n        intersection->setOperational(operational);\n    }\n}\n\nvoid TrafficSystem::synchronizeIntersection(const std::string& intersectionId) {\n    if (Intersection* intersection = findIntersection(intersectionId)) {\n        intersection->synchronizeSignals();\n    }\n}\n\nvoid TrafficSystem::displaySystemStatus() const {\n    std::cout << \"\\nTraffic System Status:\" << std::endl;\n    std::cout << \"Number of Intersections: \" << intersections.size() << std::endl;\n    for (const auto& intersection : intersections) {\n        intersection->displayStatus();\n    }\n}\n\nIntersection* TrafficSystem::findIntersection(const std::string& intersectionId) const {\n    auto it = std::find_if(intersections.begin(), intersections.end(),\n        [intersectionId](Intersection* intersection) {\n            return intersection->getIntersectionId() == intersectionId;\n        });\n    return it != intersections.end() ? *it : nullptr;\n}\n\nstd::string TrafficSystem::generateIntersectionId() {\n    return \"I\" + std::to_string(intersectionIdCounter++);\n}\n\nstd::string TrafficSystem::generateSignalId() {\n    return \"S\" + std::to_string(signalIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/TrafficSystem.hpp",
    "content": "#ifndef TRAFFIC_SYSTEM_HPP\n#define TRAFFIC_SYSTEM_HPP\n\n#include <vector>\n#include <string>\n#include \"Intersection.hpp\"\n\nclass TrafficSystem {\nprivate:\n    std::vector<Intersection*> intersections;\n    int intersectionIdCounter;\n    int signalIdCounter;\n\npublic:\n    TrafficSystem();\n    ~TrafficSystem();\n    \n    Intersection* createIntersection();\n    void removeIntersection(const std::string& intersectionId);\n    Signal* addSignal(const std::string& intersectionId,\n                     int greenDuration = 30, int yellowDuration = 5, int redDuration = 30);\n    void removeSignal(const std::string& intersectionId, const std::string& signalId);\n    void updateSystem(int timeElapsed);\n    void setIntersectionStatus(const std::string& intersectionId, bool operational);\n    void synchronizeIntersection(const std::string& intersectionId);\n    void displaySystemStatus() const;\n\nprivate:\n    Intersection* findIntersection(const std::string& intersectionId) const;\n    std::string generateIntersectionId();\n    std::string generateSignalId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/trafficsignalsystem/TrafficSystemDemo.cpp",
    "content": "#include \"TrafficSystem.hpp\"\n#include <iostream>\n#include <thread>\n#include <chrono>\n\nint main() {\n    TrafficSystem system;\n    \n    // Create an intersection\n    Intersection* intersection1 = system.createIntersection();\n    \n    // Add signals to the intersection\n    Signal* signal1 = system.addSignal(intersection1->getIntersectionId(), 20, 5, 25);\n    Signal* signal2 = system.addSignal(intersection1->getIntersectionId(), 20, 5, 25);\n    \n    // Display initial status\n    system.displaySystemStatus();\n    \n    // Simulate traffic system for a few cycles\n    for (int i = 0; i < 10; i++) {\n        std::cout << \"\\nTime step \" << i + 1 << \":\" << std::endl;\n        system.updateSystem(5);  // Update every 5 seconds\n        system.displaySystemStatus();\n        std::this_thread::sleep_for(std::chrono::seconds(1));\n    }\n    \n    // Simulate intersection failure\n    std::cout << \"\\nSimulating intersection failure...\" << std::endl;\n    system.setIntersectionStatus(intersection1->getIntersectionId(), false);\n    system.displaySystemStatus();\n    \n    // Restore intersection\n    std::cout << \"\\nRestoring intersection...\" << std::endl;\n    system.setIntersectionStatus(intersection1->getIntersectionId(), true);\n    system.synchronizeIntersection(intersection1->getIntersectionId());\n    system.displaySystemStatus();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/vendingmachine/Product.cpp",
    "content": "#include \"Product.hpp\"\n#include <iostream>\n#include <iomanip>\n\nProduct::Product(std::string productId, std::string name, double price, int quantity)\n    : productId(productId), name(name), price(price), quantity(quantity), available(true) {}\n\nstd::string Product::getProductId() const { return productId; }\nstd::string Product::getName() const { return name; }\ndouble Product::getPrice() const { return price; }\nint Product::getQuantity() const { return quantity; }\nbool Product::isAvailable() const { return available && quantity > 0; }\n\nvoid Product::setPrice(double price) {\n    this->price = price;\n}\n\nvoid Product::setQuantity(int quantity) {\n    this->quantity = quantity;\n}\n\nvoid Product::setAvailable(bool status) {\n    available = status;\n}\n\nvoid Product::addQuantity(int amount) {\n    quantity += amount;\n}\n\nbool Product::removeQuantity(int amount) {\n    if (amount <= quantity) {\n        quantity -= amount;\n        return true;\n    }\n    return false;\n}\n\nvoid Product::displayInfo() const {\n    std::cout << \"Product: \" << name << \" (ID: \" << productId << \")\" << std::endl;\n    std::cout << \"Price: $\" << std::fixed << std::setprecision(2) << price << std::endl;\n    std::cout << \"Quantity: \" << quantity << std::endl;\n    std::cout << \"Status: \" << (isAvailable() ? \"Available\" : \"Not Available\") << std::endl;\n} "
  },
  {
    "path": "solutions/cpp/vendingmachine/Product.hpp",
    "content": "#ifndef PRODUCT_HPP\n#define PRODUCT_HPP\n\n#include <string>\n\nclass Product {\nprivate:\n    std::string productId;\n    std::string name;\n    double price;\n    int quantity;\n    bool available;\n\npublic:\n    Product(std::string productId, std::string name, double price, int quantity = 0);\n    \n    std::string getProductId() const;\n    std::string getName() const;\n    double getPrice() const;\n    int getQuantity() const;\n    bool isAvailable() const;\n    \n    void setPrice(double price);\n    void setQuantity(int quantity);\n    void setAvailable(bool status);\n    void addQuantity(int amount);\n    bool removeQuantity(int amount);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/vendingmachine/README.md",
    "content": "# Designing a Vending Machine\n\n## Requirements\n1. The vending machine should support multiple products with different prices and quantities.\n1. The machine should accept coins and notes of different denominations.\n1. The machine should dispense the selected product and return change if necessary.\n1. The machine should keep track of the available products and their quantities.\n1. The machine should handle multiple transactions concurrently and ensure data consistency.\n1. The machine should provide an interface for restocking products and collecting money.\n1. The machine should handle exceptional scenarios, such as insufficient funds or out-of-stock products.\n\n## Classes, Interfaces and Enumerations\n1. The **Product** class represents a product in the vending machine, with properties such as name and price.\n2. The **Coin** and **Note** enums represent the different denominations of coins and notes accepted by the vending machine.\n3. The **Inventory** class manages the available products and their quantities in the vending machine. It uses a concurrent hash map to ensure thread safety.\n4. The **VendingMachineState** interface defines the behavior of the vending machine in different states, such as idle, ready, and dispense.\n5. The **IdleState**, **ReadyState**, and **DispenseState** classes implement the VendingMachineState interface and define the specific behaviors for each state.\n6. The **VendingMachine** class is the main class that represents the vending machine. It follows the Singleton pattern to ensure only one instance of the vending machine exists.\n7. The VendingMachine class maintains the current state, selected product, total payment, and provides methods for state transitions and payment handling.\n8. The **VendingMachineDemo** class demonstrates the usage of the vending machine by adding products to the inventory, selecting products, inserting coins and notes, dispensing products, and returning change."
  },
  {
    "path": "solutions/cpp/vendingmachine/Transaction.cpp",
    "content": "#include \"Transaction.hpp\"\n#include <iostream>\n#include <iomanip>\n\nTransaction::Transaction(std::string transactionId, std::string productId, int quantity, double amount)\n    : transactionId(transactionId), productId(productId), quantity(quantity), amount(amount),\n      successful(false) {\n    timestamp = std::time(nullptr);\n}\n\nstd::string Transaction::getTransactionId() const { return transactionId; }\nstd::string Transaction::getProductId() const { return productId; }\nint Transaction::getQuantity() const { return quantity; }\ndouble Transaction::getAmount() const { return amount; }\nstd::time_t Transaction::getTimestamp() const { return timestamp; }\nbool Transaction::isSuccessful() const { return successful; }\n\nvoid Transaction::setSuccessful(bool status) {\n    successful = status;\n}\n\nvoid Transaction::displayInfo() const {\n    std::cout << \"Transaction \" << transactionId << \":\" << std::endl;\n    std::cout << \"Product ID: \" << productId << std::endl;\n    std::cout << \"Quantity: \" << quantity << std::endl;\n    std::cout << \"Amount: $\" << std::fixed << std::setprecision(2) << amount << std::endl;\n    std::cout << \"Status: \" << (successful ? \"Successful\" : \"Failed\") << std::endl;\n    std::cout << \"Time: \" << std::ctime(&timestamp);\n} "
  },
  {
    "path": "solutions/cpp/vendingmachine/Transaction.hpp",
    "content": "#ifndef TRANSACTION_HPP\n#define TRANSACTION_HPP\n\n#include <string>\n#include <ctime>\n\nclass Transaction {\nprivate:\n    std::string transactionId;\n    std::string productId;\n    int quantity;\n    double amount;\n    std::time_t timestamp;\n    bool successful;\n\npublic:\n    Transaction(std::string transactionId, std::string productId, int quantity, double amount);\n    \n    std::string getTransactionId() const;\n    std::string getProductId() const;\n    int getQuantity() const;\n    double getAmount() const;\n    std::time_t getTimestamp() const;\n    bool isSuccessful() const;\n    \n    void setSuccessful(bool status);\n    void displayInfo() const;\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/vendingmachine/VendingMachine.cpp",
    "content": "#include \"VendingMachine.hpp\"\n#include <iostream>\n#include <iomanip>\n#include <algorithm>\n\nVendingMachine::VendingMachine(std::string machineId)\n    : machineId(machineId), cashBalance(0.0), operational(true),\n      productIdCounter(1), transactionIdCounter(1) {}\n\nVendingMachine::~VendingMachine() {\n    for (auto product : products) delete product;\n    for (auto transaction : transactions) delete transaction;\n}\n\nstd::string VendingMachine::getMachineId() const { return machineId; }\ndouble VendingMachine::getCashBalance() const { return cashBalance; }\nbool VendingMachine::isOperational() const { return operational; }\n\nProduct* VendingMachine::addProduct(const std::string& name, double price, int quantity) {\n    std::string productId = generateProductId();\n    Product* product = new Product(productId, name, price, quantity);\n    products.push_back(product);\n    return product;\n}\n\nvoid VendingMachine::removeProduct(const std::string& productId) {\n    auto it = std::find_if(products.begin(), products.end(),\n        [productId](Product* product) { return product->getProductId() == productId; });\n    \n    if (it != products.end()) {\n        delete *it;\n        products.erase(it);\n    }\n}\n\nbool VendingMachine::restockProduct(const std::string& productId, int quantity) {\n    Product* product = findProduct(productId);\n    if (!product) return false;\n    \n    product->addQuantity(quantity);\n    return true;\n}\n\nbool VendingMachine::updatePrice(const std::string& productId, double price) {\n    Product* product = findProduct(productId);\n    if (!product) return false;\n    \n    product->setPrice(price);\n    return true;\n}\n\nTransaction* VendingMachine::purchaseProduct(const std::string& productId, int quantity, double payment) {\n    if (!operational) return nullptr;\n    \n    Product* product = findProduct(productId);\n    if (!product || !product->isAvailable() || product->getQuantity()<quantity) return nullptr;\n    \n    double totalCost = product->getPrice() * quantity;\n    if (payment < totalCost) return nullptr;\n    \n    std::string transactionId = generateTransactionId();\n    Transaction* transaction = new Transaction(transactionId, productId, quantity, totalCost);\n    \n    if (product->removeQuantity(quantity)) {\n        cashBalance += totalCost;\n        transaction->setSuccessful(true);\n        transactions.push_back(transaction);\n        return transaction;\n    }\n    \n    delete transaction;\n    return nullptr;\n}\n\nvoid VendingMachine::addCash(double amount) {\n    cashBalance += amount;\n}\n\nbool VendingMachine::withdrawCash(double amount) {\n    if (amount <= cashBalance) {\n        cashBalance -= amount;\n        return true;\n    }\n    return false;\n}\n\nvoid VendingMachine::setOperational(bool status) {\n    operational = status;\n}\n\nvoid VendingMachine::displayInventory() const {\n    std::cout << \"\\nCurrent Inventory:\" << std::endl;\n    for (const auto& product : products) {\n        product->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid VendingMachine::displayTransactions() const {\n    std::cout << \"\\nTransaction History:\" << std::endl;\n    for (const auto& transaction : transactions) {\n        transaction->displayInfo();\n        std::cout << \"------------------------\" << std::endl;\n    }\n}\n\nvoid VendingMachine::displayMachineInfo() const {\n    std::cout << \"\\nVending Machine Info:\" << std::endl;\n    std::cout << \"ID: \" << machineId << std::endl;\n    std::cout << \"Status: \" << (operational ? \"Operational\" : \"Out of Service\") << std::endl;\n    std::cout << \"Cash Balance: $\" << std::fixed << std::setprecision(2) << cashBalance << std::endl;\n    std::cout << \"Products Available: \" << products.size() << std::endl;\n    std::cout << \"Total Transactions: \" << transactions.size() << std::endl;\n}\n\nProduct* VendingMachine::findProduct(const std::string& productId) const {\n    auto it = std::find_if(products.begin(), products.end(),\n        [productId](Product* product) { return product->getProductId() == productId; });\n    return it != products.end() ? *it : nullptr;\n}\n\nstd::string VendingMachine::generateProductId() {\n    return \"P\" + std::to_string(productIdCounter++);\n}\n\nstd::string VendingMachine::generateTransactionId() {\n    return \"T\" + std::to_string(transactionIdCounter++);\n} "
  },
  {
    "path": "solutions/cpp/vendingmachine/VendingMachine.hpp",
    "content": "#ifndef VENDING_MACHINE_HPP\n#define VENDING_MACHINE_HPP\n\n#include <vector>\n#include <string>\n#include \"Product.hpp\"\n#include \"Transaction.hpp\"\n\nclass VendingMachine {\nprivate:\n    std::string machineId;\n    std::vector<Product*> products;\n    std::vector<Transaction*> transactions;\n    double cashBalance;\n    bool operational;\n    int productIdCounter;\n    int transactionIdCounter;\n\npublic:\n    VendingMachine(std::string machineId);\n    ~VendingMachine();\n    \n    std::string getMachineId() const;\n    double getCashBalance() const;\n    bool isOperational() const;\n    \n    Product* addProduct(const std::string& name, double price, int quantity = 0);\n    void removeProduct(const std::string& productId);\n    bool restockProduct(const std::string& productId, int quantity);\n    bool updatePrice(const std::string& productId, double price);\n    Transaction* purchaseProduct(const std::string& productId, int quantity, double payment);\n    void addCash(double amount);\n    bool withdrawCash(double amount);\n    void setOperational(bool status);\n    \n    void displayInventory() const;\n    void displayTransactions() const;\n    void displayMachineInfo() const;\n\nprivate:\n    Product* findProduct(const std::string& productId) const;\n    std::string generateProductId();\n    std::string generateTransactionId();\n};\n\n#endif "
  },
  {
    "path": "solutions/cpp/vendingmachine/VendingMachineDemo.cpp",
    "content": "#include \"VendingMachine.hpp\"\n#include <iostream>\n\nint main() {\n    VendingMachine machine(\"VM001\");\n    \n    // Add products\n    Product* cola = machine.addProduct(\"Cola\", 2.50, 10);\n    Product* chips = machine.addProduct(\"Chips\", 1.50, 15);\n    Product* candy = machine.addProduct(\"Candy\", 1.00, 20);\n    \n    // Display initial inventory\n    std::cout << \"Initial machine status:\" << std::endl;\n    machine.displayMachineInfo();\n    machine.displayInventory();\n    \n    // Make some purchases\n    std::cout << \"\\nMaking purchases...\" << std::endl;\n    Transaction* t1 = machine.purchaseProduct(cola->getProductId(), 2, 5.00);\n    Transaction* t2 = machine.purchaseProduct(chips->getProductId(), 3, 5.00);\n    \n    // Display transactions\n    machine.displayTransactions();\n    \n    // Restock a product\n    std::cout << \"\\nRestocking Cola...\" << std::endl;\n    machine.restockProduct(cola->getProductId(), 5);\n    \n    // Update price\n    std::cout << \"\\nUpdating Candy price...\" << std::endl;\n    machine.updatePrice(candy->getProductId(), 1.25);\n    \n    // Display final status\n    std::cout << \"\\nFinal machine status:\" << std::endl;\n    machine.displayMachineInfo();\n    machine.displayInventory();\n    \n    return 0;\n} "
  },
  {
    "path": "solutions/cpp/votingsystem/README.md",
    "content": "### Airline Management System\n\nThis is a simple airline management system that allows you to manage flights, passengers, and bookings."
  },
  {
    "path": "solutions/csharp/LLDRunner.cs",
    "content": "﻿using AirlineManagementSystem;\r\nusing ATM;\r\nusing CarRentalSystem;\r\nusing ChessGame;\r\nusing CoffeeVendingMachine;\r\nusing ConcertBookingSystem;\r\nusing CourseRegistrationSystem;\r\nusing Cricinfo;\r\nusing DigitalWallet;\r\nusing ElevatorSystem;\r\nusing FoodDeliveryService;\r\nusing HotelManagement;\r\nusing LibraryManagementSystem;\r\nusing LinkedInNamespace;\r\n//using LoggingFramework;\r\nusing LRUCacheNamespace;\r\nusing MovieTicketBookingSystem;\r\nusing MusicStreamingService;\r\nusing OnlineAuctionSystem;\r\nusing OnlineShopping;\r\nusing OnlineStockBrokerageSystem;\r\nusing ParkingLot;\r\nusing PubSubSystem;\r\nusing RestaurantManagementSystem;\r\nusing RideSharingService;\r\nusing SnakeAndLadderGame;\r\nusing SocialNetworkingService;\r\nusing Splitwise;\r\nusing StackOverflow;\r\nusing TaskManagementSystem;\r\nusing TicTacToe;\r\nusing TrafficSignalSystem;\r\nusing VendingMachineApp;\r\n\r\nnamespace MyCSharpProject\r\n{\r\n    class Program\r\n    {\r\n        static void Main(string[] args)\r\n        {\r\n            // Uncomment the LLD problem you want to run with sample input defined in the corresponding Demo class.\r\n\r\n            //AirlineManagementSystemDemo.Run();\r\n            //ATMDemo.Run();\r\n            //CarRentalSystemDemo.Run();\r\n            //ChessGameDemo.Run();\r\n            //CoffeeVendingMachineDemo.Run();\r\n            //ConcertTicketBookingSystemDemo.Run();\r\n            //CourseRegistrationDemo.Run();\r\n            //CricinfoDemo.Run();\r\n            //DigitalWalletDemo.Run();\r\n            //ElevatorSystemDemo.Run();\r\n            //FoodDeliveryServiceDemo.Run();\r\n            //HotelManagementSystemDemo.Run();\r\n            //LibraryManagementSystemDemo.Run();\r\n            //LinkedInDemo.Run();\r\n            //LoggingFrameworkDemo.Run();\r\n            //LRUCacheDemo.Run();\r\n            //MovieTicketBookingDemo.Run();\r\n            //MusicStreamingServiceDemo.Run();\r\n            //AuctionSystemDemo.Run();\r\n            //OnlineShoppingServiceDemo.Run();\r\n            //StockBrokerageSystemDemo.Run();\r\n            //ParkingLotDemo.Run();\r\n            //PubSubSystemDemo.Run();\r\n            //RestaurantManagementDemo.Run();\r\n            //RideSharingServiceDemo.Run();\r\n            //SnakeAndLadderDemo.Run();\r\n            //SocialNetworkingServiceDemo.Run();\r\n            //SplitwiseDemo.Run();\r\n            //StackOverflowDemo.Run();\r\n            //TaskManagementSystemDemo.Run();\r\n            //TicTacToeDemo.Run();\r\n            //TrafficSignalSystemDemo.Run();\r\n            //VendingMachineDemo.Run();\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Aircraft.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public class Aircraft\n    {\n        public string TailNumber { get; }\n        public string Model { get; }\n        public int TotalSeats { get; }\n\n        public Aircraft(string tailNumber, string model, int totalSeats)\n        {\n            TailNumber = tailNumber;\n            Model = model;\n            TotalSeats = totalSeats;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/AirlineManagementSystem.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace AirlineManagementSystem\n{\n    public class AirlineManagementSystem\n    {\n        private readonly List<Flight> flights;\n        private readonly List<Aircraft> aircrafts;\n        private readonly FlightSearch flightSearch;\n        private readonly BookingManager bookingManager;\n        private readonly PaymentProcessor paymentProcessor;\n\n        public AirlineManagementSystem()\n        {\n            flights = new List<Flight>();\n            aircrafts = new List<Aircraft>();\n            flightSearch = new FlightSearch(flights);\n            bookingManager = BookingManager.Instance;\n            paymentProcessor = PaymentProcessor.Instance;\n        }\n\n        public void AddFlight(Flight flight)\n        {\n            flights.Add(flight);\n        }\n\n        public void AddAircraft(Aircraft aircraft)\n        {\n            aircrafts.Add(aircraft);\n        }\n\n        public List<Flight> SearchFlights(string source, string destination, DateTime date)\n        {\n            return flightSearch.SearchFlights(source, destination, date);\n        }\n\n        public Booking BookFlight(Flight flight, Passenger passenger, Seat seat, double price)\n        {\n            return bookingManager.CreateBooking(flight, passenger, seat, price);\n        }\n\n        public void CancelBooking(string bookingNumber)\n        {\n            bookingManager.CancelBooking(bookingNumber);\n        }\n\n        public void ProcessPayment(Payment payment)\n        {\n            paymentProcessor.ProcessPayment(payment);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/AirlineManagementSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AirlineManagementSystem\n{\n    public class AirlineManagementSystemDemo\n    {\n        public static void Run()\n        {\n            var airlineManagementSystem = new AirlineManagementSystem();\n\n            // Create users\n            var passenger1 = new Passenger(\"U001\", \"John Doe\", \"john@example.com\", \"1234567890\");\n\n            // Create flights\n            var departureTime1 = DateTime.Now.AddDays(1);\n            var arrivalTime1 = departureTime1.AddHours(2);\n            var flight1 = new Flight(\"F001\", \"New York\", \"London\", departureTime1, arrivalTime1);\n\n            var departureTime2 = DateTime.Now.AddDays(3);\n            var arrivalTime2 = departureTime2.AddHours(5);\n            var flight2 = new Flight(\"F002\", \"Paris\", \"Tokyo\", departureTime2, arrivalTime2);\n\n            airlineManagementSystem.AddFlight(flight1);\n            airlineManagementSystem.AddFlight(flight2);\n\n            // Create aircrafts\n            var aircraft1 = new Aircraft(\"A001\", \"Boeing 747\", 300);\n            var aircraft2 = new Aircraft(\"A002\", \"Airbus A380\", 500);\n            airlineManagementSystem.AddAircraft(aircraft1);\n            airlineManagementSystem.AddAircraft(aircraft2);\n\n            // Search flights\n            var searchResults = airlineManagementSystem.SearchFlights(\"New York\", \"London\", DateTime.Now.AddDays(1));\n            Console.WriteLine(\"Search Results:\");\n            foreach (var flight in searchResults)\n            {\n                Console.WriteLine($\"Flight: {flight.FlightNumber} - {flight.Source} to {flight.Destination}\");\n            }\n\n            var seat = new Seat(\"25A\", SeatType.ECONOMY);\n\n            // Book a flight\n            var booking = airlineManagementSystem.BookFlight(flight1, passenger1, seat, 100);\n            if (booking != null)\n            {\n                Console.WriteLine(\"Booking successful. Booking ID: \" + booking.BookingNumber);\n            }\n            else\n            {\n                Console.WriteLine(\"Booking failed.\");\n            }\n\n            // Cancel a booking\n            airlineManagementSystem.CancelBooking(booking.BookingNumber);\n            Console.WriteLine(\"Booking cancelled.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Booking.cs",
    "content": "using System;\n\nnamespace AirlineManagementSystem\n{\n    public class Booking\n    {\n        public string BookingNumber { get; }\n        public Flight Flight { get; }\n        public Passenger Passenger { get; }\n        public Seat Seat { get; }\n        public double Price { get; }\n        public BookingStatus Status { get; private set; }\n\n        public Booking(string bookingNumber, Flight flight, Passenger passenger, Seat seat, double price)\n        {\n            BookingNumber = bookingNumber;\n            Flight = flight;\n            Passenger = passenger;\n            Seat = seat;\n            Price = price;\n            Status = BookingStatus.CONFIRMED;\n        }\n\n        public void Cancel()\n        {\n            Status = BookingStatus.CANCELLED;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/BookingManager.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Threading;\n\nnamespace AirlineManagementSystem\n{\n    public class BookingManager\n    {\n        private static BookingManager instance;\n        private readonly Dictionary<string, Booking> bookings = new Dictionary<string, Booking>();\n        private readonly object lockObject = new object();\n        private static int bookingCounter = 0;\n\n        private BookingManager() { }\n\n        public static BookingManager Instance\n        {\n            get\n            {\n                if (instance == null)\n                {\n                    instance = new BookingManager();\n                }\n                return instance;\n            }\n        }\n\n        public Booking CreateBooking(Flight flight, Passenger passenger, Seat seat, double price)\n        {\n            string bookingNumber = GenerateBookingNumber();\n            var booking = new Booking(bookingNumber, flight, passenger, seat, price);\n            lock (lockObject)\n            {\n                bookings[bookingNumber] = booking;\n            }\n            return booking;\n        }\n\n        public void CancelBooking(string bookingNumber)\n        {\n            lock (lockObject)\n            {\n                if (bookings.TryGetValue(bookingNumber, out var booking))\n                {\n                    booking.Cancel();\n                }\n            }\n        }\n\n        private string GenerateBookingNumber()\n        {\n            int bookingId = Interlocked.Increment(ref bookingCounter);\n            string timestamp = DateTime.Now.ToString(\"yyyyMMddHHmmss\", CultureInfo.InvariantCulture);\n            return $\"BKG{timestamp}{bookingId:D6}\";\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/BookingStatus.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public enum BookingStatus\n    {\n        CONFIRMED,\n        CANCELLED,\n        PENDING,\n        EXPIRED\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Flight.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace AirlineManagementSystem\n{\n    public class Flight\n    {\n        public string FlightNumber { get; }\n        public string Source { get; }\n        public string Destination { get; }\n        public DateTime DepartureTime { get; }\n        public DateTime ArrivalTime { get; }\n        public List<Seat> AvailableSeats { get; }\n\n        public Flight(string flightNumber, string source, string destination, DateTime departureTime, DateTime arrivalTime)\n        {\n            FlightNumber = flightNumber;\n            Source = source;\n            Destination = destination;\n            DepartureTime = departureTime;\n            ArrivalTime = arrivalTime;\n            AvailableSeats = new List<Seat>();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/FlightSearch.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace AirlineManagementSystem\n{\n    public class FlightSearch\n    {\n        private readonly List<Flight> flights;\n\n        public FlightSearch(List<Flight> flights)\n        {\n            this.flights = flights;\n        }\n\n        public List<Flight> SearchFlights(string source, string destination, DateTime date)\n        {\n            return flights.Where(flight => flight.Source.Equals(source, StringComparison.OrdinalIgnoreCase)\n                                           && flight.Destination.Equals(destination, StringComparison.OrdinalIgnoreCase)\n                                           && flight.DepartureTime.Date == date.Date).ToList();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Passenger.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public class Passenger\n    {\n        public string Id { get; }\n        public string Name { get; }\n        public string Email { get; }\n        public string Phone { get; }\n\n        public Passenger(string id, string name, string email, string phone)\n        {\n            Id = id;\n            Name = name;\n            Email = email;\n            Phone = phone;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Payment.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public class Payment\n    {\n        public string PaymentId { get; }\n        public string PaymentMethod { get; }\n        public double Amount { get; }\n        public PaymentStatus Status { get; private set; }\n\n        public Payment(string paymentId, string paymentMethod, double amount)\n        {\n            PaymentId = paymentId;\n            PaymentMethod = paymentMethod;\n            Amount = amount;\n            Status = PaymentStatus.PENDING;\n        }\n\n        public void ProcessPayment()\n        {\n            // Process payment logic here\n            Status = PaymentStatus.COMPLETED;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/PaymentProcessor.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public class PaymentProcessor\n    {\n        private static PaymentProcessor instance;\n\n        private PaymentProcessor() { }\n\n        public static PaymentProcessor Instance\n        {\n            get\n            {\n                if (instance == null)\n                {\n                    instance = new PaymentProcessor();\n                }\n                return instance;\n            }\n        }\n\n        public void ProcessPayment(Payment payment)\n        {\n            payment.ProcessPayment();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/PaymentStatus.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public enum PaymentStatus\n    {\n        PENDING,\n        COMPLETED,\n        FAILED,\n        REFUNDED\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/README.md",
    "content": "# Designing an Airline Management System\n\n## Requirements\n1. The airline management system should allow users to search for flights based on source, destination, and date.\n2. Users should be able to book flights, select seats, and make payments.\n3. The system should manage flight schedules, aircraft assignments, and crew assignments.\n4. The system should handle passenger information, including personal details and baggage information.\n5. The system should support different types of users, such as passengers, airline staff, and administrators.\n6. The system should be able to handle cancellations, refunds, and flight changes.\n7. The system should ensure data consistency and handle concurrent access to shared resources.\n8. The system should be scalable and extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Flight** class represents a flight in the airline management system, with properties such as flight number, source, destination, departure time, arrival time, and available seats.\n2. The **Aircraft** class represents an aircraft, with properties like tail number, model, and total seats.\n3. The **Passenger** class represents a passenger, with properties such as ID, name, email, and phone number.\n4. The **Booking** class represents a booking made by a passenger for a specific flight and seat, with properties such as booking number, flight, passenger, seat, price, and booking status.\n5. The **Seat** class represents a seat on a flight, with properties like seat number, seat type, and seat status.\n6. The **Payment** class represents a payment made for a booking, with properties such as payment ID, payment method, amount, and payment status.\n7. The **FlightSearch** class provides functionality to search for flights based on source, destination, and date.\n8. The **BookingManager** class manages the creation and cancellation of bookings. It follows the Singleton pattern to ensure a single instance of the booking manager.\n9. The **PaymentProcessor** class handles the processing of payments. It follows the Singleton pattern to ensure a single instance of the payment processor.\n10. The **AirlineManagementSystem** class serves as the main entry point of the system, combining all the components and providing methods for flight management, booking, payment processing, and other operations."
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/Seat.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public class Seat\n    {\n        public string SeatNumber { get; }\n        public SeatType Type { get; }\n        public SeatStatus Status { get; private set; }\n\n        public Seat(string seatNumber, SeatType type)\n        {\n            SeatNumber = seatNumber;\n            Type = type;\n            Status = SeatStatus.AVAILABLE;\n        }\n\n        public void Reserve()\n        {\n            Status = SeatStatus.RESERVED;\n        }\n\n        public void Release()\n        {\n            Status = SeatStatus.AVAILABLE;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/SeatStatus.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public enum SeatStatus\n    {\n        AVAILABLE,\n        RESERVED,\n        OCCUPIED\n    }\n}"
  },
  {
    "path": "solutions/csharp/airlinemanagementsystem/SeatType.cs",
    "content": "namespace AirlineManagementSystem\n{\n    public enum SeatType\n    {\n        ECONOMY,\n        PREMIUM_ECONOMY,\n        BUSINESS,\n        FIRST_CLASS\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/ATM.cs",
    "content": "class ATM\n{\n    private static ATM instance;\n    private static readonly object lockObject = new object();\n    private readonly BankService bankService;\n    private readonly CashDispenser cashDispenser;\n    private static long transactionCounter = 0;\n    private IATMState currentState;\n    private Card currentCard;\n\n    private ATM()\n    {\n        currentState = new IdleState();\n        bankService = new BankService();\n\n        // Setup the dispenser chain\n        IDispenseChain c1 = new NoteDispenser100(10); // 10 x $100 notes\n        IDispenseChain c2 = new NoteDispenser50(20);  // 20 x $50 notes\n        IDispenseChain c3 = new NoteDispenser20(30);  // 30 x $20 notes\n        c1.SetNextChain(c2);\n        c2.SetNextChain(c3);\n        cashDispenser = new CashDispenser(c1);\n    }\n\n    public static ATM GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new ATM();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void ChangeState(IATMState newState)\n    {\n        currentState = newState;\n    }\n\n    public void SetCurrentCard(Card card)\n    {\n        currentCard = card;\n    }\n\n    public void InsertCard(string cardNumber)\n    {\n        currentState.InsertCard(this, cardNumber);\n    }\n\n    public void EnterPin(string pin)\n    {\n        currentState.EnterPin(this, pin);\n    }\n\n    public void SelectOperation(OperationType op, int amount = 0)\n    {\n        currentState.SelectOperation(this, op, amount);\n    }\n\n    public void CheckBalance()\n    {\n        double balance = bankService.GetBalance(currentCard);\n        Console.WriteLine($\"Your current account balance is: ${balance:F2}\");\n    }\n\n    public void WithdrawCash(int amount)\n    {\n        if (!cashDispenser.CanDispenseCash(amount))\n        {\n            throw new InvalidOperationException(\"Insufficient cash available in the ATM.\");\n        }\n\n        bankService.WithdrawMoney(currentCard, amount);\n\n        try\n        {\n            cashDispenser.DispenseCash(amount);\n        }\n        catch (Exception)\n        {\n            bankService.DepositMoney(currentCard, amount); // Deposit back if dispensing fails\n            throw;\n        }\n    }\n\n    public void DepositCash(int amount)\n    {\n        bankService.DepositMoney(currentCard, amount);\n    }\n\n    public Card GetCurrentCard() => currentCard;\n    public BankService GetBankService() => bankService;\n}"
  },
  {
    "path": "solutions/csharp/atm/ATMDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\n\npublic class ATMDemo\n{\n    public static void Main(string[] args)\n    {\n        ATM atm = ATM.GetInstance();\n\n        // Perform Check Balance operation\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"1234\");\n        atm.SelectOperation(OperationType.CHECK_BALANCE); // $1000\n\n        // Perform Withdraw Cash operation\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"1234\");\n        atm.SelectOperation(OperationType.WITHDRAW_CASH, 570);\n\n        // Perform Deposit Cash operation\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"1234\");\n        atm.SelectOperation(OperationType.DEPOSIT_CASH, 200);\n\n        // Perform Check Balance operation\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"1234\");\n        atm.SelectOperation(OperationType.CHECK_BALANCE); // $630\n\n        // Perform Withdraw Cash more than balance\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"1234\");\n        atm.SelectOperation(OperationType.WITHDRAW_CASH, 700); // Insufficient balance\n\n        // Insert Incorrect PIN\n        atm.InsertCard(\"1234-5678-9012-3456\");\n        atm.EnterPin(\"3425\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/CashDispenser.cs",
    "content": "class CashDispenser\n{\n    private readonly IDispenseChain chain;\n    private readonly object dispenserLock = new object();\n\n    public CashDispenser(IDispenseChain chain)\n    {\n        this.chain = chain;\n    }\n\n    public void DispenseCash(int amount)\n    {\n        lock (dispenserLock)\n        {\n            chain.Dispense(amount);\n        }\n    }\n\n    public bool CanDispenseCash(int amount)\n    {\n        lock (dispenserLock)\n        {\n            if (amount % 10 != 0)\n            {\n                return false;\n            }\n            return chain.CanDispense(amount);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/IDispenseChain.cs",
    "content": "interface IDispenseChain\n{\n    void SetNextChain(IDispenseChain nextChain);\n    void Dispense(int amount);\n    bool CanDispense(int amount);\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/NoteDispenser.cs",
    "content": "abstract class NoteDispenser : IDispenseChain\n{\n    private IDispenseChain nextChain;\n    private readonly int noteValue;\n    private int numNotes;\n    private readonly object dispenserLock = new object();\n\n    public NoteDispenser(int noteValue, int numNotes)\n    {\n        this.noteValue = noteValue;\n        this.numNotes = numNotes;\n    }\n\n    public void SetNextChain(IDispenseChain nextChain)\n    {\n        this.nextChain = nextChain;\n    }\n\n    public void Dispense(int amount)\n    {\n        lock (dispenserLock)\n        {\n            if (amount >= noteValue)\n            {\n                int numToDispense = Math.Min(amount / noteValue, numNotes);\n                int remainingAmount = amount - (numToDispense * noteValue);\n\n                if (numToDispense > 0)\n                {\n                    Console.WriteLine($\"Dispensing {numToDispense} x ${noteValue} note(s)\");\n                    numNotes -= numToDispense;\n                }\n\n                if (remainingAmount > 0 && nextChain != null)\n                {\n                    nextChain.Dispense(remainingAmount);\n                }\n            }\n            else if (nextChain != null)\n            {\n                nextChain.Dispense(amount);\n            }\n        }\n    }\n\n    public bool CanDispense(int amount)\n    {\n        lock (dispenserLock)\n        {\n            if (amount < 0) return false;\n            if (amount == 0) return true;\n\n            int numToUse = Math.Min(amount / noteValue, numNotes);\n            int remainingAmount = amount - (numToUse * noteValue);\n\n            if (remainingAmount == 0) return true;\n            if (nextChain != null)\n            {\n                return nextChain.CanDispense(remainingAmount);\n            }\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/NoteDispenser100.cs",
    "content": "class NoteDispenser100 : NoteDispenser\n{\n    public NoteDispenser100(int numNotes) : base(100, numNotes) { }\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/NoteDispenser20.cs",
    "content": "class NoteDispenser20 : NoteDispenser\n{\n    public NoteDispenser20(int numNotes) : base(20, numNotes) { }\n}"
  },
  {
    "path": "solutions/csharp/atm/DispenserChain/NoteDispenser50.cs",
    "content": "class NoteDispenser50 : NoteDispenser\n{\n    public NoteDispenser50(int numNotes) : base(50, numNotes) { }\n}"
  },
  {
    "path": "solutions/csharp/atm/Enums/OperationType.cs",
    "content": "enum OperationType\n{\n    CHECK_BALANCE,\n    WITHDRAW_CASH,\n    DEPOSIT_CASH\n}"
  },
  {
    "path": "solutions/csharp/atm/Models/Account.cs",
    "content": "class Account\n{\n    private readonly string accountNumber;\n    private double balance;\n    private readonly Dictionary<string, Card> cards;\n    private readonly object accountLock = new object();\n\n    public Account(string accountNumber, double balance)\n    {\n        this.accountNumber = accountNumber;\n        this.balance = balance;\n        this.cards = new Dictionary<string, Card>();\n    }\n\n    public string GetAccountNumber() => accountNumber;\n    public double GetBalance() => balance;\n    public Dictionary<string, Card> GetCards() => cards;\n\n    public void Deposit(double amount)\n    {\n        lock (accountLock)\n        {\n            balance += amount;\n        }\n    }\n\n    public bool Withdraw(double amount)\n    {\n        lock (accountLock)\n        {\n            if (balance >= amount)\n            {\n                balance -= amount;\n                return true;\n            }\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/Models/Card.cs",
    "content": "class Card\n{\n    private readonly string cardNumber;\n    private readonly string pin;\n\n    public Card(string cardNumber, string pin)\n    {\n        this.cardNumber = cardNumber;\n        this.pin = pin;\n    }\n\n    public string GetCardNumber() => cardNumber;\n    public string GetPin() => pin;\n}"
  },
  {
    "path": "solutions/csharp/atm/README.md",
    "content": "# Designing an ATM System\n\n## Requirements\n1. The ATM system should support basic operations such as balance inquiry, cash withdrawal, and cash deposit.\n2. Users should be able to authenticate themselves using a card and a PIN (Personal Identification Number).\n3. The system should interact with a bank's backend system to validate user accounts and perform transactions.\n4. The ATM should have a cash dispenser to dispense cash to users.\n5. The system should handle concurrent access and ensure data consistency.\n6. The ATM should have a user-friendly interface for users to interact with.\n\n## Classes, Interfaces and Enumerations\n1. The **Card** class represents an ATM card with a card number and PIN.\n2. The **Account** class represents a bank account with an account number and balance. It provides methods to debit and credit the account balance.\n3. The **Transaction** class is an abstract base class for different types of transactions, such as withdrawal and deposit. It is extended by WithdrawalTransaction and DepositTransaction classes.\n4. The **BankingService** class manages the bank accounts and processes transactions. It uses a thread-safe ConcurrentHashMap to store and retrieve account information.\n5. The **CashDispenser** class represents the ATM's cash dispenser and handles the dispensing of cash. It uses synchronization to ensure thread safety when dispensing cash.\n6. The **ATM** class serves as the main interface for ATM operations. It interacts with the BankingService and CashDispenser to perform user authentication, balance inquiry, cash withdrawal, and cash deposit.\n7. The **ATMDriver** class demonstrates the usage of the ATM system by creating sample accounts and performing ATM operations."
  },
  {
    "path": "solutions/csharp/atm/Service/BankService.cs",
    "content": "class BankService\n{\n    private readonly Dictionary<string, Account> accounts = new Dictionary<string, Account>();\n    private readonly Dictionary<string, Card> cards = new Dictionary<string, Card>();\n    private readonly Dictionary<Card, Account> cardAccountMap = new Dictionary<Card, Account>();\n\n    public BankService()\n    {\n        // Create sample accounts and cards\n        Account account1 = CreateAccount(\"1234567890\", 1000.0);\n        Card card1 = CreateCard(\"1234-5678-9012-3456\", \"1234\");\n        LinkCardToAccount(card1, account1);\n\n        Account account2 = CreateAccount(\"9876543210\", 500.0);\n        Card card2 = CreateCard(\"9876-5432-1098-7654\", \"4321\");\n        LinkCardToAccount(card2, account2);\n    }\n\n    public Account CreateAccount(string accountNumber, double initialBalance)\n    {\n        Account account = new Account(accountNumber, initialBalance);\n        accounts[accountNumber] = account;\n        return account;\n    }\n\n    public Card CreateCard(string cardNumber, string pin)\n    {\n        Card card = new Card(cardNumber, pin);\n        cards[cardNumber] = card;\n        return card;\n    }\n\n    public bool Authenticate(Card card, string pin)\n    {\n        return card.GetPin() == pin;\n    }\n\n    public Card AuthenticateCard(string cardNumber)\n    {\n        return cards.TryGetValue(cardNumber, out Card card) ? card : null;\n    }\n\n    public double GetBalance(Card card)\n    {\n        return cardAccountMap[card].GetBalance();\n    }\n\n    public void WithdrawMoney(Card card, double amount)\n    {\n        cardAccountMap[card].Withdraw(amount);\n    }\n\n    public void DepositMoney(Card card, double amount)\n    {\n        cardAccountMap[card].Deposit(amount);\n    }\n\n    public void LinkCardToAccount(Card card, Account account)\n    {\n        account.GetCards()[card.GetCardNumber()] = card;\n        cardAccountMap[card] = account;\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/State/AuthenticatedState.cs",
    "content": "class AuthenticatedState : IATMState\n{\n    public void InsertCard(ATM atm, string cardNumber)\n    {\n        Console.WriteLine(\"Error: A card is already inserted and a session is active.\");\n    }\n\n    public void EnterPin(ATM atm, string pin)\n    {\n        Console.WriteLine(\"Error: PIN has already been entered and authenticated.\");\n    }\n\n    public void SelectOperation(ATM atm, OperationType op, int amount = 0)\n    {\n        switch (op)\n        {\n            case OperationType.CHECK_BALANCE:\n                atm.CheckBalance();\n                break;\n\n            case OperationType.WITHDRAW_CASH:\n                if (amount <= 0)\n                {\n                    Console.WriteLine(\"Error: Invalid withdrawal amount specified.\");\n                    break;\n                }\n\n                double accountBalance = atm.GetBankService().GetBalance(atm.GetCurrentCard());\n                if (amount > accountBalance)\n                {\n                    Console.WriteLine(\"Error: Insufficient balance.\");\n                    break;\n                }\n\n                Console.WriteLine($\"Processing withdrawal for ${amount}\");\n                atm.WithdrawCash(amount);\n                break;\n\n            case OperationType.DEPOSIT_CASH:\n                if (amount <= 0)\n                {\n                    Console.WriteLine(\"Error: Invalid deposit amount specified.\");\n                    break;\n                }\n                Console.WriteLine($\"Processing deposit for ${amount}\");\n                atm.DepositCash(amount);\n                break;\n\n            default:\n                Console.WriteLine(\"Error: Invalid operation selected.\");\n                break;\n        }\n\n        // End the session after one transaction\n        Console.WriteLine(\"Transaction complete.\");\n        EjectCard(atm);\n    }\n\n    public void EjectCard(ATM atm)\n    {\n        Console.WriteLine(\"Ending session. Card has been ejected. Thank you for using our ATM.\");\n        atm.SetCurrentCard(null);\n        atm.ChangeState(new IdleState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/State/HasCardState.cs",
    "content": "class HasCardState : IATMState\n{\n    public void InsertCard(ATM atm, string cardNumber)\n    {\n        Console.WriteLine(\"Error: A card is already inserted. Cannot insert another card.\");\n    }\n\n    public void EnterPin(ATM atm, string pin)\n    {\n        Console.WriteLine(\"Authenticating PIN...\");\n        Card card = atm.GetCurrentCard();\n        bool isAuthenticated = atm.GetBankService().Authenticate(card, pin);\n\n        if (isAuthenticated)\n        {\n            Console.WriteLine(\"Authentication successful.\");\n            atm.ChangeState(new AuthenticatedState());\n        }\n        else\n        {\n            Console.WriteLine(\"Authentication failed: Incorrect PIN.\");\n            EjectCard(atm);\n        }\n    }\n\n    public void SelectOperation(ATM atm, OperationType op, int amount = 0)\n    {\n        Console.WriteLine(\"Error: Please enter your PIN first to select an operation.\");\n    }\n\n    public void EjectCard(ATM atm)\n    {\n        Console.WriteLine(\"Card has been ejected. Thank you for using our ATM.\");\n        atm.SetCurrentCard(null);\n        atm.ChangeState(new IdleState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/State/IATMState.cs",
    "content": "interface IATMState\n{\n    void InsertCard(ATM atm, string cardNumber);\n    void EnterPin(ATM atm, string pin);\n    void SelectOperation(ATM atm, OperationType op, int amount = 0);\n    void EjectCard(ATM atm);\n}"
  },
  {
    "path": "solutions/csharp/atm/State/IdleState.cs",
    "content": "class IdleState : IATMState\n{\n    public void InsertCard(ATM atm, string cardNumber)\n    {\n        Console.WriteLine(\"\\nCard has been inserted.\");\n        Card card = atm.GetBankService().AuthenticateCard(cardNumber);\n\n        if (card == null)\n        {\n            EjectCard(atm);\n        }\n        else\n        {\n            atm.SetCurrentCard(card);\n            atm.ChangeState(new HasCardState());\n        }\n    }\n\n    public void EnterPin(ATM atm, string pin)\n    {\n        Console.WriteLine(\"Error: Please insert a card first.\");\n    }\n\n    public void SelectOperation(ATM atm, OperationType op, int amount = 0)\n    {\n        Console.WriteLine(\"Error: Please insert a card first.\");\n    }\n\n    public void EjectCard(ATM atm)\n    {\n        Console.WriteLine(\"Error: Card not found.\");\n        atm.SetCurrentCard(null);\n    }\n}"
  },
  {
    "path": "solutions/csharp/atm/atm.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/bin/Debug/net8.0/c#.deps.json",
    "content": "{\n  \"runtimeTarget\": {\n    \"name\": \".NETCoreApp,Version=v8.0\",\n    \"signature\": \"\"\n  },\n  \"compilationOptions\": {},\n  \"targets\": {\n    \".NETCoreApp,Version=v8.0\": {\n      \"c#/1.0.0\": {\n        \"runtime\": {\n          \"c#.dll\": {}\n        }\n      }\n    }\n  },\n  \"libraries\": {\n    \"c#/1.0.0\": {\n      \"type\": \"project\",\n      \"serviceable\": false,\n      \"sha512\": \"\"\n    }\n  }\n}"
  },
  {
    "path": "solutions/csharp/bin/Debug/net8.0/c#.runtimeconfig.json",
    "content": "{\n  \"runtimeOptions\": {\n    \"tfm\": \"net8.0\",\n    \"framework\": {\n      \"name\": \"Microsoft.NETCore.App\",\n      \"version\": \"8.0.0\"\n    },\n    \"configProperties\": {\n      \"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization\": false\n    }\n  }\n}"
  },
  {
    "path": "solutions/csharp/c#.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <RootNamespace>c_</RootNamespace>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/c#.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.5.002.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"c#\", \"c#.csproj\", \"{78F1799C-B97B-471D-9B45-7D9E16A511E6}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{78F1799C-B97B-471D-9B45-7D9E16A511E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{78F1799C-B97B-471D-9B45-7D9E16A511E6}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{78F1799C-B97B-471D-9B45-7D9E16A511E6}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{78F1799C-B97B-471D-9B45-7D9E16A511E6}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {4CD4CD58-F1CA-4727-A9E3-D71FA3EF319D}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "solutions/csharp/carrentalsystem/Car.cs",
    "content": "namespace CarRentalSystem\n{\n    public class Car\n    {\n        public string Make { get; }\n        public string Model { get; }\n        public int Year { get; }\n        public string LicensePlate { get; }\n        public double RentalPricePerDay { get; }\n        public bool Available { get; private set; }\n\n        public Car(string make, string model, int year, string licensePlate, double rentalPricePerDay)\n        {\n            Make = make;\n            Model = model;\n            Year = year;\n            LicensePlate = licensePlate;\n            RentalPricePerDay = rentalPricePerDay;\n            Available = true;\n        }\n\n        public void SetAvailable(bool available)\n        {\n            Available = available;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/CarRentalSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace CarRentalSystem\n{\n    public class CarRentalSystemDemo\n    {\n        public static void Run()\n        {\n            var rentalSystem = RentalSystem.Instance;\n\n            // Add cars to the rental system\n            rentalSystem.AddCar(new Car(\"Toyota\", \"Camry\", 2022, \"ABC123\", 50.0));\n            rentalSystem.AddCar(new Car(\"Honda\", \"Civic\", 2021, \"XYZ789\", 45.0));\n            rentalSystem.AddCar(new Car(\"Ford\", \"Mustang\", 2023, \"DEF456\", 80.0));\n\n            // Create customers\n            var customer1 = new Customer(\"John Doe\", \"john@example.com\", \"DL1234\");\n\n            // Make reservations\n            var startDate = DateTime.Now;\n            var endDate = startDate.AddDays(3);\n            List<Car> availableCars = rentalSystem.SearchCars(\"Toyota\", \"Camry\", startDate, endDate);\n            if (availableCars.Count > 0)\n            {\n                Car selectedCar = availableCars[0];\n                var reservation = rentalSystem.MakeReservation(customer1, selectedCar, startDate, endDate);\n                if (reservation != null)\n                {\n                    bool paymentSuccess = rentalSystem.ProcessPayment(reservation);\n                    if (paymentSuccess)\n                    {\n                        Console.WriteLine(\"Reservation successful. Reservation ID: \" + reservation.ReservationId);\n                    }\n                    else\n                    {\n                        Console.WriteLine(\"Payment failed. Reservation canceled.\");\n                        rentalSystem.CancelReservation(reservation.ReservationId);\n                    }\n                }\n                else\n                {\n                    Console.WriteLine(\"Selected car is not available for the given dates.\");\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"No available cars found for the given criteria.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/CreditCardPaymentProcessor.cs",
    "content": "namespace CarRentalSystem\n{\n    public class CreditCardPaymentProcessor : IPaymentProcessor\n    {\n        public bool ProcessPayment(double amount)\n        {\n            // Simulate processing payment\n            // Actual implementation would involve integrating with a payment gateway\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/Customer.cs",
    "content": "namespace CarRentalSystem\n{\n    public class Customer\n    {\n        public string Name { get; }\n        public string ContactInfo { get; }\n        public string DriversLicenseNumber { get; }\n\n        public Customer(string name, string contactInfo, string driversLicenseNumber)\n        {\n            Name = name;\n            ContactInfo = contactInfo;\n            DriversLicenseNumber = driversLicenseNumber;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/IPaymentProcessor.cs",
    "content": "namespace CarRentalSystem\n{\n    public interface IPaymentProcessor\n    {\n        bool ProcessPayment(double amount);\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/PayPalPaymentProcessor.cs",
    "content": "namespace CarRentalSystem\n{\n    public class PayPalPaymentProcessor : IPaymentProcessor\n    {\n        public bool ProcessPayment(double amount)\n        {\n            // Simulate processing PayPal payment\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/README.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "solutions/csharp/carrentalsystem/RentalSystem.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\nnamespace CarRentalSystem\n{\n    public class RentalSystem\n    {\n        private static RentalSystem instance;\n        private readonly Dictionary<string, Car> cars;\n        private readonly Dictionary<string, Reservation> reservations;\n        private readonly IPaymentProcessor paymentProcessor;\n\n        private RentalSystem()\n        {\n            cars = new Dictionary<string, Car>();\n            reservations = new Dictionary<string, Reservation>();\n            paymentProcessor = new CreditCardPaymentProcessor();  // Default to credit card payment processor\n        }\n\n        public static RentalSystem Instance\n        {\n            get\n            {\n                if (instance == null)\n                {\n                    instance = new RentalSystem();\n                }\n                return instance;\n            }\n        }\n\n        public void AddCar(Car car)\n        {\n            cars[car.LicensePlate] = car;\n        }\n\n        public void RemoveCar(string licensePlate)\n        {\n            cars.Remove(licensePlate);\n        }\n\n        public List<Car> SearchCars(string make, string model, DateTime startDate, DateTime endDate)\n        {\n            return cars.Values\n                .Where(car => car.Make.Equals(make, StringComparison.OrdinalIgnoreCase)\n                              && car.Model.Equals(model, StringComparison.OrdinalIgnoreCase)\n                              && car.Available && IsCarAvailable(car, startDate, endDate))\n                .ToList();\n        }\n\n        private bool IsCarAvailable(Car car, DateTime startDate, DateTime endDate)\n        {\n            return reservations.Values\n                .Where(reservation => reservation.Car == car)\n                .All(reservation => endDate < reservation.StartDate || startDate > reservation.EndDate);\n        }\n\n        public Reservation MakeReservation(Customer customer, Car car, DateTime startDate, DateTime endDate)\n        {\n            if (IsCarAvailable(car, startDate, endDate))\n            {\n                var reservationId = GenerateReservationId();\n                var reservation = new Reservation(reservationId, customer, car, startDate, endDate);\n                reservations[reservationId] = reservation;\n                car.SetAvailable(false);\n                return reservation;\n            }\n            return null;\n        }\n\n        public void CancelReservation(string reservationId)\n        {\n            if (reservations.TryGetValue(reservationId, out var reservation))\n            {\n                reservations.Remove(reservationId);\n                reservation.Car.SetAvailable(true);\n            }\n        }\n\n        public bool ProcessPayment(Reservation reservation)\n        {\n            return paymentProcessor.ProcessPayment(reservation.TotalPrice);\n        }\n\n        private string GenerateReservationId()\n        {\n            return \"RES\" + Guid.NewGuid().ToString(\"N\").Substring(0, 8).ToUpper();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/carrentalsystem/Reservation.cs",
    "content": "using System;\n\nnamespace CarRentalSystem\n{\n    public class Reservation\n    {\n        public string ReservationId { get; }\n        public Customer Customer { get; }\n        public Car Car { get; }\n        public DateTime StartDate { get; }\n        public DateTime EndDate { get; }\n        public double TotalPrice { get; }\n\n        public Reservation(string reservationId, Customer customer, Car car, DateTime startDate, DateTime endDate)\n        {\n            ReservationId = reservationId;\n            Customer = customer;\n            Car = car;\n            StartDate = startDate;\n            EndDate = endDate;\n            TotalPrice = CalculateTotalPrice();\n        }\n\n        private double CalculateTotalPrice()\n        {\n            int daysRented = (EndDate - StartDate).Days + 1;\n            return Car.RentalPricePerDay * daysRented;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Bishop.cs",
    "content": "namespace ChessGame\n{\n    public class Bishop : Piece\n    {\n        public Bishop(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            int rowDiff = System.Math.Abs(destRow - Row);\n            int colDiff = System.Math.Abs(destCol - Col);\n            return rowDiff == colDiff;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Board.cs",
    "content": "using System;\n\nnamespace ChessGame\n{\n    public class Board\n    {\n        private readonly Piece[,] board;\n\n        public Board()\n        {\n            board = new Piece[8, 8];\n            InitializeBoard();\n        }\n\n        private void InitializeBoard()\n        {\n            // Initialize white pieces\n            board[0, 0] = new Rook(Color.White, 0, 0);\n            board[0, 1] = new Knight(Color.White, 0, 1);\n            board[0, 2] = new Bishop(Color.White, 0, 2);\n            board[0, 3] = new Queen(Color.White, 0, 3);\n            board[0, 4] = new King(Color.White, 0, 4);\n            board[0, 5] = new Bishop(Color.White, 0, 5);\n            board[0, 6] = new Knight(Color.White, 0, 6);\n            board[0, 7] = new Rook(Color.White, 0, 7);\n            for (int i = 0; i < 8; i++)\n            {\n                board[1, i] = new Pawn(Color.White, 1, i);\n            }\n\n            // Initialize black pieces\n            board[7, 0] = new Rook(Color.Black, 7, 0);\n            board[7, 1] = new Knight(Color.Black, 7, 1);\n            board[7, 2] = new Bishop(Color.Black, 7, 2);\n            board[7, 3] = new Queen(Color.Black, 7, 3);\n            board[7, 4] = new King(Color.Black, 7, 4);\n            board[7, 5] = new Bishop(Color.Black, 7, 5);\n            board[7, 6] = new Knight(Color.Black, 7, 6);\n            board[7, 7] = new Rook(Color.Black, 7, 7);\n            for (int i = 0; i < 8; i++)\n            {\n                board[6, i] = new Pawn(Color.Black, 6, i);\n            }\n        }\n\n        public Piece GetPiece(int row, int col)\n        {\n            return board[row, col];\n        }\n\n        public void SetPiece(int row, int col, Piece piece)\n        {\n            board[row, col] = piece;\n        }\n\n        public bool IsValidMove(Piece piece, int destRow, int destCol)\n        {\n            if (piece == null || destRow < 0 || destRow > 7 || destCol < 0 || destCol > 7)\n            {\n                return false;\n            }\n            Piece destPiece = board[destRow, destCol];\n            return (destPiece == null || destPiece.Color != piece.Color) && piece.CanMove(this, destRow, destCol);\n        }\n\n        public bool IsCheckmate(Color color)\n        {\n            // TODO: Implement checkmate logic\n            return false;\n        }\n\n        public bool IsStalemate(Color color)\n        {\n            // TODO: Implement stalemate logic\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/ChessGame.cs",
    "content": "using System;\n\nnamespace ChessGame\n{\n    public class ChessGame\n    {\n        private readonly Board board;\n        private readonly Player[] players;\n        private int currentPlayer;\n\n        public ChessGame()\n        {\n            board = new Board();\n            players = new Player[] { new Player(Color.White), new Player(Color.Black) };\n            currentPlayer = 0;\n        }\n\n        public void Start()\n        {\n            // Game loop\n            while (!IsGameOver())\n            {\n                Player player = players[currentPlayer];\n                Console.WriteLine($\"{player.Color}'s turn.\");\n\n                // Get move from the player\n                Move move = GetPlayerMove(player);\n\n                // Make the move on the board\n                try\n                {\n                    player.MakeMove(board, move);\n                }\n                catch (InvalidMoveException e)\n                {\n                    Console.WriteLine(e.Message);\n                    Console.WriteLine(\"Try again!\");\n                    continue;\n                }\n\n                // Switch to the next player\n                currentPlayer = (currentPlayer + 1) % 2;\n            }\n\n            // Display game result\n            DisplayResult();\n        }\n\n        private bool IsGameOver()\n        {\n            return board.IsCheckmate(players[0].Color) || board.IsCheckmate(players[1].Color) ||\n                   board.IsStalemate(players[0].Color) || board.IsStalemate(players[1].Color);\n        }\n\n        private Move GetPlayerMove(Player player)\n        {\n            // TODO: Implement logic to get a valid move from the player\n            Console.Write(\"Enter source row: \");\n            int sourceRow = int.Parse(Console.ReadLine());\n            Console.Write(\"Enter source column: \");\n            int sourceCol = int.Parse(Console.ReadLine());\n            Console.Write(\"Enter destination row: \");\n            int destRow = int.Parse(Console.ReadLine());\n            Console.Write(\"Enter destination column: \");\n            int destCol = int.Parse(Console.ReadLine());\n\n            Piece piece = board.GetPiece(sourceRow, sourceCol);\n            if (piece == null || piece.Color != player.Color)\n            {\n                throw new ArgumentException(\"Invalid piece selection!\");\n            }\n\n            return new Move(piece, destRow, destCol);\n        }\n\n        private void DisplayResult()\n        {\n            if (board.IsCheckmate(Color.White))\n            {\n                Console.WriteLine(\"Black wins by checkmate!\");\n            }\n            else if (board.IsCheckmate(Color.Black))\n            {\n                Console.WriteLine(\"White wins by checkmate!\");\n            }\n            else if (board.IsStalemate(Color.White) || board.IsStalemate(Color.Black))\n            {\n                Console.WriteLine(\"The game ends in a stalemate!\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/ChessGameDemo.cs",
    "content": "namespace ChessGame\n{\n    public class ChessGameDemo\n    {\n        public static void Run()\n        {\n            ChessGame chessGame = new ChessGame();\n            chessGame.Start();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Color.cs",
    "content": "namespace ChessGame\n{\n    public enum Color\n    {\n        White,\n        Black\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/InvalidMoveException.cs",
    "content": "using System;\n\nnamespace ChessGame\n{\n    public class InvalidMoveException : Exception\n    {\n        public InvalidMoveException(string message) : base(message) { }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/King.cs",
    "content": "namespace ChessGame\n{\n    public class King : Piece\n    {\n        public King(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            int rowDiff = System.Math.Abs(destRow - Row);\n            int colDiff = System.Math.Abs(destCol - Col);\n            return rowDiff <= 1 && colDiff <= 1;\n        }\n    }    \n}"
  },
  {
    "path": "solutions/csharp/chessgame/Knight.cs",
    "content": "namespace ChessGame\n{\n    public class Knight : Piece\n    {\n        public Knight(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            int rowDiff = System.Math.Abs(destRow - Row);\n            int colDiff = System.Math.Abs(destCol - Col);\n            return (rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Move.cs",
    "content": "namespace ChessGame\n{\n    public class Move\n    {\n        public Piece Piece { get; }\n        public int DestRow { get; }\n        public int DestCol { get; }\n\n        public Move(Piece piece, int destRow, int destCol)\n        {\n            Piece = piece;\n            DestRow = destRow;\n            DestCol = destCol;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Pawn.cs",
    "content": "namespace ChessGame\n{\n    public class Pawn : Piece\n    {\n        public Pawn(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            int rowDiff = destRow - Row;\n            int colDiff = System.Math.Abs(destCol - Col);\n\n            if (Color == Color.White)\n            {\n                return (rowDiff == 1 && colDiff == 0) ||\n                       (Row == 1 && rowDiff == 2 && colDiff == 0) ||\n                       (rowDiff == 1 && colDiff == 1 && board.GetPiece(destRow, destCol) != null);\n            }\n            else\n            {\n                return (rowDiff == -1 && colDiff == 0) ||\n                       (Row == 6 && rowDiff == -2 && colDiff == 0) ||\n                       (rowDiff == -1 && colDiff == 1 && board.GetPiece(destRow, destCol) != null);\n            }\n        }\n    }    \n}"
  },
  {
    "path": "solutions/csharp/chessgame/Piece.cs",
    "content": "namespace ChessGame\n{\n    public abstract class Piece\n    {\n        public Color Color { get; }\n        public int Row { get; set; }\n        public int Col { get; set; }\n\n        public Piece(Color color, int row, int col)\n        {\n            Color = color;\n            Row = row;\n            Col = col;\n        }\n\n        public abstract bool CanMove(Board board, int destRow, int destCol);\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Player.cs",
    "content": "namespace ChessGame\n{\n    public class Player\n    {\n        public Color Color { get; }\n\n        public Player(Color color)\n        {\n            Color = color;\n        }\n\n        public void MakeMove(Board board, Move move)\n        {\n            Piece piece = move.Piece;\n            int destRow = move.DestRow;\n            int destCol = move.DestCol;\n\n            if (board.IsValidMove(piece, destRow, destCol))\n            {\n                int sourceRow = piece.Row;\n                int sourceCol = piece.Col;\n                board.SetPiece(sourceRow, sourceCol, null);\n                board.SetPiece(destRow, destCol, piece);\n                piece.Row = destRow;\n                piece.Col = destCol;\n            }\n            else\n            {\n                throw new InvalidMoveException(\"Invalid move!\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/chessgame/Queen.cs",
    "content": "namespace ChessGame\n{\n    public class Queen : Piece\n    {\n        public Queen(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            int rowDiff = System.Math.Abs(destRow - Row);\n            int colDiff = System.Math.Abs(destCol - Col);\n            return rowDiff == colDiff || Row == destRow || Col == destCol;\n        }\n    }    \n}"
  },
  {
    "path": "solutions/csharp/chessgame/README.md",
    "content": "# Designing a Chess Game\n\n## Requirements\n1. The chess game should follow the standard rules of chess.\n2. The game should support two players, each controlling their own set of pieces.\n3. The game board should be represented as an 8x8 grid, with alternating black and white squares.\n4. Each player should have 16 pieces: 1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.\n5. The game should validate legal moves for each piece and prevent illegal moves.\n6. The game should detect checkmate and stalemate conditions.\n7. The game should handle player turns and allow players to make moves alternately.\n8. The game should provide a user interface for players to interact with the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Piece** class is an abstract base class representing a chess piece. It contains common attributes such as color, row, and column, and declares an abstract method canMove to be implemented by each specific piece class.\n2. The **King**, **Queen**, **Rook**, **Bishop**, **Knight**, and **Pawn** classes extend the Piece class and implement their respective movement logic in the canMove method.\n3. The **Board** class represents the chess board and manages the placement of pieces. It provides methods to get and set pieces on the board, check the validity of moves, and determine checkmate and stalemate conditions.\n4. The **Player** class represents a player in the game and has a method to make a move on the board.\n5. The Move class represents a move made by a player, containing the piece being moved and the destination coordinates.\n6. The **Game** class orchestrates the overall game flow. It initializes the board, handles player turns, and determines the game result.\n7. The **ChessGame** class is the entry point of the application and starts the game."
  },
  {
    "path": "solutions/csharp/chessgame/Rook.cs",
    "content": "namespace ChessGame\n{\n    public class Rook : Piece\n    {\n        public Rook(Color color, int row, int col) : base(color, row, col) { }\n\n        public override bool CanMove(Board board, int destRow, int destCol)\n        {\n            return Row == destRow || Col == destCol;\n        }\n    }    \n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/CoffeeVendingMachine.cs",
    "content": "class CoffeeVendingMachine\n{\n    private static CoffeeVendingMachine instance;\n    private static readonly object lockObject = new object();\n    private IVendingMachineState state;\n    private Coffee selectedCoffee;\n    private int moneyInserted;\n\n    private CoffeeVendingMachine()\n    {\n        state = new ReadyState();\n        moneyInserted = 0;\n    }\n\n    public static CoffeeVendingMachine GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new CoffeeVendingMachine();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void SelectCoffee(CoffeeType type, List<ToppingType> toppings)\n    {\n        // 1. Create the base coffee using the factory\n        Coffee coffee = CoffeeFactory.CreateCoffee(type);\n\n        // 2. Wrap it with decorators\n        foreach (ToppingType topping in toppings)\n        {\n            switch (topping)\n            {\n                case ToppingType.EXTRA_SUGAR:\n                    coffee = new ExtraSugarDecorator(coffee);\n                    break;\n                case ToppingType.CARAMEL_SYRUP:\n                    coffee = new CaramelSyrupDecorator(coffee);\n                    break;\n            }\n        }\n        // Let the state handle the rest\n        state.SelectCoffee(this, coffee);\n    }\n\n    public void InsertMoney(int amount) { state.InsertMoney(this, amount); }\n    public void DispenseCoffee() { state.DispenseCoffee(this); }\n    public void Cancel() { state.Cancel(this); }\n\n    // Getters and Setters used by State objects\n    public void SetState(IVendingMachineState state) { this.state = state; }\n    public IVendingMachineState GetState() { return state; }\n    public void SetSelectedCoffee(Coffee selectedCoffee) { this.selectedCoffee = selectedCoffee; }\n    public Coffee GetSelectedCoffee() { return selectedCoffee; }\n    public void SetMoneyInserted(int moneyInserted) { this.moneyInserted = moneyInserted; }\n    public int GetMoneyInserted() { return moneyInserted; }\n\n    public void Reset()\n    {\n        selectedCoffee = null;\n        moneyInserted = 0;\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/CoffeeVendingMachineDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class CoffeeVendingMachineDemo\n{\n    public static void Main(string[] args)\n    {\n        CoffeeVendingMachine machine = CoffeeVendingMachine.GetInstance();\n        Inventory inventory = Inventory.GetInstance();\n\n        // Initial setup: Refill inventory\n        Console.WriteLine(\"=== Initializing Vending Machine ===\");\n        inventory.AddStock(Ingredient.COFFEE_BEANS, 50);\n        inventory.AddStock(Ingredient.WATER, 500);\n        inventory.AddStock(Ingredient.MILK, 200);\n        inventory.AddStock(Ingredient.SUGAR, 100);\n        inventory.AddStock(Ingredient.CARAMEL_SYRUP, 50);\n        inventory.PrintInventory();\n\n        // Scenario 1: Successful Purchase of a Latte\n        Console.WriteLine(\"\\n--- SCENARIO 1: Buy a Latte (Success) ---\");\n        machine.SelectCoffee(CoffeeType.LATTE, new List<ToppingType>());\n        machine.InsertMoney(200);\n        machine.InsertMoney(50); // Total 250, price is 220\n        machine.DispenseCoffee();\n        inventory.PrintInventory();\n\n        // Scenario 2: Purchase with Insufficient Funds & Cancellation\n        Console.WriteLine(\"\\n--- SCENARIO 2: Buy Espresso (Insufficient Funds & Cancel) ---\");\n        machine.SelectCoffee(CoffeeType.ESPRESSO, new List<ToppingType>());\n        machine.InsertMoney(100); // Price is 150\n        machine.DispenseCoffee(); // Should fail\n        machine.Cancel(); // Should refund 100\n        inventory.PrintInventory(); // Should be unchanged\n\n        // Scenario 3: Attempt to Buy with Insufficient Ingredients\n        Console.WriteLine(\"\\n--- SCENARIO 3: Buy Cappuccino (Out of Milk) ---\");\n        inventory.PrintInventory();\n        machine.SelectCoffee(CoffeeType.CAPPUCCINO, new List<ToppingType> { ToppingType.CARAMEL_SYRUP, ToppingType.EXTRA_SUGAR });\n        machine.InsertMoney(300);\n        machine.DispenseCoffee(); // Should fail and refund\n        inventory.PrintInventory();\n\n        // Refill and final test\n        Console.WriteLine(\"\\n--- REFILLING AND FINAL TEST ---\");\n        inventory.AddStock(Ingredient.MILK, 200);\n        inventory.PrintInventory();\n        machine.SelectCoffee(CoffeeType.LATTE, new List<ToppingType> { ToppingType.CARAMEL_SYRUP });\n        machine.InsertMoney(250);\n        machine.DispenseCoffee();\n        inventory.PrintInventory();\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Decorator/CaramelSyrupDecorator.cs",
    "content": "class CaramelSyrupDecorator : CoffeeDecorator\n{\n    private const int COST = 30;\n    private static readonly Dictionary<Ingredient, int> RECIPE_ADDITION = \n        new Dictionary<Ingredient, int> { { Ingredient.CARAMEL_SYRUP, 10 } };\n\n    public CaramelSyrupDecorator(Coffee coffee) : base(coffee) { }\n\n    public override string GetCoffeeType()\n    {\n        return decoratedCoffee.GetCoffeeType() + \", Caramel Syrup\";\n    }\n\n    public override int GetPrice()\n    {\n        return decoratedCoffee.GetPrice() + COST;\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        var newRecipe = new Dictionary<Ingredient, int>(decoratedCoffee.GetRecipe());\n        foreach (var pair in RECIPE_ADDITION)\n        {\n            if (newRecipe.ContainsKey(pair.Key))\n                newRecipe[pair.Key] += pair.Value;\n            else\n                newRecipe[pair.Key] = pair.Value;\n        }\n        return newRecipe;\n    }\n\n    public override void Prepare()\n    {\n        base.Prepare();\n        Console.WriteLine(\"- Drizzling Caramel Syrup on top.\");\n    }\n}\n"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Decorator/CoffeeDecorator.cs",
    "content": "abstract class CoffeeDecorator : Coffee\n{\n    protected Coffee decoratedCoffee;\n\n    public CoffeeDecorator(Coffee coffee)\n    {\n        decoratedCoffee = coffee;\n    }\n\n    public override int GetPrice()\n    {\n        return decoratedCoffee.GetPrice();\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        return decoratedCoffee.GetRecipe();\n    }\n\n    public override void AddCondiments()\n    {\n        decoratedCoffee.AddCondiments();\n    }\n\n    public override void Prepare()\n    {\n        decoratedCoffee.Prepare();\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Decorator/ExtraSugarDecorator.cs",
    "content": "class ExtraSugarDecorator : CoffeeDecorator\n{\n    private const int COST = 10;\n    private static readonly Dictionary<Ingredient, int> RECIPE_ADDITION = \n        new Dictionary<Ingredient, int> { { Ingredient.SUGAR, 1 } };\n\n    public ExtraSugarDecorator(Coffee coffee) : base(coffee) { }\n\n    public override string GetCoffeeType()\n    {\n        return decoratedCoffee.GetCoffeeType() + \", Extra Sugar\";\n    }\n\n    public override int GetPrice()\n    {\n        return decoratedCoffee.GetPrice() + COST;\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        var newRecipe = new Dictionary<Ingredient, int>(decoratedCoffee.GetRecipe());\n        foreach (var pair in RECIPE_ADDITION)\n        {\n            if (newRecipe.ContainsKey(pair.Key))\n                newRecipe[pair.Key] += pair.Value;\n            else\n                newRecipe[pair.Key] = pair.Value;\n        }\n        return newRecipe;\n    }\n\n    public override void Prepare()\n    {\n        base.Prepare();\n        Console.WriteLine(\"- Stirring in Extra Sugar.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Enums/CoffeeType.cs",
    "content": "enum CoffeeType\n{\n    ESPRESSO,\n    LATTE,\n    CAPPUCCINO\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Enums/Ingredient.cs",
    "content": "enum Ingredient\n{\n    COFFEE_BEANS,\n    MILK,\n    SUGAR,\n    WATER,\n    CARAMEL_SYRUP\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Enums/ToppingType.cs",
    "content": "enum ToppingType\n{\n    EXTRA_SUGAR,\n    CARAMEL_SYRUP\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Factory/CoffeeFactory.cs",
    "content": "class CoffeeFactory\n{\n    public static Coffee CreateCoffee(CoffeeType type)\n    {\n        switch (type)\n        {\n            case CoffeeType.ESPRESSO:\n                return new Espresso();\n            case CoffeeType.LATTE:\n                return new Latte();\n            case CoffeeType.CAPPUCCINO:\n                return new Cappuccino();\n            default:\n                throw new ArgumentException($\"Unsupported coffee type: {type}\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/Inventory.cs",
    "content": "class Inventory\n{\n    private static Inventory instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<Ingredient, int> stock = new Dictionary<Ingredient, int>();\n    private readonly object inventoryLock = new object();\n\n    private Inventory() { }\n\n    public static Inventory GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new Inventory();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void AddStock(Ingredient ingredient, int quantity)\n    {\n        if (stock.ContainsKey(ingredient))\n            stock[ingredient] += quantity;\n        else\n            stock[ingredient] = quantity;\n    }\n\n    public bool HasIngredients(Dictionary<Ingredient, int> recipe)\n    {\n        return recipe.All(pair => stock.GetValueOrDefault(pair.Key, 0) >= pair.Value);\n    }\n\n    public void DeductIngredients(Dictionary<Ingredient, int> recipe)\n    {\n        lock (inventoryLock)\n        {\n            if (!HasIngredients(recipe))\n            {\n                Console.WriteLine(\"Not enough ingredients to make coffee.\");\n                return;\n            }\n            foreach (var pair in recipe)\n            {\n                stock[pair.Key] -= pair.Value;\n            }\n        }\n    }\n\n    public void PrintInventory()\n    {\n        Console.WriteLine(\"--- Current Inventory ---\");\n        foreach (var pair in stock)\n        {\n            Console.WriteLine($\"{pair.Key}: {pair.Value}\");\n        }\n        Console.WriteLine(\"-------------------------\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/README.md",
    "content": "# Designing a Coffee Vending Machine\n\n## Requirements\n1. The coffee vending machine should support different types of coffee, such as espresso, cappuccino, and latte.\n2. Each type of coffee should have a specific price and recipe (ingredients and their quantities).\n3. The machine should have a menu to display the available coffee options and their prices.\n4. Users should be able to select a coffee type and make a payment.\n5. The machine should dispense the selected coffee and provide change if necessary.\n6. The machine should track the inventory of ingredients and notify when they are running low.\n7. The machine should handle multiple user requests concurrently and ensure thread safety.\n\n## Classes, Interfaces and Enumerations\n1. The **Coffee** class represents a coffee type with its name, price, and recipe (ingredients and their quantities).\n2. The **Ingredient** class represents an ingredient used in making coffee, with its name and quantity. It provides a synchronized method to update the quantity.\n3. The **Payment** class represents a payment made by a user, with the amount paid.\n4. The **CoffeeMachine** class is the main class that manages the coffee vending machine. It follows the Singleton pattern to ensure a single instance of the machine.\n5. The **CoffeeMachine** class initializes the coffee menu and ingredients in its constructor. It provides methods to display the menu, select a coffee, dispense coffee, and update ingredient quantities.\n6. The hasEnoughIngredients method checks if there are sufficient ingredients to make a selected coffee, while the updateIngredients method updates the ingredient quantities after dispensing a coffee.\n7. The **CoffeeVendingMachine** class is the entry point of the application and demonstrates the usage of the coffee vending machine. It creates an instance of the machine, displays the menu, and simulates concurrent user requests using an ExecutorService."
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/States/IVendingMachineState.cs",
    "content": "interface IVendingMachineState\n{\n    void SelectCoffee(CoffeeVendingMachine machine, Coffee coffee);\n    void InsertMoney(CoffeeVendingMachine machine, int amount);\n    void DispenseCoffee(CoffeeVendingMachine machine);\n    void Cancel(CoffeeVendingMachine machine);\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/States/OutOfIngredientState.cs",
    "content": "class OutOfIngredientState : IVendingMachineState\n{\n    public void SelectCoffee(CoffeeVendingMachine machine, Coffee coffee)\n    {\n        Console.WriteLine(\"Sorry, we are sold out.\");\n    }\n\n    public void InsertMoney(CoffeeVendingMachine machine, int amount)\n    {\n        Console.WriteLine(\"Sorry, we are sold out. Money refunded.\");\n    }\n\n    public void DispenseCoffee(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine(\"Sorry, we are sold out.\");\n    }\n\n    public void Cancel(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine($\"Refunding {machine.GetMoneyInserted()}\");\n        machine.Reset();\n        machine.SetState(new ReadyState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/States/PaidState.cs",
    "content": "class PaidState : IVendingMachineState\n{\n    public void SelectCoffee(CoffeeVendingMachine machine, Coffee coffee)\n    {\n        Console.WriteLine(\"Already paid. Please dispense or cancel.\");\n    }\n\n    public void InsertMoney(CoffeeVendingMachine machine, int amount)\n    {\n        machine.SetMoneyInserted(machine.GetMoneyInserted() + amount);\n        Console.WriteLine($\"Additional {amount} inserted. Total: {machine.GetMoneyInserted()}\");\n    }\n\n    public void DispenseCoffee(CoffeeVendingMachine machine)\n    {\n        Inventory inventory = Inventory.GetInstance();\n        Coffee coffee = machine.GetSelectedCoffee();\n\n        if (!inventory.HasIngredients(coffee.GetRecipe()))\n        {\n            Console.WriteLine(\"Sorry, we are out of ingredients. Refunding your money.\");\n            Console.WriteLine($\"Refunding {machine.GetMoneyInserted()}\");\n            machine.Reset();\n            machine.SetState(new OutOfIngredientState());\n            return;\n        }\n\n        // Deduct ingredients and prepare coffee\n        inventory.DeductIngredients(coffee.GetRecipe());\n        coffee.Prepare();\n\n        // Calculate change\n        int change = machine.GetMoneyInserted() - coffee.GetPrice();\n        if (change > 0)\n        {\n            Console.WriteLine($\"Here's your change: {change}\");\n        }\n\n        machine.Reset();\n        machine.SetState(new ReadyState());\n    }\n\n    public void Cancel(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine($\"Transaction cancelled. Refunding {machine.GetMoneyInserted()}\");\n        machine.Reset();\n        machine.SetState(new ReadyState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/States/ReadyState.cs",
    "content": "class ReadyState : IVendingMachineState\n{\n    public void SelectCoffee(CoffeeVendingMachine machine, Coffee coffee)\n    {\n        machine.SetSelectedCoffee(coffee);\n        machine.SetState(new SelectingState());\n        Console.WriteLine($\"{coffee.GetCoffeeType()} selected. Price: {coffee.GetPrice()}\");\n    }\n\n    public void InsertMoney(CoffeeVendingMachine machine, int amount)\n    {\n        Console.WriteLine(\"Please select a coffee first.\");\n    }\n\n    public void DispenseCoffee(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine(\"Please select and pay first.\");\n    }\n\n    public void Cancel(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine(\"Nothing to cancel.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/States/SelectingState.cs",
    "content": "class SelectingState : IVendingMachineState\n{\n    public void SelectCoffee(CoffeeVendingMachine machine, Coffee coffee)\n    {\n        Console.WriteLine(\"Already selected. Please pay or cancel.\");\n    }\n\n    public void InsertMoney(CoffeeVendingMachine machine, int amount)\n    {\n        machine.SetMoneyInserted(machine.GetMoneyInserted() + amount);\n        Console.WriteLine($\"Inserted {amount}. Total: {machine.GetMoneyInserted()}\");\n        if (machine.GetMoneyInserted() >= machine.GetSelectedCoffee().GetPrice())\n        {\n            machine.SetState(new PaidState());\n        }\n    }\n\n    public void DispenseCoffee(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine(\"Please insert enough money first.\");\n    }\n\n    public void Cancel(CoffeeVendingMachine machine)\n    {\n        Console.WriteLine($\"Transaction cancelled. Refunding {machine.GetMoneyInserted()}\");\n        machine.Reset();\n        machine.SetState(new ReadyState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/TemplateMethod/Cappuccino.cs",
    "content": "class Cappuccino : Coffee\n{\n    public Cappuccino()\n    {\n        coffeeType = \"Cappuccino\";\n    }\n\n    public override void AddCondiments()\n    {\n        Console.WriteLine(\"- Adding steamed milk and foam.\");\n    }\n\n    public override int GetPrice()\n    {\n        return 250;\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        return new Dictionary<Ingredient, int>\n        {\n            { Ingredient.COFFEE_BEANS, 7 },\n            { Ingredient.WATER, 30 },\n            { Ingredient.MILK, 100 }\n        };\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/TemplateMethod/Coffee.cs",
    "content": "abstract class Coffee\n{\n    protected string coffeeType = \"Unknown Coffee\";\n\n    public virtual string GetCoffeeType()\n    {\n        return coffeeType;\n    }\n\n    // The Template Method\n    public virtual void Prepare()\n    {\n        Console.WriteLine($\"\\nPreparing your {GetCoffeeType()}...\");\n        GrindBeans();\n        Brew();\n        AddCondiments(); // The \"hook\" for base coffee types\n        PourIntoCup();\n        Console.WriteLine($\"{GetCoffeeType()} is ready!\");\n    }\n\n    // Common steps\n    private void GrindBeans() { Console.WriteLine(\"- Grinding fresh coffee beans.\"); }\n    private void Brew() { Console.WriteLine(\"- Brewing coffee with hot water.\"); }\n    private void PourIntoCup() { Console.WriteLine(\"- Pouring into a cup.\"); }\n\n    // Abstract step to be implemented by subclasses\n    public abstract void AddCondiments();\n\n    public abstract int GetPrice();\n    public abstract Dictionary<Ingredient, int> GetRecipe();\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/TemplateMethod/Espresso.cs",
    "content": "class Espresso : Coffee\n{\n    public Espresso()\n    {\n        coffeeType = \"Espresso\";\n    }\n\n    public override void AddCondiments()\n    {\n        // No extra condiments for espresso\n    }\n\n    public override int GetPrice()\n    {\n        return 150;\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        return new Dictionary<Ingredient, int>\n        {\n            { Ingredient.COFFEE_BEANS, 7 },\n            { Ingredient.WATER, 30 }\n        };\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/TemplateMethod/Latte.cs",
    "content": "class Latte : Coffee\n{\n    public Latte()\n    {\n        coffeeType = \"Latte\";\n    }\n\n    public override void AddCondiments()\n    {\n        Console.WriteLine(\"- Adding steamed milk.\");\n    }\n\n    public override int GetPrice()\n    {\n        return 220;\n    }\n\n    public override Dictionary<Ingredient, int> GetRecipe()\n    {\n        return new Dictionary<Ingredient, int>\n        {\n            { Ingredient.COFFEE_BEANS, 7 },\n            { Ingredient.WATER, 30 },\n            { Ingredient.MILK, 150 }\n        };\n    }\n}"
  },
  {
    "path": "solutions/csharp/coffeevendingmachine/coffeevendingmachine.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/Booking.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ConcertBookingSystem\n{\n    public class Booking\n    {\n        public string Id { get; }\n        public User User { get; }\n        public Concert Concert { get; }\n        public List<Seat> Seats { get; }\n        public double TotalPrice { get; }\n        public BookingStatus Status { get; private set; }\n\n        public Booking(string id, User user, Concert concert, List<Seat> seats)\n        {\n            Id = id;\n            User = user;\n            Concert = concert;\n            Seats = seats;\n            TotalPrice = CalculateTotalPrice();\n            Status = BookingStatus.PENDING;\n        }\n\n        private double CalculateTotalPrice()\n        {\n            return Seats.Sum(seat => seat.Price);\n        }\n\n        public void ConfirmBooking()\n        {\n            if (Status == BookingStatus.PENDING)\n            {\n                Status = BookingStatus.CONFIRMED;\n                // Send booking confirmation\n            }\n        }\n\n        public void CancelBooking()\n        {\n            if (Status == BookingStatus.CONFIRMED)\n            {\n                Status = BookingStatus.CANCELLED;\n                Seats.ForEach(seat => seat.Release());\n                Console.WriteLine($\"Booking {Id} cancelled\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/BookingStatus.cs",
    "content": "namespace ConcertBookingSystem\n{\n    public enum BookingStatus\n    {\n        PENDING,\n        CONFIRMED,\n        CANCELLED\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/Concert.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace ConcertBookingSystem\n{\n    public class Concert\n    {\n        public string Id { get; }\n        public string Artist { get; }\n        public string Venue { get; }\n        public DateTime DateTime { get; }\n        public List<Seat> Seats { get; }\n\n        public Concert(string id, string artist, string venue, DateTime dateTime, List<Seat> seats)\n        {\n            Id = id;\n            Artist = artist;\n            Venue = venue;\n            DateTime = dateTime;\n            Seats = seats;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/ConcertTicketBookingSystem.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ConcertBookingSystem\n{\n    public class ConcertTicketBookingSystem\n    {\n        private static ConcertTicketBookingSystem _instance;\n        private readonly ConcurrentDictionary<string, Concert> concerts;\n        private readonly ConcurrentDictionary<string, Booking> bookings;\n        private readonly object lockObject = new object();\n\n        private ConcertTicketBookingSystem()\n        {\n            concerts = new ConcurrentDictionary<string, Concert>();\n            bookings = new ConcurrentDictionary<string, Booking>();\n        }\n\n        public static ConcertTicketBookingSystem Instance\n        {\n            get\n            {\n                if (_instance == null)\n                {\n                    _instance = new ConcertTicketBookingSystem();\n                }\n                return _instance;\n            }\n        }\n\n        public void AddConcert(Concert concert)\n        {\n            concerts.TryAdd(concert.Id, concert);\n        }\n\n        public Concert GetConcert(string concertId)\n        {\n            concerts.TryGetValue(concertId, out var concert);\n            return concert;\n        }\n\n        public List<Concert> SearchConcerts(string artist, string venue, DateTime dateTime)\n        {\n            return concerts.Values.Where(concert =>\n                concert.Artist.Equals(artist, StringComparison.OrdinalIgnoreCase) &&\n                concert.Venue.Equals(venue, StringComparison.OrdinalIgnoreCase) &&\n                concert.DateTime == dateTime).ToList();\n        }\n\n        public Booking BookTickets(User user, Concert concert, List<Seat> seats)\n        {\n            lock (lockObject)\n            {\n                foreach (var seat in seats)\n                {\n                    if (seat.Status != SeatStatus.AVAILABLE)\n                    {\n                        throw new SeatNotAvailableException($\"Seat {seat.SeatNumber} is not available.\");\n                    }\n                }\n\n                seats.ForEach(seat => seat.Book());\n\n                string bookingId = GenerateBookingId();\n                var booking = new Booking(bookingId, user, concert, seats);\n                bookings.TryAdd(bookingId, booking);\n\n                ProcessPayment(booking);\n                booking.ConfirmBooking();\n\n                Console.WriteLine($\"Booking {booking.Id} - {booking.Seats.Count} seats booked\");\n\n                return booking;\n            }\n        }\n\n        public void CancelBooking(string bookingId)\n        {\n            bookings.TryRemove(bookingId, out var booking);\n            booking?.CancelBooking();\n        }\n\n        private void ProcessPayment(Booking booking)\n        {\n            // Simulate payment processing logic here\n        }\n\n        private string GenerateBookingId()\n        {\n            return \"BKG\" + Guid.NewGuid();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/ConcertTicketBookingSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ConcertBookingSystem\n{\n    public class ConcertTicketBookingSystemDemo\n    {\n        public static void Run()\n        {\n            // Create concert ticket booking system instance\n            var bookingSystem = ConcertTicketBookingSystem.Instance;\n\n            // Create concerts\n            var concert1Seats = GenerateSeats(100);\n            var concert1 = new Concert(\"C001\", \"Artist 1\", \"Venue 1\", DateTime.Now.AddDays(30), concert1Seats);\n            bookingSystem.AddConcert(concert1);\n\n            var concert2Seats = GenerateSeats(50);\n            var concert2 = new Concert(\"C002\", \"Artist 2\", \"Venue 2\", DateTime.Now.AddDays(60), concert2Seats);\n            bookingSystem.AddConcert(concert2);\n\n            // Create users\n            var user1 = new User(\"U001\", \"John Doe\", \"john@example.com\");\n            var user2 = new User(\"U002\", \"Jane Smith\", \"jane@example.com\");\n\n            // Search concerts\n            var searchResults = bookingSystem.SearchConcerts(\"Artist 1\", \"Venue 1\", DateTime.Now.AddDays(30));\n            Console.WriteLine(\"Search Results:\");\n            foreach (var concert in searchResults)\n            {\n                Console.WriteLine($\"Concert: {concert.Artist} at {concert.Venue}\");\n            }\n\n            // Book tickets\n            var selectedSeats1 = SelectSeats(concert1, 3);\n            var booking1 = bookingSystem.BookTickets(user1, concert1, selectedSeats1);\n\n            var selectedSeats2 = SelectSeats(concert2, 2);\n            var booking2 = bookingSystem.BookTickets(user2, concert2, selectedSeats2);\n\n            // Cancel booking\n            bookingSystem.CancelBooking(booking1.Id);\n\n            // Book tickets again\n            var selectedSeats3 = SelectSeats(concert1, 2);\n            var booking3 = bookingSystem.BookTickets(user2, concert1, selectedSeats3);\n        }\n\n        private static List<Seat> GenerateSeats(int numberOfSeats)\n        {\n            var seats = new List<Seat>();\n            for (int i = 1; i <= numberOfSeats; i++)\n            {\n                string seatNumber = \"S\" + i;\n                SeatType seatType = (i <= 10) ? SeatType.VIP : (i <= 30) ? SeatType.PREMIUM : SeatType.REGULAR;\n                double price = seatType switch\n                {\n                    SeatType.VIP => 100.0,\n                    SeatType.PREMIUM => 75.0,\n                    _ => 50.0,\n                };\n                seats.Add(new Seat(seatNumber, seatNumber, seatType, price));\n            }\n            return seats;\n        }\n\n        private static List<Seat> SelectSeats(Concert concert, int numberOfSeats)\n        {\n            var availableSeats = concert.Seats\n                .Where(seat => seat.Status == SeatStatus.AVAILABLE)\n                .Take(numberOfSeats)\n                .ToList();\n            return availableSeats;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/README.md",
    "content": "# Designing a Concert Ticket Booking System\n\n## Requirements\n1. The concert ticket booking system should allow users to view available concerts and their seating arrangements.\n2. Users should be able to search for concerts based on various criteria such as artist, venue, date, and time.\n3. Users should be able to select seats and purchase tickets for a specific concert.\n4. The system should handle concurrent booking requests to avoid double-booking of seats.\n5. The system should ensure fair booking opportunities for all users.\n6. The system should handle payment processing securely.\n7. The system should generate booking confirmations and send them to users via email or SMS.\n8. The system should provide a waiting list functionality for sold-out concerts.\n\n## Classes, Interfaces and Enumerations\n1. The **Concert** class represents a concert event, with properties such as ID, artist, venue, date and time, and a list of seats.\n2. The **Seat** class represents a seat in a concert, with properties like ID, seat number, seat type, price, and status. It provides methods to book and release a seat.\n3. The **SeatType** enum represents the different types of seats available, such as regular, premium, and VIP.\n4. The **SeatStatus** enum represents the status of a seat, which can be available, booked, or reserved.\n5. The **Booking** class represents a booking made by a user for a specific concert and seats. It contains properties such as ID, user, concert, seats, total price, and status. It provides methods to confirm and cancel a booking.\n6. The **BookingStatus** enum represents the status of a booking, which can be pending, confirmed, or cancelled.\n7. The **User** class represents a user of the concert ticket booking system, with properties like ID, name, and email.\n8. The **ConcertTicketBookingSystem** class is the central component of the system. It follows the Singleton pattern to ensure a single instance of the system. It manages concerts, bookings, and provides methods to add concerts, search concerts, book tickets, and cancel bookings.\n9. The **SeatNotAvailableException** is a custom exception used to handle cases where a seat is not available for booking."
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/Seat.cs",
    "content": "namespace ConcertBookingSystem\n{\n    public class Seat\n    {\n        public string Id { get; }\n        public string SeatNumber { get; }\n        public SeatType SeatType { get; }\n        public double Price { get; }\n        public SeatStatus Status { get; private set; }\n\n        public Seat(string id, string seatNumber, SeatType seatType, double price)\n        {\n            Id = id;\n            SeatNumber = seatNumber;\n            SeatType = seatType;\n            Price = price;\n            Status = SeatStatus.AVAILABLE;\n        }\n\n        public void Book()\n        {\n            if (Status == SeatStatus.AVAILABLE)\n            {\n                Status = SeatStatus.BOOKED;\n            }\n            else\n            {\n                throw new SeatNotAvailableException(\"Seat is already booked or reserved.\");\n            }\n        }\n\n        public void Release()\n        {\n            if (Status == SeatStatus.BOOKED)\n            {\n                Status = SeatStatus.AVAILABLE;\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/SeatNotAvailableException.cs",
    "content": "using System;\n\nnamespace ConcertBookingSystem\n{\n    public class SeatNotAvailableException : Exception\n    {\n        public SeatNotAvailableException(string message) : base(message)\n        {\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/SeatStatus.cs",
    "content": "namespace ConcertBookingSystem\n{\n    public enum SeatStatus\n    {\n        AVAILABLE,\n        BOOKED,\n        RESERVED\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/SeatType.cs",
    "content": "namespace ConcertBookingSystem\n{\n    public enum SeatType\n    {\n        REGULAR,\n        PREMIUM,\n        VIP\n    }\n}"
  },
  {
    "path": "solutions/csharp/concertticketbookingsystem/User.cs",
    "content": "namespace ConcertBookingSystem\n{\n    public class User\n    {\n        public string Id { get; }\n        public string Name { get; }\n        public string Email { get; }\n\n        public User(string id, string name, string email)\n        {\n            Id = id;\n            Name = name;\n            Email = email;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/Course.cs",
    "content": "namespace CourseRegistrationSystem\n{\n    public class Course\n    {\n        private readonly string code;\n        private readonly string name;\n        private readonly string instructor;\n        private readonly int maxCapacity;\n        private int enrolledStudents;\n\n        public Course(string code, string name, string instructor, int maxCapacity, int enrolledStudents)\n        {\n            this.code = code;\n            this.name = name;\n            this.instructor = instructor;\n            this.maxCapacity = maxCapacity;\n            this.enrolledStudents = enrolledStudents;\n        }\n\n        public string GetCode() => code;\n        public string GetName() => name;\n        public string GetInstructor() => instructor;\n        public int GetMaxCapacity() => maxCapacity;\n        public int GetEnrolledStudents() => enrolledStudents;\n\n        public void SetEnrolledStudents(int enrolledStudents) => this.enrolledStudents = enrolledStudents;\n    }\n}"
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/CourseRegistrationDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace CourseRegistrationSystem\n{\n    public class CourseRegistrationDemo\n    {\n        public static void Run()\n        {\n            CourseRegistrationSystem registrationSystem = CourseRegistrationSystem.GetInstance();\n\n            // Create courses\n            Course course1 = new Course(\"CS101\", \"Introduction to Programming\", \"John Doe\", 50, 0);\n            Course course2 = new Course(\"CS201\", \"Data Structures and Algorithms\", \"Jane Smith\", 30, 0);\n            registrationSystem.AddCourse(course1);\n            registrationSystem.AddCourse(course2);\n\n            // Create students\n            Student student1 = new Student(1, \"Alice\", \"alice@example.com\", new List<Course>());\n            Student student2 = new Student(2, \"Bob\", \"bob@example.com\", new List<Course>());\n            registrationSystem.AddStudent(student1);\n            registrationSystem.AddStudent(student2);\n\n            // Search for courses\n            List<Course> searchResults = registrationSystem.SearchCourses(\"CS\");\n            Console.WriteLine(\"Search Results:\");\n            foreach (Course course in searchResults)\n            {\n                Console.WriteLine(course.GetCode() + \" - \" + course.GetName());\n            }\n\n            // Register courses for students\n            bool registered1 = registrationSystem.RegisterCourse(student1, course1);\n            bool registered2 = registrationSystem.RegisterCourse(student2, course1);\n            bool registered3 = registrationSystem.RegisterCourse(student1, course2);\n\n            Console.WriteLine(\"Registration Results:\");\n            Console.WriteLine(\"Student 1 - Course 1: \" + registered1);\n            Console.WriteLine(\"Student 2 - Course 1: \" + registered2);\n            Console.WriteLine(\"Student 1 - Course 2: \" + registered3);\n\n            // Get registered courses for a student\n            List<Course> registeredCourses = registrationSystem.GetRegisteredCourses(student1);\n            Console.WriteLine(\"Registered Courses for Student 1:\");\n            foreach (Course course in registeredCourses)\n            {\n                Console.WriteLine(course.GetCode() + \" - \" + course.GetName());\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/CourseRegistrationSystem.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace CourseRegistrationSystem\n{\n    public class CourseRegistrationSystem\n    {\n        private static CourseRegistrationSystem instance;\n        private readonly ConcurrentDictionary<string, Course> courses;\n        private readonly ConcurrentDictionary<int, Student> students;\n        private readonly List<Registration> registrations;\n\n        private CourseRegistrationSystem()\n        {\n            courses = new ConcurrentDictionary<string, Course>();\n            students = new ConcurrentDictionary<int, Student>();\n            registrations = new List<Registration>();\n        }\n\n        public static CourseRegistrationSystem GetInstance()\n        {\n            if (instance == null)\n            {\n                instance = new CourseRegistrationSystem();\n            }\n            return instance;\n        }\n\n        public void AddCourse(Course course) => courses[course.GetCode()] = course;\n\n        public void AddStudent(Student student) => students[student.GetId()] = student;\n\n        public List<Course> SearchCourses(string query)\n        {\n            return courses.Values\n                          .Where(course => course.GetCode().Contains(query) || course.GetName().Contains(query))\n                          .ToList();\n        }\n\n        public bool RegisterCourse(Student student, Course course)\n        {\n            if (course.GetEnrolledStudents() < course.GetMaxCapacity())\n            {\n                Registration registration = new Registration(student, course, DateTime.Now);\n                registrations.Add(registration);\n                student.GetRegisteredCourses().Add(course);\n                course.SetEnrolledStudents(course.GetEnrolledStudents() + 1);\n                NotifyObservers(course);\n                return true;\n            }\n            return false;\n        }\n\n        public List<Course> GetRegisteredCourses(Student student) => student.GetRegisteredCourses();\n\n        private void NotifyObservers(Course course)\n        {\n            // Notify observers (e.g., UI) about the updated course enrollment\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/README.md",
    "content": "# Designing a University Course Registration System\n\n## Requirements\n1. The course registration system should allow students to register for courses and view their registered courses.\n2. Each course should have a course code, name, instructor, and maximum enrollment capacity.\n3. Students should be able to search for courses based on course code or name.\n4. The system should prevent students from registering for courses that have reached their maximum enrollment capacity.\n5. The system should handle concurrent registration requests from multiple students.\n6. The system should ensure data consistency and prevent race conditions.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Student** class represents a student in the course registration system, with properties such as ID, name, email, and a list of registered courses.\n2. The **Course** class represents a course offered in the system, with properties such as code, name, instructor, maximum capacity, and the number of enrolled students.\n3. The **Registration** class represents a registration record, associating a student with a course and capturing the registration timestamp.\n4. The **CourseRegistrationSystem** class is the main class that manages the course registration system. It follows the Singleton pattern to ensure only one instance of the system exists.\n5. The CourseRegistrationSystem class provides methods for adding courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student.\n6. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as courses and registrations.\n7. The registerCourse method is synchronized to ensure thread safety when multiple students are registering for courses simultaneously.\n8. The notifyObservers method is a placeholder for notifying observers (e.g., UI components) about updates to course enrollment.\n9. The **CourseRegistrationDemo** class demonstrates the usage of the course registration system by creating courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student."
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/Registration.cs",
    "content": "using System;\n\nnamespace CourseRegistrationSystem\n{\n    public class Registration\n    {\n        private readonly Student student;\n        private readonly Course course;\n        private readonly DateTime registrationTime;\n\n        public Registration(Student student, Course course, DateTime registrationTime)\n        {\n            this.student = student;\n            this.course = course;\n            this.registrationTime = registrationTime;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/courseregistrationsystem/Student.cs",
    "content": "using System.Collections.Generic;\n\nnamespace CourseRegistrationSystem\n{\n    public class Student\n    {\n        private readonly int id;\n        private readonly string name;\n        private readonly string email;\n        private readonly List<Course> registeredCourses;\n\n        public Student(int id, string name, string email, List<Course> registeredCourses)\n        {\n            this.id = id;\n            this.name = name;\n            this.email = email;\n            this.registeredCourses = registeredCourses;\n        }\n\n        public int GetId() => id;\n        public string GetName() => name;\n        public string GetEmail() => email;\n        public List<Course> GetRegisteredCourses() => registeredCourses;\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/CommentaryManager.cs",
    "content": "class CommentaryManager\n{\n    private static volatile CommentaryManager instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<string, List<string>> commentaryTemplates;\n    private readonly Random random;\n\n    private CommentaryManager()\n    {\n        commentaryTemplates = new Dictionary<string, List<string>>();\n        random = new Random();\n        InitializeTemplates();\n    }\n\n    public static CommentaryManager GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new CommentaryManager();\n                }\n            }\n        }\n        return instance;\n    }\n\n    private void InitializeTemplates()\n    {\n        commentaryTemplates[\"RUNS_0\"] = new List<string>\n        {\n            \"%s defends solidly.\",\n            \"No run, good fielding by the cover fielder.\",\n            \"A dot ball to end the over.\",\n            \"Pushed to mid-on, but no run.\"\n        };\n\n        commentaryTemplates[\"RUNS_1\"] = new List<string>\n        {\n            \"Tucked away to the leg side for a single.\",\n            \"Quick single taken by %s.\",\n            \"Pushed to long-on for one.\"\n        };\n\n        commentaryTemplates[\"RUNS_2\"] = new List<string>\n        {\n            \"Two runs taken!\",\n            \"Quick double taken by %s.\",\n            \"Pushed to mid-on for two.\"\n        };\n\n        commentaryTemplates[\"RUNS_4\"] = new List<string>\n        {\n            \"FOUR! %s smashes it through the covers!\",\n            \"Beautiful shot! That's a boundary.\",\n            \"Finds the gap perfectly. Four runs.\"\n        };\n\n        commentaryTemplates[\"RUNS_6\"] = new List<string>\n        {\n            \"SIX! That's out of the park!\",\n            \"%s sends it sailing over the ropes!\",\n            \"Massive hit! It's a maximum.\"\n        };\n\n        commentaryTemplates[\"WICKET_BOWLED\"] = new List<string>\n        {\n            \"BOWLED HIM! %s misses completely and the stumps are shattered!\",\n            \"Cleaned up! A perfect yorker from %s.\"\n        };\n\n        commentaryTemplates[\"WICKET_CAUGHT\"] = new List<string>\n        {\n            \"CAUGHT! %s skies it and the fielder takes a comfortable catch.\",\n            \"Out! A brilliant catch in the deep by %s.\"\n        };\n\n        commentaryTemplates[\"WICKET_LBW\"] = new List<string>\n        {\n            \"LBW! That one kept low and struck %s right in front.\",\n            \"%s completely misjudged the line and pays the price.\"\n        };\n\n        commentaryTemplates[\"WICKET_STUMPED\"] = new List<string>\n        {\n            \"STUMPED! %s misses it, and the keeper does the rest!\",\n            \"Gone! Lightning-fast work by the keeper to stump %s.\"\n        };\n\n        commentaryTemplates[\"EXTRA_WIDE\"] = new List<string>\n        {\n            \"That's a wide. The umpire signals an extra run.\",\n            \"Too far down the leg side, that'll be a wide.\"\n        };\n\n        commentaryTemplates[\"EXTRA_NO_BALL\"] = new List<string>\n        {\n            \"No ball! %s has overstepped. It's a free hit.\",\n            \"It's a no-ball for overstepping.\"\n        };\n    }\n\n    public string GenerateCommentary(Ball ball)\n    {\n        string key = GetEventKey(ball);\n        var templates = commentaryTemplates.ContainsKey(key) ? \n                       commentaryTemplates[key] : \n                       new List<string> { \"Just a standard delivery.\" };\n\n        string template = templates[random.Next(templates.Count)];\n\n        string batsmanName = ball.GetFacedBy()?.GetName() ?? \"\";\n\n        return template.Replace(\"%s\", batsmanName);\n    }\n\n    private string GetEventKey(Ball ball)\n    {\n        if (ball.IsWicket())\n        {\n            return $\"WICKET_{ball.GetWicket().GetWicketType()}\";\n        }\n\n        if (ball.GetExtraType().HasValue)\n        {\n            return $\"EXTRA_{ball.GetExtraType().Value}\";\n        }\n\n        int runs = ball.GetRunsScored();\n        if (runs >= 0 && runs <= 6)\n        {\n            return $\"RUNS_{runs}\";\n        }\n\n        return \"DEFAULT\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/CricinfoDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class CricinfoDemo\n{\n    public static void Main()\n    {\n        var service = CricInfoService.GetInstance();\n\n        // Setup Players and Teams\n        var p1 = service.AddPlayer(\"P1\", \"Virat\", PlayerRole.BATSMAN);\n        var p2 = service.AddPlayer(\"P2\", \"Rohit\", PlayerRole.BATSMAN);\n        var p3 = service.AddPlayer(\"P3\", \"Bumrah\", PlayerRole.BOWLER);\n        var p4 = service.AddPlayer(\"P4\", \"Jadeja\", PlayerRole.ALL_ROUNDER);\n\n        var p5 = service.AddPlayer(\"P5\", \"Warner\", PlayerRole.BATSMAN);\n        var p6 = service.AddPlayer(\"P6\", \"Smith\", PlayerRole.BATSMAN);\n        var p7 = service.AddPlayer(\"P7\", \"Starc\", PlayerRole.BOWLER);\n        var p8 = service.AddPlayer(\"P8\", \"Maxwell\", PlayerRole.ALL_ROUNDER);\n\n        var india = new Team(\"T1\", \"India\", new List<Player> { p1, p2, p3, p4 });\n        var australia = new Team(\"T2\", \"Australia\", new List<Player> { p5, p6, p7, p8 });\n\n        // Create a T20 Match\n        var t20Match = service.CreateMatch(india, australia, new T20FormatStrategy());\n        string matchId = t20Match.GetId();\n\n        // Create and subscribe observers\n        var scorecard = new ScorecardDisplay();\n        var commentary = new CommentaryDisplay();\n        var notifier = new UserNotifier();\n\n        service.SubscribeToMatch(matchId, scorecard);\n        service.SubscribeToMatch(matchId, commentary);\n        service.SubscribeToMatch(matchId, notifier);\n\n        // Start the match\n        service.StartMatch(matchId);\n\n        Console.WriteLine(\"\\n--- SIMULATING FIRST INNINGS ---\");\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p7).WithFacedBy(p2).WithRuns(6).Build());\n\n        var p2Wicket = new WicketBuilder(WicketType.BOWLED, p2).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p7).WithFacedBy(p2).WithRuns(0).WithWicket(p2Wicket).Build());\n\n        var p3Wicket = new WicketBuilder(WicketType.LBW, p3).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p7).WithFacedBy(p3).WithRuns(0).WithWicket(p3Wicket).Build());\n\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p7).WithFacedBy(p4).WithRuns(4).Build());\n\n        var p4Wicket = new WicketBuilder(WicketType.CAUGHT, p4).WithCaughtBy(p6).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p7).WithFacedBy(p4).WithRuns(0).WithWicket(p4Wicket).Build());\n\n        Console.WriteLine(\"\\n\\n--- INNINGS BREAK ---\");\n        Console.WriteLine(\"Players are off the field. Preparing for the second innings.\");\n\n        // Start the second innings\n        service.StartNextInnings(matchId);\n\n        Console.WriteLine(\"\\n--- SIMULATING SECOND INNINGS ---\");\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p3).WithFacedBy(p5).WithRuns(4).Build());\n\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p3).WithFacedBy(p5).WithRuns(1).Build());\n\n        var p5Wicket = new WicketBuilder(WicketType.BOWLED, p5).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p3).WithFacedBy(p5).WithRuns(0).WithWicket(p5Wicket).Build());\n\n        var p7Wicket = new WicketBuilder(WicketType.LBW, p7).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p3).WithFacedBy(p7).WithRuns(0).WithWicket(p7Wicket).Build());\n\n        var p8Wicket = new WicketBuilder(WicketType.STUMPED, p8).Build();\n        service.ProcessBallUpdate(matchId, new BallBuilder()\n                                   .WithBowledBy(p3).WithFacedBy(p8).WithRuns(0).WithWicket(p8Wicket).Build());\n\n        service.EndMatch(matchId);\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/CricinfoService.cs",
    "content": "class CricInfoService\n{\n    private static volatile CricInfoService instance;\n    private static readonly object lockObject = new object();\n    private readonly MatchRepository matchRepository;\n    private readonly PlayerRepository playerRepository;\n\n    private CricInfoService()\n    {\n        matchRepository = new MatchRepository();\n        playerRepository = new PlayerRepository();\n    }\n\n    public static CricInfoService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new CricInfoService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public Match CreateMatch(Team team1, Team team2, IMatchFormatStrategy format)\n    {\n        string matchId = Guid.NewGuid().ToString();\n        var match = new Match(matchId, team1, team2, format);\n        matchRepository.Save(match);\n        Console.WriteLine($\"Match {format.GetFormatName()} created between {team1.GetName()} and {team2.GetName()}.\");\n        return match;\n    }\n\n    public void StartMatch(string matchId)\n    {\n        var match = matchRepository.FindById(matchId);\n        if (match != null)\n        {\n            match.SetState(new LiveState());\n            Console.WriteLine($\"Match {matchId} is now LIVE.\");\n        }\n    }\n\n    public void ProcessBallUpdate(string matchId, Ball ball)\n    {\n        var match = matchRepository.FindById(matchId);\n        match?.ProcessBall(ball);\n    }\n\n    public void StartNextInnings(string matchId)\n    {\n        var match = matchRepository.FindById(matchId);\n        match?.StartNextInnings();\n    }\n\n    public void SubscribeToMatch(string matchId, IMatchObserver observer)\n    {\n        var match = matchRepository.FindById(matchId);\n        match?.AddObserver(observer);\n    }\n\n    public void EndMatch(string matchId)\n    {\n        var match = matchRepository.FindById(matchId);\n        if (match != null)\n        {\n            match.SetState(new FinishedState());\n            Console.WriteLine($\"Match {matchId} has FINISHED.\");\n        }\n    }\n\n    public Player AddPlayer(string playerId, string playerName, PlayerRole playerRole)\n    {\n        var player = new Player(playerId, playerName, playerRole);\n        playerRepository.Save(player);\n        return player;\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Enums/ExtraType.cs",
    "content": "enum ExtraType\n{\n    WIDE,\n    NO_BALL,\n    BYE,\n    LEG_BYE\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Enums/MatchStatus.cs",
    "content": "enum MatchStatus\n{\n    SCHEDULED,\n    LIVE,\n    IN_BREAK,\n    FINISHED,\n    ABANDONED\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Enums/MatchType.cs",
    "content": "enum MatchType\n{\n    T20,\n    ODI,\n    TEST\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Enums/PlayerRole.cs",
    "content": "enum PlayerRole\n{\n    BATSMAN,\n    BOWLER,\n    ALL_ROUNDER,\n    WICKET_KEEPER\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Enums/WicketType.cs",
    "content": "enum WicketType\n{\n    BOWLED,\n    CAUGHT,\n    LBW,\n    RUN_OUT,\n    STUMPED,\n    HIT_WICKET\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Ball.cs",
    "content": "class Ball\n{\n    private readonly int ballNumber;\n    private readonly Player bowledBy;\n    private readonly Player facedBy;\n    private readonly int runsScored;\n    private readonly Wicket wicket;\n    private readonly ExtraType? extraType;\n    private readonly string commentary;\n\n    public Ball(BallBuilder builder)\n    {\n        ballNumber = builder.BallNumber;\n        bowledBy = builder.BowledBy;\n        facedBy = builder.FacedBy;\n        runsScored = builder.RunsScored;\n        wicket = builder.Wicket;\n        extraType = builder.ExtraType;\n        commentary = builder.Commentary;\n    }\n\n    public bool IsWicket() => wicket != null;\n    public bool IsBoundary() => runsScored == 4 || runsScored == 6;\n\n    public int GetBallNumber() => ballNumber;\n    public Player GetBowledBy() => bowledBy;\n    public Player GetFacedBy() => facedBy;\n    public int GetRunsScored() => runsScored;\n    public Wicket GetWicket() => wicket;\n    public ExtraType? GetExtraType() => extraType;\n    public string GetCommentary() => commentary;\n}\n\nclass BallBuilder\n{\n    private int ballNumber;\n    private Player bowledBy;\n    private Player facedBy;\n    private int runsScored;\n    private Wicket wicket;\n    private ExtraType? extraType;\n    private string commentary;\n\n    public BallBuilder WithBallNumber(int number)\n    {\n        ballNumber = number;\n        return this;\n    }\n\n    public BallBuilder WithBowledBy(Player bowler)\n    {\n        bowledBy = bowler;\n        return this;\n    }\n\n    public BallBuilder WithFacedBy(Player batsman)\n    {\n        facedBy = batsman;\n        return this;\n    }\n\n    public BallBuilder WithRuns(int runs)\n    {\n        runsScored = runs;\n        return this;\n    }\n\n    public BallBuilder WithWicket(Wicket w)\n    {\n        wicket = w;\n        return this;\n    }\n\n    public BallBuilder WithExtraType(ExtraType extra)\n    {\n        extraType = extra;\n        return this;\n    }\n\n    public BallBuilder WithCommentary(string comm)\n    {\n        commentary = comm;\n        return this;\n    }\n\n    public Ball Build()\n    {\n        var tempBall = new Ball(this);\n\n        if (string.IsNullOrEmpty(commentary))\n        {\n            commentary = CommentaryManager.GetInstance().GenerateCommentary(tempBall);\n        }\n\n        return new Ball(this);\n    }\n\n    internal int BallNumber => ballNumber;\n    internal Player BowledBy => bowledBy;\n    internal Player FacedBy => facedBy;\n    internal int RunsScored => runsScored;\n    internal Wicket Wicket => wicket;\n    internal ExtraType? ExtraType => extraType;\n    internal string Commentary => commentary;\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Innings.cs",
    "content": "class Innings\n{\n    private readonly Team battingTeam;\n    private readonly Team bowlingTeam;\n    private int score;\n    private int wickets;\n    private readonly List<Ball> balls;\n    private readonly Dictionary<Player, PlayerStats> playerStats;\n\n    public Innings(Team batting, Team bowling)\n    {\n        battingTeam = batting;\n        bowlingTeam = bowling;\n        score = 0;\n        wickets = 0;\n        balls = new List<Ball>();\n        playerStats = new Dictionary<Player, PlayerStats>();\n\n        foreach (var player in battingTeam.GetPlayers())\n        {\n            playerStats[player] = new PlayerStats();\n        }\n        foreach (var player in bowlingTeam.GetPlayers())\n        {\n            playerStats[player] = new PlayerStats();\n        }\n    }\n\n    public void AddBall(Ball ball)\n    {\n        balls.Add(ball);\n        int runsScored = ball.GetRunsScored();\n        score += runsScored;\n\n        if (ball.GetExtraType() == ExtraType.WIDE || ball.GetExtraType() == ExtraType.NO_BALL)\n        {\n            score += 1;\n        }\n        else\n        {\n            ball.GetFacedBy().GetStats().UpdateRuns(runsScored);\n            ball.GetFacedBy().GetStats().IncrementBallsPlayed();\n            playerStats[ball.GetFacedBy()].UpdateRuns(runsScored);\n            playerStats[ball.GetFacedBy()].IncrementBallsPlayed();\n        }\n\n        if (ball.IsWicket())\n        {\n            wickets++;\n            ball.GetBowledBy().GetStats().IncrementWickets();\n            playerStats[ball.GetBowledBy()].IncrementWickets();\n        }\n    }\n\n    public void PrintPlayerStats()\n    {\n        foreach (var entry in playerStats)\n        {\n            var player = entry.Key;\n            var stats = entry.Value;\n\n            if (stats.GetBallsPlayed() > 0 || stats.GetWickets() > 0)\n            {\n                Console.WriteLine($\"Player: {player.GetName()} - Stats: {stats}\");\n            }\n        }\n    }\n\n    public double GetOvers()\n    {\n        int validBalls = balls.Count(b => b.GetExtraType() != ExtraType.WIDE && b.GetExtraType() != ExtraType.NO_BALL);\n\n        int completedOvers = validBalls / 6;\n        int ballsInCurrentOver = validBalls % 6;\n\n        return completedOvers + (ballsInCurrentOver / 10.0);\n    }\n\n    public Team GetBattingTeam() => battingTeam;\n    public Team GetBowlingTeam() => bowlingTeam;\n    public int GetScore() => score;\n    public int GetWickets() => wickets;\n    public List<Ball> GetBalls() => balls;\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Match.cs",
    "content": "class Match\n{\n    private readonly string id;\n    private readonly Team team1;\n    private readonly Team team2;\n    private readonly IMatchFormatStrategy formatStrategy;\n    private readonly List<Innings> innings;\n    private IMatchState currentState;\n    private MatchStatus currentStatus;\n    private readonly List<IMatchObserver> observers;\n    private Team winner;\n    private string resultMessage;\n\n    public Match(string matchId, Team t1, Team t2, IMatchFormatStrategy format)\n    {\n        id = matchId;\n        team1 = t1;\n        team2 = t2;\n        formatStrategy = format;\n        innings = new List<Innings> { new Innings(team1, team2) };\n        currentState = new ScheduledState();\n        observers = new List<IMatchObserver>();\n        resultMessage = \"\";\n    }\n\n    public void ProcessBall(Ball ball)\n    {\n        currentState.ProcessBall(this, ball);\n    }\n\n    public void StartNextInnings()\n    {\n        currentState.StartNextInnings(this);\n    }\n\n    public void CreateNewInnings()\n    {\n        if (innings.Count >= formatStrategy.GetTotalInnings())\n        {\n            Console.WriteLine(\"Cannot create a new innings, match has already reached its limit.\");\n            return;\n        }\n\n        var nextInnings = new Innings(team2, team1);\n        innings.Add(nextInnings);\n    }\n\n    public void AddObserver(IMatchObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IMatchObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers(Ball ball)\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(this, ball);\n        }\n    }\n\n    public Innings GetCurrentInnings()\n    {\n        return innings.Last();\n    }\n\n    public string GetId() => id;\n    public Team GetTeam1() => team1;\n    public Team GetTeam2() => team2;\n    public IMatchFormatStrategy GetFormatStrategy() => formatStrategy;\n    public List<Innings> GetInnings() => innings;\n    public MatchStatus GetCurrentStatus() => currentStatus;\n    public Team GetWinner() => winner;\n    public string GetResultMessage() => resultMessage;\n\n    public void SetState(IMatchState state) { currentState = state; }\n    public void SetCurrentStatus(MatchStatus status) { currentStatus = status; }\n    public void SetWinner(Team w) { winner = w; }\n    public void SetResultMessage(string message) { resultMessage = message; }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Player.cs",
    "content": "class Player\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly PlayerRole role;\n    private readonly PlayerStats stats;\n\n    public Player(string playerId, string playerName, PlayerRole playerRole)\n    {\n        id = playerId;\n        name = playerName;\n        role = playerRole;\n        stats = new PlayerStats();\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n    public PlayerRole GetRole() => role;\n    public PlayerStats GetStats() => stats;\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/PlayerStats.cs",
    "content": "class PlayerStats\n{\n    private int runs;\n    private int ballsPlayed;\n    private int wickets;\n\n    public PlayerStats()\n    {\n        runs = 0;\n        ballsPlayed = 0;\n        wickets = 0;\n    }\n\n    public void UpdateRuns(int runScored)\n    {\n        runs += runScored;\n    }\n\n    public void IncrementBallsPlayed()\n    {\n        ballsPlayed++;\n    }\n\n    public void IncrementWickets()\n    {\n        wickets++;\n    }\n\n    public int GetRuns() => runs;\n    public int GetBallsPlayed() => ballsPlayed;\n    public int GetWickets() => wickets;\n\n    public override string ToString()\n    {\n        return $\"Runs: {runs}, Balls Played: {ballsPlayed}, Wickets: {wickets}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Team.cs",
    "content": "class Team\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly List<Player> players;\n\n    public Team(string teamId, string teamName, List<Player> teamPlayers)\n    {\n        id = teamId;\n        name = teamName;\n        players = teamPlayers;\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n    public List<Player> GetPlayers() => players;\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Models/Wicket.cs",
    "content": "class Wicket\n{\n    private readonly WicketType wicketType;\n    private readonly Player playerOut;\n    private readonly Player caughtBy;\n    private readonly Player runoutBy;\n\n    public Wicket(WicketBuilder builder)\n    {\n        wicketType = builder.WicketType;\n        playerOut = builder.PlayerOut;\n        caughtBy = builder.CaughtBy;\n        runoutBy = builder.RunoutBy;\n    }\n\n    public WicketType GetWicketType() => wicketType;\n    public Player GetPlayerOut() => playerOut;\n    public Player GetCaughtBy() => caughtBy;\n    public Player GetRunoutBy() => runoutBy;\n}\n\nclass WicketBuilder\n{\n    private readonly WicketType wicketType;\n    private readonly Player playerOut;\n    private Player caughtBy;\n    private Player runoutBy;\n\n    public WicketBuilder(WicketType type, Player player)\n    {\n        wicketType = type;\n        playerOut = player;\n    }\n\n    public WicketBuilder WithCaughtBy(Player player)\n    {\n        caughtBy = player;\n        return this;\n    }\n\n    public WicketBuilder WithRunoutBy(Player player)\n    {\n        runoutBy = player;\n        return this;\n    }\n\n    public Wicket Build()\n    {\n        return new Wicket(this);\n    }\n\n    internal WicketType WicketType => wicketType;\n    internal Player PlayerOut => playerOut;\n    internal Player CaughtBy => caughtBy;\n    internal Player RunoutBy => runoutBy;\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Observers/CommentaryDisplay.cs",
    "content": "class CommentaryDisplay : IMatchObserver\n{\n    public void Update(Match match, Ball lastBall)\n    {\n        if (match.GetCurrentStatus() == MatchStatus.FINISHED)\n        {\n            Console.WriteLine(\"[COMMENTARY]: Match has finished!\");\n        }\n        else if (match.GetCurrentStatus() == MatchStatus.IN_BREAK)\n        {\n            Console.WriteLine(\"[COMMENTARY]: Inning has ended!\");\n        }\n        else if (lastBall != null)\n        {\n            Console.WriteLine($\"[COMMENTARY]: {lastBall.GetCommentary()}\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Observers/IMatchObserver.cs",
    "content": "interface IMatchObserver\n{\n    void Update(Match match, Ball lastBall);\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Observers/ScorecardDisplay.cs",
    "content": "class ScorecardDisplay : IMatchObserver\n{\n    public void Update(Match match, Ball lastBall)\n    {\n        if (match.GetCurrentStatus() == MatchStatus.FINISHED)\n        {\n            Console.WriteLine(\"\\n--- MATCH RESULT ---\");\n            Console.WriteLine(match.GetResultMessage().ToUpper());\n            Console.WriteLine(\"--------------------\");\n\n            Console.WriteLine(\"Player Stats:\");\n            int counter = 1;\n            foreach (var inning in match.GetInnings())\n            {\n                Console.WriteLine($\"Inning {counter++}\");\n                inning.PrintPlayerStats();\n            }\n        }\n        else if (match.GetCurrentStatus() == MatchStatus.IN_BREAK)\n        {\n            Console.WriteLine(\"\\n--- END OF INNINGS ---\");\n            var lastInnings = match.GetInnings().Last();\n            Console.WriteLine($\"Final Score: {lastInnings.GetBattingTeam().GetName()}: \" +\n                             $\"{lastInnings.GetScore()}/{lastInnings.GetWickets()} \" +\n                             $\"(Overs: {lastInnings.GetOvers():F1})\");\n            Console.WriteLine(\"------------------------\");\n        }\n        else\n        {\n            Console.WriteLine(\"\\n--- SCORECARD UPDATE ---\");\n            var currentInnings = match.GetCurrentInnings();\n            Console.WriteLine($\"{currentInnings.GetBattingTeam().GetName()}: \" +\n                             $\"{currentInnings.GetScore()}/{currentInnings.GetWickets()} \" +\n                             $\"(Overs: {currentInnings.GetOvers():F1})\");\n            Console.WriteLine(\"------------------------\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Observers/UserNotifier.cs",
    "content": "class UserNotifier : IMatchObserver\n{\n    public void Update(Match match, Ball lastBall)\n    {\n        if (match.GetCurrentStatus() == MatchStatus.FINISHED)\n        {\n            Console.WriteLine(\"[NOTIFICATION]: Match has finished!\");\n        }\n        else if (match.GetCurrentStatus() == MatchStatus.IN_BREAK)\n        {\n            Console.WriteLine(\"[NOTIFICATION]: Inning has ended!\");\n        }\n        else if (lastBall != null && lastBall.IsWicket())\n        {\n            Console.WriteLine(\"[NOTIFICATION]: Wicket! A player is out.\");\n        }\n        else if (lastBall != null && lastBall.IsBoundary())\n        {\n            Console.WriteLine($\"[NOTIFICATION]: It's a boundary! {lastBall.GetRunsScored()} runs.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/README.md",
    "content": "# Designing a Cricket Information System like CricInfo\n\n## Requirements\n1. The Cricinfo system should provide information about cricket matches, teams, players, and live scores.\n2. Users should be able to view the schedule of upcoming matches and the results of completed matches.\n3. The system should allow users to search for specific matches, teams, or players.\n4. Users should be able to view detailed information about a particular match, including the scorecard, commentary, and statistics.\n5. The system should support real-time updates of live scores and match information.\n6. The system should handle concurrent access to match data and ensure data consistency.\n7. The system should be scalable and able to handle a large volume of user requests.\n8. The system should be extensible to accommodate new features and enhancements in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **Match** class represents a cricket match, with properties such as ID, title, venue, start time, teams, status, and scorecard.\n2. The **Team** class represents a cricket team, with properties like ID, name, and a list of players.\n3. The **Player** class represents a cricket player, with properties such as ID, name, and role.\n4. The **Scorecard** class represents the scorecard of a match, containing team scores and a list of innings.\n5. The **Innings** class represents an innings in a match, with properties like ID, batting team, bowling team, and a list of overs.\n6. The **Over** class represents an over in an innings, containing a list of balls.\n7. The **Ball** class represents a ball bowled in an over, with properties such as ball number, bowler, batsman, and result.\n8. The **MatchStatus** enum represents the different statuses of a match, such as scheduled, in progress, completed, or abandoned.\n9. The **MatchService** class manages the matches in the system, providing methods to add, retrieve, and update match information. It follows the Singleton pattern to ensure a single instance of the service.\n10. The **ScorecardService** class manages the scorecards of matches, allowing the creation, retrieval, and update of scorecards and their associated data, such as innings and scores. It also follows the Singleton pattern.\n11. The **CricinfoSystem** class serves as the main entry point of the system, integrating the match and scorecard services and providing high-level methods for interacting with the system."
  },
  {
    "path": "solutions/csharp/cricinfo/Repositories/MatchRepository.cs",
    "content": "class MatchRepository\n{\n    private readonly Dictionary<string, Match> matches = new Dictionary<string, Match>();\n\n    public void Save(Match match)\n    {\n        matches[match.GetId()] = match;\n    }\n\n    public Match FindById(string id)\n    {\n        return matches.ContainsKey(id) ? matches[id] : null;\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Repositories/PlayerRepository.cs",
    "content": "class PlayerRepository\n{\n    private readonly Dictionary<string, Player> players = new Dictionary<string, Player>();\n\n    public void Save(Player player)\n    {\n        players[player.GetId()] = player;\n    }\n\n    public Player FindById(string id)\n    {\n        return players.ContainsKey(id) ? players[id] : null;\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/States/FinishedState.cs",
    "content": "class FinishedState : IMatchState\n{\n    public void ProcessBall(Match match, Ball ball)\n    {\n        Console.WriteLine(\"ERROR: Cannot process a ball for a finished match.\");\n    }\n\n    public void StartNextInnings(Match match)\n    {\n        Console.WriteLine(\"ERROR: Cannot start the next innings from the current state.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/States/IMatchState.cs",
    "content": "interface IMatchState\n{\n    void ProcessBall(Match match, Ball ball);\n    void StartNextInnings(Match match);\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/States/InBreakState.cs",
    "content": "class InBreakState : IMatchState\n{\n    public void ProcessBall(Match match, Ball ball)\n    {\n        Console.WriteLine(\"ERROR: Cannot process a ball. The match is currently in a break.\");\n    }\n\n    public void StartNextInnings(Match match)\n    {\n        Console.WriteLine(\"Starting the next innings...\");\n        match.CreateNewInnings();\n        match.SetState(new LiveState());\n        match.SetCurrentStatus(MatchStatus.LIVE);\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/States/LiveState.cs",
    "content": "class LiveState : IMatchState\n{\n    public void ProcessBall(Match match, Ball ball)\n    {\n        var currentInnings = match.GetCurrentInnings();\n        currentInnings.AddBall(ball);\n        match.NotifyObservers(ball);\n        CheckForMatchEnd(match);\n    }\n\n    public void StartNextInnings(Match match)\n    {\n        Console.WriteLine(\"ERROR: Cannot start the next innings from the current state.\");\n    }\n\n    private void CheckForMatchEnd(Match match)\n    {\n        var currentInnings = match.GetCurrentInnings();\n        int inningsCount = match.GetInnings().Count;\n        bool isFinalInnings = (inningsCount == match.GetFormatStrategy().GetTotalInnings());\n\n        if (isFinalInnings)\n        {\n            int targetScore = match.GetInnings()[0].GetScore() + 1;\n            if (currentInnings.GetScore() >= targetScore)\n            {\n                int wicketsRemaining = (currentInnings.GetBattingTeam().GetPlayers().Count - 1) - currentInnings.GetWickets();\n                DeclareWinner(match, currentInnings.GetBattingTeam(), $\"won by {wicketsRemaining} wickets\");\n                return;\n            }\n        }\n\n        if (IsInningsOver(match))\n        {\n            if (isFinalInnings)\n            {\n                int score1 = match.GetInnings()[0].GetScore();\n                int score2 = currentInnings.GetScore();\n\n                if (score1 > score2)\n                {\n                    DeclareWinner(match, match.GetTeam1(), $\"won by {score1 - score2} runs\");\n                }\n                else if (score2 > score1)\n                {\n                    int wicketsRemaining = (currentInnings.GetBattingTeam().GetPlayers().Count - 1) - currentInnings.GetWickets();\n                    DeclareWinner(match, currentInnings.GetBattingTeam(), $\"won by {wicketsRemaining} wickets\");\n                }\n                else\n                {\n                    DeclareWinner(match, null, \"Match Tied\");\n                }\n            }\n            else\n            {\n                Console.WriteLine(\"End of the innings!\");\n                match.SetState(new InBreakState());\n                match.SetCurrentStatus(MatchStatus.IN_BREAK);\n                match.NotifyObservers(null);\n            }\n        }\n    }\n\n    private void DeclareWinner(Match match, Team winningTeam, string message)\n    {\n        Console.WriteLine(\"MATCH FINISHED!\");\n        match.SetWinner(winningTeam);\n        string resultMessage = winningTeam != null ? $\"{winningTeam.GetName()} {message}\" : message;\n        match.SetResultMessage(resultMessage);\n\n        match.SetState(new FinishedState());\n        match.SetCurrentStatus(MatchStatus.FINISHED);\n        match.NotifyObservers(null);\n    }\n\n    private bool IsInningsOver(Match match)\n    {\n        var currentInnings = match.GetCurrentInnings();\n        bool allOut = currentInnings.GetWickets() >= currentInnings.GetBattingTeam().GetPlayers().Count - 1;\n        bool oversFinished = (int)currentInnings.GetOvers() >= match.GetFormatStrategy().GetTotalOvers();\n        return allOut || oversFinished;\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/States/ScheduledState.cs",
    "content": "class ScheduledState : IMatchState\n{\n    public void ProcessBall(Match match, Ball ball)\n    {\n        Console.WriteLine(\"ERROR: Cannot process a ball for a match that has not started.\");\n    }\n\n    public void StartNextInnings(Match match)\n    {\n        Console.WriteLine(\"ERROR: Cannot start the next innings from the current state.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Strategy/IMatchFormatStrategy.cs",
    "content": "interface IMatchFormatStrategy\n{\n    int GetTotalInnings();\n    int GetTotalOvers();\n    string GetFormatName();\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Strategy/ODIFormatStrategy.cs",
    "content": "class ODIFormatStrategy : IMatchFormatStrategy\n{\n    public int GetTotalInnings() => 2;\n    public int GetTotalOvers() => 50;\n    public string GetFormatName() => \"ODI\";\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/Strategy/T20FormatStrategy.cs",
    "content": "class T20FormatStrategy : IMatchFormatStrategy\n{\n    public int GetTotalInnings() => 2;\n    public int GetTotalOvers() => 20;\n    public string GetFormatName() => \"T20\";\n}"
  },
  {
    "path": "solutions/csharp/cricinfo/cricinfo.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/Account.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class Account\n    {\n        private readonly string id;\n        private readonly User user;\n        private readonly string accountNumber;\n        private readonly Currency currency;\n        private decimal balance;\n        private readonly List<Transaction> transactions;\n\n        public Account(string id, User user, string accountNumber, Currency currency)\n        {\n            this.id = id;\n            this.user = user;\n            this.accountNumber = accountNumber;\n            this.currency = currency;\n            this.balance = 0.0M;\n            this.transactions = new List<Transaction>();\n        }\n\n        public void Deposit(decimal amount)\n        {\n            balance = balance + amount;\n        }\n\n        public void Withdraw(decimal amount)\n        {\n            if (balance.CompareTo(amount) >= 0)\n            {\n                balance = balance - amount;\n            }\n            else\n            {\n                throw new InsufficientFundsException(\"Insufficient funds in the account.\");\n            }\n        }\n\n        public void AddTransaction(Transaction transaction)\n        {\n            transactions.Add(transaction);\n        }\n\n        public string GetId()\n        {\n            return id;\n        }\n\n        public User GetUser()\n        {\n            return user;\n        }\n\n        public Currency GetCurrency()\n        {\n            return currency;\n        }\n\n        public decimal GetBalance()\n        {\n            return balance;\n        }\n\n        public List<Transaction> GetTransactions()\n        {\n            return transactions;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/BankAccount.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class BankAccount : PaymentMethod\n    {\n        private readonly string accountNumber;\n        private readonly string routingNumber;\n\n        public BankAccount(string id, User user, string accountNumber, string routingNumber)\n            : base(id, user)\n        {\n            this.accountNumber = accountNumber;\n            this.routingNumber = routingNumber;\n        }\n\n        public override bool ProcessPayment(decimal amount, Currency currency)\n        {\n            // Process bank account payment logic\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/CreditCard.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class CreditCard : PaymentMethod\n    {\n        private readonly string cardNumber;\n        private readonly string expirationDate;\n        private readonly string cvv;\n\n        public CreditCard(string id, User user, string cardNumber, string expirationDate, string cvv)\n            : base(id, user)\n        {\n            this.cardNumber = cardNumber;\n            this.expirationDate = expirationDate;\n            this.cvv = cvv;\n        }\n\n        public override bool ProcessPayment(decimal amount, Currency currency)\n        {\n            // Process credit card payment logic\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/Currency.cs",
    "content": "namespace DigitalWallet\n{\n    public enum Currency\n    {\n        USD,\n        EUR,\n        GBP,\n        JPY\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/CurrencyConverter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class CurrencyConverter\n    {\n        private static readonly Dictionary<Currency, decimal> exchangeRates = new Dictionary<Currency, decimal>\n        {\n            { Currency.USD, 1.00M },\n            { Currency.EUR, 0.85M },\n            { Currency.GBP, 0.72M },\n            { Currency.JPY, 110.00M }\n        };\n\n        public static decimal Convert(decimal amount, Currency sourceCurrency, Currency targetCurrency)\n        {\n            decimal sourceRate = exchangeRates[sourceCurrency];\n            decimal targetRate = exchangeRates[targetCurrency];\n            return amount * sourceRate / targetRate;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/DigitalWallet.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class DigitalWallet\n    {\n        private static DigitalWallet instance;\n        private readonly ConcurrentDictionary<string, User> users;\n        private readonly ConcurrentDictionary<string, Account> accounts;\n        private readonly ConcurrentDictionary<string, PaymentMethod> paymentMethods;\n\n        private DigitalWallet()\n        {\n            users = new ConcurrentDictionary<string, User>();\n            accounts = new ConcurrentDictionary<string, Account>();\n            paymentMethods = new ConcurrentDictionary<string, PaymentMethod>();\n        }\n\n        public static DigitalWallet GetInstance()\n        {\n            if (instance == null)\n            {\n                instance = new DigitalWallet();\n            }\n            return instance;\n        }\n\n        public void CreateUser(User user)\n        {\n            users[user.GetId()] = user;\n        }\n\n        public User GetUser(string userId)\n        {\n            return users.ContainsKey(userId) ? users[userId] : null;\n        }\n\n        public void CreateAccount(Account account)\n        {\n            accounts[account.GetId()] = account;\n            account.GetUser().AddAccount(account);\n        }\n\n        public Account GetAccount(string accountId)\n        {\n            return accounts.ContainsKey(accountId) ? accounts[accountId] : null;\n        }\n\n        public void AddPaymentMethod(PaymentMethod paymentMethod)\n        {\n            paymentMethods[paymentMethod.GetId()] = paymentMethod;\n        }\n\n        public PaymentMethod GetPaymentMethod(string paymentMethodId)\n        {\n            return paymentMethods.ContainsKey(paymentMethodId) ? paymentMethods[paymentMethodId] : null;\n        }\n\n        public void TransferFunds(Account sourceAccount, Account destinationAccount, decimal amount, Currency currency)\n        {\n            if (sourceAccount.GetCurrency() != currency)\n            {\n                amount = CurrencyConverter.Convert(amount, currency, sourceAccount.GetCurrency());\n            }\n            sourceAccount.Withdraw(amount);\n\n            if (destinationAccount.GetCurrency() != currency)\n            {\n                amount = CurrencyConverter.Convert(amount, currency, destinationAccount.GetCurrency());\n            }\n            destinationAccount.Deposit(amount);\n\n            string transactionId = GenerateTransactionId();\n            Transaction transaction = new Transaction(transactionId, sourceAccount, destinationAccount, amount, currency);\n            sourceAccount.AddTransaction(transaction);\n            destinationAccount.AddTransaction(transaction);\n        }\n\n        public List<Transaction> GetTransactionHistory(Account account)\n        {\n            return account.GetTransactions();\n        }\n\n        private string GenerateTransactionId()\n        {\n            return \"TXN\" + Guid.NewGuid().ToString().Substring(0, 8).ToUpper();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/DigitalWalletDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class DigitalWalletDemo\n    {\n        public static void Run()\n        {\n            DigitalWallet digitalWallet = DigitalWallet.GetInstance();\n\n            // Create users\n            User user1 = new User(\"U001\", \"John Doe\", \"john@example.com\", \"password123\");\n            User user2 = new User(\"U002\", \"Jane Smith\", \"jane@example.com\", \"password456\");\n            digitalWallet.CreateUser(user1);\n            digitalWallet.CreateUser(user2);\n\n            // Create accounts\n            Account account1 = new Account(\"A001\", user1, \"1234567890\", Currency.USD);\n            Account account2 = new Account(\"A002\", user2, \"9876543210\", Currency.EUR);\n            digitalWallet.CreateAccount(account1);\n            digitalWallet.CreateAccount(account2);\n\n            // Add payment methods\n            PaymentMethod creditCard = new CreditCard(\"PM001\", user1, \"1234567890123456\", \"12/25\", \"123\");\n            PaymentMethod bankAccount = new BankAccount(\"PM002\", user2, \"9876543210\", \"987654321\");\n            digitalWallet.AddPaymentMethod(creditCard);\n            digitalWallet.AddPaymentMethod(bankAccount);\n\n            // Deposit funds\n            account1.Deposit(1000.00M);\n            account2.Deposit(500.00M);\n\n            // Transfer funds\n            digitalWallet.TransferFunds(account1, account2, 100.00M, Currency.USD);\n\n            // Get transaction history\n            List<Transaction> transactionHistory1 = digitalWallet.GetTransactionHistory(account1);\n            List<Transaction> transactionHistory2 = digitalWallet.GetTransactionHistory(account2);\n\n            // Print transaction history\n            Console.WriteLine(\"Transaction History for Account 1:\");\n            foreach (Transaction transaction in transactionHistory1)\n            {\n                Console.WriteLine(\"Transaction ID: \" + transaction.GetId());\n                Console.WriteLine(\"Amount: \" + transaction.GetAmount() + \" \" + transaction.GetCurrency());\n                Console.WriteLine(\"Timestamp: \" + transaction.GetTimestamp());\n                Console.WriteLine();\n            }\n\n            Console.WriteLine(\"Transaction History for Account 2:\");\n            foreach (Transaction transaction in transactionHistory2)\n            {\n                Console.WriteLine(\"Transaction ID: \" + transaction.GetId());\n                Console.WriteLine(\"Amount: \" + transaction.GetAmount() + \" \" + transaction.GetCurrency());\n                Console.WriteLine(\"Timestamp: \" + transaction.GetTimestamp());\n                Console.WriteLine();\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/InsufficientFundsException.cs",
    "content": "using System;\n\nnamespace DigitalWallet\n{\n    public class InsufficientFundsException : Exception\n    {\n        public InsufficientFundsException(string message) : base(message) { }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/PaymentMethod.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public abstract class PaymentMethod\n    {\n        protected readonly string id;\n        protected readonly User user;\n\n        protected PaymentMethod(string id, User user)\n        {\n            this.id = id;\n            this.user = user;\n        }\n\n        public abstract bool ProcessPayment(decimal amount, Currency currency);\n\n        public string GetId()\n        {\n            return id;\n        }\n\n        public User GetUser()\n        {\n            return user;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/README.md",
    "content": "# Designing a Digital Wallet System\n\n## Requirements\n1. The digital wallet should allow users to create an account and manage their personal information.\n2. Users should be able to add and remove payment methods, such as credit cards or bank accounts.\n3. The digital wallet should support fund transfers between users and to external accounts.\n4. The system should handle transaction history and provide a statement of transactions.\n5. The digital wallet should support multiple currencies and perform currency conversions.\n6. The system should ensure the security of user information and transactions.\n7. The digital wallet should handle concurrent transactions and ensure data consistency.\n8. The system should be scalable to handle a large number of users and transactions.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the digital wallet, with properties such as ID, name, email, password, and a list of accounts.\n2. The **Account** class represents a user's account within the digital wallet, with properties like ID, user, account number, currency, balance, and a list of transactions. It provides methods to deposit and withdraw funds.\n3. The **Transaction** class represents a financial transaction between two accounts, containing properties such as ID, source account, destination account, amount, currency, and timestamp.\n4. The **PaymentMethod** class is an abstract base class for different payment methods, such as credit cards and bank accounts. It defines the common properties and methods for processing payments.\n5. The **CreditCard** and **BankAccount** classes are concrete implementations of the PaymentMethod class, representing specific payment methods.\n6. The **Currency** enum represents different currencies supported by the digital wallet.\n7. The **CurrencyConverter** class provides a static method to convert amounts between different currencies based on predefined exchange rates.\n8. The **DigitalWallet** class is the central component of the digital wallet system. It follows the Singleton pattern to ensure only one instance of the digital wallet exists. It provides methods to create users, accounts, add payment methods, transfer funds, and retrieve transaction history. It handles concurrent access to shared resources using synchronization.\n9. The **DigitalWalletDemo** class demonstrates the usage of the digital wallet system by creating users, accounts, adding payment methods, depositing funds, transferring funds, and retrieving transaction history."
  },
  {
    "path": "solutions/csharp/digitalwalletservice/Transaction.cs",
    "content": "using System;\nusing System.Numerics;\n\nnamespace DigitalWallet\n{\n    public class Transaction\n    {\n        private readonly string id;\n        private readonly Account sourceAccount;\n        private readonly Account destinationAccount;\n        private readonly decimal amount;\n        private readonly Currency currency;\n        private readonly DateTime timestamp;\n\n        public Transaction(string id, Account sourceAccount, Account destinationAccount, decimal amount, Currency currency)\n        {\n            this.id = id;\n            this.sourceAccount = sourceAccount;\n            this.destinationAccount = destinationAccount;\n            this.amount = amount;\n            this.currency = currency;\n            this.timestamp = DateTime.Now;\n        }\n\n        public string GetId()\n        {\n            return id;\n        }\n\n        public Account GetSourceAccount()\n        {\n            return sourceAccount;\n        }\n\n        public Account GetDestinationAccount()\n        {\n            return destinationAccount;\n        }\n\n        public decimal GetAmount()\n        {\n            return amount;\n        }\n\n        public Currency GetCurrency()\n        {\n            return currency;\n        }\n\n        public DateTime GetTimestamp()\n        {\n            return timestamp;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/digitalwalletservice/User.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace DigitalWallet\n{\n    public class User\n    {\n        private readonly string id;\n        private readonly string name;\n        private readonly string email;\n        private readonly string password;\n        private readonly List<Account> accounts;\n\n        public User(string id, string name, string email, string password)\n        {\n            this.id = id;\n            this.name = name;\n            this.email = email;\n            this.password = password;\n            this.accounts = new List<Account>();\n        }\n\n        public void AddAccount(Account account)\n        {\n            accounts.Add(account);\n        }\n\n        public void RemoveAccount(Account account)\n        {\n            accounts.Remove(account);\n        }\n\n        public string GetId()\n        {\n            return id;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/ElevatorSystem.cs",
    "content": "class ElevatorSystem\n{\n    private static ElevatorSystem instance;\n    private static readonly object lockObject = new object();\n\n    private readonly Dictionary<int, Elevator> elevators;\n    private readonly IElevatorSelectionStrategy selectionStrategy;\n    private readonly List<Task> elevatorTasks;\n\n    private ElevatorSystem(int numElevators)\n    {\n        this.selectionStrategy = new NearestElevatorStrategy();\n        this.elevatorTasks = new List<Task>();\n\n        List<Elevator> elevatorList = new List<Elevator>();\n        Display display = new Display(); // Create the observer\n\n        for (int i = 1; i <= numElevators; i++)\n        {\n            Elevator elevator = new Elevator(i);\n            elevator.AddObserver(display); // Attach the observer\n            elevatorList.Add(elevator);\n        }\n\n        this.elevators = elevatorList.ToDictionary(e => e.GetId(), e => e);\n    }\n\n    public static ElevatorSystem GetInstance(int numElevators)\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new ElevatorSystem(numElevators);\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void Start()\n    {\n        foreach (Elevator elevator in elevators.Values)\n        {\n            elevatorTasks.Add(Task.Run(() => elevator.Run()));\n        }\n    }\n\n    // --- Facade Methods ---\n\n    // EXTERNAL Request (Hall Call)\n    public void RequestElevator(int floor, Direction direction)\n    {\n        Console.WriteLine($\"\\n>> EXTERNAL Request: User at floor {floor} wants to go {direction}\");\n        Request request = new Request(floor, direction, RequestSource.EXTERNAL);\n\n        // Use strategy to find the best elevator\n        Elevator selectedElevator = selectionStrategy.SelectElevator(elevators.Values.ToList(), request);\n\n        if (selectedElevator != null)\n        {\n            selectedElevator.AddRequest(request);\n        }\n        else\n        {\n            Console.WriteLine(\"System busy, please wait.\");\n        }\n    }\n\n    // INTERNAL Request (Cabin Call)\n    public void SelectFloor(int elevatorId, int destinationFloor)\n    {\n        Console.WriteLine($\"\\n>> INTERNAL Request: User in Elevator {elevatorId} selected floor {destinationFloor}\");\n        Request request = new Request(destinationFloor, Direction.IDLE, RequestSource.INTERNAL);\n\n        if (elevators.TryGetValue(elevatorId, out Elevator elevator))\n        {\n            elevator.AddRequest(request);\n        }\n        else\n        {\n            Console.Error.WriteLine(\"Invalid elevator ID.\");\n        }\n    }\n\n    public void Shutdown()\n    {\n        Console.WriteLine(\"Shutting down elevator system...\");\n        foreach (Elevator elevator in elevators.Values)\n        {\n            elevator.StopElevator();\n        }\n        Task.WaitAll(elevatorTasks.ToArray());\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/ElevatorSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Linq;\n\npublic class ElevatorSystemDemo\n{\n    public static void Main(string[] args)\n    {\n        // Setup: A building with 2 elevators\n        int numElevators = 2;\n        // The GetInstance method now initializes the elevators and attaches the Display (Observer).\n        ElevatorSystem elevatorSystem = ElevatorSystem.GetInstance(numElevators);\n\n        // Start the elevator system\n        elevatorSystem.Start();\n        Console.WriteLine(\"Elevator system started. ConsoleDisplay is observing.\\n\");\n\n        // --- SIMULATION START ---\n\n        // 1. External Request: User at floor 5 wants to go UP.\n        // The system will dispatch this to the nearest elevator (likely E1 or E2, both at floor 1).\n        elevatorSystem.RequestElevator(5, Direction.UP);\n        Thread.Sleep(100); // Wait for the elevator to start moving\n\n        // 2. Internal Request: Assume E1 took the previous request.\n        // The user gets in at floor 5 and presses 10.\n        // We send this request directly to E1.\n\n        // Note: In a real simulation, we'd wait until E1 reaches floor 5, but for this demo,\n        // we simulate the internal button press shortly after the external one.\n        elevatorSystem.SelectFloor(1, 10);\n        Thread.Sleep(200);\n\n        // 3. External Request: User at floor 3 wants to go DOWN.\n        // E2 (likely still idle at floor 1) might take this, or E1 if it's convenient.\n        elevatorSystem.RequestElevator(3, Direction.DOWN);\n        Thread.Sleep(300);\n\n        // 4. Internal Request: User in E2 presses 1.\n        elevatorSystem.SelectFloor(2, 1);\n\n        // Let the simulation run for a while to observe the display updates\n        Console.WriteLine(\"\\n--- Letting simulation run for 1 second ---\");\n        Thread.Sleep(1000);\n\n        // Shutdown the system\n        elevatorSystem.Shutdown();\n        Console.WriteLine(\"\\n--- SIMULATION END ---\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Enums/Direction.cs",
    "content": "enum Direction\n{\n    UP,\n    DOWN,\n    IDLE\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Enums/RequestSource.cs",
    "content": "enum RequestSource\n{\n    INTERNAL, // From inside the cabin\n    EXTERNAL  // From the hall/floor\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Models/Elevator.cs",
    "content": "class Elevator\n{\n    private readonly int id;\n    private int currentFloor;\n    private IElevatorState state;\n    private volatile bool isRunning = true;\n\n    private readonly SortedSet<int> upRequests;\n    private readonly SortedSet<int> downRequests;\n    private readonly object lockObject = new object();\n\n    // Observer Pattern: List of observers\n    private readonly List<IElevatorObserver> observers = new List<IElevatorObserver>();\n\n    public Elevator(int id)\n    {\n        this.id = id;\n        this.currentFloor = 1;\n        this.upRequests = new SortedSet<int>();\n        this.downRequests = new SortedSet<int>(Comparer<int>.Create((a, b) => b.CompareTo(a)));\n        this.state = new IdleState();\n    }\n\n    // --- Observer Pattern Methods ---\n    public void AddObserver(IElevatorObserver observer)\n    {\n        observers.Add(observer);\n        observer.Update(this); // Send initial state\n    }\n\n    public void NotifyObservers()\n    {\n        foreach (IElevatorObserver observer in observers)\n        {\n            observer.Update(this);\n        }\n    }\n\n    // --- State Pattern Methods ---\n    public void SetState(IElevatorState state)\n    {\n        this.state = state;\n        NotifyObservers(); // Notify observers on direction change\n    }\n\n    public void Move()\n    {\n        state.Move(this);\n    }\n\n    // --- Request Handling ---\n    public void AddRequest(Request request)\n    {\n        lock (lockObject)\n        {\n            Console.WriteLine($\"Elevator {id} processing: {request}\");\n            state.AddRequest(this, request);\n        }\n    }\n\n    // --- Getters and Setters ---\n    public int GetId() => id;\n    \n    public int GetCurrentFloor()\n    {\n        lock (lockObject)\n        {\n            return currentFloor;\n        }\n    }\n\n    public void SetCurrentFloor(int floor)\n    {\n        lock (lockObject)\n        {\n            this.currentFloor = floor;\n        }\n        NotifyObservers(); // Notify observers on floor change\n    }\n\n    public Direction GetDirection() => state.GetDirection();\n    public SortedSet<int> GetUpRequests() => upRequests;\n    public SortedSet<int> GetDownRequests() => downRequests;\n    public bool IsRunning() => isRunning;\n    public void StopElevator() => isRunning = false;\n\n    public void Run()\n    {\n        while (isRunning)\n        {\n            Move();\n            try\n            {\n                Thread.Sleep(1000); // Simulate movement time\n            }\n            catch (ThreadInterruptedException)\n            {\n                isRunning = false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Models/Request.cs",
    "content": "class Request\n{\n    private readonly int targetFloor;\n    private readonly Direction direction;\n    private readonly RequestSource source;\n\n    public Request(int targetFloor, Direction direction, RequestSource source)\n    {\n        this.targetFloor = targetFloor;\n        this.direction = direction;\n        this.source = source;\n    }\n\n    public int GetTargetFloor() => targetFloor;\n    public Direction GetDirection() => direction;\n    public RequestSource GetSource() => source;\n\n    public override string ToString()\n    {\n        if (source == RequestSource.EXTERNAL)\n        {\n            return $\"{source} Request to floor {targetFloor} going {direction}\";\n        }\n        else\n        {\n            return $\"{source} Request to floor {targetFloor}\";\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Observer/Display.cs",
    "content": "class Display : IElevatorObserver\n{\n    public void Update(Elevator elevator)\n    {\n        Console.WriteLine($\"[DISPLAY] Elevator {elevator.GetId()} | Current Floor: {elevator.GetCurrentFloor()} | Direction: {elevator.GetDirection()}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Observer/IElevatorObserver.cs",
    "content": "interface IElevatorObserver\n{\n    void Update(Elevator elevator);\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/README.md",
    "content": "# Designing an Elevator System\n\n## Requirements\n1. The elevator system should consist of multiple elevators serving multiple floors.\n2. Each elevator should have a capacity limit and should not exceed it.\n3. Users should be able to request an elevator from any floor and select a destination floor.\n4. The elevator system should efficiently handle user requests and optimize the movement of elevators to minimize waiting time.\n5. The system should prioritize requests based on the direction of travel and the proximity of the elevators to the requested floor.\n6. The elevators should be able to handle multiple requests concurrently and process them in an optimal order.\n7. The system should ensure thread safety and prevent race conditions when multiple threads interact with the elevators.\n\n## Classes, Interfaces and Enumerations\n1. The **Direction** enum represents the possible directions of elevator movement (UP or DOWN).\n2. The **Request** class represents a user request for an elevator, containing the source floor and destination floor.\n3. The **Elevator** class represents an individual elevator in the system. It has a capacity limit and maintains a list of 4. requests. The elevator processes requests concurrently and moves between floors based on the requests.\n4. The **ElevatorController** class manages multiple elevators and handles user requests. It finds the optimal elevator to serve a request based on the proximity of the elevators to the requested floor.\n5. The **ElevatorSystem** class is the entry point of the application and demonstrates the usage of the elevator system."
  },
  {
    "path": "solutions/csharp/elevatorsystem/States/IElevatorState.cs",
    "content": "interface IElevatorState\n{\n    void Move(Elevator elevator);\n    void AddRequest(Elevator elevator, Request request);\n    Direction GetDirection();\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/States/IdleState.cs",
    "content": "class IdleState : IElevatorState\n{\n    public void Move(Elevator elevator)\n    {\n        if (elevator.GetUpRequests().Count > 0)\n        {\n            elevator.SetState(new MovingUpState());\n        }\n        else if (elevator.GetDownRequests().Count > 0)\n        {\n            elevator.SetState(new MovingDownState());\n        }\n        // Else stay idle\n    }\n\n    public void AddRequest(Elevator elevator, Request request)\n    {\n        if (request.GetTargetFloor() > elevator.GetCurrentFloor())\n        {\n            elevator.GetUpRequests().Add(request.GetTargetFloor());\n        }\n        else if (request.GetTargetFloor() < elevator.GetCurrentFloor())\n        {\n            elevator.GetDownRequests().Add(request.GetTargetFloor());\n        }\n        // If request is for current floor, doors would open (handled implicitly by moving to that floor)\n    }\n\n    public Direction GetDirection() => Direction.IDLE;\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/States/MovingDownState.cs",
    "content": "class MovingDownState : IElevatorState\n{\n    public void Move(Elevator elevator)\n    {\n        if (elevator.GetDownRequests().Count == 0)\n        {\n            elevator.SetState(new IdleState());\n            return;\n        }\n\n        int nextFloor = elevator.GetDownRequests().Max();\n        elevator.SetCurrentFloor(elevator.GetCurrentFloor() - 1);\n\n        if (elevator.GetCurrentFloor() == nextFloor)\n        {\n            Console.WriteLine($\"Elevator {elevator.GetId()} stopped at floor {nextFloor}\");\n            elevator.GetDownRequests().Remove(nextFloor);\n        }\n\n        if (elevator.GetDownRequests().Count == 0)\n        {\n            elevator.SetState(new IdleState());\n        }\n    }\n\n    public void AddRequest(Elevator elevator, Request request)\n    {\n        // Internal requests always get added to the appropriate queue\n        if (request.GetSource() == RequestSource.INTERNAL)\n        {\n            if (request.GetTargetFloor() > elevator.GetCurrentFloor())\n            {\n                elevator.GetUpRequests().Add(request.GetTargetFloor());\n            }\n            else\n            {\n                elevator.GetDownRequests().Add(request.GetTargetFloor());\n            }\n            return;\n        }\n\n        // External requests\n        if (request.GetDirection() == Direction.DOWN && request.GetTargetFloor() <= elevator.GetCurrentFloor())\n        {\n            elevator.GetDownRequests().Add(request.GetTargetFloor());\n        }\n        else if (request.GetDirection() == Direction.UP)\n        {\n            elevator.GetUpRequests().Add(request.GetTargetFloor());\n        }\n    }\n\n    public Direction GetDirection() => Direction.DOWN;\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/States/MovingUpState.cs",
    "content": "class MovingUpState : IElevatorState\n{\n    public void Move(Elevator elevator)\n    {\n        if (elevator.GetUpRequests().Count == 0)\n        {\n            elevator.SetState(new IdleState());\n            return;\n        }\n\n        int nextFloor = elevator.GetUpRequests().Min();\n        elevator.SetCurrentFloor(elevator.GetCurrentFloor() + 1);\n\n        if (elevator.GetCurrentFloor() == nextFloor)\n        {\n            Console.WriteLine($\"Elevator {elevator.GetId()} stopped at floor {nextFloor}\");\n            elevator.GetUpRequests().Remove(nextFloor);\n        }\n\n        if (elevator.GetUpRequests().Count == 0)\n        {\n            elevator.SetState(new IdleState());\n        }\n    }\n\n    public void AddRequest(Elevator elevator, Request request)\n    {\n        // Internal requests always get added to the appropriate queue\n        if (request.GetSource() == RequestSource.INTERNAL)\n        {\n            if (request.GetTargetFloor() > elevator.GetCurrentFloor())\n            {\n                elevator.GetUpRequests().Add(request.GetTargetFloor());\n            }\n            else\n            {\n                elevator.GetDownRequests().Add(request.GetTargetFloor());\n            }\n            return;\n        }\n\n        // External requests\n        if (request.GetDirection() == Direction.UP && request.GetTargetFloor() >= elevator.GetCurrentFloor())\n        {\n            elevator.GetUpRequests().Add(request.GetTargetFloor());\n        }\n        else if (request.GetDirection() == Direction.DOWN)\n        {\n            elevator.GetDownRequests().Add(request.GetTargetFloor());\n        }\n    }\n\n    public Direction GetDirection() => Direction.UP;\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Strategy/IElevatorSelectionStrategy.cs",
    "content": "interface IElevatorSelectionStrategy\n{\n    Elevator SelectElevator(List<Elevator> elevators, Request request);\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/Strategy/NearestElevatorStrategy.cs",
    "content": "class NearestElevatorStrategy : IElevatorSelectionStrategy\n{\n    public Elevator SelectElevator(List<Elevator> elevators, Request request)\n    {\n        Elevator bestElevator = null;\n        int minDistance = int.MaxValue;\n\n        foreach (Elevator elevator in elevators)\n        {\n            if (IsSuitable(elevator, request))\n            {\n                int distance = Math.Abs(elevator.GetCurrentFloor() - request.GetTargetFloor());\n                if (distance < minDistance)\n                {\n                    minDistance = distance;\n                    bestElevator = elevator;\n                }\n            }\n        }\n        return bestElevator;\n    }\n\n    private bool IsSuitable(Elevator elevator, Request request)\n    {\n        if (elevator.GetDirection() == Direction.IDLE)\n            return true;\n        if (elevator.GetDirection() == request.GetDirection())\n        {\n            if (request.GetDirection() == Direction.UP && elevator.GetCurrentFloor() <= request.GetTargetFloor())\n                return true;\n            if (request.GetDirection() == Direction.DOWN && elevator.GetCurrentFloor() >= request.GetTargetFloor())\n                return true;\n        }\n        return false;\n    }\n}"
  },
  {
    "path": "solutions/csharp/elevatorsystem/elevatorsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Enums/OrderStatus.cs",
    "content": "enum OrderStatus\n{\n    PENDING,\n    CONFIRMED,\n    PREPARING,\n    READY_FOR_PICKUP,\n    OUT_FOR_DELIVERY,\n    DELIVERED,\n    CANCELLED\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/FoodDeliveryService.cs",
    "content": "using System.Collections.Concurrent;\n\nclass FoodDeliveryService\n{\n    private static volatile FoodDeliveryService instance;\n    private static readonly object lockObject = new object();\n    private readonly ConcurrentDictionary<string, Customer> customers = new ConcurrentDictionary<string, Customer>();\n    private readonly ConcurrentDictionary<string, Restaurant> restaurants = new ConcurrentDictionary<string, Restaurant>();\n    private readonly ConcurrentDictionary<string, DeliveryAgent> deliveryAgents = new ConcurrentDictionary<string, DeliveryAgent>();\n    private readonly ConcurrentDictionary<string, Order> orders = new ConcurrentDictionary<string, Order>();\n    private IDeliveryAssignmentStrategy assignmentStrategy;\n\n    private FoodDeliveryService() { }\n\n    public static FoodDeliveryService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                    instance = new FoodDeliveryService();\n            }\n        }\n        return instance;\n    }\n\n    public void SetAssignmentStrategy(IDeliveryAssignmentStrategy assignmentStrategy)\n    {\n        this.assignmentStrategy = assignmentStrategy;\n    }\n\n    public Customer RegisterCustomer(string name, string phone, Address address)\n    {\n        Customer customer = new Customer(name, phone, address);\n        customers.TryAdd(customer.GetId(), customer);\n        return customer;\n    }\n\n    public Restaurant RegisterRestaurant(string name, Address address)\n    {\n        Restaurant restaurant = new Restaurant(name, address);\n        restaurants.TryAdd(restaurant.GetId(), restaurant);\n        return restaurant;\n    }\n\n    public DeliveryAgent RegisterDeliveryAgent(string name, string phone, Address initialLocation)\n    {\n        DeliveryAgent deliveryAgent = new DeliveryAgent(name, phone, initialLocation);\n        deliveryAgents.TryAdd(deliveryAgent.GetId(), deliveryAgent);\n        return deliveryAgent;\n    }\n\n    public Order PlaceOrder(string customerId, string restaurantId, List<OrderItem> items)\n    {\n        if (!customers.TryGetValue(customerId, out Customer customer) ||\n            !restaurants.TryGetValue(restaurantId, out Restaurant restaurant))\n        {\n            throw new KeyNotFoundException(\"Customer or Restaurant not found.\");\n        }\n\n        Order order = new Order(customer, restaurant, items);\n        orders.TryAdd(order.GetId(), order);\n        customer.AddOrderToHistory(order);\n        Console.WriteLine($\"Order {order.GetId()} placed by {customer.GetName()} at {restaurant.GetName()}.\");\n        order.SetStatus(OrderStatus.PENDING);\n        return order;\n    }\n\n    public void UpdateOrderStatus(string orderId, OrderStatus newStatus)\n    {\n        if (!orders.TryGetValue(orderId, out Order order))\n        {\n            throw new KeyNotFoundException(\"Order not found.\");\n        }\n\n        order.SetStatus(newStatus);\n\n        if (newStatus == OrderStatus.READY_FOR_PICKUP)\n        {\n            AssignDelivery(order);\n        }\n    }\n\n    public void CancelOrder(string orderId)\n    {\n        if (!orders.TryGetValue(orderId, out Order order))\n        {\n            Console.WriteLine($\"ERROR: Order with ID {orderId} not found.\");\n            return;\n        }\n\n        if (order.Cancel())\n        {\n            Console.WriteLine($\"SUCCESS: Order {orderId} has been successfully canceled.\");\n        }\n        else\n        {\n            Console.WriteLine($\"FAILED: Order {orderId} could not be canceled. Its status is: {order.GetStatus()}\");\n        }\n    }\n\n    private void AssignDelivery(Order order)\n    {\n        List<DeliveryAgent> availableAgents = deliveryAgents.Values.ToList();\n\n        DeliveryAgent agent = assignmentStrategy.FindAgent(order, availableAgents);\n        if (agent != null)\n        {\n            order.AssignDeliveryAgent(agent);\n            double distance = agent.GetCurrentLocation().DistanceTo(order.GetRestaurant().GetAddress());\n            Console.WriteLine($\"Agent {agent.GetName()} (dist: {distance:F2}) assigned to order {order.GetId()}.\");\n            order.SetStatus(OrderStatus.OUT_FOR_DELIVERY);\n        }\n        else\n        {\n            Console.WriteLine($\"No available delivery agents found for order {order.GetId()}\");\n        }\n    }\n\n    public List<Restaurant> SearchRestaurants(List<IRestaurantSearchStrategy> strategies)\n    {\n        List<Restaurant> results = restaurants.Values.ToList();\n\n        foreach (var strategy in strategies)\n        {\n            results = strategy.Filter(results);\n        }\n\n        return results;\n    }\n\n    public Menu GetRestaurantMenu(string restaurantId)\n    {\n        if (!restaurants.TryGetValue(restaurantId, out Restaurant restaurant))\n        {\n            throw new KeyNotFoundException($\"Restaurant with ID {restaurantId} not found.\");\n        }\n        return restaurant.GetMenu();\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/FoodDeliveryServiceDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class FoodDeliveryServiceDemo\n{\n    public static void Main(string[] args)\n    {\n        // 1. Setup the system\n        FoodDeliveryService service = FoodDeliveryService.GetInstance();\n        service.SetAssignmentStrategy(new NearestAvailableAgentStrategy());\n\n        // 2. Define Addresses\n        Address aliceAddress = new Address(\"123 Maple St\", \"Springfield\", \"12345\", 40.7128, -74.0060);\n        Address pizzaAddress = new Address(\"456 Oak Ave\", \"Springfield\", \"12345\", 40.7138, -74.0070);\n        Address burgerAddress = new Address(\"789 Pine Ln\", \"Springfield\", \"12345\", 40.7108, -74.0050);\n        Address tacoAddress = new Address(\"101 Elm Ct\", \"Shelbyville\", \"54321\", 41.7528, -75.0160);\n\n        // 3. Register entities\n        Customer alice = service.RegisterCustomer(\"Alice\", \"123-4567-890\", aliceAddress);\n        Restaurant pizzaPalace = service.RegisterRestaurant(\"Pizza Palace\", pizzaAddress);\n        Restaurant burgerBarn = service.RegisterRestaurant(\"Burger Barn\", burgerAddress);\n        Restaurant tacoTown = service.RegisterRestaurant(\"Taco Town\", tacoAddress);\n        service.RegisterDeliveryAgent(\"Bob\", \"321-4567-880\", new Address(\"1 B\", \"Springfield\", \"12345\", 40.71, -74.00));\n\n        // 4. Setup menus\n        pizzaPalace.AddToMenu(new MenuItem(\"P001\", \"Margherita Pizza\", 12.99));\n        pizzaPalace.AddToMenu(new MenuItem(\"P002\", \"Veggie Pizza\", 11.99));\n        burgerBarn.AddToMenu(new MenuItem(\"B001\", \"Classic Burger\", 8.99));\n        tacoTown.AddToMenu(new MenuItem(\"T001\", \"Crunchy Taco\", 3.50));\n\n        // 5. Demonstrate Search Functionality\n        Console.WriteLine(\"\\n--- 1. Searching for Restaurants ---\");\n\n        // (A) Search by City\n        Console.WriteLine(\"\\n(A) Restaurants in 'Springfield':\");\n        List<IRestaurantSearchStrategy> citySearch = new List<IRestaurantSearchStrategy> { new SearchByCityStrategy(\"Springfield\") };\n        List<Restaurant> springfieldRestaurants = service.SearchRestaurants(citySearch);\n        foreach (var r in springfieldRestaurants)\n        {\n            Console.WriteLine($\"  - {r.GetName()}\");\n        }\n\n        // (B) Search for restaurants near Alice\n        Console.WriteLine(\"\\n(B) Restaurants near Alice (within 0.01 distance units):\");\n        List<IRestaurantSearchStrategy> proximitySearch = new List<IRestaurantSearchStrategy> { new SearchByProximityStrategy(aliceAddress, 0.01) };\n        List<Restaurant> nearbyRestaurants = service.SearchRestaurants(proximitySearch);\n        foreach (var r in nearbyRestaurants)\n        {\n            Console.WriteLine($\"  - {r.GetName()} (Distance: {aliceAddress.DistanceTo(r.GetAddress()):F4})\");\n        }\n\n        // (C) Search for restaurants that serve 'Pizza'\n        Console.WriteLine(\"\\n(C) Restaurants that serve 'Pizza':\");\n        List<IRestaurantSearchStrategy> menuSearch = new List<IRestaurantSearchStrategy> { new SearchByMenuKeywordStrategy(\"Pizza\") };\n        List<Restaurant> pizzaRestaurants = service.SearchRestaurants(menuSearch);\n        foreach (var r in pizzaRestaurants)\n        {\n            Console.WriteLine($\"  - {r.GetName()}\");\n        }\n\n        // (D) Combined Search: Find restaurants near Alice that serve 'Burger'\n        Console.WriteLine(\"\\n(D) Burger joints near Alice:\");\n        List<IRestaurantSearchStrategy> combinedSearch = new List<IRestaurantSearchStrategy>\n        {\n            new SearchByProximityStrategy(aliceAddress, 0.01),\n            new SearchByMenuKeywordStrategy(\"Burger\")\n        };\n        List<Restaurant> burgerJointsNearAlice = service.SearchRestaurants(combinedSearch);\n        foreach (var r in burgerJointsNearAlice)\n        {\n            Console.WriteLine($\"  - {r.GetName()}\");\n        }\n\n        // 6. Demonstrate Browsing a Menu\n        Console.WriteLine(\"\\n--- 2. Browsing a Menu ---\");\n        Console.WriteLine(\"\\nMenu for 'Pizza Palace':\");\n        Menu pizzaMenu = service.GetRestaurantMenu(pizzaPalace.GetId());\n        foreach (var item in pizzaMenu.GetItems().Values)\n        {\n            Console.WriteLine($\"  - {item.GetName()}: ${item.GetPrice():F2}\");\n        }\n\n        // 7. Alice places an order from a searched restaurant\n        Console.WriteLine(\"\\n--- 3. Placing an Order ---\");\n        if (pizzaRestaurants.Count > 0)\n        {\n            Restaurant chosenRestaurant = pizzaRestaurants[0];\n            MenuItem chosenItem = chosenRestaurant.GetMenu().GetItem(\"P001\");\n\n            Console.WriteLine($\"\\nAlice is ordering '{chosenItem.GetName()}' from '{chosenRestaurant.GetName()}'.\");\n            var order = service.PlaceOrder(alice.GetId(), chosenRestaurant.GetId(), new List<OrderItem> { new OrderItem(chosenItem, 1) });\n\n            Console.WriteLine(\"\\n--- Restaurant starts preparing the order ---\");\n            service.UpdateOrderStatus(order.GetId(), OrderStatus.PREPARING);\n\n            Console.WriteLine(\"\\n--- Order is ready for pickup ---\");\n            Console.WriteLine(\"System will now find the nearest available delivery agent...\");\n            service.UpdateOrderStatus(order.GetId(), OrderStatus.READY_FOR_PICKUP);\n\n            Console.WriteLine(\"\\n--- Agent delivers the order ---\");\n            service.UpdateOrderStatus(order.GetId(), OrderStatus.DELIVERED);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/Address.cs",
    "content": "class Address\n{\n    private readonly string street;\n    private readonly string city;\n    private readonly string zipCode;\n    private readonly double latitude;\n    private readonly double longitude;\n\n    public Address(string street, string city, string zipCode, double latitude, double longitude)\n    {\n        this.street = street;\n        this.city = city;\n        this.zipCode = zipCode;\n        this.latitude = latitude;\n        this.longitude = longitude;\n    }\n\n    public string GetCity()\n    {\n        return city;\n    }\n\n    public double DistanceTo(Address other)\n    {\n        double latDiff = latitude - other.latitude;\n        double lonDiff = longitude - other.longitude;\n        return Math.Sqrt(latDiff * latDiff + lonDiff * lonDiff);\n    }\n\n    public override string ToString()\n    {\n        return $\"{street}, {city}, {zipCode} @({latitude}, {longitude})\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/Customer.cs",
    "content": "class Customer : User\n{\n    private readonly Address address;\n    private readonly List<Order> orderHistory = new List<Order>();\n\n    public Customer(string name, string phone, Address address) : base(name, phone)\n    {\n        this.address = address;\n    }\n\n    public void AddOrderToHistory(Order order)\n    {\n        orderHistory.Add(order);\n    }\n\n    public Address GetAddress()\n    {\n        return address;\n    }\n\n    public override void OnUpdate(Order order)\n    {\n        Console.WriteLine($\"--- Notification for Customer {GetName()} ---\");\n        Console.WriteLine($\"  Order {order.GetId()} is now {order.GetStatus()}.\");\n        Console.WriteLine(\"-------------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/DeliveryAgent.cs",
    "content": "class DeliveryAgent : User\n{\n    private volatile bool isAvailable = true;\n    private Address currentLocation;\n    private readonly object locationLock = new object();\n\n    public DeliveryAgent(string name, string phone, Address currentLocation) : base(name, phone)\n    {\n        this.currentLocation = currentLocation;\n    }\n\n    public void SetAvailable(bool available)\n    {\n        isAvailable = available;\n    }\n\n    public bool IsAvailableAgent()\n    {\n        return isAvailable;\n    }\n\n    public void SetCurrentLocation(Address currentLocation)\n    {\n        lock (locationLock)\n        {\n            this.currentLocation = currentLocation;\n        }\n    }\n\n    public Address GetCurrentLocation()\n    {\n        lock (locationLock)\n        {\n            return currentLocation;\n        }\n    }\n\n    public override void OnUpdate(Order order)\n    {\n        Console.WriteLine($\"--- Notification for Delivery Agent {GetName()} ---\");\n        Console.WriteLine($\"  Order {order.GetId()} update: Status is {order.GetStatus()}.\");\n        Console.WriteLine(\"-------------------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/Menu.cs",
    "content": "class Menu\n{\n    private readonly Dictionary<string, MenuItem> items = new Dictionary<string, MenuItem>();\n\n    public void AddItem(MenuItem item)\n    {\n        items[item.GetId()] = item;\n    }\n\n    public MenuItem GetItem(string id)\n    {\n        return items.ContainsKey(id) ? items[id] : null;\n    }\n\n    public Dictionary<string, MenuItem> GetItems()\n    {\n        return new Dictionary<string, MenuItem>(items);\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/MenuItem.cs",
    "content": "class MenuItem\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly double price;\n    private bool available;\n\n    public MenuItem(string id, string name, double price)\n    {\n        this.id = id;\n        this.name = name;\n        this.price = price;\n        this.available = true;\n    }\n\n    public string GetId() { return id; }\n    public void SetAvailable(bool available) { this.available = available; }\n    public string GetName() { return name; }\n    public double GetPrice() { return price; }\n\n    public string GetMenuItem()\n    {\n        return $\"Name: {name}, Price: {price}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/Order.cs",
    "content": "class Order\n{\n    private readonly string id;\n    private readonly Customer customer;\n    private readonly Restaurant restaurant;\n    private readonly List<OrderItem> items;\n    private OrderStatus status;\n    private DeliveryAgent deliveryAgent;\n    private readonly List<IOrderObserver> observers = new List<IOrderObserver>();\n\n    public Order(Customer customer, Restaurant restaurant, List<OrderItem> items)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.customer = customer;\n        this.restaurant = restaurant;\n        this.items = items;\n        this.status = OrderStatus.PENDING;\n        AddObserver(customer);\n        AddObserver(restaurant);\n    }\n\n    public void AddObserver(IOrderObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    private void NotifyObservers()\n    {\n        foreach (var observer in observers)\n        {\n            observer.OnUpdate(this);\n        }\n    }\n\n    public void SetStatus(OrderStatus newStatus)\n    {\n        if (status != newStatus)\n        {\n            status = newStatus;\n            NotifyObservers();\n        }\n    }\n\n    public bool Cancel()\n    {\n        if (status == OrderStatus.PENDING)\n        {\n            SetStatus(OrderStatus.CANCELLED);\n            return true;\n        }\n        return false;\n    }\n\n    public void AssignDeliveryAgent(DeliveryAgent agent)\n    {\n        deliveryAgent = agent;\n        AddObserver(agent);\n        agent.SetAvailable(false);\n    }\n\n    public string GetId() { return id; }\n    public OrderStatus GetStatus() { return status; }\n    public Customer GetCustomer() { return customer; }\n    public Restaurant GetRestaurant() { return restaurant; }\n    public DeliveryAgent GetDeliveryAgent() { return deliveryAgent; }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/OrderItem.cs",
    "content": "class OrderItem\n{\n    private readonly MenuItem item;\n    private readonly int quantity;\n\n    public OrderItem(MenuItem item, int quantity)\n    {\n        this.item = item;\n        this.quantity = quantity;\n    }\n\n    public MenuItem GetItem() { return item; }\n    public int GetQuantity() { return quantity; }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/Restaurant.cs",
    "content": "class Restaurant : IOrderObserver\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly Address address;\n    private readonly Menu menu;\n\n    public Restaurant(string name, Address address)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.address = address;\n        this.menu = new Menu();\n    }\n\n    public void AddToMenu(MenuItem item)\n    {\n        menu.AddItem(item);\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public Address GetAddress() { return address; }\n    public Menu GetMenu() { return menu; }\n\n    public void OnUpdate(Order order)\n    {\n        Console.WriteLine($\"--- Notification for Restaurant {GetName()} ---\");\n        Console.WriteLine($\"  Order {order.GetId()} has been updated to {order.GetStatus()}.\");\n        Console.WriteLine(\"---------------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Models/User.cs",
    "content": "abstract class User : IOrderObserver\n{\n    protected readonly string id;\n    protected readonly string name;\n    protected readonly string phone;\n\n    public User(string name, string phone)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.phone = phone;\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n\n    public abstract void OnUpdate(Order order);\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Observer/IOrderObserver.cs",
    "content": "interface IOrderObserver\n{\n    void OnUpdate(Order order);\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/README.md",
    "content": "# Designing an Online Food Delivery Service Like Swiggy\n\n## Requirements\n1. The food delivery service should allow customers to browse restaurants, view menus, and place orders.\n2. Restaurants should be able to manage their menus, prices, and availability.\n3. Delivery agents should be able to accept and fulfill orders.\n4. The system should handle order tracking and status updates.\n5. The system should support multiple payment methods.\n6. The system should handle concurrent orders and ensure data consistency.\n7. The system should be scalable and handle a high volume of orders.\n8. The system should provide real-time notifications to customers, restaurants, and delivery agents.\n\n## Classes, Interfaces and Enumerations\n1. The **Customer** class represents a customer who can place orders. It contains customer details such as ID, name, email, and phone number.\n2. The **Restaurant** class represents a restaurant that offers menu items. It contains restaurant details such as ID, name, address, and a list of menu items. It provides methods to add and remove menu items.\n3. The **MenuItem** class represents an item on a restaurant's menu. It contains details such as ID, name, description, price, and availability status.\n4. The **Order** class represents an order placed by a customer. It contains order details such as ID, customer, restaurant, list of order items, status, and assigned delivery agent. It provides methods to add and remove order items, update order status, and assign a delivery agent.\n5. The **OrderItem** class represents an item within an order. It contains the selected menu item and the quantity ordered.\n6. The **OrderStatus** enum represents the different statuses an order can have, such as PENDING, CONFIRMED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.\n7. The **DeliveryAgent** class represents a delivery agent who fulfills orders. It contains details such as ID, name, phone number, and availability status.\n8. The **FoodDeliveryService** class is the main class that manages the food delivery service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register customers, restaurants, and delivery agents, retrieve available restaurants and menus, place orders, update order status, cancel orders, and assign delivery agents to orders. It also handles notifications to customers, restaurants, and delivery agents."
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/assignment/IDeliveryAssignmentStrategy.cs",
    "content": "interface IDeliveryAssignmentStrategy\n{\n    DeliveryAgent FindAgent(Order order, List<DeliveryAgent> agents);\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/assignment/NearestAvailableAgentStrategy.cs",
    "content": "class NearestAvailableAgentStrategy : IDeliveryAssignmentStrategy\n{\n    public DeliveryAgent FindAgent(Order order, List<DeliveryAgent> availableAgents)\n    {\n        Address restaurantAddress = order.GetRestaurant().GetAddress();\n        Address customerAddress = order.GetCustomer().GetAddress();\n\n        return availableAgents\n            .Where(agent => agent.IsAvailableAgent())\n            .OrderBy(agent => CalculateTotalDistance(agent, restaurantAddress, customerAddress))\n            .FirstOrDefault();\n    }\n\n    private double CalculateTotalDistance(DeliveryAgent agent, Address restaurantAddress, Address customerAddress)\n    {\n        double agentToRestaurantDist = agent.GetCurrentLocation().DistanceTo(restaurantAddress);\n        double restaurantToCustomerDist = restaurantAddress.DistanceTo(customerAddress);\n        return agentToRestaurantDist + restaurantToCustomerDist;\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/search/IRestaurantSearchStrategy.cs",
    "content": "interface IRestaurantSearchStrategy\n{\n    List<Restaurant> Filter(List<Restaurant> allRestaurants);\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/search/SearchByCityStrategy.cs",
    "content": "class SearchByCityStrategy : IRestaurantSearchStrategy\n{\n    private readonly string city;\n\n    public SearchByCityStrategy(string city)\n    {\n        this.city = city;\n    }\n\n    public List<Restaurant> Filter(List<Restaurant> allRestaurants)\n    {\n        return allRestaurants\n            .Where(r => r.GetAddress().GetCity().Equals(city, StringComparison.OrdinalIgnoreCase))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/search/SearchByMenuKeywordStrategy.cs",
    "content": "class SearchByMenuKeywordStrategy : IRestaurantSearchStrategy\n{\n    private readonly string keyword;\n\n    public SearchByMenuKeywordStrategy(string keyword)\n    {\n        this.keyword = keyword.ToLower();\n    }\n\n    public List<Restaurant> Filter(List<Restaurant> allRestaurants)\n    {\n        return allRestaurants\n            .Where(r => r.GetMenu().GetItems().Values\n                .Any(item => item.GetName().ToLower().Contains(keyword)))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/Strategies/search/SearchByProximityStrategy.cs",
    "content": "class SearchByProximityStrategy : IRestaurantSearchStrategy\n{\n    private readonly Address userLocation;\n    private readonly double maxDistance;\n\n    public SearchByProximityStrategy(Address userLocation, double maxDistance)\n    {\n        this.userLocation = userLocation;\n        this.maxDistance = maxDistance;\n    }\n\n    public List<Restaurant> Filter(List<Restaurant> allRestaurants)\n    {\n        return allRestaurants\n            .Where(r => userLocation.DistanceTo(r.GetAddress()) <= maxDistance)\n            .OrderBy(r => userLocation.DistanceTo(r.GetAddress()))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/fooddeliveryservice/fooddeliveryservice.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/CashPayment.cs",
    "content": "namespace HotelManagement\n{\n    public class CashPayment : Payment\n    {\n        public bool ProcessPayment(double amount)\n        {\n            // Process cash payment\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/CreditCardPayment.cs",
    "content": "namespace HotelManagement\n{\n    public class CreditCardPayment : Payment\n    {\n        public bool ProcessPayment(double amount)\n        {\n            // Process credit card payment\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/Guest.cs",
    "content": "namespace HotelManagement\n{\n    public class Guest\n    {\n        public string Id { get; }\n        public string Name { get; }\n        public string Email { get; }\n        public string PhoneNumber { get; }\n\n        public Guest(string id, string name, string email, string phoneNumber)\n        {\n            Id = id;\n            Name = name;\n            Email = email;\n            PhoneNumber = phoneNumber;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/HotelManagementSystem.cs",
    "content": "using System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace HotelManagement\n{\n    public class HotelManagementSystem\n    {\n        private static HotelManagementSystem _instance;\n        private readonly ConcurrentDictionary<string, Guest> _guests;\n        private readonly ConcurrentDictionary<string, Room> _rooms;\n        private readonly ConcurrentDictionary<string, Reservation> _reservations;\n\n        private HotelManagementSystem()\n        {\n            _guests = new ConcurrentDictionary<string, Guest>();\n            _rooms = new ConcurrentDictionary<string, Room>();\n            _reservations = new ConcurrentDictionary<string, Reservation>();\n        }\n\n        public static HotelManagementSystem Instance\n        {\n            get\n            {\n                if (_instance == null)\n                {\n                    _instance = new HotelManagementSystem();\n                }\n                return _instance;\n            }\n        }\n\n        public void AddGuest(Guest guest)\n        {\n            _guests[guest.Id] = guest;\n        }\n\n        public Guest GetGuest(string guestId)\n        {\n            _guests.TryGetValue(guestId, out var guest);\n            return guest;\n        }\n\n        public void AddRoom(Room room)\n        {\n            _rooms[room.Id] = room;\n        }\n\n        public Room GetRoom(string roomId)\n        {\n            _rooms.TryGetValue(roomId, out var room);\n            return room;\n        }\n\n        public Reservation BookRoom(Guest guest, Room room, DateTime checkInDate, DateTime checkOutDate)\n        {\n            lock (room)\n            {\n                if (room.Status == RoomStatus.AVAILABLE)\n                {\n                    room.Book();\n                    var reservationId = GenerateReservationId();\n                    var reservation = new Reservation(reservationId, guest, room, checkInDate, checkOutDate);\n                    _reservations[reservationId] = reservation;\n                    return reservation;\n                }\n                return null;\n            }\n        }\n\n        public void CancelReservation(string reservationId)\n        {\n            lock (this)\n            {\n                if (_reservations.TryGetValue(reservationId, out var reservation))\n                {\n                    reservation.Cancel();\n                    _reservations.TryRemove(reservationId, out _);\n                }\n            }\n        }\n\n        public void CheckIn(string reservationId)\n        {\n            lock (this)\n            {\n                if (_reservations.TryGetValue(reservationId, out var reservation) && reservation.Status == ReservationStatus.CONFIRMED)\n                {\n                    reservation.Room.CheckIn();\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"Invalid reservation or reservation not confirmed.\");\n                }\n            }\n        }\n\n        public void CheckOut(string reservationId, Payment payment)\n        {\n            lock (this)\n            {\n                if (_reservations.TryGetValue(reservationId, out var reservation) && reservation.Status == ReservationStatus.CONFIRMED)\n                {\n                    var room = reservation.Room;\n                    var amount = room.Price * (reservation.CheckOutDate - reservation.CheckInDate).TotalDays;\n                    if (payment.ProcessPayment(amount))\n                    {\n                        room.CheckOut();\n                        _reservations.TryRemove(reservationId, out _);\n                    }\n                    else\n                    {\n                        throw new InvalidOperationException(\"Payment failed.\");\n                    }\n                }\n                else\n                {\n                    throw new InvalidOperationException(\"Invalid reservation or reservation not confirmed.\");\n                }\n            }\n        }\n\n        private string GenerateReservationId()\n        {\n            return \"RES\" + Guid.NewGuid().ToString(\"N\").Substring(0, 8).ToUpper();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/HotelManagementSystemDemo.cs",
    "content": "using System;\n\nnamespace HotelManagement\n{\n    public class HotelManagementSystemDemo\n    {\n        public static void Run()\n        {\n            var hotelManagementSystem = HotelManagementSystem.Instance;\n\n            // Create guests\n            var guest1 = new Guest(\"G001\", \"John Doe\", \"john@example.com\", \"1234567890\");\n            var guest2 = new Guest(\"G002\", \"Jane Smith\", \"jane@example.com\", \"9876543210\");\n            hotelManagementSystem.AddGuest(guest1);\n            hotelManagementSystem.AddGuest(guest2);\n\n            // Create rooms\n            var room1 = new Room(\"R001\", RoomType.SINGLE, 100.0);\n            var room2 = new Room(\"R002\", RoomType.DOUBLE, 200.0);\n            hotelManagementSystem.AddRoom(room1);\n            hotelManagementSystem.AddRoom(room2);\n\n            // Book a room\n            var checkInDate = DateTime.Now;\n            var checkOutDate = checkInDate.AddDays(3);\n            var reservation1 = hotelManagementSystem.BookRoom(guest1, room1, checkInDate, checkOutDate);\n            if (reservation1 != null)\n            {\n                Console.WriteLine(\"Reservation created: \" + reservation1.Id);\n            }\n            else\n            {\n                Console.WriteLine(\"Room not available for booking.\");\n            }\n\n            // Check-in\n            hotelManagementSystem.CheckIn(reservation1.Id);\n            Console.WriteLine(\"Checked in: \" + reservation1.Id);\n\n            // Check-out and process payment\n            var payment = new CreditCardPayment();\n            hotelManagementSystem.CheckOut(reservation1.Id, payment);\n            Console.WriteLine(\"Checked out: \" + reservation1.Id);\n\n            // Cancel a reservation\n            hotelManagementSystem.CancelReservation(reservation1.Id);\n            Console.WriteLine(\"Reservation cancelled: \" + reservation1.Id);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/Payment.cs",
    "content": "namespace HotelManagement\n{\n    public interface Payment\n    {\n        bool ProcessPayment(double amount);\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/README.md",
    "content": "# Designing a Hotel Management System\n\n## Requirements\n1. The hotel management system should allow guests to book rooms, check-in, and check-out.\n2. The system should manage different types of rooms, such as single, double, deluxe, and suite.\n3. The system should handle room availability and reservation status.\n4. The system should allow the hotel staff to manage guest information, room assignments, and billing.\n5. The system should support multiple payment methods, such as cash, credit card, and online payment.\n6. The system should handle concurrent bookings and ensure data consistency.\n7. The system should provide reporting and analytics features for hotel management.\n8. The system should be scalable and handle a large number of rooms and guests.\n\n## Classes, Interfaces and Enumerations\n1. The **Guest** class represents a guest of the hotel, with properties such as ID, name, email, and phone number.\n2. The **Room** class represents a room in the hotel, with properties like ID, room type, price, and status. It provides methods to book, check-in, and check-out a room.\n3. The **RoomType** enum represents the different types of rooms available in the hotel.\n4. The **RoomStatus** enum represents the status of a room, which can be available, booked, or occupied.\n5. The **Reservation** class represents a reservation made by a guest for a specific room and date range. It contains properties such as ID, guest, room, check-in date, check-out date, and status. It provides a method to cancel a reservation.\n6. The **ReservationStatus** enum represents the status of a reservation, which can be confirmed or cancelled.\n7. The **Payment** interface defines the contract for processing payments. It is implemented by concrete payment classes like CashPayment and CreditCardPayment.\n8. The **HotelManagementSystem** class is the central component of the hotel management system. It follows the Singleton pattern to ensure only one instance of the system exists. It provides methods to add guests and rooms, book rooms, cancel reservations, check-in, check-out, and process payments. It also handles concurrent access to shared resources using synchronization.\n9. The **HotelManagementSystemDemo** class demonstrates the usage of the hotel management system by creating guests, rooms, booking a room, checking in, checking out, and cancelling a reservation."
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/Reservation.cs",
    "content": "using System;\n\nnamespace HotelManagement\n{\n    public class Reservation\n    {\n        public string Id { get; }\n        public Guest Guest { get; }\n        public Room Room { get; }\n        public DateTime CheckInDate { get; }\n        public DateTime CheckOutDate { get; }\n        public ReservationStatus Status { get; private set; }\n\n        public Reservation(string id, Guest guest, Room room, DateTime checkInDate, DateTime checkOutDate)\n        {\n            Id = id;\n            Guest = guest;\n            Room = room;\n            CheckInDate = checkInDate;\n            CheckOutDate = checkOutDate;\n            Status = ReservationStatus.CONFIRMED;\n        }\n\n        public void Cancel()\n        {\n            if (Status == ReservationStatus.CONFIRMED)\n            {\n                Status = ReservationStatus.CANCELLED;\n                Room.CheckOut();\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Reservation is not confirmed.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/ReservationStatus.cs",
    "content": "namespace HotelManagement\n{\n    public enum ReservationStatus\n    {\n        CONFIRMED,\n        CANCELLED\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/Room.cs",
    "content": "namespace HotelManagement\n{\n    public class Room\n    {\n        public string Id { get; }\n        public RoomType Type { get; }\n        public double Price { get; }\n        public RoomStatus Status { get; private set; }\n\n        public Room(string id, RoomType type, double price)\n        {\n            Id = id;\n            Type = type;\n            Price = price;\n            Status = RoomStatus.AVAILABLE;\n        }\n\n        public void Book()\n        {\n            if (Status == RoomStatus.AVAILABLE)\n            {\n                Status = RoomStatus.BOOKED;\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Room is not available for booking.\");\n            }\n        }\n\n        public void CheckIn()\n        {\n            if (Status == RoomStatus.BOOKED)\n            {\n                Status = RoomStatus.OCCUPIED;\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Room is not booked.\");\n            }\n        }\n\n        public void CheckOut()\n        {\n            if (Status == RoomStatus.OCCUPIED)\n            {\n                Status = RoomStatus.AVAILABLE;\n            }\n            else\n            {\n                throw new InvalidOperationException(\"Room is not occupied.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/RoomStatus.cs",
    "content": "namespace HotelManagement\n{\n    public enum RoomStatus\n    {\n        AVAILABLE,\n        BOOKED,\n        OCCUPIED\n    }\n}"
  },
  {
    "path": "solutions/csharp/hotelmanagementsystem/RoomType.cs",
    "content": "namespace HotelManagement\n{\n    public enum RoomType\n    {\n        SINGLE,\n        DOUBLE,\n        DELUXE,\n        SUITE\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Enum/ItemType.cs",
    "content": "enum ItemType\n{\n    BOOK,\n    MAGAZINE\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Factory/ItemFactory.cs",
    "content": "class ItemFactory\n{\n    public static LibraryItem CreateItem(ItemType type, string id, string title, string author)\n    {\n        switch (type)\n        {\n            case ItemType.BOOK:\n                return new Book(id, title, author);\n            case ItemType.MAGAZINE:\n                return new Magazine(id, title, author);\n            default:\n                throw new ArgumentException(\"Unknown item type.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/LibraryManagementSystem.cs",
    "content": "class LibraryManagementSystem\n{\n    private static readonly LibraryManagementSystem instance = new LibraryManagementSystem();\n    private readonly Dictionary<string, LibraryItem> catalog = new Dictionary<string, LibraryItem>();\n    private readonly Dictionary<string, Member> members = new Dictionary<string, Member>();\n    private readonly Dictionary<string, BookCopy> copies = new Dictionary<string, BookCopy>();\n\n    private LibraryManagementSystem() { }\n    public static LibraryManagementSystem GetInstance() { return instance; }\n\n    public List<BookCopy> AddItem(ItemType type, string id, string title, string author, int numCopies)\n    {\n        var bookCopies = new List<BookCopy>();\n        var item = ItemFactory.CreateItem(type, id, title, author);\n        catalog[id] = item;\n        \n        for (int i = 0; i < numCopies; i++)\n        {\n            string copyId = $\"{id}-c{i + 1}\";\n            var copy = new BookCopy(copyId, item);\n            copies[copyId] = copy;\n            bookCopies.Add(copy);\n        }\n        \n        Console.WriteLine($\"Added {numCopies} copies of '{title}'\");\n        return bookCopies;\n    }\n\n    public Member AddMember(string id, string name)\n    {\n        var member = new Member(id, name);\n        members[id] = member;\n        return member;\n    }\n\n    public void Checkout(string memberId, string copyId)\n    {\n        if (members.TryGetValue(memberId, out var member) && copies.TryGetValue(copyId, out var copy))\n        {\n            copy.Checkout(member);\n        }\n        else\n        {\n            Console.WriteLine(\"Error: Invalid member or copy ID.\");\n        }\n    }\n\n    public void ReturnItem(string copyId)\n    {\n        if (copies.TryGetValue(copyId, out var copy))\n        {\n            copy.ReturnItem();\n        }\n        else\n        {\n            Console.WriteLine(\"Error: Invalid copy ID.\");\n        }\n    }\n\n    public void PlaceHold(string memberId, string itemId)\n    {\n        if (members.TryGetValue(memberId, out var member) && catalog.TryGetValue(itemId, out var item))\n        {\n            var checkedOutCopy = item.GetCopies().FirstOrDefault(c => !c.IsAvailable());\n            checkedOutCopy?.PlaceHold(member);\n        }\n    }\n\n    public List<LibraryItem> Search(string query, ISearchStrategy strategy)\n    {\n        return strategy.Search(query, catalog.Values.ToList());\n    }\n\n    public void PrintCatalog()\n    {\n        Console.WriteLine(\"\\n--- Library Catalog ---\");\n        foreach (var item in catalog.Values)\n        {\n            Console.WriteLine($\"ID: {item.GetId()}, Title: {item.GetTitle()}, \" +\n                            $\"Author/Publisher: {item.GetAuthorOrPublisher()}, \" +\n                            $\"Available: {item.GetAvailableCopyCount()}\");\n        }\n        Console.WriteLine(\"-----------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/LibraryManagementSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class LibraryManagementDemo\n{\n    public static void Main(string[] args)\n    {\n        var library = LibraryManagementSystem.GetInstance();\n\n        // === Setting up the Library ===\n        Console.WriteLine(\"=== Setting up the Library ===\");\n\n        var hobbitCopies = library.AddItem(ItemType.BOOK, \"B001\", \"The Hobbit\", \"J.R.R. Tolkien\", 2);\n        var duneCopies = library.AddItem(ItemType.BOOK, \"B002\", \"Dune\", \"Frank Herbert\", 1);\n        var natGeoCopies = library.AddItem(ItemType.MAGAZINE, \"M001\", \"National Geographic\", \"NatGeo Society\", 3);\n\n        var alice = library.AddMember(\"MEM01\", \"Alice\");\n        var bob = library.AddMember(\"MEM02\", \"Bob\");\n        var charlie = library.AddMember(\"MEM03\", \"Charlie\");\n        library.PrintCatalog();\n\n        // === Scenario 1: Searching (Strategy Pattern) ===\n        Console.WriteLine(\"\\n=== Scenario 1: Searching for Items ===\");\n        Console.WriteLine(\"Searching for title 'Dune':\");\n        var titleResults = library.Search(\"Dune\", new SearchByTitleStrategy());\n        foreach (var item in titleResults)\n        {\n            Console.WriteLine($\"Found: {item.GetTitle()}\");\n        }\n\n        Console.WriteLine(\"\\nSearching for author 'Tolkien':\");\n        var authorResults = library.Search(\"Tolkien\", new SearchByAuthorStrategy());\n        foreach (var item in authorResults)\n        {\n            Console.WriteLine($\"Found: {item.GetTitle()}\");\n        }\n\n        // === Scenario 2: Checkout and Return (State Pattern) ===\n        Console.WriteLine(\"\\n\\n=== Scenario 2: Checkout and Return ===\");\n        library.Checkout(alice.GetId(), hobbitCopies[0].GetId());\n        library.Checkout(bob.GetId(), duneCopies[0].GetId());\n        library.PrintCatalog();\n\n        Console.WriteLine(\"Attempting to checkout an already checked-out book:\");\n        library.Checkout(charlie.GetId(), hobbitCopies[0].GetId());\n\n        Console.WriteLine(\"\\nAlice returns The Hobbit:\");\n        library.ReturnItem(hobbitCopies[0].GetId());\n        library.PrintCatalog();\n\n        // === Scenario 3: Holds and Notifications (Observer Pattern) ===\n        Console.WriteLine(\"\\n\\n=== Scenario 3: Placing a Hold ===\");\n        Console.WriteLine(\"Dune is checked out by Bob. Charlie places a hold.\");\n        library.PlaceHold(charlie.GetId(), \"B002\");\n\n        Console.WriteLine(\"\\nBob returns Dune. Charlie should be notified.\");\n        library.ReturnItem(duneCopies[0].GetId());\n\n        Console.WriteLine(\"\\nCharlie checks out the book that was on hold for him.\");\n        library.Checkout(charlie.GetId(), duneCopies[0].GetId());\n\n        Console.WriteLine(\"\\nTrying to check out the same on-hold item by another member (Alice):\");\n        library.Checkout(alice.GetId(), duneCopies[0].GetId());\n\n        library.PrintCatalog();\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/Book.cs",
    "content": "class Book : LibraryItem\n{\n    private readonly string author;\n\n    public Book(string id, string title, string author) : base(id, title)\n    {\n        this.author = author;\n    }\n\n    public override string GetAuthorOrPublisher() { return author; }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/BookCopy.cs",
    "content": "class BookCopy\n{\n    private readonly string id;\n    private readonly LibraryItem item;\n    private IItemState currentState;\n\n    public BookCopy(string id, LibraryItem item)\n    {\n        this.id = id;\n        this.item = item;\n        this.currentState = new AvailableState();\n        item.AddCopy(this);\n    }\n\n    public void Checkout(Member member) { currentState.Checkout(this, member); }\n    public void ReturnItem() { currentState.ReturnItem(this); }\n    public void PlaceHold(Member member) { currentState.PlaceHold(this, member); }\n\n    public void SetState(IItemState state) { this.currentState = state; }\n    public string GetId() { return id; }\n    public LibraryItem GetItem() { return item; }\n    public bool IsAvailable() { return currentState is AvailableState; }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/LibraryItem.cs",
    "content": "abstract class LibraryItem\n{\n    private readonly string id;\n    private readonly string title;\n    protected readonly List<BookCopy> copies = new List<BookCopy>();\n    private readonly List<Member> observers = new List<Member>();\n\n    public LibraryItem(string id, string title)\n    {\n        this.id = id;\n        this.title = title;\n    }\n\n    public void AddCopy(BookCopy copy) { copies.Add(copy); }\n    public void AddObserver(Member member) { observers.Add(member); }\n    public void RemoveObserver(Member member) { observers.Remove(member); }\n\n    public void NotifyObservers()\n    {\n        Console.WriteLine($\"Notifying {observers.Count} observers for '{title}'...\");\n        var observersCopy = new List<Member>(observers);\n        foreach (var observer in observersCopy)\n        {\n            observer.Update(this);\n        }\n    }\n\n    public BookCopy GetAvailableCopy()\n    {\n        return copies.FirstOrDefault(copy => copy.IsAvailable());\n    }\n\n    public string GetId() { return id; }\n    public string GetTitle() { return title; }\n    public List<BookCopy> GetCopies() { return copies; }\n\n    public abstract string GetAuthorOrPublisher();\n\n    public long GetAvailableCopyCount()\n    {\n        return copies.Count(copy => copy.IsAvailable());\n    }\n\n    public bool HasObservers() { return observers.Count > 0; }\n    public bool IsObserver(Member member) { return observers.Contains(member); }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/Loan.cs",
    "content": "class Loan\n{\n    private readonly BookCopy copy;\n    private readonly Member member;\n    private readonly DateTime checkoutDate;\n\n    public Loan(BookCopy copy, Member member)\n    {\n        this.copy = copy;\n        this.member = member;\n        this.checkoutDate = DateTime.Now;\n    }\n\n    public BookCopy GetCopy() { return copy; }\n    public Member GetMember() { return member; }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/Magazine.cs",
    "content": "class Magazine : LibraryItem\n{\n    private readonly string publisher;\n\n    public Magazine(string id, string title, string publisher) : base(id, title)\n    {\n        this.publisher = publisher;\n    }\n\n    public override string GetAuthorOrPublisher() { return publisher; }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/Member.cs",
    "content": "class Member\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly List<Loan> loans = new List<Loan>();\n\n    public Member(string id, string name)\n    {\n        this.id = id;\n        this.name = name;\n    }\n\n    public void Update(LibraryItem item)\n    {\n        Console.WriteLine($\"NOTIFICATION for {name}: The book '{item.GetTitle()}' you placed a hold on is now available!\");\n    }\n\n    public void AddLoan(Loan loan) { loans.Add(loan); }\n    public void RemoveLoan(Loan loan) { loans.Remove(loan); }\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public List<Loan> GetLoans() { return loans; }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Models/TransactionService.cs",
    "content": "class TransactionService\n{\n    private static readonly TransactionService instance = new TransactionService();\n    private readonly Dictionary<string, Loan> activeLoans = new Dictionary<string, Loan>();\n\n    private TransactionService() { }\n    public static TransactionService GetInstance() { return instance; }\n\n    public void CreateLoan(BookCopy copy, Member member)\n    {\n        if (activeLoans.ContainsKey(copy.GetId()))\n        {\n            throw new InvalidOperationException(\"This copy is already on loan.\");\n        }\n        \n        var loan = new Loan(copy, member);\n        activeLoans[copy.GetId()] = loan;\n        member.AddLoan(loan);\n    }\n\n    public void EndLoan(BookCopy copy)\n    {\n        if (activeLoans.TryGetValue(copy.GetId(), out var loan))\n        {\n            activeLoans.Remove(copy.GetId());\n            loan.GetMember().RemoveLoan(loan);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/README.md",
    "content": "# Designing a Library Management System\n\n## Requirements\n1. The library management system should allow librarians to manage books, members, and borrowing activities.\n2. The system should support adding, updating, and removing books from the library catalog.\n3. Each book should have details such as title, author, ISBN, publication year, and availability status.\n4. The system should allow members to borrow and return books.\n5. Each member should have details such as name, member ID, contact information, and borrowing history.\n6. The system should enforce borrowing rules, such as a maximum number of books that can be borrowed at a time and loan duration.\n7. The system should handle concurrent access to the library catalog and member records.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Book** class represents a book in the library catalog, with properties such as ISBN, title, author, publication year, and availability status.\n2. The **Member** class represents a library member, with properties like member ID, name, contact information, and a list of borrowed books.\n3. The **LibraryManager** class is the core of the library management system and follows the Singleton pattern to ensure a single instance of the library manager.\n4. The LibraryManager class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to the library catalog and member records.\n5. The LibraryManager class provides methods for adding and removing books, registering and unregistering members, borrowing and returning books, and searching for books based on keywords.\n6. The **LibraryManagementSystemDemo** class serves as the entry point of the application and demonstrates the usage of the library management system."
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/States/AvailableState.cs",
    "content": "class AvailableState : IItemState\n{\n    public void Checkout(BookCopy copy, Member member)\n    {\n        TransactionService.GetInstance().CreateLoan(copy, member);\n        copy.SetState(new CheckedOutState());\n        Console.WriteLine($\"{copy.GetId()} checked out by {member.GetName()}\");\n    }\n\n    public void ReturnItem(BookCopy copy)\n    {\n        Console.WriteLine(\"Cannot return an item that is already available.\");\n    }\n\n    public void PlaceHold(BookCopy copy, Member member)\n    {\n        Console.WriteLine(\"Cannot place hold on an available item. Please check it out.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/States/CheckedOutState.cs",
    "content": "class CheckedOutState : IItemState\n{\n    public void Checkout(BookCopy copy, Member member)\n    {\n        Console.WriteLine($\"{copy.GetId()} is already checked out.\");\n    }\n\n    public void ReturnItem(BookCopy copy)\n    {\n        TransactionService.GetInstance().EndLoan(copy);\n        Console.WriteLine($\"{copy.GetId()} returned.\");\n        \n        if (copy.GetItem().HasObservers())\n        {\n            copy.SetState(new OnHoldState());\n            copy.GetItem().NotifyObservers();\n        }\n        else\n        {\n            copy.SetState(new AvailableState());\n        }\n    }\n\n    public void PlaceHold(BookCopy copy, Member member)\n    {\n        copy.GetItem().AddObserver(member);\n        Console.WriteLine($\"{member.GetName()} placed a hold on '{copy.GetItem().GetTitle()}'\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/States/IItemState.cs",
    "content": "interface IItemState\n{\n    void Checkout(BookCopy copy, Member member);\n    void ReturnItem(BookCopy copy);\n    void PlaceHold(BookCopy copy, Member member);\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/States/OnHoldState.cs",
    "content": "class OnHoldState : IItemState\n{\n    public void Checkout(BookCopy copy, Member member)\n    {\n        if (copy.GetItem().IsObserver(member))\n        {\n            TransactionService.GetInstance().CreateLoan(copy, member);\n            copy.GetItem().RemoveObserver(member);\n            copy.SetState(new CheckedOutState());\n            Console.WriteLine($\"Hold fulfilled. {copy.GetId()} checked out by {member.GetName()}\");\n        }\n        else\n        {\n            Console.WriteLine(\"This item is on hold for another member.\");\n        }\n    }\n\n    public void ReturnItem(BookCopy copy)\n    {\n        Console.WriteLine(\"Invalid action. Item is on hold, not checked out.\");\n    }\n\n    public void PlaceHold(BookCopy copy, Member member)\n    {\n        Console.WriteLine(\"Item is already on hold.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Strategy/ISearchStrategy.cs",
    "content": "interface ISearchStrategy\n{\n    List<LibraryItem> Search(string query, List<LibraryItem> items);\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Strategy/SearchByAuthorStrategy.cs",
    "content": "class SearchByAuthorStrategy : ISearchStrategy\n{\n    public List<LibraryItem> Search(string query, List<LibraryItem> items)\n    {\n        return items.Where(item => item.GetAuthorOrPublisher().ToLower().Contains(query.ToLower())).ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/Strategy/SearchByTitleStrategy.cs",
    "content": "class SearchByTitleStrategy : ISearchStrategy\n{\n    public List<LibraryItem> Search(string query, List<LibraryItem> items)\n    {\n        return items.Where(item => item.GetTitle().ToLower().Contains(query.ToLower())).ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/librarymanagementsystem/librarymanagementsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/linkedIn/Enums/ConnectionStatus.cs",
    "content": "enum ConnectionStatus\n{\n    PENDING,\n    ACCEPTED,\n    REJECTED,\n    WITHDRAWN\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Enums/NotificationType.cs",
    "content": "enum NotificationType\n{\n    CONNECTION_REQUEST,\n    POST_LIKE,\n    POST_COMMENT\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/LinkedInDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class LinkedInDemo\n{\n    public static void Main(string[] args)\n    {\n        var system = LinkedInSystem.GetInstance();\n\n        // 1. Create Members using the Builder Pattern\n        Console.WriteLine(\"--- 1. Member Registration ---\");\n        var alice = new MemberBuilder(\"Alice\", \"alice@example.com\")\n            .WithSummary(\"Senior Software Engineer with 10 years of experience.\")\n            .AddExperience(new Experience(\"Sr. Software Engineer\", \"Google\", \"2018-01-01\", null))\n            .AddExperience(new Experience(\"Software Engineer\", \"Microsoft\", \"2014-06-01\", \"2017-12-31\"))\n            .AddEducation(new Education(\"Princeton University\", \"M.S. in Computer Science\", 2012, 2014))\n            .Build();\n\n        var bob = new MemberBuilder(\"Bob\", \"bob@example.com\")\n            .WithSummary(\"Product Manager at Stripe.\")\n            .AddExperience(new Experience(\"Product Manager\", \"Stripe\", \"2020-02-01\", null))\n            .AddEducation(new Education(\"MIT\", \"B.S. in Business Analytics\", 2015, 2019))\n            .Build();\n\n        var charlie = new MemberBuilder(\"Charlie\", \"charlie@example.com\").Build();\n\n        system.RegisterMember(alice);\n        system.RegisterMember(bob);\n        system.RegisterMember(charlie);\n\n        alice.DisplayProfile();\n\n        // 2. Connection Management\n        Console.WriteLine(\"\\n--- 2. Connection Management ---\");\n        string requestId1 = system.SendConnectionRequest(alice, bob);\n        string requestId2 = system.SendConnectionRequest(alice, charlie);\n\n        bob.ViewNotifications();\n\n        Console.WriteLine(\"\\nBob accepts Alice's request.\");\n        system.AcceptConnectionRequest(requestId1);\n        Console.WriteLine(\"Alice and Bob are now connected.\");\n\n        // 3. Posting and News Feed\n        Console.WriteLine(\"\\n--- 3. Posting & News Feed ---\");\n        bob.DisplayProfile();\n        system.CreatePost(bob.GetId(), \"Excited to share we've launched our new feature! #productmanagement\");\n\n        system.ViewNewsFeed(alice.GetId());\n        system.ViewNewsFeed(charlie.GetId());\n\n        // 4. Interacting with a Post\n        Console.WriteLine(\"\\n--- 4. Post Interaction & Notifications ---\");\n        var bobsPost = system.GetLatestPostByMember(bob.GetId());\n        if (bobsPost != null)\n        {\n            bobsPost.AddLike(alice);\n            bobsPost.AddComment(alice, \"This looks amazing! Great work!\");\n        }\n\n        bob.ViewNotifications();\n\n        // 5. Searching for Members\n        Console.WriteLine(\"\\n--- 5. Member Search ---\");\n        var searchResults = system.SearchMemberByName(\"ali\");\n        Console.WriteLine(\"Search results for 'ali':\");\n        foreach (var member in searchResults)\n        {\n            Console.WriteLine($\" - {member.GetName()}\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/LinkedInSystem.cs",
    "content": "class LinkedInSystem\n{\n    private static volatile LinkedInSystem instance;\n    private static readonly object syncRoot = new object();\n\n    private readonly Dictionary<string, Member> members = new Dictionary<string, Member>();\n    private readonly ConnectionService connectionService;\n    private readonly NewsFeedService newsFeedService;\n    private readonly SearchService searchService;\n\n    private LinkedInSystem()\n    {\n        connectionService = new ConnectionService(new NotificationService());\n        newsFeedService = new NewsFeedService();\n        searchService = new SearchService(members.Values);\n    }\n\n    public static LinkedInSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (syncRoot)\n            {\n                if (instance == null)\n                {\n                    instance = new LinkedInSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void RegisterMember(Member member)\n    {\n        members[member.GetId()] = member;\n        Console.WriteLine($\"New member registered: {member.GetName()}\");\n    }\n\n    public Member GetMember(string name)\n    {\n        return members.Values.FirstOrDefault(m => m.GetName() == name);\n    }\n\n    public string SendConnectionRequest(Member from, Member to)\n    {\n        return connectionService.SendRequest(from, to);\n    }\n\n    public void AcceptConnectionRequest(string requestId)\n    {\n        connectionService.AcceptRequest(requestId);\n    }\n\n    public void CreatePost(string memberId, string content)\n    {\n        var author = members[memberId];\n        var post = new Post(author, content);\n        newsFeedService.AddPost(author, post);\n        Console.WriteLine($\"{author.GetName()} created a new post.\");\n    }\n\n    public Post GetLatestPostByMember(string memberId)\n    {\n        var memberPosts = newsFeedService.GetMemberPosts(members[memberId]);\n        return memberPosts.LastOrDefault();\n    }\n\n    public void ViewNewsFeed(string memberId)\n    {\n        var member = members[memberId];\n        Console.WriteLine($\"\\n--- News Feed for {member.GetName()} ---\");\n        newsFeedService.DisplayFeedForMember(member, new ChronologicalSortStrategy());\n    }\n\n    public List<Member> SearchMemberByName(string name)\n    {\n        return searchService.SearchByName(name);\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Comment.cs",
    "content": "class Comment\n{\n    private readonly Member author;\n    private readonly string text;\n    private readonly DateTime createdAt;\n\n    public Comment(Member author, string text)\n    {\n        this.author = author;\n        this.text = text;\n        this.createdAt = DateTime.Now;\n    }\n\n    public Member GetAuthor() { return author; }\n    public string GetText() { return text; }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Connection.cs",
    "content": "class Connection\n{\n    private readonly Member fromMember;\n    private readonly Member toMember;\n    private ConnectionStatus status;\n    private readonly DateTime requestedAt;\n    private DateTime acceptedAt;\n\n    public Connection(Member fromMember, Member toMember)\n    {\n        this.fromMember = fromMember;\n        this.toMember = toMember;\n        this.status = ConnectionStatus.PENDING;\n        this.requestedAt = DateTime.Now;\n    }\n\n    public Member GetFromMember() { return fromMember; }\n    public Member GetToMember() { return toMember; }\n    public ConnectionStatus GetStatus() { return status; }\n\n    public void SetStatus(ConnectionStatus status)\n    {\n        this.status = status;\n        if (status == ConnectionStatus.ACCEPTED)\n        {\n            this.acceptedAt = DateTime.Now;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Education.cs",
    "content": "class Education\n{\n    private readonly string school;\n    private readonly string degree;\n    private readonly int startYear;\n    private readonly int endYear;\n\n    public Education(string school, string degree, int startYear, int endYear)\n    {\n        this.school = school;\n        this.degree = degree;\n        this.startYear = startYear;\n        this.endYear = endYear;\n    }\n\n    public override string ToString()\n    {\n        return $\"{degree}, {school} ({startYear} - {endYear})\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Experience.cs",
    "content": "class Experience\n{\n    private readonly string title;\n    private readonly string company;\n    private readonly string startDate;\n    private readonly string endDate; // null for current job\n\n    public Experience(string title, string company, string startDate, string endDate)\n    {\n        this.title = title;\n        this.company = company;\n        this.startDate = startDate;\n        this.endDate = endDate;\n    }\n\n    public override string ToString()\n    {\n        string end = string.IsNullOrEmpty(endDate) ? \"Present\" : endDate;\n        return $\"{title} at {company} ({startDate} to {end})\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Like.cs",
    "content": "class Like\n{\n    private readonly Member member;\n    private readonly DateTime createdAt;\n\n    public Like(Member member)\n    {\n        this.member = member;\n        this.createdAt = DateTime.Now;\n    }\n\n    public Member GetMember() { return member; }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Member.cs",
    "content": "class Member : INotificationObserver\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n    private readonly Profile profile;\n    private readonly HashSet<Member> connections = new HashSet<Member>();\n    private readonly List<Notification> notifications = new List<Notification>();\n\n    public Member(string id, string name, string email, Profile profile)\n    {\n        this.id = id;\n        this.name = name;\n        this.email = email;\n        this.profile = profile;\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public string GetEmail() { return email; }\n    public HashSet<Member> GetConnections() { return connections; }\n    public Profile GetProfile() { return profile; }\n\n    public void AddConnection(Member member)\n    {\n        connections.Add(member);\n    }\n\n    public void DisplayProfile()\n    {\n        Console.WriteLine($\"\\n--- Profile for {name} ({email}) ---\");\n        profile.Display();\n        Console.WriteLine($\"  Connections: {connections.Count}\");\n    }\n\n    public void ViewNotifications()\n    {\n        Console.WriteLine($\"\\n--- Notifications for {name} ---\");\n        var unreadNotifications = notifications.Where(n => !n.IsRead()).ToList();\n\n        if (!unreadNotifications.Any())\n        {\n            Console.WriteLine(\"  No new notifications.\");\n            return;\n        }\n\n        foreach (var notification in unreadNotifications)\n        {\n            Console.WriteLine($\"  - {notification.GetContent()}\");\n            notification.MarkAsRead();\n        }\n    }\n\n    public void Update(Notification notification)\n    {\n        notifications.Add(notification);\n        Console.WriteLine($\"Notification pushed to {name}: {notification.GetContent()}\");\n    }\n}\n\nclass MemberBuilder\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n    private readonly Profile profile = new Profile();\n\n    public MemberBuilder(string name, string email)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public MemberBuilder WithSummary(string summary)\n    {\n        profile.SetSummary(summary);\n        return this;\n    }\n\n    public MemberBuilder AddExperience(Experience experience)\n    {\n        profile.AddExperience(experience);\n        return this;\n    }\n\n    public MemberBuilder AddEducation(Education education)\n    {\n        profile.AddEducation(education);\n        return this;\n    }\n\n    public Member Build()\n    {\n        return new Member(id, name, email, profile);\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/NewsFeed.cs",
    "content": "class NewsFeed\n{\n    private readonly List<Post> posts;\n\n    public NewsFeed(List<Post> posts)\n    {\n        this.posts = posts;\n    }\n\n    public void Display(IFeedSortingStrategy strategy)\n    {\n        var sortedPosts = strategy.Sort(posts);\n        if (!sortedPosts.Any())\n        {\n            Console.WriteLine(\"  Your news feed is empty.\");\n            return;\n        }\n\n        foreach (var post in sortedPosts)\n        {\n            Console.WriteLine(\"----------------------------------------\");\n            Console.WriteLine($\"Post by: {post.GetAuthor().GetName()} (at {post.GetCreatedAt().ToShortDateString()})\");\n            Console.WriteLine($\"Content: {post.GetContent()}\");\n            Console.WriteLine($\"Likes: {post.GetLikes().Count}, Comments: {post.GetComments().Count}\");\n            Console.WriteLine(\"----------------------------------------\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Notification.cs",
    "content": "class Notification\n{\n    private readonly string id;\n    private readonly string memberId;\n    private readonly NotificationType type;\n    private readonly string content;\n    private readonly DateTime createdAt;\n    private bool isRead = false;\n\n    public Notification(string memberId, NotificationType type, string content)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.memberId = memberId;\n        this.type = type;\n        this.content = content;\n        this.createdAt = DateTime.Now;\n    }\n\n    public string GetContent() { return content; }\n    public void MarkAsRead() { isRead = true; }\n    public bool IsRead() { return isRead; }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Post.cs",
    "content": "class Post : Subject\n{\n    private readonly string id;\n    private readonly Member author;\n    private readonly string content;\n    private readonly DateTime createdAt;\n    private readonly List<Like> likes = new List<Like>();\n    private readonly List<Comment> comments = new List<Comment>();\n\n    public Post(Member author, string content)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.author = author;\n        this.content = content;\n        this.createdAt = DateTime.Now;\n        AddObserver(author);\n    }\n\n    public void AddLike(Member member)\n    {\n        likes.Add(new Like(member));\n        string notificationContent = $\"{member.GetName()} liked your post.\";\n        var notification = new Notification(author.GetId(), NotificationType.POST_LIKE, notificationContent);\n        NotifyObservers(notification);\n    }\n\n    public void AddComment(Member member, string text)\n    {\n        comments.Add(new Comment(member, text));\n        string notificationContent = $\"{member.GetName()} commented on your post: \\\"{text}\\\"\";\n        var notification = new Notification(author.GetId(), NotificationType.POST_COMMENT, notificationContent);\n        NotifyObservers(notification);\n    }\n\n    public string GetId() { return id; }\n    public Member GetAuthor() { return author; }\n    public string GetContent() { return content; }\n    public DateTime GetCreatedAt() { return createdAt; }\n    public List<Like> GetLikes() { return likes; }\n    public List<Comment> GetComments() { return comments; }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Models/Profile.cs",
    "content": "class Profile\n{\n    private string summary;\n    private readonly List<Experience> experiences = new List<Experience>();\n    private readonly List<Education> educations = new List<Education>();\n\n    public void SetSummary(string summary) { this.summary = summary; }\n    public void AddExperience(Experience experience) { experiences.Add(experience); }\n    public void AddEducation(Education education) { educations.Add(education); }\n\n    public void Display()\n    {\n        Console.WriteLine($\"  Summary: {(summary ?? \"N/A\")}\");\n\n        Console.WriteLine(\"  Experience:\");\n        if (!experiences.Any())\n        {\n            Console.WriteLine(\"    - None\");\n        }\n        else\n        {\n            foreach (var exp in experiences)\n            {\n                Console.WriteLine($\"    - {exp}\");\n            }\n        }\n\n        Console.WriteLine(\"  Education:\");\n        if (!educations.Any())\n        {\n            Console.WriteLine(\"    - None\");\n        }\n        else\n        {\n            foreach (var edu in educations)\n            {\n                Console.WriteLine($\"    - {edu}\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Observer/INotificationObserver.cs",
    "content": "interface INotificationObserver\n{\n    void Update(Notification notification);\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Observer/Subject.cs",
    "content": "abstract class Subject\n{\n    private readonly List<INotificationObserver> observers = new List<INotificationObserver>();\n\n    public void AddObserver(INotificationObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(INotificationObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers(Notification notification)\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(notification);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/README.md",
    "content": "# Designing a Professional Networking Platform like LinkedIn\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their professional information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their professional information, such as profile picture, headline, summary, experience, education, and skills.\n- Users should be able to update their profile information.\n#### Connections:\n- Users should be able to send connection requests to other users.\n- Users should be able to accept or decline connection requests.\n- Users should be able to view their list of connections.\n#### Messaging:\n- Users should be able to send messages to their connections.\n- Users should be able to view their inbox and sent messages.\n#### Job Postings:\n- Employers should be able to post job listings with details such as title, description, requirements, and location.\n- Users should be able to view and apply for job postings.\n#### Search Functionality:\n- Users should be able to search for other users, companies, and job postings based on relevant criteria.\n- Search results should be ranked based on relevance and user preferences.\n#### Notifications:\n- Users should receive notifications for events such as connection requests, messages, and job postings.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the LinkedIn system, containing properties such as ID, name, email, password, profile, connections, inbox, and sent messages.\n2. The **Profile** class represents a user's profile, containing properties such as profile picture, headline, summary, experiences, educations, and skills.\n3. The **Experience**, **Education**, and **Skill** classes represent different components of a user's profile.\n4. The **Connection** class represents a connection between two users, containing the user and the connection date.\n5. The **Message** class represents a message sent between users, containing properties such as ID, sender, receiver, content, and timestamp.\n6. The **JobPosting** class represents a job listing posted by an employer, containing properties such as ID, title, description, requirements, location, and post date.\n7. The **Notification** class represents a notification generated for a user, containing properties such as ID, user, notification type, content, and timestamp.\n8. The **NotificationType** enum defines the different types of notifications, such as connection request, message, and job posting.\n9. The **LinkedInService** class is the main class that manages the LinkedIn system. It follows the Singleton pattern to ensure only one instance of the service exists.\n10. The **LinkedInService** class provides methods for user registration, login, profile updates, connection requests, job postings, user and job search, messaging, and notifications.\n11. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n12. The **LinkedInDemo** class demonstrates the usage of the LinkedIn system by registering users, logging in, updating profiles, sending connection requests, posting job listings, searching for users and jobs, sending messages, and retrieving notifications."
  },
  {
    "path": "solutions/csharp/linkedIn/Services/ConnectionService.cs",
    "content": "class ConnectionService\n{\n    private readonly NotificationService notificationService;\n    private readonly Dictionary<string, Connection> connectionRequests = new Dictionary<string, Connection>();\n    private readonly object lockObj = new object();\n\n    public ConnectionService(NotificationService notificationService)\n    {\n        this.notificationService = notificationService;\n    }\n\n    public string SendRequest(Member from, Member to)\n    {\n        var connection = new Connection(from, to);\n        string requestId = Guid.NewGuid().ToString();\n        \n        lock (lockObj)\n        {\n            connectionRequests[requestId] = connection;\n        }\n\n        Console.WriteLine($\"{from.GetName()} sent a connection request to {to.GetName()}.\");\n\n        var notification = new Notification(\n            to.GetId(),\n            NotificationType.CONNECTION_REQUEST,\n            $\"{from.GetName()} wants to connect with you. Request ID: {requestId}\"\n        );\n        notificationService.SendNotification(to, notification);\n\n        return requestId;\n    }\n\n    public void AcceptRequest(string requestId)\n    {\n        lock (lockObj)\n        {\n            if (connectionRequests.TryGetValue(requestId, out var request) && \n                request.GetStatus() == ConnectionStatus.PENDING)\n            {\n                request.SetStatus(ConnectionStatus.ACCEPTED);\n\n                var from = request.GetFromMember();\n                var to = request.GetToMember();\n\n                from.AddConnection(to);\n                to.AddConnection(from);\n\n                Console.WriteLine($\"{to.GetName()} accepted the connection request from {from.GetName()}.\");\n                connectionRequests.Remove(requestId);\n            }\n            else\n            {\n                Console.WriteLine(\"Invalid or already handled request ID.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Services/NewsFeedService.cs",
    "content": "class NewsFeedService\n{\n    private readonly Dictionary<string, List<Post>> allPosts = new Dictionary<string, List<Post>>();\n    private readonly object lockObj = new object();\n\n    public void AddPost(Member member, Post post)\n    {\n        lock (lockObj)\n        {\n            if (!allPosts.ContainsKey(member.GetId()))\n            {\n                allPosts[member.GetId()] = new List<Post>();\n            }\n            allPosts[member.GetId()].Add(post);\n        }\n    }\n\n    public List<Post> GetMemberPosts(Member member)\n    {\n        lock (lockObj)\n        {\n            return allPosts.TryGetValue(member.GetId(), out var posts) ? posts : new List<Post>();\n        }\n    }\n\n    public void DisplayFeedForMember(Member member, IFeedSortingStrategy feedSortingStrategy)\n    {\n        var feedPosts = new List<Post>();\n\n        foreach (var connection in member.GetConnections())\n        {\n            var connectionPosts = GetMemberPosts(connection);\n            feedPosts.AddRange(connectionPosts);\n        }\n\n        var feed = new NewsFeed(feedPosts);\n        feed.Display(feedSortingStrategy);\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Services/NotificationService.cs",
    "content": "class NotificationService\n{\n    public void SendNotification(Member member, Notification notification)\n    {\n        member.Update(notification);\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Services/SearchService.cs",
    "content": "class SearchService\n{\n    private readonly ICollection<Member> members;\n\n    public SearchService(ICollection<Member> members)\n    {\n        this.members = members;\n    }\n\n    public List<Member> SearchByName(string name)\n    {\n        return members\n            .Where(member => member.GetName().ToLower().Contains(name.ToLower()))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Strategy/ChronologicalSortStrategy.cs",
    "content": "class ChronologicalSortStrategy : IFeedSortingStrategy\n{\n    public List<Post> Sort(List<Post> posts)\n    {\n        return posts.OrderByDescending(post => post.GetCreatedAt()).ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/Strategy/IFeedSortingStrategy.cs",
    "content": "interface IFeedSortingStrategy\n{\n    List<Post> Sort(List<Post> posts);\n}"
  },
  {
    "path": "solutions/csharp/linkedIn/linkedIn.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/loggingframework/Appenders/ConsoleAppender.cs",
    "content": "class ConsoleAppender : ILogAppender\n{\n    private ILogFormatter formatter;\n\n    public ConsoleAppender()\n    {\n        this.formatter = new SimpleTextFormatter();\n    }\n\n    public void Append(LogMessage logMessage)\n    {\n        Console.Write(formatter.Format(logMessage));\n    }\n\n    public void Close() { }\n\n    public void SetFormatter(ILogFormatter formatter)\n    {\n        this.formatter = formatter;\n    }\n\n    public ILogFormatter GetFormatter()\n    {\n        return formatter;\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Appenders/FileAppender.cs",
    "content": "class FileAppender : ILogAppender\n{\n    private StreamWriter writer;\n    private ILogFormatter formatter;\n    private readonly object fileLock = new object();\n\n    public FileAppender(string filePath)\n    {\n        this.formatter = new SimpleTextFormatter();\n        try\n        {\n            this.writer = new StreamWriter(filePath, true);\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"Failed to create writer for file logs, exception: {e.Message}\");\n            this.writer = null;\n        }\n    }\n\n    public void Append(LogMessage logMessage)\n    {\n        lock (fileLock)\n        {\n            if (writer != null)\n            {\n                try\n                {\n                    writer.Write(formatter.Format(logMessage) + \"\\n\");\n                    writer.Flush();\n                }\n                catch (Exception e)\n                {\n                    Console.WriteLine($\"Failed to write logs to file, exception: {e.Message}\");\n                }\n            }\n        }\n    }\n\n    public void Close()\n    {\n        if (writer != null)\n        {\n            try\n            {\n                writer.Close();\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine($\"Failed to close logs file, exception: {e.Message}\");\n            }\n        }\n    }\n\n    public void SetFormatter(ILogFormatter formatter)\n    {\n        this.formatter = formatter;\n    }\n\n    public ILogFormatter GetFormatter()\n    {\n        return formatter;\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Appenders/ILogAppender.cs",
    "content": "interface ILogAppender\n{\n    void Append(LogMessage logMessage);\n    void Close();\n    ILogFormatter GetFormatter();\n    void SetFormatter(ILogFormatter formatter);\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/AsyncLogProcessor.cs",
    "content": "using System.Collections.Concurrent;\n\nclass AsyncLogProcessor\n{\n    private readonly ConcurrentQueue<Action> taskQueue = new ConcurrentQueue<Action>();\n    private readonly AutoResetEvent signal = new AutoResetEvent(false);\n    private volatile bool shutdownFlag = false;\n    private readonly Thread workerThread;\n\n    public AsyncLogProcessor()\n    {\n        workerThread = new Thread(WorkerLoop)\n        {\n            Name = \"AsyncLogProcessor\",\n            IsBackground = true\n        };\n        workerThread.Start();\n    }\n\n    private void WorkerLoop()\n    {\n        while (!shutdownFlag)\n        {\n            signal.WaitOne();\n            \n            while (taskQueue.TryDequeue(out Action task))\n            {\n                try\n                {\n                    task();\n                }\n                catch (Exception e)\n                {\n                    Console.WriteLine($\"Error processing log task: {e.Message}\");\n                }\n            }\n        }\n    }\n\n    public void Process(LogMessage logMessage, List<ILogAppender> appenders)\n    {\n        if (shutdownFlag)\n        {\n            Console.Error.WriteLine(\"Logger is shut down. Cannot process log message.\");\n            return;\n        }\n\n        taskQueue.Enqueue(() =>\n        {\n            foreach (var appender in appenders)\n            {\n                appender.Append(logMessage);\n            }\n        });\n        signal.Set();\n    }\n\n    public void Stop()\n    {\n        shutdownFlag = true;\n        signal.Set();\n        \n        if (!workerThread.Join(TimeSpan.FromSeconds(2)))\n        {\n            Console.Error.WriteLine(\"Logger executor did not terminate in the specified time.\");\n            workerThread.Abort();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Enum/LogLevel.cs",
    "content": "enum LogLevel\n{\n    DEBUG = 1,\n    INFO = 2,\n    WARN = 3,\n    ERROR = 4,\n    FATAL = 5\n}\n\nstatic class LogLevelExtensions\n{\n    public static bool IsGreaterOrEqual(this LogLevel level, LogLevel other)\n    {\n        return (int)level >= (int)other;\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Formatters/ILogFormatter.cs",
    "content": "interface ILogFormatter\n{\n    string Format(LogMessage logMessage);\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Formatters/SimpleTextFormatter.cs",
    "content": "class SimpleTextFormatter : ILogFormatter\n{\n    public string Format(LogMessage logMessage)\n    {\n        return $\"{logMessage.GetTimestamp():yyyy-MM-dd HH:mm:ss.fff} [{logMessage.GetThreadName()}] {logMessage.GetLevel()} - {logMessage.GetLoggerName()}: {logMessage.GetMessage()}\\n\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/LogManager.cs",
    "content": "using System.Collections.Concurrent;\n\nclass LogManager\n{\n    private static volatile LogManager instance;\n    private static readonly object lockObject = new object();\n    private readonly ConcurrentDictionary<string, Logger> loggers = new ConcurrentDictionary<string, Logger>();\n    private readonly Logger rootLogger;\n    private readonly AsyncLogProcessor processor;\n\n    private LogManager()\n    {\n        this.rootLogger = new Logger(\"root\", null);\n        this.loggers.TryAdd(\"root\", rootLogger);\n        this.processor = new AsyncLogProcessor();\n    }\n\n    public static LogManager GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                    instance = new LogManager();\n            }\n        }\n        return instance;\n    }\n\n    public Logger GetLogger(string name)\n    {\n        return loggers.GetOrAdd(name, CreateLogger);\n    }\n\n    private Logger CreateLogger(string name)\n    {\n        if (name.Equals(\"root\"))\n        {\n            return rootLogger;\n        }\n        int lastDot = name.LastIndexOf('.');\n        string parentName = (lastDot == -1) ? \"root\" : name.Substring(0, lastDot);\n        Logger parent = GetLogger(parentName);\n        return new Logger(name, parent);\n    }\n\n    public Logger GetRootLogger()\n    {\n        return rootLogger;\n    }\n\n    public AsyncLogProcessor GetProcessor()\n    {\n        return processor;\n    }\n\n    public void Shutdown()\n    {\n        // Stop the processor first to ensure all logs are written\n        processor.Stop();\n\n        // Then, close all appenders\n        var allAppenders = loggers.Values\n            .SelectMany(logger => logger.GetAppenders())\n            .Distinct()\n            .ToList();\n\n        foreach (var appender in allAppenders)\n        {\n            appender.Close();\n        }\n\n        Console.WriteLine(\"Logging framework shut down gracefully.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Logger.cs",
    "content": "class Logger\n{\n    private readonly string name;\n    private LogLevel? level;\n    private readonly Logger parent;\n    private readonly List<ILogAppender> appenders;\n    private bool additivity = true;\n\n    public Logger(string name, Logger parent)\n    {\n        this.name = name;\n        this.parent = parent;\n        this.appenders = new List<ILogAppender>();\n    }\n\n    public void AddAppender(ILogAppender appender)\n    {\n        appenders.Add(appender);\n    }\n\n    public List<ILogAppender> GetAppenders()\n    {\n        return new List<ILogAppender>(appenders);\n    }\n\n    public void SetLevel(LogLevel minLevel)\n    {\n        this.level = minLevel;\n    }\n\n    public void SetAdditivity(bool additivity)\n    {\n        this.additivity = additivity;\n    }\n\n    public LogLevel GetEffectiveLevel()\n    {\n        for (Logger logger = this; logger != null; logger = logger.parent)\n        {\n            LogLevel? currentLevel = logger.level;\n            if (currentLevel.HasValue)\n            {\n                return currentLevel.Value;\n            }\n        }\n        return LogLevel.DEBUG; // Default root level\n    }\n\n    public void Log(LogLevel messageLevel, string message)\n    {\n        if (messageLevel.IsGreaterOrEqual(GetEffectiveLevel()))\n        {\n            LogMessage logMessage = new LogMessage(messageLevel, this.name, message);\n            CallAppenders(logMessage);\n        }\n    }\n\n    private void CallAppenders(LogMessage logMessage)\n    {\n        if (appenders.Count > 0)\n        {\n            LogManager.GetInstance().GetProcessor().Process(logMessage, this.appenders);\n        }\n        if (additivity && parent != null)\n        {\n            parent.CallAppenders(logMessage);\n        }\n    }\n\n    public void Debug(string message)\n    {\n        Log(LogLevel.DEBUG, message);\n    }\n\n    public void Info(string message)\n    {\n        Log(LogLevel.INFO, message);\n    }\n\n    public void Warn(string message)\n    {\n        Log(LogLevel.WARN, message);\n    }\n\n    public void Error(string message)\n    {\n        Log(LogLevel.ERROR, message);\n    }\n\n    public void Fatal(string message)\n    {\n        Log(LogLevel.FATAL, message);\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/LoggingFrameworkDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Linq;\n\npublic class LoggingFrameworkDemo\n{\n    public static void Main(string[] args)\n    {\n        // --- 1. Initial Configuration ---\n        LogManager logManager = LogManager.GetInstance();\n        Logger rootLogger = logManager.GetRootLogger();\n        rootLogger.SetLevel(LogLevel.INFO); // Set global minimum level to INFO\n\n        // Add a console appender to the root logger\n        rootLogger.AddAppender(new ConsoleAppender());\n\n        Console.WriteLine(\"--- Initial Logging Demo ---\");\n        Logger mainLogger = logManager.GetLogger(\"com.example.Main\");\n        mainLogger.Info(\"Application starting up.\");\n        mainLogger.Debug(\"This is a debug message, it should NOT appear.\"); // Below root level\n        mainLogger.Warn(\"This is a warning message.\");\n\n        // --- 2. Hierarchy and Additivity Demo ---\n        Console.WriteLine(\"\\n--- Logger Hierarchy Demo ---\");\n        Logger dbLogger = logManager.GetLogger(\"com.example.db\");\n        // dbLogger inherits level and appenders from root\n        dbLogger.Info(\"Database connection pool initializing.\");\n\n        // Let's create a more specific logger and override its level\n        Logger serviceLogger = logManager.GetLogger(\"com.example.service.UserService\");\n        serviceLogger.SetLevel(LogLevel.DEBUG); // More verbose logging for this specific service\n        serviceLogger.Info(\"User service starting.\");\n        serviceLogger.Debug(\"This debug message SHOULD now appear for the service logger.\");\n\n        // --- 3. Dynamic Configuration Change ---\n        Console.WriteLine(\"\\n--- Dynamic Configuration Demo ---\");\n        Console.WriteLine(\"Changing root log level to DEBUG...\");\n        rootLogger.SetLevel(LogLevel.DEBUG);\n        mainLogger.Debug(\"This debug message should now be visible.\");\n\n        try\n        {\n            Thread.Sleep(500);\n            logManager.Shutdown();\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine(\"Caught exception\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/Models/LogMessage.cs",
    "content": "class LogMessage\n{\n    private readonly DateTime timestamp;\n    private readonly LogLevel level;\n    private readonly string loggerName;\n    private readonly string threadName;\n    private readonly string message;\n\n    public LogMessage(LogLevel level, string loggerName, string message)\n    {\n        this.timestamp = DateTime.Now;\n        this.level = level;\n        this.loggerName = loggerName;\n        this.message = message;\n        this.threadName = Thread.CurrentThread.Name ?? Thread.CurrentThread.ManagedThreadId.ToString();\n    }\n\n    public DateTime GetTimestamp() { return timestamp; }\n    public LogLevel GetLevel() { return level; }\n    public string GetLoggerName() { return loggerName; }\n    public string GetThreadName() { return threadName; }\n    public string GetMessage() { return message; }\n}"
  },
  {
    "path": "solutions/csharp/loggingframework/README.md",
    "content": "# Designing a Logging Framework\n\n## Requirements\n1. The logging framework should support different log levels, such as DEBUG, INFO, WARNING, ERROR, and FATAL.\n2. It should allow logging messages with a timestamp, log level, and message content.\n3. The framework should support multiple output destinations, such as console, file, and database.\n4. It should provide a configuration mechanism to set the log level and output destination.\n5. The logging framework should be thread-safe to handle concurrent logging from multiple threads.\n6. It should be extensible to accommodate new log levels and output destinations in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **LogLevel** enum defines the different log levels supported by the logging framework.\n2. The **LogMessage** class represents a log message with a timestamp, log level, and message content.\n3. The **LogAppender** interface defines the contract for appending log messages to different output destinations.\n4. The **ConsoleAppender**, **FileAppender**, and **DatabaseAppender** classes are concrete implementations of the LogAppender interface, supporting logging to the console, file, and database, respectively.\n5. The **LoggerConfig** class holds the configuration settings for the logger, including the log level and the selected log appender.\n6. The **Logger** class is a singleton that provides the main logging functionality. It allows setting the configuration, logging messages at different levels, and provides convenience methods for each log level.\n7. The **LoggingExample** class demonstrates the usage of the logging framework, showcasing different log levels, changing the configuration, and logging from multiple threads."
  },
  {
    "path": "solutions/csharp/loggingframework/loggingframework.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/lrucache/DoublyLinkedList.cs",
    "content": "class DoublyLinkedList<K, V>\n{\n    private readonly Node<K, V> head;\n    private readonly Node<K, V> tail;\n\n    public DoublyLinkedList()\n    {\n        head = new Node<K, V>(default(K), default(V));\n        tail = new Node<K, V>(default(K), default(V));\n        head.next = tail;\n        tail.prev = head;\n    }\n\n    public void AddFirst(Node<K, V> node)\n    {\n        node.next = head.next;\n        node.prev = head;\n        head.next.prev = node;\n        head.next = node;\n    }\n\n    public void Remove(Node<K, V> node)\n    {\n        node.prev.next = node.next;\n        node.next.prev = node.prev;\n    }\n\n    public void MoveToFront(Node<K, V> node)\n    {\n        Remove(node);\n        AddFirst(node);\n    }\n\n    public Node<K, V> RemoveLast()\n    {\n        if (tail.prev == head) return null;\n        Node<K, V> last = tail.prev;\n        Remove(last);\n        return last;\n    }\n}"
  },
  {
    "path": "solutions/csharp/lrucache/LRUCache.cs",
    "content": "class LRUCache<K, V>\n{\n    private readonly int capacity;\n    private readonly Dictionary<K, Node<K, V>> map;\n    private readonly DoublyLinkedList<K, V> dll;\n    private readonly object lockObject = new object();\n\n    public LRUCache(int capacity)\n    {\n        this.capacity = capacity;\n        this.map = new Dictionary<K, Node<K, V>>();\n        this.dll = new DoublyLinkedList<K, V>();\n    }\n\n    public V Get(K key)\n    {\n        lock (lockObject)\n        {\n            if (!map.ContainsKey(key)) return default(V);\n            Node<K, V> node = map[key];\n            dll.MoveToFront(node);\n            return node.value;\n        }\n    }\n\n    public void Put(K key, V value)\n    {\n        lock (lockObject)\n        {\n            if (map.ContainsKey(key))\n            {\n                Node<K, V> node = map[key];\n                node.value = value;\n                dll.MoveToFront(node);\n            }\n            else\n            {\n                if (map.Count == capacity)\n                {\n                    Node<K, V> lru = dll.RemoveLast();\n                    if (lru != null) map.Remove(lru.key);\n                }\n                Node<K, V> newNode = new Node<K, V>(key, value);\n                dll.AddFirst(newNode);\n                map[key] = newNode;\n            }\n        }\n    }\n\n    public void Remove(K key)\n    {\n        lock (lockObject)\n        {\n            if (!map.ContainsKey(key)) return;\n            Node<K, V> node = map[key];\n            dll.Remove(node);\n            map.Remove(key);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/lrucache/LRUCacheDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\npublic class LRUCacheDemo\n{\n    public static void Main()\n    {\n        LRUCache<string, int> cache = new LRUCache<string, int>(3);\n\n        cache.Put(\"a\", 1);\n        cache.Put(\"b\", 2);\n        cache.Put(\"c\", 3);\n\n        Console.WriteLine(cache.Get(\"a\")); // 1\n\n        cache.Put(\"d\", 4);\n\n        Console.WriteLine(cache.Get(\"b\")); // 0 (default for int when null)\n    }\n}"
  },
  {
    "path": "solutions/csharp/lrucache/Node.cs",
    "content": "class Node<K, V>\n{\n    public K key;\n    public V value;\n    public Node<K, V> prev;\n    public Node<K, V> next;\n\n    public Node(K key, V value)\n    {\n        this.key = key;\n        this.value = value;\n    }\n}"
  },
  {
    "path": "solutions/csharp/lrucache/README.md",
    "content": "# Designing a LRU Cache\n\n## Requirements\n1. The LRU cache should support the following operations:\n- put(key, value): Insert a key-value pair into the cache. If the cache is at capacity, remove the least recently used item before inserting the new item.\n- get(key): Get the value associated with the given key. If the key exists in the cache, move it to the front of the cache (most recently used) and return its value. If the key does not exist, return -1.\n2. The cache should have a fixed capacity, specified during initialization.\n3. The cache should be thread-safe, allowing concurrent access from multiple threads.\n4. The cache should be efficient in terms of time complexity for both put and get operations, ideally O(1).\n\n## Classes, Interfaces and Enumerations\n1. The **Node** class represents a node in the doubly linked list, containing the key, value, and references to the previous and next nodes.\n2. The **LRUCache** class implements the LRU cache functionality using a combination of a hash map (cache) and a doubly linked list (head and tail).\n3. The get method retrieves the value associated with a given key. If the key exists in the cache, it is moved to the head of the linked list (most recently used) and its value is returned. If the key does not exist, null is returned.\n4. The put method inserts a key-value pair into the cache. If the key already exists, its value is updated, and the node is moved to the head of the linked list. If the key does not exist and the cache is at capacity, the least recently used item (at the tail of the linked list) is removed, and the new item is inserted at the head.\n5. The addToHead, removeNode, moveToHead, and removeTail methods are helper methods to manipulate the doubly linked list.\n6. The synchronized keyword is used on the get and put methods to ensure thread safety, allowing concurrent access from multiple threads.\n7. The **LRUCacheDemo** class demonstrates the usage of the LRU cache by creating an instance of LRUCache with a capacity of 3, performing various put and get operations, and printing the results."
  },
  {
    "path": "solutions/csharp/lrucache/lrucache.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/BookingManager.cs",
    "content": "class BookingManager\n{\n    private readonly SeatLockManager seatLockManager;\n\n    public BookingManager(SeatLockManager seatLockManager)\n    {\n        this.seatLockManager = seatLockManager;\n    }\n\n    public Booking CreateBooking(User user, Show show, List<Seat> seats, IPaymentStrategy paymentStrategy)\n    {\n        // 1. Lock the seats\n        seatLockManager.LockSeats(show, seats, user.GetId());\n\n        // 2. Calculate the total price\n        double totalAmount = show.GetPricingStrategy().CalculatePrice(seats);\n\n        // 3. Process Payment\n        Payment payment = paymentStrategy.Pay(totalAmount);\n\n        // 4. If payment is successful, create the booking\n        if (payment.GetStatus() == PaymentStatus.SUCCESS)\n        {\n            Booking booking = new BookingBuilder()\n                .SetUser(user)\n                .SetShow(show)\n                .SetSeats(seats)\n                .SetTotalAmount(totalAmount)\n                .SetPayment(payment)\n                .Build();\n\n            // 5. Confirm the booking (mark seats as BOOKED)\n            booking.ConfirmBooking();\n\n            // Clean up the lock map\n            seatLockManager.UnlockSeats(show, seats, user.GetId());\n\n            return booking;\n        }\n        else\n        {\n            Console.WriteLine(\"Payment failed. Please try again.\");\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Enums/PaymentStatus.cs",
    "content": "enum PaymentStatus\n{\n    SUCCESS,\n    FAILURE,\n    PENDING\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Enums/SeatStatus.cs",
    "content": "enum SeatStatus\n{\n    AVAILABLE,\n    BOOKED,\n    LOCKED // Temporarily held during booking process\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Enums/SeatType.cs",
    "content": "enum SeatType\n{\n    REGULAR,\n    PREMIUM,\n    RECLINER\n}\n\nstatic class SeatTypeExtensions\n{\n    public static double GetPrice(this SeatType seatType)\n    {\n        switch (seatType)\n        {\n            case SeatType.REGULAR: return 50.0;\n            case SeatType.PREMIUM: return 80.0;\n            case SeatType.RECLINER: return 120.0;\n            default: return 50.0;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Booking.cs",
    "content": "class Booking\n{\n    private readonly string id;\n    private readonly User user;\n    private readonly Show show;\n    private readonly List<Seat> seats;\n    private readonly double totalAmount;\n    private readonly Payment payment;\n\n    public Booking(string id, User user, Show show, List<Seat> seats, double totalAmount, Payment payment)\n    {\n        this.id = id;\n        this.user = user;\n        this.show = show;\n        this.seats = seats;\n        this.totalAmount = totalAmount;\n        this.payment = payment;\n    }\n\n    public void ConfirmBooking()\n    {\n        foreach (var seat in seats)\n        {\n            seat.SetStatus(SeatStatus.BOOKED);\n        }\n    }\n\n    public string GetId() { return id; }\n    public User GetUser() { return user; }\n    public Show GetShow() { return show; }\n    public List<Seat> GetSeats() { return seats; }\n    public double GetTotalAmount() { return totalAmount; }\n    public Payment GetPayment() { return payment; }\n}\n\nclass BookingBuilder\n{\n    private string id;\n    private User user;\n    private Show show;\n    private List<Seat> seats;\n    private double totalAmount;\n    private Payment payment;\n\n    public BookingBuilder SetId(string id)\n    {\n        this.id = id;\n        return this;\n    }\n\n    public BookingBuilder SetUser(User user)\n    {\n        this.user = user;\n        return this;\n    }\n\n    public BookingBuilder SetShow(Show show)\n    {\n        this.show = show;\n        return this;\n    }\n\n    public BookingBuilder SetSeats(List<Seat> seats)\n    {\n        this.seats = seats;\n        return this;\n    }\n\n    public BookingBuilder SetTotalAmount(double totalAmount)\n    {\n        this.totalAmount = totalAmount;\n        return this;\n    }\n\n    public BookingBuilder SetPayment(Payment payment)\n    {\n        this.payment = payment;\n        return this;\n    }\n\n    public Booking Build()\n    {\n        // Validations can be added here\n        return new Booking(id ?? Guid.NewGuid().ToString(), user, show, seats, totalAmount, payment);\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Cinema.cs",
    "content": "class Cinema\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly City city;\n    private readonly List<Screen> screens;\n\n    public Cinema(string id, string name, City city, List<Screen> screens)\n    {\n        this.id = id;\n        this.name = name;\n        this.city = city;\n        this.screens = screens;\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public City GetCity() { return city; }\n    public List<Screen> GetScreens() { return screens; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/City.cs",
    "content": "class City\n{\n    private readonly string id;\n    private readonly string name;\n\n    public City(string id, string name)\n    {\n        this.id = id;\n        this.name = name;\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Movie.cs",
    "content": "class Movie : MovieSubject\n{\n    private readonly string id;\n    private readonly string title;\n    private readonly int durationInMinutes;\n\n    public Movie(string id, string title, int durationInMinutes)\n    {\n        this.id = id;\n        this.title = title;\n        this.durationInMinutes = durationInMinutes;\n    }\n\n    public string GetId() { return id; }\n    public string GetTitle() { return title; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Payment.cs",
    "content": "class Payment\n{\n    private readonly string id;\n    private readonly double amount;\n    private readonly PaymentStatus status;\n    private readonly string transactionId;\n\n    public Payment(double amount, PaymentStatus status, string transactionId)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.amount = amount;\n        this.status = status;\n        this.transactionId = transactionId;\n    }\n\n    public PaymentStatus GetStatus() { return status; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Screen.cs",
    "content": "class Screen\n{\n    private readonly string id;\n    private readonly List<Seat> seats;\n\n    public Screen(string id)\n    {\n        this.id = id;\n        this.seats = new List<Seat>();\n    }\n\n    public void AddSeat(Seat seat)\n    {\n        seats.Add(seat);\n    }\n\n    public string GetId() { return id; }\n    public List<Seat> GetSeats() { return seats; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Seat.cs",
    "content": "class Seat\n{\n    private readonly string id;\n    private readonly int row;\n    private readonly int col;\n    private readonly SeatType type;\n    private SeatStatus status;\n\n    public Seat(string id, int row, int col, SeatType type)\n    {\n        this.id = id;\n        this.row = row;\n        this.col = col;\n        this.type = type;\n        this.status = SeatStatus.AVAILABLE;\n    }\n\n    public string GetId() { return id; }\n    public int GetRow() { return row; }\n    public int GetCol() { return col; }\n    public SeatType GetSeatType() { return type; }\n    public SeatStatus GetStatus() { return status; }\n    public void SetStatus(SeatStatus status) { this.status = status; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/Show.cs",
    "content": "class Show\n{\n    private readonly string id;\n    private readonly Movie movie;\n    private readonly Screen screen;\n    private readonly DateTime startTime;\n    private readonly IPricingStrategy pricingStrategy;\n\n    public Show(string id, Movie movie, Screen screen, DateTime startTime, IPricingStrategy pricingStrategy)\n    {\n        this.id = id;\n        this.movie = movie;\n        this.screen = screen;\n        this.startTime = startTime;\n        this.pricingStrategy = pricingStrategy;\n    }\n\n    public string GetId() { return id; }\n    public Movie GetMovie() { return movie; }\n    public Screen GetScreen() { return screen; }\n    public DateTime GetStartTime() { return startTime; }\n    public IPricingStrategy GetPricingStrategy() { return pricingStrategy; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Models/User.cs",
    "content": "class User\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n\n    public User(string name, string email)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/MovieBookingDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic class MovieBookingDemo\n{\n    public static void Main(string[] args)\n    {\n        // Setup\n        var service = MovieBookingService.GetInstance();\n\n        var nyc = service.AddCity(\"city1\", \"New York\");\n        var la = service.AddCity(\"city2\", \"Los Angeles\");\n\n        // 2. Add movies\n        var matrix = new Movie(\"M1\", \"The Matrix\", 120);\n        var avengers = new Movie(\"M2\", \"Avengers: Endgame\", 170);\n        service.AddMovie(matrix);\n        service.AddMovie(avengers);\n\n        // Add Seats for a Screen\n        var screen1 = new Screen(\"S1\");\n\n        for (int i = 1; i <= 10; i++)\n        {\n            var seatType = i <= 5 ? SeatType.REGULAR : SeatType.PREMIUM;\n            screen1.AddSeat(new Seat($\"A{i}\", 1, i, seatType));\n            screen1.AddSeat(new Seat($\"B{i}\", 2, i, seatType));\n        }\n\n        // Add Cinemas\n        var amcNYC = service.AddCinema(\"cinema1\", \"AMC Times Square\", nyc.GetId(), new List<Screen> { screen1 });\n\n        // Add Shows\n        var matrixShow = service.AddShow(\"show1\", matrix, screen1, DateTime.Now.AddHours(2), new WeekdayPricingStrategy());\n        var avengersShow = service.AddShow(\"show2\", avengers, screen1, DateTime.Now.AddHours(5), new WeekdayPricingStrategy());\n\n        // --- User and Observer Setup ---\n        var alice = service.CreateUser(\"Alice\", \"alice@example.com\");\n        var aliceObserver = new UserObserver(alice);\n        avengers.AddObserver(aliceObserver);\n\n        // Simulate movie release\n        Console.WriteLine(\"\\n--- Notifying Observers about Movie Release ---\");\n        avengers.NotifyObservers();\n\n        // --- User Story: Alice books tickets ---\n        Console.WriteLine(\"\\n--- Alice's Booking Flow ---\");\n        string cityName = \"New York\";\n        string movieTitle = \"Avengers: Endgame\";\n\n        // 1. Search for shows\n        var availableShows = service.FindShows(movieTitle, cityName);\n        if (!availableShows.Any())\n        {\n            Console.WriteLine($\"No shows found for {movieTitle} in {cityName}\");\n            return;\n        }\n        var selectedShow = availableShows[0]; // Alice selects the first show\n\n        // 2. View available seats\n        var availableSeats = selectedShow.GetScreen().GetSeats()\n            .Where(seat => seat.GetStatus() == SeatStatus.AVAILABLE)\n            .ToList();\n        \n        Console.WriteLine($\"Available seats for '{selectedShow.GetMovie().GetTitle()}' at {selectedShow.GetStartTime()}: {string.Join(\", \", availableSeats.Select(s => s.GetId()))}\");\n\n        // 3. Select seats\n        var desiredSeats = new List<Seat> { availableSeats[2], availableSeats[3] };\n        Console.WriteLine($\"Alice selects seats: {string.Join(\", \", desiredSeats.Select(s => s.GetId()))}\");\n\n        // 4. Book Tickets\n        var booking = service.BookTickets(\n            alice.GetId(),\n            selectedShow.GetId(),\n            desiredSeats,\n            new CreditCardPaymentStrategy(\"1234-5678-9876-5432\", \"123\")\n        );\n\n        if (booking != null)\n        {\n            Console.WriteLine(\"\\n--- Booking Successful! ---\");\n            Console.WriteLine($\"Booking ID: {booking.GetId()}\");\n            Console.WriteLine($\"User: {booking.GetUser().GetName()}\");\n            Console.WriteLine($\"Movie: {booking.GetShow().GetMovie().GetTitle()}\");\n            Console.WriteLine($\"Seats: {string.Join(\", \", booking.GetSeats().Select(s => s.GetId()))}\");\n            Console.WriteLine($\"Total Amount: ${booking.GetTotalAmount()}\");\n            Console.WriteLine($\"Payment Status: {booking.GetPayment().GetStatus()}\");\n        }\n        else\n        {\n            Console.WriteLine(\"Booking failed.\");\n        }\n\n        // 5. Verify seat status after booking\n        Console.WriteLine(\"\\nSeat status after Alice's booking:\");\n        foreach (var seat in desiredSeats)\n        {\n            Console.WriteLine($\"Seat {seat.GetId()} status: {seat.GetStatus()}\");\n        }\n\n        // 6. Shut down the system to release resources like the scheduler.\n        service.Shutdown();\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/MovieBookingService.cs",
    "content": "class MovieBookingService\n{\n    private static volatile MovieBookingService instance;\n    private static readonly object syncRoot = new object();\n\n    private readonly Dictionary<string, City> cities;\n    private readonly Dictionary<string, Cinema> cinemas;\n    private readonly Dictionary<string, Movie> movies;\n    private readonly Dictionary<string, User> users;\n    private readonly Dictionary<string, Show> shows;\n\n    private readonly SeatLockManager seatLockManager;\n    private readonly BookingManager bookingManager;\n\n    private MovieBookingService()\n    {\n        this.cities = new Dictionary<string, City>();\n        this.cinemas = new Dictionary<string, Cinema>();\n        this.movies = new Dictionary<string, Movie>();\n        this.users = new Dictionary<string, User>();\n        this.shows = new Dictionary<string, Show>();\n\n        this.seatLockManager = new SeatLockManager();\n        this.bookingManager = new BookingManager(seatLockManager);\n    }\n\n    public static MovieBookingService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (syncRoot)\n            {\n                if (instance == null)\n                {\n                    instance = new MovieBookingService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public BookingManager GetBookingManager()\n    {\n        return bookingManager;\n    }\n\n    public City AddCity(string id, string name)\n    {\n        var city = new City(id, name);\n        cities[city.GetId()] = city;\n        return city;\n    }\n\n    public Cinema AddCinema(string id, string name, string cityId, List<Screen> screens)\n    {\n        var city = cities[cityId];\n        var cinema = new Cinema(id, name, city, screens);\n        cinemas[cinema.GetId()] = cinema;\n        return cinema;\n    }\n\n    public void AddMovie(Movie movie)\n    {\n        movies[movie.GetId()] = movie;\n    }\n\n    public Show AddShow(string id, Movie movie, Screen screen, DateTime startTime, IPricingStrategy pricingStrategy)\n    {\n        var show = new Show(id, movie, screen, startTime, pricingStrategy);\n        shows[show.GetId()] = show;\n        return show;\n    }\n\n    public User CreateUser(string name, string email)\n    {\n        var user = new User(name, email);\n        users[user.GetId()] = user;\n        return user;\n    }\n\n    public Booking BookTickets(string userId, string showId, List<Seat> desiredSeats, IPaymentStrategy paymentStrategy)\n    {\n        return bookingManager.CreateBooking(\n            users[userId],\n            shows[showId],\n            desiredSeats,\n            paymentStrategy\n        );\n    }\n\n    public List<Show> FindShows(string movieTitle, string cityName)\n    {\n        var result = new List<Show>();\n        foreach (var show in shows.Values)\n        {\n            if (show.GetMovie().GetTitle().Equals(movieTitle, StringComparison.OrdinalIgnoreCase))\n            {\n                var cinema = FindCinemaForShow(show);\n                if (cinema != null && cinema.GetCity().GetName().Equals(cityName, StringComparison.OrdinalIgnoreCase))\n                {\n                    result.Add(show);\n                }\n            }\n        }\n        return result;\n    }\n\n    private Cinema FindCinemaForShow(Show show)\n    {\n        return cinemas.Values.FirstOrDefault(cinema => cinema.GetScreens().Contains(show.GetScreen()));\n    }\n\n    public void Shutdown()\n    {\n        seatLockManager.Shutdown();\n        Console.WriteLine(\"MovieTicketBookingSystem has been shut down.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Observer/IMovieObserver.cs",
    "content": "interface IMovieObserver\n{\n    void Update(Movie movie);\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Observer/MovieSubject.cs",
    "content": "abstract class MovieSubject\n{\n    private readonly List<IMovieObserver> observers = new List<IMovieObserver>();\n\n    public void AddObserver(IMovieObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IMovieObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers()\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update((Movie)this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Observer/UserObserver.cs",
    "content": "class UserObserver : IMovieObserver\n{\n    private readonly User user;\n\n    public UserObserver(User user)\n    {\n        this.user = user;\n    }\n\n    public void Update(Movie movie)\n    {\n        Console.WriteLine($\"Notification for {user.GetName()} ({user.GetId()}): Movie '{movie.GetTitle()}' is now available for booking!\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/README.md",
    "content": "# Designing a Movie Ticket Booking System like BookMyShow\n\n## Requirements\n1. The system should allow users to view the list of movies playing in different theaters.\n2. Users should be able to select a movie, theater, and show timing to book tickets.\n3. The system should display the seating arrangement of the selected show and allow users to choose seats.\n4. Users should be able to make payments and confirm their booking.\n5. The system should handle concurrent bookings and ensure seat availability is updated in real-time.\n6. The system should support different types of seats (e.g., normal, premium) and pricing.\n7. The system should allow theater administrators to add, update, and remove movies, shows, and seating arrangements.\n8. The system should be scalable to handle a large number of concurrent users and bookings.\n\n## Classes, Interfaces and Enumerations\n1. The **Movie** class represents a movie with properties such as ID, title, description, and duration.\n2. The **Theater** class represents a theater with properties such as ID, name, location, and a list of shows.\n3. The **Show** class represents a movie show in a theater, with properties such as ID, movie, theater, start time, end time, and a map of seats.\n4. The **Seat** class represents a seat in a show, with properties such as ID, row, column, type, price, and status.\n5. The **SeatType** enum defines the different types of seats (normal or premium).\n6. The **SeatStatus** enum defines the different statuses of a seat (available or booked).\n7. The **Booking** class represents a booking made by a user, with properties such as ID, user, show, selected seats, total price, and status.\n8. The **BookingStatus** enum defines the different statuses of a booking (pending, confirmed, or cancelled).\n9. The **User** class represents a user of the booking system, with properties such as ID, name, and email.\n10. The **MovieTicketBookingSystem** class is the main class that manages the movie ticket booking system. It follows the Singleton pattern to ensure only one instance of the system exists.\n11. The MovieTicketBookingSystem class provides methods for adding movies, theaters, and shows, as well as booking tickets, confirming bookings, and cancelling bookings.\n12. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap to handle concurrent access to shared resources like shows and bookings.\n13. The **MovieTicketBookingDemo** class demonstrates the usage of the movie ticket booking system by adding movies, theaters, shows, booking tickets, and confirming or cancelling bookings."
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/SeatLockManager.cs",
    "content": "class SeatLockManager\n{\n    private readonly Dictionary<Show, Dictionary<Seat, string>> lockedSeats = new Dictionary<Show, Dictionary<Seat, string>>();\n    private readonly object lockObj = new object();\n    private const int LOCK_TIMEOUT_MS = 500; // 0.5 seconds\n\n    public void LockSeats(Show show, List<Seat> seats, string userId)\n    {\n        lock (lockObj)\n        {\n            // Check if any of the requested seats are already locked or booked\n            foreach (var seat in seats)\n            {\n                if (seat.GetStatus() != SeatStatus.AVAILABLE)\n                {\n                    Console.WriteLine($\"Seat {seat.GetId()} is not available.\");\n                    return;\n                }\n            }\n\n            // Lock the seats\n            foreach (var seat in seats)\n            {\n                seat.SetStatus(SeatStatus.LOCKED);\n            }\n\n            if (!lockedSeats.ContainsKey(show))\n            {\n                lockedSeats[show] = new Dictionary<Seat, string>();\n            }\n\n            foreach (var seat in seats)\n            {\n                lockedSeats[show][seat] = userId;\n            }\n\n            // Schedule a task to unlock the seats after a timeout\n            Task.Delay(LOCK_TIMEOUT_MS).ContinueWith(_ => UnlockSeats(show, seats, userId));\n\n            Console.WriteLine($\"Locked seats: {string.Join(\", \", seats.Select(s => s.GetId()))} for user {userId}\");\n        }\n    }\n\n    public void UnlockSeats(Show show, List<Seat> seats, string userId)\n    {\n        lock (lockObj)\n        {\n            if (lockedSeats.TryGetValue(show, out var showLocks))\n            {\n                foreach (var seat in seats)\n                {\n                    if (showLocks.TryGetValue(seat, out var lockedUserId) && lockedUserId == userId)\n                    {\n                        showLocks.Remove(seat);\n                        if (seat.GetStatus() == SeatStatus.LOCKED)\n                        {\n                            seat.SetStatus(SeatStatus.AVAILABLE);\n                            Console.WriteLine($\"Unlocked seat: {seat.GetId()} due to timeout.\");\n                        }\n                        else\n                        {\n                            Console.WriteLine($\"Unlocked seat: {seat.GetId()} due to booking completion.\");\n                        }\n                    }\n                }\n\n                if (!showLocks.Any())\n                {\n                    lockedSeats.Remove(show);\n                }\n            }\n        }\n    }\n\n    public void Shutdown()\n    {\n        Console.WriteLine(\"Shutting down SeatLockProvider scheduler.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Strategies/Payment/CreditCardPaymentStrategy.cs",
    "content": "class CreditCardPaymentStrategy : IPaymentStrategy\n{\n    private readonly string cardNumber;\n    private readonly string cvv;\n\n    public CreditCardPaymentStrategy(string cardNumber, string cvv)\n    {\n        this.cardNumber = cardNumber;\n        this.cvv = cvv;\n    }\n\n    public Payment Pay(double amount)\n    {\n        Console.WriteLine($\"Processing credit card payment of ${amount:F2}\");\n        // Simulate payment gateway interaction\n        var random = new Random();\n        bool paymentSuccess = random.NextDouble() > 0.05; // 95% success rate\n        \n        return new Payment(\n            amount,\n            paymentSuccess ? PaymentStatus.SUCCESS : PaymentStatus.FAILURE,\n            $\"TXN_{Guid.NewGuid()}\"\n        );\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Strategies/Payment/IPaymentStrategy.cs",
    "content": "interface IPaymentStrategy\n{\n    Payment Pay(double amount);\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Strategies/Pricing/IPricingStrategy.cs",
    "content": "interface IPricingStrategy\n{\n    double CalculatePrice(List<Seat> seats);\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Strategies/Pricing/WeekdayPricingStrategy.cs",
    "content": "class WeekdayPricingStrategy : IPricingStrategy\n{\n    public double CalculatePrice(List<Seat> seats)\n    {\n        return seats.Sum(seat => seat.GetSeatType().GetPrice());\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/Strategies/Pricing/WeekendPricingStrategy.cs",
    "content": "class WeekendPricingStrategy : IPricingStrategy\n{\n    private const double WEEKEND_SURCHARGE = 1.2; // 20% surcharge\n\n    public double CalculatePrice(List<Seat> seats)\n    {\n        double basePrice = seats.Sum(seat => seat.GetSeatType().GetPrice());\n        return basePrice * WEEKEND_SURCHARGE;\n    }\n}"
  },
  {
    "path": "solutions/csharp/movieticketbookingsystem/movieticketbookingsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Commands/ICommand.cs",
    "content": "interface ICommand\n{\n    void Execute();\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Commands/NextTrackCommand.cs",
    "content": "class NextTrackCommand : ICommand\n{\n    private readonly Player player;\n\n    public NextTrackCommand(Player player)\n    {\n        this.player = player;\n    }\n\n    public void Execute()\n    {\n        player.ClickNext();\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Commands/PauseCommand.cs",
    "content": "class PauseCommand : ICommand\n{\n    private readonly Player player;\n\n    public PauseCommand(Player player)\n    {\n        this.player = player;\n    }\n\n    public void Execute()\n    {\n        player.ClickPause();\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Commands/PlayCommand.cs",
    "content": "class PlayCommand : ICommand\n{\n    private readonly Player player;\n\n    public PlayCommand(Player player)\n    {\n        this.player = player;\n    }\n\n    public void Execute()\n    {\n        player.ClickPlay();\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Enums/PlayerStatus.cs",
    "content": "enum PlayerStatus\n{\n    PLAYING,\n    PAUSED,\n    STOPPED\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Enums/SubscriptionTier.cs",
    "content": "enum SubscriptionTier\n{\n    FREE,\n    PREMIUM\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/Album.cs",
    "content": "class Album : IPlayable\n{\n    private readonly string title;\n    private readonly List<Song> tracks = new List<Song>();\n\n    public Album(string title)\n    {\n        this.title = title;\n    }\n\n    public void AddTrack(Song song)\n    {\n        tracks.Add(song);\n    }\n\n    public List<Song> GetTracks()\n    {\n        return new List<Song>(tracks);\n    }\n\n    public string GetTitle() => title;\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/Artist.cs",
    "content": "class Artist : Subject\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly List<Album> discography = new List<Album>();\n\n    public Artist(string id, string name)\n    {\n        this.id = id;\n        this.name = name;\n    }\n\n    public void ReleaseAlbum(Album album)\n    {\n        discography.Add(album);\n        Console.WriteLine($\"[System] Artist {name} has released a new album: {album.GetTitle()}\");\n        NotifyObservers(this, album);\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/IPlayable.cs",
    "content": "interface IPlayable\n{\n    List<Song> GetTracks();\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/Player.cs",
    "content": "class Player\n{\n    private PlayerState state;\n    private PlayerStatus status;\n    private List<Song> queue = new List<Song>();\n    private int currentIndex = -1;\n    private Song currentSong;\n    private User currentUser;\n\n    public Player()\n    {\n        this.state = new StoppedState();\n        this.status = PlayerStatus.STOPPED;\n    }\n\n    public void Load(IPlayable playable, User user)\n    {\n        this.currentUser = user;\n        this.queue = playable.GetTracks();\n        this.currentIndex = 0;\n        Console.WriteLine($\"Loaded {queue.Count} tracks for user {user.GetName()}.\");\n        this.state = new StoppedState();\n    }\n\n    public void PlayCurrentSongInQueue()\n    {\n        if (currentIndex >= 0 && currentIndex < queue.Count)\n        {\n            Song songToPlay = queue[currentIndex];\n            currentUser.GetPlaybackStrategy().Play(songToPlay, this);\n        }\n    }\n\n    public void ClickPlay() => state.Play(this);\n    public void ClickPause() => state.Pause(this);\n\n    public void ClickNext()\n    {\n        if (currentIndex < queue.Count - 1)\n        {\n            currentIndex++;\n            PlayCurrentSongInQueue();\n        }\n        else\n        {\n            Console.WriteLine(\"End of queue.\");\n            state.Stop(this);\n        }\n    }\n\n    public void ChangeState(PlayerState state) => this.state = state;\n    public void SetStatus(PlayerStatus status) => this.status = status;\n    public void SetCurrentSong(Song song) => this.currentSong = song;\n    public bool HasQueue() => queue.Count > 0;\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/Playlist.cs",
    "content": "class Playlist : IPlayable\n{\n    private readonly string name;\n    private readonly List<Song> tracks = new List<Song>();\n\n    public Playlist(string name)\n    {\n        this.name = name;\n    }\n\n    public void AddTrack(Song song)\n    {\n        tracks.Add(song);\n    }\n\n    public List<Song> GetTracks()\n    {\n        return new List<Song>(tracks);\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/Song.cs",
    "content": "class Song : IPlayable\n{\n    private readonly string id;\n    private readonly string title;\n    private readonly Artist artist;\n    private readonly int durationInSeconds;\n\n    public Song(string id, string title, Artist artist, int durationInSeconds)\n    {\n        this.id = id;\n        this.title = title;\n        this.artist = artist;\n        this.durationInSeconds = durationInSeconds;\n    }\n\n    public List<Song> GetTracks()\n    {\n        return new List<Song> { this };\n    }\n\n    public override string ToString()\n    {\n        return $\"'{title}' by {artist.GetName()}\";\n    }\n\n    public string GetId() => id;\n    public string GetTitle() => title;\n    public Artist GetArtist() => artist;\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Models/User.cs",
    "content": "class User : IArtistObserver\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly PlaybackStrategy playbackStrategy;\n    private readonly HashSet<Artist> followedArtists = new HashSet<Artist>();\n\n    public User(string id, string name, PlaybackStrategy strategy)\n    {\n        this.id = id;\n        this.name = name;\n        this.playbackStrategy = strategy;\n    }\n\n    public void FollowArtist(Artist artist)\n    {\n        followedArtists.Add(artist);\n        artist.AddObserver(this);\n    }\n\n    public void Update(Artist artist, Album newAlbum)\n    {\n        Console.WriteLine($\"[Notification for {name}] Your followed artist {artist.GetName()} \" +\n                         $\"just released a new album: {newAlbum.GetTitle()}!\");\n    }\n\n    public PlaybackStrategy GetPlaybackStrategy() => playbackStrategy;\n    public string GetId() => id;\n    public string GetName() => name;\n}\n\nclass UserBuilder\n{\n    private readonly string id;\n    private readonly string name;\n    private PlaybackStrategy playbackStrategy;\n\n    public UserBuilder(string name)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n    }\n\n    public UserBuilder WithSubscription(SubscriptionTier tier, int songsPlayed)\n    {\n        this.playbackStrategy = PlaybackStrategy.GetStrategy(tier, songsPlayed);\n        return this;\n    }\n\n    public User Build()\n    {\n        return new User(id, name, playbackStrategy);\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/MusicStreamingDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class MusicStreamingDemo\n{\n    public static void Main(string[] args)\n    {\n        MusicStreamingSystem system = MusicStreamingSystem.GetInstance();\n\n        // --- Setup Catalog ---\n        Artist daftPunk = new Artist(\"art1\", \"Daft Punk\");\n        system.AddArtist(daftPunk);\n\n        Album discovery = new Album(\"Discovery\");\n        Song s1 = system.AddSong(\"s1\", \"One More Time\", daftPunk.GetId(), 320);\n        Song s2 = system.AddSong(\"s2\", \"Aerodynamic\", daftPunk.GetId(), 212);\n        Song s3 = system.AddSong(\"s3\", \"Digital Love\", daftPunk.GetId(), 301);\n        Song s4 = system.AddSong(\"s4\", \"Radioactive\", daftPunk.GetId(), 311);\n        discovery.AddTrack(s1);\n        discovery.AddTrack(s2);\n        discovery.AddTrack(s3);\n        discovery.AddTrack(s4);\n\n        // --- Register Users (Builder Pattern) ---\n        User freeUser = new UserBuilder(\"Alice\").WithSubscription(SubscriptionTier.FREE, 0).Build();\n        User premiumUser = new UserBuilder(\"Bob\").WithSubscription(SubscriptionTier.PREMIUM, 0).Build();\n        system.RegisterUser(freeUser);\n        system.RegisterUser(premiumUser);\n\n        // --- Observer Pattern: User follows artist ---\n        Console.WriteLine(\"--- Observer Pattern Demo ---\");\n        premiumUser.FollowArtist(daftPunk);\n        daftPunk.ReleaseAlbum(discovery); // This will notify Bob\n        Console.WriteLine();\n\n        // --- Strategy Pattern: Playback behavior ---\n        Console.WriteLine(\"--- Strategy Pattern (Free vs Premium) & State Pattern (Player) Demo ---\");\n        Player player = system.GetPlayer();\n        player.Load(discovery, freeUser);\n\n        // --- Command Pattern: Controlling the player ---\n        ICommand play = new PlayCommand(player);\n        ICommand pause = new PauseCommand(player);\n        ICommand nextTrack = new NextTrackCommand(player);\n\n        play.Execute(); // Plays song 1\n        nextTrack.Execute(); // Plays song 2\n        pause.Execute(); // Pauses song 2\n        play.Execute(); // Resumes song 2\n        nextTrack.Execute(); // Plays song 3\n        nextTrack.Execute(); // Plays song 4 (ad for free user)\n        Console.WriteLine();\n\n        // --- Premium user experience (no ads) ---\n        Console.WriteLine(\"--- Premium User Experience ---\");\n        player.Load(discovery, premiumUser);\n        play.Execute();\n        nextTrack.Execute();\n        Console.WriteLine();\n\n        // --- Composite Pattern: Play a playlist ---\n        Console.WriteLine(\"--- Composite Pattern Demo ---\");\n        Playlist myPlaylist = new Playlist(\"My Awesome Mix\");\n        myPlaylist.AddTrack(s3); // Digital Love\n        myPlaylist.AddTrack(s1); // One More Time\n\n        player.Load(myPlaylist, premiumUser);\n        play.Execute();\n        nextTrack.Execute();\n        Console.WriteLine();\n\n        // --- Search and Recommendation ---\n        Console.WriteLine(\"--- Search and Recommendation Service Demo ---\");\n        List<Song> searchResults = system.SearchSongsByTitle(\"love\");\n        Console.WriteLine($\"Search results for 'love': {string.Join(\", \", searchResults)}\");\n\n        List<Song> recommendations = system.GetSongRecommendations();\n        Console.WriteLine($\"Your daily recommendations: {string.Join(\", \", recommendations)}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/MusicStreamingSystem.cs",
    "content": "class MusicStreamingSystem\n{\n    private static MusicStreamingSystem instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<string, User> users = new Dictionary<string, User>();\n    private readonly Dictionary<string, Song> songs = new Dictionary<string, Song>();\n    private readonly Dictionary<string, Artist> artists = new Dictionary<string, Artist>();\n    private readonly Player player;\n    private readonly SearchService searchService;\n    private readonly RecommendationService recommendationService;\n\n    private MusicStreamingSystem()\n    {\n        this.player = new Player();\n        this.searchService = new SearchService();\n        this.recommendationService = new RecommendationService(new GenreBasedRecommendationStrategy());\n    }\n\n    public static MusicStreamingSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new MusicStreamingSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void RegisterUser(User user)\n    {\n        users[user.GetId()] = user;\n    }\n\n    public Song AddSong(string id, string title, string artistId, int duration)\n    {\n        Song song = new Song(id, title, artists[artistId], duration);\n        songs[song.GetId()] = song;\n        return song;\n    }\n\n    public void AddArtist(Artist artist)\n    {\n        artists[artist.GetId()] = artist;\n    }\n\n    public List<Song> SearchSongsByTitle(string title)\n    {\n        return searchService.SearchSongsByTitle(songs.Values.ToList(), title);\n    }\n\n    public List<Song> GetSongRecommendations()\n    {\n        return recommendationService.GenerateRecommendations(songs.Values.ToList());\n    }\n\n    public Player GetPlayer() => player;\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Observer/IArtistObserver.cs",
    "content": "interface IArtistObserver\n{\n    void Update(Artist artist, Album newAlbum);\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Observer/Subject.cs",
    "content": "abstract class Subject\n{\n    private readonly List<IArtistObserver> observers = new List<IArtistObserver>();\n\n    public void AddObserver(IArtistObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IArtistObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers(Artist artist, Album album)\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(artist, album);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/README.md",
    "content": "# Designing an Online Music Streaming Service Like Spotify\n\n## Requirements\n1. The music streaming service should allow users to browse and search for songs, albums, and artists.\n2. Users should be able to create and manage playlists.\n3. The system should support user authentication and authorization.\n4. Users should be able to play, pause, skip, and seek within songs.\n5. The system should recommend songs and playlists based on user preferences and listening history.\n6. The system should handle concurrent requests and ensure smooth streaming experience for multiple users.\n7. The system should be scalable and handle a large volume of songs and users.\n8. The system should be extensible to support additional features such as social sharing and offline playback.\n\n## Classes, Interfaces and Enumerations\n1. The **Song**, **Album**, and **Artist** classes represent the basic entities in the music streaming service, with properties such as ID, title, artist, album, duration, and relationships between them.\n2. The **User** class represents a user of the music streaming service, with properties like ID, username, password, and a list of playlists.\n3. The **Playlist** class represents a user-created playlist, containing a list of songs.\n4. The **MusicLibrary** class serves as a central repository for storing and managing songs, albums, and artists. It follows the Singleton pattern to ensure a single instance of the music library.\n5. The **UserManager** class handles user registration, login, and other user-related operations. It also follows the Singleton pattern.\n6. The **MusicPlayer** class represents the music playback functionality, allowing users to play, pause, skip, and seek within songs.\n7. The **MusicRecommender** class generates song recommendations based on user preferences and listening history. It follows the Singleton pattern.\n8. The **MusicStreamingService** class is the main entry point of the music streaming service. It initializes the necessary components, handles user requests, and manages the overall functionality of the service."
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Services/RecommendationService.cs",
    "content": "class RecommendationService\n{\n    private RecommendationStrategy strategy;\n\n    public RecommendationService(RecommendationStrategy strategy)\n    {\n        this.strategy = strategy;\n    }\n\n    public void SetStrategy(RecommendationStrategy strategy)\n    {\n        this.strategy = strategy;\n    }\n\n    public List<Song> GenerateRecommendations(List<Song> allSongs)\n    {\n        return strategy.Recommend(allSongs);\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Services/SearchService.cs",
    "content": "class SearchService\n{\n    public List<Song> SearchSongsByTitle(List<Song> songs, string query)\n    {\n        return songs.Where(s => s.GetTitle().ToLower().Contains(query.ToLower())).ToList();\n    }\n\n    public List<Artist> SearchArtistsByName(List<Artist> artists, string query)\n    {\n        return artists.Where(a => a.GetName().ToLower().Contains(query.ToLower())).ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/States/PausedState.cs",
    "content": "class PausedState : PlayerState\n{\n    public override void Play(Player player)\n    {\n        Console.WriteLine(\"Resuming playback.\");\n        player.ChangeState(new PlayingState());\n        player.SetStatus(PlayerStatus.PLAYING);\n    }\n\n    public override void Pause(Player player)\n    {\n        Console.WriteLine(\"Already paused.\");\n    }\n\n    public override void Stop(Player player)\n    {\n        Console.WriteLine(\"Stopping playback from paused state.\");\n        player.ChangeState(new StoppedState());\n        player.SetStatus(PlayerStatus.STOPPED);\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/States/PlayerState.cs",
    "content": "abstract class PlayerState\n{\n    public abstract void Play(Player player);\n    public abstract void Pause(Player player);\n    public abstract void Stop(Player player);\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/States/PlayingState.cs",
    "content": "class PlayingState : PlayerState\n{\n    public override void Play(Player player)\n    {\n        Console.WriteLine(\"Already playing.\");\n    }\n\n    public override void Pause(Player player)\n    {\n        Console.WriteLine(\"Pausing playback.\");\n        player.ChangeState(new PausedState());\n        player.SetStatus(PlayerStatus.PAUSED);\n    }\n\n    public override void Stop(Player player)\n    {\n        Console.WriteLine(\"Stopping playback.\");\n        player.ChangeState(new StoppedState());\n        player.SetStatus(PlayerStatus.STOPPED);\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/States/StoppedState.cs",
    "content": "class StoppedState : PlayerState\n{\n    public override void Play(Player player)\n    {\n        if (player.HasQueue())\n        {\n            Console.WriteLine(\"Starting playback.\");\n            player.ChangeState(new PlayingState());\n            player.SetStatus(PlayerStatus.PLAYING);\n            player.PlayCurrentSongInQueue();\n        }\n        else\n        {\n            Console.WriteLine(\"Queue is empty. Load songs to play.\");\n        }\n    }\n\n    public override void Pause(Player player)\n    {\n        Console.WriteLine(\"Cannot pause. Player is stopped.\");\n    }\n\n    public override void Stop(Player player)\n    {\n        Console.WriteLine(\"Already stopped.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Strategies/Playback/FreePlaybackStrategy.cs",
    "content": "class FreePlaybackStrategy : PlaybackStrategy\n{\n    private int songsPlayed;\n    private const int SONGS_BEFORE_AD = 3;\n\n    public FreePlaybackStrategy(int initialSongsPlayed)\n    {\n        this.songsPlayed = initialSongsPlayed;\n    }\n\n    public override void Play(Song song, Player player)\n    {\n        if (songsPlayed > 0 && songsPlayed % SONGS_BEFORE_AD == 0)\n        {\n            Console.WriteLine(\"\\n>>> Playing Advertisement: 'Buy Spotify Premium for ad-free music!' <<<\\n\");\n        }\n        player.SetCurrentSong(song);\n        Console.WriteLine($\"Free User is now playing: {song}\");\n        songsPlayed++;\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Strategies/Playback/PlaybackStrategy.cs",
    "content": "abstract class PlaybackStrategy\n{\n    public abstract void Play(Song song, Player player);\n\n    public static PlaybackStrategy GetStrategy(SubscriptionTier tier, int songsPlayed)\n    {\n        if (tier == SubscriptionTier.PREMIUM)\n        {\n            return new PremiumPlaybackStrategy();\n        }\n        else\n        {\n            return new FreePlaybackStrategy(songsPlayed);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Strategies/Playback/PremiumPlaybackStrategy.cs",
    "content": "class PremiumPlaybackStrategy : PlaybackStrategy\n{\n    public override void Play(Song song, Player player)\n    {\n        player.SetCurrentSong(song);\n        Console.WriteLine($\"Premium User is now playing: {song}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Strategies/Recommendation/GenreBasedRecommendationStrategy.cs",
    "content": "class GenreBasedRecommendationStrategy : RecommendationStrategy\n{\n    public override List<Song> Recommend(List<Song> allSongs)\n    {\n        Console.WriteLine(\"Generating genre-based recommendations (simulated)...\");\n        var shuffled = new List<Song>(allSongs);\n        var random = new Random();\n        for (int i = shuffled.Count - 1; i > 0; i--)\n        {\n            int j = random.Next(i + 1);\n            var temp = shuffled[i];\n            shuffled[i] = shuffled[j];\n            shuffled[j] = temp;\n        }\n        return shuffled.Take(Math.Min(5, shuffled.Count)).ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/Strategies/Recommendation/RecommendationStrategy.cs",
    "content": "abstract class RecommendationStrategy\n{\n    public abstract List<Song> Recommend(List<Song> allSongs);\n}"
  },
  {
    "path": "solutions/csharp/musicstreamingservice/musicstreamingservice.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs",
    "content": "// <autogenerated />\r\nusing System;\r\nusing System.Reflection;\r\n[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(\".NETCoreApp,Version=v8.0\", FrameworkDisplayName = \".NET 8.0\")]\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.AssemblyInfo.cs",
    "content": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nusing System;\nusing System.Reflection;\n\n[assembly: System.Reflection.AssemblyCompanyAttribute(\"c#\")]\n[assembly: System.Reflection.AssemblyConfigurationAttribute(\"Debug\")]\n[assembly: System.Reflection.AssemblyFileVersionAttribute(\"1.0.0.0\")]\n[assembly: System.Reflection.AssemblyInformationalVersionAttribute(\"1.0.0+1379ab56cefd982c99776878aa6ef1d39bbc7b22\")]\n[assembly: System.Reflection.AssemblyProductAttribute(\"c#\")]\n[assembly: System.Reflection.AssemblyTitleAttribute(\"c#\")]\n[assembly: System.Reflection.AssemblyVersionAttribute(\"1.0.0.0\")]\n\n// Generated by the MSBuild WriteCodeFragment class.\n\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.AssemblyInfoInputs.cache",
    "content": "25fb3ba4eeb06496c566fa0153595600436e9ec4373e73b31184698121ae05ae\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.GeneratedMSBuildEditorConfig.editorconfig",
    "content": "is_global = true\nbuild_property.TargetFramework = net8.0\nbuild_property.TargetPlatformMinVersion = \nbuild_property.UsingMicrosoftNETSdkWeb = \nbuild_property.ProjectTypeGuids = \nbuild_property.InvariantGlobalization = \nbuild_property.PlatformNeutralAssembly = \nbuild_property.EnforceExtendedAnalyzerRules = \nbuild_property._SupportedPlatformList = Linux,macOS,Windows\nbuild_property.RootNamespace = c_\nbuild_property.ProjectDir = /Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/\nbuild_property.EnableComHosting = \nbuild_property.EnableGeneratedComInterfaceComImportInterop = \n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.GlobalUsings.g.cs",
    "content": "// <auto-generated/>\nglobal using global::System;\nglobal using global::System.Collections.Generic;\nglobal using global::System.IO;\nglobal using global::System.Linq;\nglobal using global::System.Net.Http;\nglobal using global::System.Threading;\nglobal using global::System.Threading.Tasks;\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.csproj.CoreCompileInputs.cache",
    "content": "3c047aad63a937978d53f58242d12a232581b441bab25fd4fd674ff3245acf0e\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.csproj.FileListAbsolute.txt",
    "content": "/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/bin/Debug/net8.0/c#\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/bin/Debug/net8.0/c#.deps.json\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/bin/Debug/net8.0/c#.runtimeconfig.json\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/bin/Debug/net8.0/c#.dll\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/bin/Debug/net8.0/c#.pdb\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.GeneratedMSBuildEditorConfig.editorconfig\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.AssemblyInfoInputs.cache\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.AssemblyInfo.cs\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.csproj.CoreCompileInputs.cache\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.sourcelink.json\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.dll\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/refint/c#.dll\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.pdb\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/c#.genruntimeconfig.cache\n/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/Debug/net8.0/ref/c#.dll\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.genruntimeconfig.cache",
    "content": "7b28f71545fc472760ef5d7fcd67cc395e8399231e52d61e9317f967eeadb7ab\n"
  },
  {
    "path": "solutions/csharp/obj/Debug/net8.0/c#.sourcelink.json",
    "content": "{\"documents\":{\"/Users/ashishps/Documents/Github/awesome-low-level-design/*\":\"https://raw.githubusercontent.com/ashishps1/awesome-low-level-design/670a8c96828227383eaee93e411465d985a546d0/*\"}}"
  },
  {
    "path": "solutions/csharp/obj/c#.csproj.nuget.dgspec.json",
    "content": "{\n  \"format\": 1,\n  \"restore\": {\n    \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\": {}\n  },\n  \"projects\": {\n    \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\": {\n      \"version\": \"1.0.0\",\n      \"restore\": {\n        \"projectUniqueName\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\",\n        \"projectName\": \"c#\",\n        \"projectPath\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\",\n        \"packagesPath\": \"/Users/ashishps/.nuget/packages/\",\n        \"outputPath\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/\",\n        \"projectStyle\": \"PackageReference\",\n        \"configFilePaths\": [\n          \"/Users/ashishps/.nuget/NuGet/NuGet.Config\"\n        ],\n        \"originalTargetFrameworks\": [\n          \"net8.0\"\n        ],\n        \"sources\": {\n          \"https://api.nuget.org/v3/index.json\": {}\n        },\n        \"frameworks\": {\n          \"net8.0\": {\n            \"targetAlias\": \"net8.0\",\n            \"projectReferences\": {}\n          }\n        },\n        \"warningProperties\": {\n          \"warnAsError\": [\n            \"NU1605\"\n          ]\n        },\n        \"restoreAuditProperties\": {\n          \"enableAudit\": \"true\",\n          \"auditLevel\": \"low\",\n          \"auditMode\": \"direct\"\n        }\n      },\n      \"frameworks\": {\n        \"net8.0\": {\n          \"targetAlias\": \"net8.0\",\n          \"imports\": [\n            \"net461\",\n            \"net462\",\n            \"net47\",\n            \"net471\",\n            \"net472\",\n            \"net48\",\n            \"net481\"\n          ],\n          \"assetTargetFallback\": true,\n          \"warn\": true,\n          \"frameworkReferences\": {\n            \"Microsoft.NETCore.App\": {\n              \"privateAssets\": \"all\"\n            }\n          },\n          \"runtimeIdentifierGraphPath\": \"/usr/local/share/dotnet/sdk/8.0.403/PortableRuntimeIdentifierGraph.json\"\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "solutions/csharp/obj/c#.csproj.nuget.g.props",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<Project ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup Condition=\" '$(ExcludeRestorePackageImports)' != 'true' \">\n    <RestoreSuccess Condition=\" '$(RestoreSuccess)' == '' \">True</RestoreSuccess>\n    <RestoreTool Condition=\" '$(RestoreTool)' == '' \">NuGet</RestoreTool>\n    <ProjectAssetsFile Condition=\" '$(ProjectAssetsFile)' == '' \">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>\n    <NuGetPackageRoot Condition=\" '$(NuGetPackageRoot)' == '' \">/Users/ashishps/.nuget/packages/</NuGetPackageRoot>\n    <NuGetPackageFolders Condition=\" '$(NuGetPackageFolders)' == '' \">/Users/ashishps/.nuget/packages/</NuGetPackageFolders>\n    <NuGetProjectStyle Condition=\" '$(NuGetProjectStyle)' == '' \">PackageReference</NuGetProjectStyle>\n    <NuGetToolVersion Condition=\" '$(NuGetToolVersion)' == '' \">6.11.1</NuGetToolVersion>\n  </PropertyGroup>\n  <ItemGroup Condition=\" '$(ExcludeRestorePackageImports)' != 'true' \">\n    <SourceRoot Include=\"/Users/ashishps/.nuget/packages/\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "solutions/csharp/obj/c#.csproj.nuget.g.targets",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<Project ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" />"
  },
  {
    "path": "solutions/csharp/obj/project.assets.json",
    "content": "{\n  \"version\": 3,\n  \"targets\": {\n    \"net8.0\": {}\n  },\n  \"libraries\": {},\n  \"projectFileDependencyGroups\": {\n    \"net8.0\": []\n  },\n  \"packageFolders\": {\n    \"/Users/ashishps/.nuget/packages/\": {}\n  },\n  \"project\": {\n    \"version\": \"1.0.0\",\n    \"restore\": {\n      \"projectUniqueName\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\",\n      \"projectName\": \"c#\",\n      \"projectPath\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\",\n      \"packagesPath\": \"/Users/ashishps/.nuget/packages/\",\n      \"outputPath\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/obj/\",\n      \"projectStyle\": \"PackageReference\",\n      \"configFilePaths\": [\n        \"/Users/ashishps/.nuget/NuGet/NuGet.Config\"\n      ],\n      \"originalTargetFrameworks\": [\n        \"net8.0\"\n      ],\n      \"sources\": {\n        \"https://api.nuget.org/v3/index.json\": {}\n      },\n      \"frameworks\": {\n        \"net8.0\": {\n          \"targetAlias\": \"net8.0\",\n          \"projectReferences\": {}\n        }\n      },\n      \"warningProperties\": {\n        \"warnAsError\": [\n          \"NU1605\"\n        ]\n      },\n      \"restoreAuditProperties\": {\n        \"enableAudit\": \"true\",\n        \"auditLevel\": \"low\",\n        \"auditMode\": \"direct\"\n      }\n    },\n    \"frameworks\": {\n      \"net8.0\": {\n        \"targetAlias\": \"net8.0\",\n        \"imports\": [\n          \"net461\",\n          \"net462\",\n          \"net47\",\n          \"net471\",\n          \"net472\",\n          \"net48\",\n          \"net481\"\n        ],\n        \"assetTargetFallback\": true,\n        \"warn\": true,\n        \"frameworkReferences\": {\n          \"Microsoft.NETCore.App\": {\n            \"privateAssets\": \"all\"\n          }\n        },\n        \"runtimeIdentifierGraphPath\": \"/usr/local/share/dotnet/sdk/8.0.403/PortableRuntimeIdentifierGraph.json\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "solutions/csharp/obj/project.nuget.cache",
    "content": "{\n  \"version\": 2,\n  \"dgSpecHash\": \"E8dOOPle2Ps=\",\n  \"success\": true,\n  \"projectFilePath\": \"/Users/ashishps/Documents/Github/awesome-low-level-design/solutions/c#/c#.csproj\",\n  \"expectedPackageFiles\": [],\n  \"logs\": []\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/AuctionService.cs",
    "content": "using System.Collections.Concurrent;\n\nclass AuctionService\n{\n    private static AuctionService instance;\n    private static readonly object lockObject = new object();\n    private readonly ConcurrentDictionary<string, User> users;\n    private readonly ConcurrentDictionary<string, Auction> auctions;\n    private readonly List<Task> scheduledTasks;\n    private bool shutdown;\n\n    private AuctionService()\n    {\n        users = new ConcurrentDictionary<string, User>();\n        auctions = new ConcurrentDictionary<string, Auction>();\n        scheduledTasks = new List<Task>();\n        shutdown = false;\n    }\n\n    public static AuctionService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new AuctionService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public User CreateUser(string name)\n    {\n        User user = new User(name);\n        users.TryAdd(user.GetId(), user);\n        return user;\n    }\n\n    public User GetUser(string userId)\n    {\n        users.TryGetValue(userId, out User user);\n        return user;\n    }\n\n    public Auction CreateAuction(string itemName, string description, decimal startingPrice, DateTime endTime)\n    {\n        Auction auction = new Auction(itemName, description, startingPrice, endTime);\n        auctions.TryAdd(auction.GetId(), auction);\n\n        TimeSpan delay = endTime - DateTime.Now;\n        if (delay.TotalMilliseconds > 0)\n        {\n            Task scheduledTask = Task.Run(async () =>\n            {\n                await Task.Delay(delay);\n                if (!shutdown)\n                {\n                    EndAuction(auction.GetId());\n                }\n            });\n            scheduledTasks.Add(scheduledTask);\n        }\n\n        Console.WriteLine($\"New auction created for '{itemName}' (ID: {auction.GetId()}), ending at {endTime}.\");\n        return auction;\n    }\n\n    public List<Auction> ViewActiveAuctions()\n    {\n        return auctions.Values.Where(auction => auction.IsActive()).ToList();\n    }\n\n    public void PlaceBid(string auctionId, string bidderId, decimal amount)\n    {\n        Auction auction = GetAuction(auctionId);\n        auction.PlaceBid(users[bidderId], amount);\n    }\n\n    public void EndAuction(string auctionId)\n    {\n        Auction auction = GetAuction(auctionId);\n        auction.EndAuction();\n    }\n\n    public Auction GetAuction(string auctionId)\n    {\n        if (!auctions.TryGetValue(auctionId, out Auction auction))\n        {\n            throw new KeyNotFoundException($\"Auction with ID {auctionId} not found.\");\n        }\n        return auction;\n    }\n\n    public void Shutdown()\n    {\n        shutdown = true;\n        Task.WaitAll(scheduledTasks.ToArray());\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/AuctionSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic class AuctionSystemDemo\n{\n    public static void Main(string[] args)\n    {\n        AuctionService auctionService = AuctionService.GetInstance();\n\n        User alice = auctionService.CreateUser(\"Alice\");\n        User bob = auctionService.CreateUser(\"Bob\");\n        User carol = auctionService.CreateUser(\"Carol\");\n\n        Console.WriteLine(\"=============================================\");\n        Console.WriteLine(\"        Online Auction System Demo           \");\n        Console.WriteLine(\"=============================================\");\n\n        DateTime endTime = DateTime.Now.AddSeconds(10);\n        Auction laptopAuction = auctionService.CreateAuction(\n            \"Vintage Laptop\",\n            \"A rare 1990s laptop, in working condition.\",\n            100.00m,\n            endTime\n        );\n        Console.WriteLine();\n\n        try\n        {\n            auctionService.PlaceBid(laptopAuction.GetId(), alice.GetId(), 110.00m);\n            Thread.Sleep(500);\n\n            auctionService.PlaceBid(laptopAuction.GetId(), bob.GetId(), 120.00m);\n            Thread.Sleep(500);\n\n            auctionService.PlaceBid(laptopAuction.GetId(), carol.GetId(), 125.00m);\n            Thread.Sleep(500);\n\n            auctionService.PlaceBid(laptopAuction.GetId(), alice.GetId(), 150.00m);\n\n            Console.WriteLine(\"\\n--- Waiting for auction to end automatically... ---\");\n            Thread.Sleep(2000);\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"An error occurred during bidding: {e.Message}\");\n        }\n\n        Console.WriteLine(\"\\n--- Post-Auction Information ---\");\n        Auction endedAuction = auctionService.GetAuction(laptopAuction.GetId());\n\n        if (endedAuction.GetWinningBid() != null)\n        {\n            Console.WriteLine($\"Final Winner: {endedAuction.GetWinningBid().GetBidder().GetName()}\");\n            Console.WriteLine($\"Winning Price: ${endedAuction.GetWinningBid().GetAmount():F2}\");\n        }\n        else\n        {\n            Console.WriteLine(\"The auction ended with no winner.\");\n        }\n\n        Console.WriteLine(\"\\nFull Bid History:\");\n        foreach (Bid bid in endedAuction.GetBidHistory())\n        {\n            Console.WriteLine(bid.ToString());\n        }\n\n        Console.WriteLine(\"\\n--- Attempting to bid on an ended auction ---\");\n        try\n        {\n            auctionService.PlaceBid(laptopAuction.GetId(), bob.GetId(), 200.00m);\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"CAUGHT EXPECTED ERROR: {e.Message}\");\n        }\n\n        auctionService.Shutdown();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/Enum/AuctionState.cs",
    "content": "enum AuctionState\n{\n    PENDING,\n    ACTIVE,\n    CLOSED\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/Models/Auction.cs",
    "content": "class Auction\n{\n    private readonly string id;\n    private readonly string itemName;\n    private readonly string description;\n    private readonly decimal startingPrice;\n    private readonly DateTime endTime;\n    private readonly List<Bid> bids;\n    private readonly HashSet<IAuctionObserver> observers;\n    private AuctionState state;\n    private Bid winningBid;\n    private readonly object lockObject = new object();\n\n    public Auction(string itemName, string description, decimal startingPrice, DateTime endTime)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.itemName = itemName;\n        this.description = description;\n        this.startingPrice = startingPrice;\n        this.endTime = endTime;\n        this.bids = new List<Bid>();\n        this.observers = new HashSet<IAuctionObserver>();\n        this.state = AuctionState.ACTIVE;\n    }\n\n    public void PlaceBid(User bidder, decimal amount)\n    {\n        lock (lockObject)\n        {\n            if (state != AuctionState.ACTIVE)\n            {\n                throw new InvalidOperationException(\"Auction is not active.\");\n            }\n            if (DateTime.Now > endTime)\n            {\n                EndAuction();\n                throw new InvalidOperationException(\"Auction has already ended.\");\n            }\n\n            Bid highestBid = GetHighestBid();\n            decimal currentMaxAmount = (highestBid == null) ? startingPrice : highestBid.GetAmount();\n\n            if (amount <= currentMaxAmount)\n            {\n                throw new ArgumentException(\"Bid must be higher than the current highest bid.\");\n            }\n\n            User previousHighestBidder = (highestBid != null) ? highestBid.GetBidder() : null;\n\n            Bid newBid = new Bid(bidder, amount);\n            bids.Add(newBid);\n            AddObserver(bidder);\n\n            Console.WriteLine($\"SUCCESS: {bidder.GetName()} placed a bid of ${amount:F2} on '{itemName}'.\");\n\n            if (previousHighestBidder != null && !previousHighestBidder.Equals(bidder))\n            {\n                NotifyObserver(previousHighestBidder, $\"You have been outbid on '{itemName}'! The new highest bid is ${amount:F2}.\");\n            }\n        }\n    }\n\n    public void EndAuction()\n    {\n        lock (lockObject)\n        {\n            if (state != AuctionState.ACTIVE)\n            {\n                return;\n            }\n\n            state = AuctionState.CLOSED;\n            winningBid = GetHighestBid();\n\n            string endMessage;\n            if (winningBid != null)\n            {\n                endMessage = $\"Auction for '{itemName}' has ended. Winner is {winningBid.GetBidder().GetName()} with a bid of ${winningBid.GetAmount():F2}!\";\n            }\n            else\n            {\n                endMessage = $\"Auction for '{itemName}' has ended. There were no bids.\";\n            }\n\n            Console.WriteLine($\"\\n{endMessage.ToUpper()}\");\n            NotifyAllObservers(endMessage);\n        }\n    }\n\n    public Bid GetHighestBid()\n    {\n        if (bids.Count == 0)\n        {\n            return null;\n        }\n        return bids.Max();\n    }\n\n    public bool IsActive()\n    {\n        return state == AuctionState.ACTIVE;\n    }\n\n    private void AddObserver(IAuctionObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    private void NotifyAllObservers(string message)\n    {\n        foreach (IAuctionObserver observer in observers)\n        {\n            observer.OnUpdate(this, message);\n        }\n    }\n\n    private void NotifyObserver(IAuctionObserver observer, string message)\n    {\n        observer.OnUpdate(this, message);\n    }\n\n    public string GetId() { return id; }\n    public string GetItemName() { return itemName; }\n    public List<Bid> GetBidHistory() { return new List<Bid>(bids); }\n    public AuctionState GetState() { return state; }\n    public Bid GetWinningBid() { return winningBid; }\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/Models/Bid.cs",
    "content": "class Bid : IComparable<Bid>\n{\n    private readonly User bidder;\n    private readonly decimal amount;\n    private readonly DateTime timestamp;\n\n    public Bid(User bidder, decimal amount)\n    {\n        this.bidder = bidder;\n        this.amount = amount;\n        this.timestamp = DateTime.Now;\n    }\n\n    public User GetBidder()\n    {\n        return bidder;\n    }\n\n    public decimal GetAmount()\n    {\n        return amount;\n    }\n\n    public DateTime GetTimestamp()\n    {\n        return timestamp;\n    }\n\n    public int CompareTo(Bid other)\n    {\n        int amountComparison = amount.CompareTo(other.amount);\n        if (amountComparison != 0)\n        {\n            return amountComparison;\n        }\n        return other.timestamp.CompareTo(timestamp);\n    }\n\n    public override string ToString()\n    {\n        return $\"Bidder: {bidder.GetName()}, Amount: {amount:F2}, Time: {timestamp}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/Models/User.cs",
    "content": "class User : IAuctionObserver\n{\n    private readonly string id;\n    private readonly string name;\n\n    public User(string name)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n    }\n\n    public string GetId()\n    {\n        return id;\n    }\n\n    public string GetName()\n    {\n        return name;\n    }\n\n    public void OnUpdate(Auction auction, string message)\n    {\n        Console.WriteLine($\"--- Notification for {name} ---\");\n        Console.WriteLine($\"Auction: {auction.GetItemName()}\");\n        Console.WriteLine($\"Message: {message}\");\n        Console.WriteLine(\"---------------------------\\n\");\n    }\n\n    public override bool Equals(object obj)\n    {\n        if (this == obj) return true;\n        if (obj == null || GetType() != obj.GetType()) return false;\n        User user = (User)obj;\n        return id.Equals(user.id);\n    }\n\n    public override int GetHashCode()\n    {\n        return id.GetHashCode();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/Observer/IAuctionObserver.cs",
    "content": "interface IAuctionObserver\n{\n    void OnUpdate(Auction auction, string message);\n}"
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/README.md",
    "content": "# Designing an Online Auction System\nIn this article, we delve into the object-oriented design and implementation of an Online Auction System using Java. \n\nThis system allows for the creation and management of auctions, user participation in bidding, and handling transactions.\n\n## Requirements\n1. The online auction system should allow users to register and log in to their accounts.\n2. Users should be able to create new auction listings with details such as item name, description, starting price, and auction duration.\n3. Users should be able to browse and search for auction listings based on various criteria (e.g., item name, category, price range).\n4. Users should be able to place bids on active auction listings.\n5. The system should automatically update the current highest bid and notify the bidders accordingly.\n6. The auction should end when the specified duration is reached, and the highest bidder should be declared the winner.\n7. The system should handle concurrent access to auction listings and ensure data consistency.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online auction system, with properties such as id, username, and email.\n2. The **AuctionStatus** enum defines the possible states of an auction listing, such as active and closed.\n3. The **AuctionListing** class represents an auction listing in the system, with properties like id, item name, description, starting price, duration, seller, current highest bid, and a list of bids.\n4. The **Bid** class represents a bid placed by a user on an auction listing, with properties such as id, bidder, amount, and timestamp.\n5. The **AuctionSystem** class is the core of the online auction system and follows the Singleton pattern to ensure a single instance of the auction system.\n6. The AuctionSystem class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to auction listings and ensure thread safety.\n7. The AuctionSystem class provides methods for registering users, creating auction listings, searching auction listings, and placing bids.\n8. The **AuctionSystemDemo** class serves as the entry point of the application and demonstrates the usage of the online auction system."
  },
  {
    "path": "solutions/csharp/onlineauctionsystem/onlineauctionsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Decorators/GiftWrapDecorator.cs",
    "content": "class GiftWrapDecorator : ProductDecorator\n{\n    private const double GIFT_WRAP_COST = 5.00;\n\n    public GiftWrapDecorator(Product product) : base(product) { }\n\n    public override double GetPrice()\n    {\n        return base.GetPrice() + GIFT_WRAP_COST;\n    }\n\n    public override string GetDescription()\n    {\n        return base.GetDescription() + \" (Gift Wrapped)\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Decorators/ProductDecorator.cs",
    "content": "abstract class ProductDecorator : Product\n{\n    protected Product decoratedProduct;\n\n    public ProductDecorator(Product product)\n    {\n        decoratedProduct = product;\n    }\n\n    public override string GetId() { return decoratedProduct.GetId(); }\n    public override string GetName() { return decoratedProduct.GetName(); }\n    public override double GetPrice() { return decoratedProduct.GetPrice(); }\n    public override string GetDescription() { return decoratedProduct.GetDescription(); }\n    public override ProductCategory GetCategory() { return decoratedProduct.GetCategory(); }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Enums/OrderStatus.cs",
    "content": "enum OrderStatus\n{\n    PENDING_PAYMENT,\n    PLACED,\n    SHIPPED,\n    DELIVERED,\n    CANCELLED,\n    RETURNED\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Enums/ProductCategory.cs",
    "content": "enum ProductCategory\n{\n    ELECTRONICS,\n    BOOKS,\n    CLOTHING,\n    HOME_GOODS,\n    GROCERY\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Exceptions/OutOfStockException.cs",
    "content": "class OutOfStockException : Exception\n{\n    public OutOfStockException(string message) : base(message) { }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/Account.cs",
    "content": "class Account\n{\n    private readonly string username;\n    private readonly string password;\n    private readonly ShoppingCart cart;\n\n    public Account(string username, string password)\n    {\n        this.username = username;\n        this.password = password;\n        this.cart = new ShoppingCart();\n    }\n\n    public ShoppingCart GetCart() { return cart; }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/Address.cs",
    "content": "class Address\n{\n    private readonly string street;\n    private readonly string city;\n    private readonly string state;\n    private readonly string zipCode;\n\n    public Address(string street, string city, string state, string zipCode)\n    {\n        this.street = street;\n        this.city = city;\n        this.state = state;\n        this.zipCode = zipCode;\n    }\n\n    public override string ToString()\n    {\n        return $\"{street}, {city}, {state} {zipCode}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/CartItem.cs",
    "content": "class CartItem\n{\n    private readonly Product product;\n    private int quantity;\n\n    public CartItem(Product product, int quantity)\n    {\n        this.product = product;\n        this.quantity = quantity;\n    }\n\n    public Product GetProduct() { return product; }\n    public int GetQuantity() { return quantity; }\n    public void IncrementQuantity(int amount) { quantity += amount; }\n    public double GetPrice() { return product.GetPrice() * quantity; }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/Customer.cs",
    "content": "class Customer : IOrderObserver\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n    private readonly Account account;\n    private Address shippingAddress;\n\n    public Customer(string name, string email, string password, Address shippingAddress)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n        this.account = new Account(email, password);\n        this.shippingAddress = shippingAddress;\n    }\n\n    public void Update(Order order)\n    {\n        Console.WriteLine($\"[Notification for {name}]: Your order #{order.GetId()} status has been updated to: {order.GetStatus()}.\");\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public Account GetAccount() { return account; }\n    public Address GetShippingAddress() { return shippingAddress; }\n    public void SetShippingAddress(Address address) { shippingAddress = address; }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/Order.cs",
    "content": "class Order : Subject\n{\n    private readonly string id;\n    private readonly Customer customer;\n    private readonly List<OrderLineItem> items;\n    private readonly Address shippingAddress;\n    private readonly double totalAmount;\n    private readonly DateTime orderDate;\n    private OrderStatus status;\n    private IOrderState currentState;\n\n    public Order(Customer customer, List<OrderLineItem> items, Address shippingAddress, double totalAmount)\n    {\n        this.id = Guid.NewGuid().ToString().Substring(0, 8);\n        this.customer = customer;\n        this.items = items;\n        this.shippingAddress = shippingAddress;\n        this.totalAmount = totalAmount;\n        this.orderDate = DateTime.Now;\n        this.status = OrderStatus.PLACED;\n        this.currentState = new PlacedState();\n        AddObserver(customer);\n    }\n\n    public void ShipOrder() { currentState.Ship(this); }\n    public void DeliverOrder() { currentState.Deliver(this); }\n    public void CancelOrder() { currentState.Cancel(this); }\n\n    public string GetId() { return id; }\n    public OrderStatus GetStatus() { return status; }\n    public void SetState(IOrderState state) { currentState = state; }\n    public void SetStatus(OrderStatus status)\n    {\n        this.status = status;\n        NotifyObservers(this);\n    }\n    public List<OrderLineItem> GetItems() { return items; }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/OrderLineItem.cs",
    "content": "class OrderLineItem\n{\n    private readonly string productId;\n    private readonly string productName;\n    private readonly int quantity;\n    private readonly double priceAtPurchase;\n\n    public OrderLineItem(string productId, string productName, int quantity, double priceAtPurchase)\n    {\n        this.productId = productId;\n        this.productName = productName;\n        this.quantity = quantity;\n        this.priceAtPurchase = priceAtPurchase;\n    }\n\n    public string GetProductId() { return productId; }\n    public int GetQuantity() { return quantity; }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/Product.cs",
    "content": "abstract class Product\n{\n    protected string id;\n    protected string name;\n    protected string description;\n    protected double price;\n    protected ProductCategory category;\n\n    public abstract string GetId();\n    public abstract string GetName();\n    public abstract string GetDescription();\n    public abstract double GetPrice();\n    public abstract ProductCategory GetCategory();\n}\n\nclass BaseProduct : Product\n{\n    public BaseProduct(string id, string name, string description, double price, ProductCategory category)\n    {\n        this.id = id;\n        this.name = name;\n        this.description = description;\n        this.price = price;\n        this.category = category;\n    }\n\n    public override string GetId() { return id; }\n    public override string GetName() { return name; }\n    public override string GetDescription() { return description; }\n    public override double GetPrice() { return price; }\n    public override ProductCategory GetCategory() { return category; }\n}\n\nclass ProductBuilder\n{\n    private readonly string name;\n    private readonly double price;\n    private string description = \"\";\n    private ProductCategory category;\n\n    public ProductBuilder(string name, double price)\n    {\n        this.name = name;\n        this.price = price;\n    }\n\n    public ProductBuilder WithDescription(string description)\n    {\n        this.description = description;\n        return this;\n    }\n\n    public ProductBuilder WithCategory(ProductCategory category)\n    {\n        this.category = category;\n        return this;\n    }\n\n    public Product Build()\n    {\n        return new BaseProduct(Guid.NewGuid().ToString(), name, description, price, category);\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Models/ShoppingCart.cs",
    "content": "class ShoppingCart\n{\n    private readonly Dictionary<string, CartItem> items = new Dictionary<string, CartItem>();\n\n    public void AddItem(Product product, int quantity)\n    {\n        if (items.ContainsKey(product.GetId()))\n        {\n            items[product.GetId()].IncrementQuantity(quantity);\n        }\n        else\n        {\n            items[product.GetId()] = new CartItem(product, quantity);\n        }\n    }\n\n    public void RemoveItem(string productId)\n    {\n        items.Remove(productId);\n    }\n\n    public Dictionary<string, CartItem> GetItems()\n    {\n        return new Dictionary<string, CartItem>(items);\n    }\n\n    public double CalculateTotal()\n    {\n        return items.Values.Sum(item => item.GetPrice());\n    }\n\n    public void ClearCart()\n    {\n        items.Clear();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Observer/IOrderObserver.cs",
    "content": "interface IOrderObserver\n{\n    void Update(Order order);\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Observer/Subject.cs",
    "content": "abstract class Subject\n{\n    private readonly List<IOrderObserver> observers = new List<IOrderObserver>();\n\n    public void AddObserver(IOrderObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IOrderObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers(Order order)\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(order);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/OnlineShoppingDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class OnlineShoppingDemo\n{\n    public static void Main()\n    {\n        // System Setup (Singleton and Services)\n        var system = OnlineShoppingSystem.GetInstance();\n\n        // Create and Add Products to Catalog (Builder Pattern)\n        var laptop = new ProductBuilder(\"Dell XPS 15\", 1499.99)\n            .WithDescription(\"A powerful and sleek laptop.\")\n            .WithCategory(ProductCategory.ELECTRONICS)\n            .Build();\n\n        var book = new ProductBuilder(\"The Pragmatic Programmer\", 45.50)\n            .WithDescription(\"A classic book for software developers.\")\n            .WithCategory(ProductCategory.BOOKS)\n            .Build();\n\n        system.AddProduct(laptop, 10); // 10 laptops in stock\n        system.AddProduct(book, 50);   // 50 books in stock\n\n        // Register a Customer\n        var aliceAddress = new Address(\"123 Main St\", \"Anytown\", \"CA\", \"12345\");\n        var alice = system.RegisterCustomer(\"Alice\", \"alice@example.com\", \"password123\", aliceAddress);\n\n        // Alice Shops\n        Console.WriteLine(\"--- Alice starts shopping ---\");\n\n        // Alice adds a laptop to her cart\n        system.AddToCart(alice.GetId(), laptop.GetId(), 1);\n        Console.WriteLine(\"Alice added a laptop to her cart.\");\n\n        // Alice decides to gift-wrap the book (Decorator Pattern)\n        var giftWrappedBook = new GiftWrapDecorator(book);\n        system.AddToCart(alice.GetId(), giftWrappedBook.GetId(), 1);\n        Console.WriteLine($\"Alice added a gift-wrapped book. Original price: ${book.GetPrice():F2}, New price: ${giftWrappedBook.GetPrice():F2}\");\n\n        var aliceCart = system.GetCustomerCart(alice.GetId());\n        Console.WriteLine($\"Alice's cart total: ${aliceCart.CalculateTotal():F2}\");\n\n        // Alice Checks Out\n        Console.WriteLine(\"\\n--- Alice proceeds to checkout ---\");\n        var aliceOrder = system.PlaceOrder(alice.GetId(), new CreditCardPaymentStrategy(\"1234-5678-9876-5432\"));\n        if (aliceOrder == null)\n        {\n            Console.WriteLine(\"Order placement failed.\");\n            return;\n        }\n\n        Console.WriteLine($\"Order #{aliceOrder.GetId()} placed successfully for Alice.\");\n\n        // Order State and Notifications (State, Observer Patterns)\n        Console.WriteLine(\"\\n--- Order processing starts ---\");\n\n        // The warehouse ships the order\n        aliceOrder.ShipOrder(); // This will trigger a notification to Alice\n\n        // The delivery service marks the order as delivered\n        aliceOrder.DeliverOrder(); // This will also trigger a notification\n\n        // Try to cancel a delivered order (State pattern prevents this)\n        aliceOrder.CancelOrder();\n\n        Console.WriteLine(\"\\n--- Out of Stock Scenario ---\");\n        var bob = system.RegisterCustomer(\"Bob\", \"bob@example.com\", \"pass123\", aliceAddress);\n\n        // Bob tries to buy 15 laptops, but only 9 are left (1 was bought by Alice)\n        system.AddToCart(bob.GetId(), laptop.GetId(), 15);\n\n        var bobOrder = system.PlaceOrder(bob.GetId(), new UPIPaymentStrategy(\"testupi@hdfc\"));\n        if (bobOrder == null)\n        {\n            Console.WriteLine(\"Bob's order was correctly prevented due to insufficient stock.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/OnlineShoppingSystem.cs",
    "content": "class OnlineShoppingSystem\n{\n    private static volatile OnlineShoppingSystem instance;\n    private static readonly object syncRoot = new object();\n\n    private readonly Dictionary<string, Product> products = new Dictionary<string, Product>();\n    private readonly Dictionary<string, Customer> customers = new Dictionary<string, Customer>();\n    private readonly Dictionary<string, Order> orders = new Dictionary<string, Order>();\n\n    private readonly InventoryService inventoryService;\n    private readonly PaymentService paymentService;\n    private readonly OrderService orderService;\n    private readonly SearchService searchService;\n\n    private OnlineShoppingSystem()\n    {\n        inventoryService = new InventoryService();\n        paymentService = new PaymentService();\n        orderService = new OrderService(inventoryService);\n        searchService = new SearchService(products.Values);\n    }\n\n    public static OnlineShoppingSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (syncRoot)\n            {\n                if (instance == null)\n                {\n                    instance = new OnlineShoppingSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void AddProduct(Product product, int initialStock)\n    {\n        products[product.GetId()] = product;\n        inventoryService.AddStock(product, initialStock);\n    }\n\n    public Customer RegisterCustomer(string name, string email, string password, Address address)\n    {\n        var customer = new Customer(name, email, password, address);\n        customers[customer.GetId()] = customer;\n        return customer;\n    }\n\n    public void AddToCart(string customerId, string productId, int quantity)\n    {\n        var customer = customers[customerId];\n        var product = products[productId];\n        customer.GetAccount().GetCart().AddItem(product, quantity);\n    }\n\n    public ShoppingCart GetCustomerCart(string customerId)\n    {\n        var customer = customers[customerId];\n        return customer.GetAccount().GetCart();\n    }\n\n    public List<Product> SearchProducts(string name)\n    {\n        return searchService.SearchByName(name);\n    }\n\n    public Order PlaceOrder(string customerId, IPaymentStrategy paymentStrategy)\n    {\n        var customer = customers[customerId];\n        var cart = customer.GetAccount().GetCart();\n\n        if (!cart.GetItems().Any())\n        {\n            Console.WriteLine(\"Cannot place an order with an empty cart.\");\n            return null;\n        }\n\n        // 1. Process payment\n        bool paymentSuccess = paymentService.ProcessPayment(paymentStrategy, cart.CalculateTotal());\n        if (!paymentSuccess)\n        {\n            Console.WriteLine(\"Payment failed. Please try again.\");\n            return null;\n        }\n\n        // 2. Create order and update inventory\n        try\n        {\n            var order = orderService.CreateOrder(customer, cart);\n            orders[order.GetId()] = order;\n\n            // 3. Clear the cart\n            cart.ClearCart();\n\n            return order;\n        }\n        catch (Exception e)\n        {\n            Console.WriteLine($\"Order placement failed: {e.Message}\");\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/README.md",
    "content": "# Designing an Online Shopping System Like Amazon\n\n## Requirements\n1. The online shopping service should allow users to browse products, add them to the shopping cart, and place orders.\n2. The system should support multiple product categories and provide search functionality.\n3. Users should be able to manage their profiles, view order history, and track order status.\n4. The system should handle inventory management and update product availability accordingly.\n5. The system should support multiple payment methods and ensure secure transactions.\n6. The system should handle concurrent user requests and ensure data consistency.\n7. The system should be scalable to handle a large number of products and users.\n8. The system should provide a user-friendly interface for a seamless shopping experience.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online shopping service, with properties such as ID, name, email, password, and a list of orders.\n2. The **Product** class represents a product available for purchase, with properties like ID, name, description, price, and quantity. It provides methods to update the quantity and check product availability.\n3. The **Order** class represents an order placed by a user, containing properties such as ID, user, order items, total amount, and order status. It calculates the total amount based on the order items.\n4. The **OrderItem** class represents an item within an order, consisting of the product and the quantity ordered.\n5. The **OrderStatus** enum represents the different statuses an order can have, such as pending, processing, shipped, delivered, or cancelled.\n6. The **ShoppingCart** class represents the user's shopping cart, allowing them to add, remove, and update item quantities. It maintains a map of product IDs and order items.\n7. The **Payment** interface defines the contract for processing payments, with a concrete implementation CreditCardPayment.\n8. The **OnlineShoppingService** class is the central component of the online shopping service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register users, add products, search products, place orders, and retrieve order information. It handles concurrent access to shared resources using synchronization.\n9. The **OnlineShoppingServiceDemo** class demonstrates the usage of the online shopping service by registering users, adding products, searching for products, placing orders, and viewing order history."
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Services/InventoryService.cs",
    "content": "class InventoryService\n{\n    private readonly Dictionary<string, int> stock = new Dictionary<string, int>();\n    private readonly object lockObj = new object();\n\n    public void AddStock(Product product, int quantity)\n    {\n        lock (lockObj)\n        {\n            if (!stock.ContainsKey(product.GetId()))\n            {\n                stock[product.GetId()] = 0;\n            }\n            stock[product.GetId()] += quantity;\n        }\n    }\n\n    public void UpdateStockForOrder(List<OrderLineItem> items)\n    {\n        lock (lockObj)\n        {\n            // First, check if all items are in stock\n            foreach (var item in items)\n            {\n                if (!stock.ContainsKey(item.GetProductId()) || stock[item.GetProductId()] < item.GetQuantity())\n                {\n                    throw new OutOfStockException($\"Not enough stock for product ID: {item.GetProductId()}\");\n                }\n            }\n\n            // If all checks pass, deduct the stock\n            foreach (var item in items)\n            {\n                stock[item.GetProductId()] -= item.GetQuantity();\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Services/OrderService.cs",
    "content": "class OrderService\n{\n    private readonly InventoryService inventoryService;\n\n    public OrderService(InventoryService inventoryService)\n    {\n        this.inventoryService = inventoryService;\n    }\n\n    public Order CreateOrder(Customer customer, ShoppingCart cart)\n    {\n        var orderItems = cart.GetItems().Values\n            .Select(cartItem => new OrderLineItem(\n                cartItem.GetProduct().GetId(),\n                cartItem.GetProduct().GetName(),\n                cartItem.GetQuantity(),\n                cartItem.GetProduct().GetPrice()))\n            .ToList();\n\n        inventoryService.UpdateStockForOrder(orderItems);\n\n        return new Order(customer, orderItems, customer.GetShippingAddress(), cart.CalculateTotal());\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Services/PaymentService.cs",
    "content": "class PaymentService\n{\n    public bool ProcessPayment(IPaymentStrategy strategy, double amount)\n    {\n        return strategy.Pay(amount);\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Services/SearchService.cs",
    "content": "class SearchService\n{\n    private readonly ICollection<Product> productCatalog;\n\n    public SearchService(ICollection<Product> productCatalog)\n    {\n        this.productCatalog = productCatalog;\n    }\n\n    public List<Product> SearchByName(string name)\n    {\n        return productCatalog\n            .Where(p => p.GetName().ToLower().Contains(name.ToLower()))\n            .ToList();\n    }\n\n    public List<Product> SearchByCategory(ProductCategory category)\n    {\n        return productCatalog\n            .Where(p => p.GetCategory() == category)\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/States/CancelledState.cs",
    "content": "class CancelledState : IOrderState\n{\n    public void Ship(Order order)\n    {\n        Console.WriteLine(\"Cannot ship a cancelled order.\");\n    }\n\n    public void Deliver(Order order)\n    {\n        Console.WriteLine(\"Cannot deliver a cancelled order.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine(\"Order is already cancelled.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/States/DeliveredState.cs",
    "content": "class DeliveredState : IOrderState\n{\n    public void Ship(Order order)\n    {\n        Console.WriteLine(\"Order already delivered.\");\n    }\n\n    public void Deliver(Order order)\n    {\n        Console.WriteLine(\"Order already delivered.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine(\"Cannot cancel a delivered order.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/States/IOrderState.cs",
    "content": "interface IOrderState\n{\n    void Ship(Order order);\n    void Deliver(Order order);\n    void Cancel(Order order);\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/States/PlacedState.cs",
    "content": "class PlacedState : IOrderState\n{\n    public void Ship(Order order)\n    {\n        Console.WriteLine($\"Shipping order {order.GetId()}\");\n        order.SetStatus(OrderStatus.SHIPPED);\n        order.SetState(new ShippedState());\n    }\n\n    public void Deliver(Order order)\n    {\n        Console.WriteLine(\"Cannot deliver an order that has not been shipped.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine($\"Cancelling order {order.GetId()}\");\n        order.SetStatus(OrderStatus.CANCELLED);\n        order.SetState(new CancelledState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/States/ShippedState.cs",
    "content": "class ShippedState : IOrderState\n{\n    public void Ship(Order order)\n    {\n        Console.WriteLine(\"Order is already shipped.\");\n    }\n\n    public void Deliver(Order order)\n    {\n        Console.WriteLine($\"Delivering order {order.GetId()}\");\n        order.SetStatus(OrderStatus.DELIVERED);\n        order.SetState(new DeliveredState());\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine(\"Cannot cancel a shipped order.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Strategy/CreditCardPaymentStrategy.cs",
    "content": "class CreditCardPaymentStrategy : IPaymentStrategy\n{\n    private readonly string cardNumber;\n\n    public CreditCardPaymentStrategy(string cardNumber)\n    {\n        this.cardNumber = cardNumber;\n    }\n\n    public bool Pay(double amount)\n    {\n        Console.WriteLine($\"Processing credit card payment of ${amount:F2} with card {cardNumber}.\");\n        return true;\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Strategy/IPaymentStrategy.cs",
    "content": "interface IPaymentStrategy\n{\n    bool Pay(double amount);\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/Strategy/UPIPaymentStrategy.cs",
    "content": "class UPIPaymentStrategy : IPaymentStrategy\n{\n    private readonly string upiId;\n\n    public UPIPaymentStrategy(string upiId)\n    {\n        this.upiId = upiId;\n    }\n\n    public bool Pay(double amount)\n    {\n        Console.WriteLine($\"Processing UPI payment of ${amount:F2} with upi id {upiId}.\");\n        return true;\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlineshoppingservice/onlineshoppingservice.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Commands/BuyStockCommand.cs",
    "content": "class BuyStockCommand : IOrderCommand\n{\n    private readonly Account account;\n    private readonly Order order;\n    private readonly StockExchange stockExchange;\n\n    public BuyStockCommand(Account account, Order order)\n    {\n        this.account = account;\n        this.order = order;\n        this.stockExchange = StockExchange.GetInstance();\n    }\n\n    public void Execute()\n    {\n        double estimatedCost = order.GetQuantity() * order.GetPrice();\n        if (order.GetOrderType() == OrderType.LIMIT && account.GetBalance() < estimatedCost)\n        {\n            throw new InsufficientFundsException(\"Not enough cash to place limit buy order.\");\n        }\n        Console.WriteLine($\"Placing BUY order {order.GetOrderId()} for {order.GetQuantity()} shares of {order.GetStock().GetSymbol()}.\");\n        stockExchange.PlaceBuyOrder(order);\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Commands/IOrderCommand.cs",
    "content": "interface IOrderCommand\n{\n    void Execute();\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Commands/SellStockCommand.cs",
    "content": "class SellStockCommand : IOrderCommand\n{\n    private readonly Account account;\n    private readonly Order order;\n    private readonly StockExchange stockExchange;\n\n    public SellStockCommand(Account account, Order order)\n    {\n        this.account = account;\n        this.order = order;\n        this.stockExchange = StockExchange.GetInstance();\n    }\n\n    public void Execute()\n    {\n        if (account.GetStockQuantity(order.GetStock().GetSymbol()) < order.GetQuantity())\n        {\n            throw new InsufficientStockException(\"Not enough stock to place sell order.\");\n        }\n        Console.WriteLine($\"Placing SELL order {order.GetOrderId()} for {order.GetQuantity()} shares of {order.GetStock().GetSymbol()}.\");\n        stockExchange.PlaceSellOrder(order);\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Enums/OrderStatus.cs",
    "content": "enum OrderStatus\n{\n    OPEN,\n    PARTIALLY_FILLED,\n    FILLED,\n    CANCELLED,\n    FAILED\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Enums/OrderType.cs",
    "content": "enum OrderType\n{\n    MARKET,\n    LIMIT\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Enums/TransactionType.cs",
    "content": "enum TransactionType\n{\n    BUY,\n    SELL\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Exceptions/InsufficientFundsException.cs",
    "content": "class InsufficientFundsException : Exception\n{\n    public InsufficientFundsException(string message) : base(message) { }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Exceptions/InsufficientStockException.cs",
    "content": "class InsufficientStockException : Exception\n{\n    public InsufficientStockException(string message) : base(message) { }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Models/Account.cs",
    "content": "class Account\n{\n    private double balance;\n    private readonly Dictionary<string, int> portfolio; // Stock symbol -> quantity\n    private readonly object lockObj = new object();\n\n    public Account(double initialCash)\n    {\n        this.balance = initialCash;\n        this.portfolio = new Dictionary<string, int>();\n    }\n\n    public void Debit(double amount)\n    {\n        lock (lockObj)\n        {\n            if (balance < amount)\n            {\n                throw new InsufficientFundsException($\"Insufficient funds to debit {amount}\");\n            }\n            balance -= amount;\n        }\n    }\n\n    public void Credit(double amount)\n    {\n        lock (lockObj)\n        {\n            balance += amount;\n        }\n    }\n\n    public void AddStock(string symbol, int quantity)\n    {\n        lock (lockObj)\n        {\n            if (!portfolio.ContainsKey(symbol))\n            {\n                portfolio[symbol] = 0;\n            }\n            portfolio[symbol] += quantity;\n        }\n    }\n\n    public void RemoveStock(string symbol, int quantity)\n    {\n        lock (lockObj)\n        {\n            int currentQuantity = portfolio.ContainsKey(symbol) ? portfolio[symbol] : 0;\n            if (currentQuantity < quantity)\n            {\n                throw new InsufficientStockException($\"Not enough {symbol} stock to sell.\");\n            }\n            portfolio[symbol] = currentQuantity - quantity;\n        }\n    }\n\n    public double GetBalance() { return balance; }\n    public Dictionary<string, int> GetPortfolio() { return new Dictionary<string, int>(portfolio); }\n    public int GetStockQuantity(string symbol) { return portfolio.ContainsKey(symbol) ? portfolio[symbol] : 0; }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Models/Order.cs",
    "content": "class Order\n{\n    private readonly string orderId;\n    private readonly User user;\n    private readonly Stock stock;\n    private readonly OrderType type;\n    private readonly int quantity;\n    private readonly double price; // Limit price for Limit orders\n    private OrderStatus status;\n    private readonly User owner;\n    private IOrderState currentState;\n    private readonly IExecutionStrategy executionStrategy;\n\n    public Order(string orderId, User user, Stock stock, OrderType type, int quantity, \n                 double price, IExecutionStrategy strategy, User owner)\n    {\n        this.orderId = orderId;\n        this.user = user;\n        this.stock = stock;\n        this.type = type;\n        this.quantity = quantity;\n        this.price = price;\n        this.executionStrategy = strategy;\n        this.owner = owner;\n        this.currentState = new OpenState(); // Initial state\n        this.status = OrderStatus.OPEN;\n    }\n\n    public void Cancel()\n    {\n        currentState.Cancel(this);\n    }\n\n    // Getters\n    public string GetOrderId() { return orderId; }\n    public User GetUser() { return user; }\n    public Stock GetStock() { return stock; }\n    public OrderType GetOrderType() { return type; }\n    public int GetQuantity() { return quantity; }\n    public double GetPrice() { return price; }\n    public OrderStatus GetStatus() { return status; }\n    public IExecutionStrategy GetExecutionStrategy() { return executionStrategy; }\n\n    // Setters for state transitions\n    public void SetState(IOrderState state)\n    {\n        this.currentState = state;\n    }\n\n    public void SetStatus(OrderStatus status)\n    {\n        this.status = status;\n        NotifyOwner();\n    }\n\n    private void NotifyOwner()\n    {\n        if (owner != null)\n        {\n            owner.OrderStatusUpdate(this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Models/OrderBuilder.cs",
    "content": "class OrderBuilder\n{\n    private User user;\n    private Stock stock;\n    private OrderType type;\n    private TransactionType transactionType;\n    private int quantity;\n    private double price;\n\n    public OrderBuilder ForUser(User user)\n    {\n        this.user = user;\n        return this;\n    }\n\n    public OrderBuilder WithStock(Stock stock)\n    {\n        this.stock = stock;\n        return this;\n    }\n\n    public OrderBuilder Buy(int quantity)\n    {\n        this.transactionType = TransactionType.BUY;\n        this.quantity = quantity;\n        return this;\n    }\n\n    public OrderBuilder Sell(int quantity)\n    {\n        this.transactionType = TransactionType.SELL;\n        this.quantity = quantity;\n        return this;\n    }\n\n    public OrderBuilder AtMarketPrice()\n    {\n        this.type = OrderType.MARKET;\n        this.price = 0; // Not needed for market order\n        return this;\n    }\n\n    public OrderBuilder WithLimit(double limitPrice)\n    {\n        this.type = OrderType.LIMIT;\n        this.price = limitPrice;\n        return this;\n    }\n\n    public Order Build()\n    {\n        IExecutionStrategy strategy = type == OrderType.MARKET ? \n            (IExecutionStrategy) new MarketOrderStrategy() : \n            (IExecutionStrategy) new LimitOrderStrategy(transactionType);\n        \n        return new Order(\n            Guid.NewGuid().ToString(),\n            user,\n            stock,\n            type,\n            quantity,\n            price,\n            strategy,\n            user\n        );\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Models/Stock.cs",
    "content": "class Stock\n{\n    private readonly string symbol;\n    private double price;\n    private readonly List<IStockObserver> observers = new List<IStockObserver>();\n\n    public Stock(string symbol, double initialPrice)\n    {\n        this.symbol = symbol;\n        this.price = initialPrice;\n    }\n\n    public string GetSymbol() { return symbol; }\n    public double GetPrice() { return price; }\n\n    public void SetPrice(double newPrice)\n    {\n        if (this.price != newPrice)\n        {\n            this.price = newPrice;\n            NotifyObservers();\n        }\n    }\n\n    public void AddObserver(IStockObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IStockObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    private void NotifyObservers()\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Models/User.cs",
    "content": "class User : IStockObserver\n{\n    private readonly string userId;\n    private readonly string name;\n    private readonly Account account;\n\n    public User(string name, double initialCash)\n    {\n        this.userId = Guid.NewGuid().ToString();\n        this.name = name;\n        this.account = new Account(initialCash);\n    }\n\n    public string GetUserId() { return userId; }\n    public string GetName() { return name; }\n    public Account GetAccount() { return account; }\n\n    public void Update(Stock stock)\n    {\n        Console.WriteLine($\"[Notification for {name}] Stock {stock.GetSymbol()} price updated to: ${stock.GetPrice():F2}\");\n    }\n\n    public void OrderStatusUpdate(Order order)\n    {\n        Console.WriteLine($\"[Order Notification for {name}] Order {order.GetOrderId()} for {order.GetStock().GetSymbol()} is now {order.GetStatus()}.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Observer/IStockObserver.cs",
    "content": "interface IStockObserver\n{\n    void Update(Stock stock);\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/README.md",
    "content": "# Designing an Online Stock Brokerage System\n\n## Requirements\n1. The online stock brokerage system should allow users to create and manage their trading accounts.\n2. Users should be able to buy and sell stocks, as well as view their portfolio and transaction history.\n3. The system should provide real-time stock quotes and market data to users.\n4. The system should handle order placement, execution, and settlement processes.\n5. The system should enforce various business rules and validations, such as checking account balances and stock availability.\n6. The system should handle concurrent user requests and ensure data consistency and integrity.\n7. The system should be scalable and able to handle a large number of users and transactions.\n8. The system should be secure and protect sensitive user information.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the stock brokerage system, with properties such as user ID, name, and email.\n2. The **Account** class represents a user's trading account, with properties like account ID, associated user, and balance. It provides methods for depositing and withdrawing funds.\n3. The **Stock** class represents a stock that can be traded, with properties such as symbol, name, and price. It provides a method for updating the stock price.\n4. The **Order** class is an abstract base class representing an order placed by a user. It contains common properties such as order ID, associated account, stock, quantity, price, and order status. The execute() method is declared as abstract, to be implemented by concrete order classes.\n5. The **BuyOrder** and **SellOrder** classes are concrete implementations of the Order class, representing buy and sell orders respectively. They provide the implementation for the execute() method specific to each order type.\n6. The **OrderStatus** enum represents the possible statuses of an order, such as PENDING, EXECUTED, or REJECTED.\n7. The **Portfolio** class represents a user's portfolio, which holds the stocks owned by the user. It provides methods for adding and removing stocks from the portfolio.\n8. The **StockBroker** class is the central component of the stock brokerage system. It follows the Singleton pattern to ensure a single instance of the stock broker. It manages user accounts, stocks, and order processing. It provides methods for creating accounts, adding stocks, placing orders, and processing orders.\n9. The **InsufficientFundsException** and **InsufficientStockException** classes are custom exceptions used to handle insufficient funds and insufficient stock scenarios respectively.\n10. The **StockBrokerageSystem** class serves as the entry point of the application and demonstrates the usage of the stock brokerage system."
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/States/CancelledState.cs",
    "content": "class CancelledState : IOrderState\n{\n    public void Handle(Order order)\n    {\n        Console.WriteLine(\"Order is cancelled.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine(\"Order is already cancelled.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/States/FilledState.cs",
    "content": "class FilledState : IOrderState\n{\n    public void Handle(Order order)\n    {\n        Console.WriteLine(\"Order is already filled.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        Console.WriteLine(\"Cannot cancel a filled order.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/States/IOrderState.cs",
    "content": "interface IOrderState\n{\n    void Handle(Order order);\n    void Cancel(Order order);\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/States/OpenState.cs",
    "content": "class OpenState : IOrderState\n{\n    public void Handle(Order order)\n    {\n        Console.WriteLine(\"Order is open and waiting for execution.\");\n    }\n\n    public void Cancel(Order order)\n    {\n        order.SetStatus(OrderStatus.CANCELLED);\n        order.SetState(new CancelledState());\n        Console.WriteLine($\"Order {order.GetOrderId()} has been cancelled.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/StockBrokerageSystem.cs",
    "content": "class StockBrokerageSystem\n{\n    private static volatile StockBrokerageSystem instance;\n    private static readonly object syncRoot = new object();\n    private readonly Dictionary<string, User> users;\n    private readonly Dictionary<string, Stock> stocks;\n\n    private StockBrokerageSystem()\n    {\n        this.users = new Dictionary<string, User>();\n        this.stocks = new Dictionary<string, Stock>();\n    }\n\n    public static StockBrokerageSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (syncRoot)\n            {\n                if (instance == null)\n                {\n                    instance = new StockBrokerageSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public User RegisterUser(string name, double initialAmount)\n    {\n        var user = new User(name, initialAmount);\n        users[user.GetUserId()] = user;\n        return user;\n    }\n\n    public Stock AddStock(string symbol, double initialPrice)\n    {\n        var stock = new Stock(symbol, initialPrice);\n        stocks[stock.GetSymbol()] = stock;\n        return stock;\n    }\n\n    public void PlaceBuyOrder(Order order)\n    {\n        var user = order.GetUser();\n        IOrderCommand command = new BuyStockCommand(user.GetAccount(), order);\n        command.Execute();\n    }\n\n    public void PlaceSellOrder(Order order)\n    {\n        var user = order.GetUser();\n        IOrderCommand command = new SellStockCommand(user.GetAccount(), order);\n        command.Execute();\n    }\n\n    public void CancelOrder(Order order)\n    {\n        order.Cancel();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/StockBrokerageSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic class StockBrokerageSystemDemo\n{\n    public static void Main(string[] args)\n    {\n        // System Setup\n        var system = StockBrokerageSystem.GetInstance();\n\n        // Create Stocks\n        var apple = system.AddStock(\"AAPL\", 150.00);\n        var google = system.AddStock(\"GOOG\", 2800.00);\n\n        // Create Members (Users)\n        var alice = system.RegisterUser(\"Alice\", 20000.00);\n        var bob = system.RegisterUser(\"Bob\", 25000.00);\n\n        // Bob already owns some Apple stock\n        bob.GetAccount().AddStock(\"AAPL\", 50);\n\n        // Members subscribe to stock notifications (Observer Pattern)\n        apple.AddObserver(alice);\n        google.AddObserver(alice);\n        apple.AddObserver(bob);\n\n        Console.WriteLine(\"--- Initial State ---\");\n        PrintAccountStatus(alice);\n        PrintAccountStatus(bob);\n\n        Console.WriteLine(\"\\n--- Trading Simulation Starts ---\\n\");\n\n        // SCENARIO 1: Limit Order Match\n        Console.WriteLine(\"--- SCENARIO 1: Alice places a limit buy, Bob places a limit sell that matches ---\");\n\n        // Alice wants to buy 10 shares of AAPL if the price is $150.50 or less\n        var aliceBuyOrder = new OrderBuilder()\n            .ForUser(alice)\n            .Buy(10)\n            .WithStock(apple)\n            .WithLimit(150.50)\n            .Build();\n        system.PlaceBuyOrder(aliceBuyOrder);\n\n        // Bob wants to sell 20 of his shares if the price is $150.50 or more\n        var bobSellOrder = new OrderBuilder()\n            .ForUser(bob)\n            .Sell(20)\n            .WithStock(apple)\n            .WithLimit(150.50)\n            .Build();\n        system.PlaceSellOrder(bobSellOrder);\n\n        // The exchange will automatically match and execute this trade.\n        Thread.Sleep(100); // Give time for notifications to print\n        Console.WriteLine(\"\\n--- Account Status After Trade 1 ---\");\n        PrintAccountStatus(alice);\n        PrintAccountStatus(bob);\n\n        // SCENARIO 2: Price Update triggers notifications\n        Console.WriteLine(\"\\n--- SCENARIO 2: Market price of GOOG changes ---\");\n        google.SetPrice(2850.00); // Alice will get a notification\n\n        // SCENARIO 3: Order Cancellation (State Pattern)\n        Console.WriteLine(\"\\n--- SCENARIO 3: Alice places an order and then cancels it ---\");\n        var aliceCancelOrder = new OrderBuilder()\n            .ForUser(alice)\n            .Buy(5)\n            .WithStock(google)\n            .WithLimit(2700.00) // Price is too low, so it won't execute immediately\n            .Build();\n        system.PlaceBuyOrder(aliceCancelOrder);\n\n        Console.WriteLine($\"Order status before cancellation: {aliceCancelOrder.GetStatus()}\");\n        system.CancelOrder(aliceCancelOrder);\n        Console.WriteLine($\"Order status after cancellation attempt: {aliceCancelOrder.GetStatus()}\");\n\n        // Now try to cancel an already filled order\n        Console.WriteLine(\"\\n--- Trying to cancel an already FILLED order (State Pattern) ---\");\n        Console.WriteLine($\"Bob's sell order status: {bobSellOrder.GetStatus()}\");\n        system.CancelOrder(bobSellOrder); // This should fail\n        Console.WriteLine($\"Bob's sell order status after cancel attempt: {bobSellOrder.GetStatus()}\");\n    }\n\n    private static void PrintAccountStatus(User user)\n    {\n        var portfolio = user.GetAccount().GetPortfolio();\n        var portfolioStr = string.Join(\", \", portfolio.Select(kvp => $\"{kvp.Key}: {kvp.Value}\"));\n        Console.WriteLine($\"Member: {user.GetName()}, Cash: ${user.GetAccount().GetBalance():F2}, Portfolio: {{{portfolioStr}}}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/StockExchange.cs",
    "content": "class StockExchange\n{\n    private static volatile StockExchange instance;\n    private static readonly object syncRoot = new object();\n    private readonly Dictionary<string, List<Order>> buyOrders;\n    private readonly Dictionary<string, List<Order>> sellOrders;\n    private readonly object matchLock = new object();\n\n    private StockExchange()\n    {\n        this.buyOrders = new Dictionary<string, List<Order>>();\n        this.sellOrders = new Dictionary<string, List<Order>>();\n    }\n\n    public static StockExchange GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (syncRoot)\n            {\n                if (instance == null)\n                {\n                    instance = new StockExchange();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void PlaceBuyOrder(Order order)\n    {\n        if (!buyOrders.ContainsKey(order.GetStock().GetSymbol()))\n        {\n            buyOrders[order.GetStock().GetSymbol()] = new List<Order>();\n        }\n        buyOrders[order.GetStock().GetSymbol()].Add(order);\n        MatchOrders(order.GetStock());\n    }\n\n    public void PlaceSellOrder(Order order)\n    {\n        if (!sellOrders.ContainsKey(order.GetStock().GetSymbol()))\n        {\n            sellOrders[order.GetStock().GetSymbol()] = new List<Order>();\n        }\n        sellOrders[order.GetStock().GetSymbol()].Add(order);\n        MatchOrders(order.GetStock());\n    }\n\n    private void MatchOrders(Stock stock)\n    {\n        lock (matchLock) // Critical section to prevent race conditions during matching\n        {\n            var buys = buyOrders.ContainsKey(stock.GetSymbol()) ? buyOrders[stock.GetSymbol()] : new List<Order>();\n            var sells = sellOrders.ContainsKey(stock.GetSymbol()) ? sellOrders[stock.GetSymbol()] : new List<Order>();\n\n            if (!buys.Any() || !sells.Any()) return;\n\n            bool matchFound;\n            do\n            {\n                matchFound = false;\n                var bestBuy = FindBestBuy(buys);\n                var bestSell = FindBestSell(sells);\n\n                if (bestBuy != null && bestSell != null)\n                {\n                    double buyPrice = bestBuy.GetOrderType() == OrderType.MARKET ? stock.GetPrice() : bestBuy.GetPrice();\n                    double sellPrice = bestSell.GetOrderType() == OrderType.MARKET ? stock.GetPrice() : bestSell.GetPrice();\n\n                    if (buyPrice >= sellPrice)\n                    {\n                        ExecuteTrade(bestBuy, bestSell, sellPrice); // Trade at the seller's asking price\n                        matchFound = true;\n                    }\n                }\n            } while (matchFound);\n        }\n    }\n\n    private void ExecuteTrade(Order buyOrder, Order sellOrder, double tradePrice)\n    {\n        Console.WriteLine($\"--- Executing Trade for {buyOrder.GetStock().GetSymbol()} at ${tradePrice:F2} ---\");\n\n        var buyer = buyOrder.GetUser();\n        var seller = sellOrder.GetUser();\n\n        int tradeQuantity = Math.Min(buyOrder.GetQuantity(), sellOrder.GetQuantity());\n        double totalCost = tradeQuantity * tradePrice;\n\n        // Perform transaction\n        buyer.GetAccount().Debit(totalCost);\n        buyer.GetAccount().AddStock(buyOrder.GetStock().GetSymbol(), tradeQuantity);\n\n        seller.GetAccount().Credit(totalCost);\n        seller.GetAccount().RemoveStock(sellOrder.GetStock().GetSymbol(), tradeQuantity);\n\n        // Update orders\n        UpdateOrderStatus(buyOrder, tradeQuantity);\n        UpdateOrderStatus(sellOrder, tradeQuantity);\n\n        // Update stock's market price to last traded price\n        buyOrder.GetStock().SetPrice(tradePrice);\n\n        Console.WriteLine(\"--- Trade Complete ---\");\n    }\n\n    private void UpdateOrderStatus(Order order, int quantityTraded)\n    {\n        // This is a simplified update logic. A real system would handle partial fills.\n        order.SetStatus(OrderStatus.FILLED);\n        order.SetState(new FilledState());\n        string stockSymbol = order.GetStock().GetSymbol();\n        \n        // Remove from books\n        if (buyOrders.ContainsKey(stockSymbol))\n            buyOrders[stockSymbol].Remove(order);\n        if (sellOrders.ContainsKey(stockSymbol))\n            sellOrders[stockSymbol].Remove(order);\n    }\n\n    private Order FindBestBuy(List<Order> buys)\n    {\n        return buys\n            .Where(o => o.GetStatus() == OrderStatus.OPEN)\n            .OrderByDescending(o => o.GetPrice()) // Highest limit price is best\n            .FirstOrDefault();\n    }\n\n    private Order FindBestSell(List<Order> sells)\n    {\n        return sells\n            .Where(o => o.GetStatus() == OrderStatus.OPEN)\n            .OrderBy(o => o.GetPrice()) // Lowest limit price is best\n            .FirstOrDefault();\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Strategy/IExecutionStrategy.cs",
    "content": "interface IExecutionStrategy\n{\n    bool CanExecute(Order order, double marketPrice);\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Strategy/LimitOrderStrategy.cs",
    "content": "class LimitOrderStrategy : IExecutionStrategy\n{\n    private readonly TransactionType type;\n\n    public LimitOrderStrategy(TransactionType type)\n    {\n        this.type = type;\n    }\n\n    public bool CanExecute(Order order, double marketPrice)\n    {\n        if (type == TransactionType.BUY)\n        {\n            // Buy if market price is less than or equal to limit price\n            return marketPrice <= order.GetPrice();\n        }\n        else // SELL\n        {\n            // Sell if market price is greater than or equal to limit price\n            return marketPrice >= order.GetPrice();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/Strategy/MarketOrderStrategy.cs",
    "content": "class MarketOrderStrategy : IExecutionStrategy\n{\n    public bool CanExecute(Order order, double marketPrice)\n    {\n        return true; // Market orders can always execute\n    }\n}"
  },
  {
    "path": "solutions/csharp/onlinestockbrokeragesystem/onlinestockbrokeragesystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/parkinglot/Enums/VehicleSize.cs",
    "content": "enum VehicleSize\n{\n    SMALL,\n    MEDIUM,\n    LARGE\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Models/ParkingFloor.cs",
    "content": "class ParkingFloor\n{\n    private readonly int floorNumber;\n    private readonly Dictionary<string, ParkingSpot> spots;\n    private readonly object lockObject = new object();\n\n    public ParkingFloor(int floorNumber)\n    {\n        this.floorNumber = floorNumber;\n        this.spots = new Dictionary<string, ParkingSpot>();\n    }\n\n    public void AddSpot(ParkingSpot spot)\n    {\n        spots[spot.GetSpotId()] = spot;\n    }\n\n    public ParkingSpot FindAvailableSpot(Vehicle vehicle)\n    {\n        lock (lockObject)\n        {\n            var availableSpots = spots.Values\n                .Where(spot => !spot.IsOccupiedSpot() && spot.CanFitVehicle(vehicle))\n                .OrderBy(spot => (int)spot.GetSpotSize())\n                .ToList();\n\n            return availableSpots.FirstOrDefault();\n        }\n    }\n\n    public void DisplayAvailability()\n    {\n        Console.WriteLine($\"--- Floor {floorNumber} Availability ---\");\n        var availableCounts = new Dictionary<VehicleSize, int>\n        {\n            { VehicleSize.SMALL, 0 },\n            { VehicleSize.MEDIUM, 0 },\n            { VehicleSize.LARGE, 0 }\n        };\n\n        foreach (var spot in spots.Values)\n        {\n            if (!spot.IsOccupiedSpot())\n            {\n                availableCounts[spot.GetSpotSize()]++;\n            }\n        }\n\n        foreach (VehicleSize size in Enum.GetValues(typeof(VehicleSize)))\n        {\n            Console.WriteLine($\"  {size} spots: {availableCounts[size]}\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Models/ParkingSpot.cs",
    "content": "class ParkingSpot\n{\n    private readonly string spotId;\n    private readonly VehicleSize spotSize;\n    private bool isOccupied;\n    private Vehicle parkedVehicle;\n    private readonly object lockObject = new object();\n\n    public ParkingSpot(string spotId, VehicleSize spotSize)\n    {\n        this.spotId = spotId;\n        this.spotSize = spotSize;\n        this.isOccupied = false;\n        this.parkedVehicle = null;\n    }\n\n    public string GetSpotId()\n    {\n        return spotId;\n    }\n\n    public VehicleSize GetSpotSize()\n    {\n        return spotSize;\n    }\n\n    public bool IsAvailable()\n    {\n        lock (lockObject)\n        {\n            return !isOccupied;\n        }\n    }\n\n    public bool IsOccupiedSpot()\n    {\n        return isOccupied;\n    }\n\n    public void ParkVehicle(Vehicle vehicle)\n    {\n        lock (lockObject)\n        {\n            this.parkedVehicle = vehicle;\n            this.isOccupied = true;\n        }\n    }\n\n    public void UnparkVehicle()\n    {\n        lock (lockObject)\n        {\n            this.parkedVehicle = null;\n            this.isOccupied = false;\n        }\n    }\n\n    public bool CanFitVehicle(Vehicle vehicle)\n    {\n        if (isOccupied) return false;\n\n        switch (vehicle.GetSize())\n        {\n            case VehicleSize.SMALL:\n                return spotSize == VehicleSize.SMALL;\n            case VehicleSize.MEDIUM:\n                return spotSize == VehicleSize.MEDIUM || spotSize == VehicleSize.LARGE;\n            case VehicleSize.LARGE:\n                return spotSize == VehicleSize.LARGE;\n            default:\n                return false;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Models/ParkingTicket.cs",
    "content": "class ParkingTicket\n{\n    private readonly string ticketId;\n    private readonly Vehicle vehicle;\n    private readonly ParkingSpot spot;\n    private readonly long entryTimestamp;\n    private long exitTimestamp;\n\n    public ParkingTicket(Vehicle vehicle, ParkingSpot spot)\n    {\n        this.ticketId = Guid.NewGuid().ToString();\n        this.vehicle = vehicle;\n        this.spot = spot;\n        this.entryTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n        this.exitTimestamp = 0;\n    }\n\n    public string GetTicketId() { return ticketId; }\n    public Vehicle GetVehicle() { return vehicle; }\n    public ParkingSpot GetSpot() { return spot; }\n    public long GetEntryTimestamp() { return entryTimestamp; }\n    public long GetExitTimestamp() { return exitTimestamp; }\n\n    public void SetExitTimestamp()\n    {\n        this.exitTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Models/Vehicle.cs",
    "content": "abstract class Vehicle\n{\n    protected readonly string licenseNumber;\n    protected readonly VehicleSize size;\n\n    public Vehicle(string licenseNumber, VehicleSize size)\n    {\n        this.licenseNumber = licenseNumber;\n        this.size = size;\n    }\n\n    public string GetLicenseNumber()\n    {\n        return licenseNumber;\n    }\n\n    public VehicleSize GetSize()\n    {\n        return size;\n    }\n}\n\nclass Bike : Vehicle\n{\n    public Bike(string licenseNumber) : base(licenseNumber, VehicleSize.SMALL)\n    {\n    }\n}\n\nclass Car : Vehicle\n{\n    public Car(string licenseNumber) : base(licenseNumber, VehicleSize.MEDIUM)\n    {\n    }\n}\n\nclass Truck : Vehicle\n{\n    public Truck(string licenseNumber) : base(licenseNumber, VehicleSize.LARGE)\n    {\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/ParkingLot.cs",
    "content": "using System.Collections.Concurrent;\n\nclass ParkingLot\n{\n    private static ParkingLot instance;\n    private static readonly object instanceLock = new object();\n    private readonly List<ParkingFloor> floors;\n    private readonly ConcurrentDictionary<string, ParkingTicket> activeTickets;\n    private IFeeStrategy feeStrategy;\n    private IParkingStrategy parkingStrategy;\n    private readonly object mainLock = new object();\n\n    private ParkingLot()\n    {\n        floors = new List<ParkingFloor>();\n        activeTickets = new ConcurrentDictionary<string, ParkingTicket>();\n        feeStrategy = new FlatRateFeeStrategy();\n        parkingStrategy = new NearestFirstStrategy();\n    }\n\n    public static ParkingLot GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (instanceLock)\n            {\n                if (instance == null)\n                {\n                    instance = new ParkingLot();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void AddFloor(ParkingFloor floor)\n    {\n        floors.Add(floor);\n    }\n\n    public void SetFeeStrategy(IFeeStrategy feeStrategy)\n    {\n        this.feeStrategy = feeStrategy;\n    }\n\n    public void SetParkingStrategy(IParkingStrategy parkingStrategy)\n    {\n        this.parkingStrategy = parkingStrategy;\n    }\n\n    public ParkingTicket ParkVehicle(Vehicle vehicle)\n    {\n        lock (mainLock)\n        {\n            var spot = parkingStrategy.FindSpot(floors, vehicle);\n            if (spot != null)\n            {\n                spot.ParkVehicle(vehicle);\n                var ticket = new ParkingTicket(vehicle, spot);\n                activeTickets.TryAdd(vehicle.GetLicenseNumber(), ticket);\n                Console.WriteLine($\"Vehicle {vehicle.GetLicenseNumber()} parked at spot {spot.GetSpotId()}\");\n                return ticket;\n            }\n            else\n            {\n                Console.WriteLine($\"No available spot for vehicle {vehicle.GetLicenseNumber()}\");\n                return null;\n            }\n        }\n    }\n\n    public double? UnparkVehicle(string licenseNumber)\n    {\n        lock (mainLock)\n        {\n            if (!activeTickets.TryRemove(licenseNumber, out ParkingTicket ticket))\n            {\n                Console.WriteLine($\"Ticket not found for vehicle {licenseNumber}\");\n                return null;\n            }\n\n            ticket.GetSpot().UnparkVehicle();\n            ticket.SetExitTimestamp();\n            double fee = feeStrategy.CalculateFee(ticket);\n            Console.WriteLine($\"Vehicle {licenseNumber} unparked from spot {ticket.GetSpot().GetSpotId()}\");\n            return fee;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/ParkingLotDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class ParkingLotDemo\n{\n    public static void Main()\n    {\n        var parkingLot = ParkingLot.GetInstance();\n\n        // 1. Initialize the parking lot with floors and spots\n        var floor1 = new ParkingFloor(1);\n        floor1.AddSpot(new ParkingSpot(\"F1-S1\", VehicleSize.SMALL));\n        floor1.AddSpot(new ParkingSpot(\"F1-M1\", VehicleSize.MEDIUM));\n        floor1.AddSpot(new ParkingSpot(\"F1-L1\", VehicleSize.LARGE));\n\n        var floor2 = new ParkingFloor(2);\n        floor2.AddSpot(new ParkingSpot(\"F2-M1\", VehicleSize.MEDIUM));\n        floor2.AddSpot(new ParkingSpot(\"F2-M2\", VehicleSize.MEDIUM));\n\n        parkingLot.AddFloor(floor1);\n        parkingLot.AddFloor(floor2);\n\n        parkingLot.SetFeeStrategy(new VehicleBasedFeeStrategy());\n\n        // 2. Simulate vehicle entries\n        Console.WriteLine(\"\\n--- Vehicle Entries ---\");\n        floor1.DisplayAvailability();\n        floor2.DisplayAvailability();\n\n        var bike = new Bike(\"B-123\");\n        var car = new Car(\"C-456\");\n        var truck = new Truck(\"T-789\");\n\n        var bikeTicket = parkingLot.ParkVehicle(bike);\n        var carTicket = parkingLot.ParkVehicle(car);\n        var truckTicket = parkingLot.ParkVehicle(truck);\n\n        Console.WriteLine(\"\\n--- Availability after parking ---\");\n        floor1.DisplayAvailability();\n        floor2.DisplayAvailability();\n\n        // 3. Simulate another car entry (should go to floor 2)\n        var car2 = new Car(\"C-999\");\n        var car2Ticket = parkingLot.ParkVehicle(car2);\n\n        // 4. Simulate a vehicle entry that fails (no available spots)\n        var bike2 = new Bike(\"B-000\");\n        var failedBikeTicket = parkingLot.ParkVehicle(bike2);\n\n        // 5. Simulate vehicle exits and fee calculation\n        Console.WriteLine(\"\\n--- Vehicle Exits ---\");\n\n        if (carTicket != null)\n        {\n            var fee = parkingLot.UnparkVehicle(car.GetLicenseNumber());\n            if (fee.HasValue)\n            {\n                Console.WriteLine($\"Car C-456 unparked. Fee: ${fee.Value:F2}\");\n            }\n        }\n\n        Console.WriteLine(\"\\n--- Availability after one car leaves ---\");\n        floor1.DisplayAvailability();\n        floor2.DisplayAvailability();\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/README.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot should have multiple levels, each level with a certain number of parking spots.\n2. The parking lot should support different types of vehicles, such as cars, motorcycles, and trucks.\n3. Each parking spot should be able to accommodate a specific type of vehicle.\n4. The system should assign a parking spot to a vehicle upon entry and release it when the vehicle exits.\n5. The system should track the availability of parking spots and provide real-time information to customers.\n6. The system should handle multiple entry and exit points and support concurrent access.\n\n## Classes, Interfaces and Enumerations\n1. The **ParkingLot** class follows the Singleton pattern to ensure only one instance of the parking lot exists. It maintains a list of levels and provides methods to park and unpark vehicles.\n2. The **Level** class represents a level in the parking lot and contains a list of parking spots. It handles parking and unparking of vehicles within the level.\n3. The **ParkingSpot** class represents an individual parking spot and tracks the availability and the parked vehicle.\n4. The **Vehicle** class is an abstract base class for different types of vehicles. It is extended by Car, Motorcycle, and Truck classes.\n5. The **VehicleType** enum defines the different types of vehicles supported by the parking lot.\n6. Multi-threading is achieved through the use of synchronized keyword on critical sections to ensure thread safety.\n7. The **Main** class demonstrates the usage of the parking lot system.\n\n## Design Patterns Used:\n1. Singleton Pattern: Ensures only one instance of the ParkingLot class.\n2. Factory Pattern (optional extension): Could be used for creating vehicles based on input.\n3. Observer Pattern (optional extension): Could notify customers about available spots."
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Fee/FlatRateFeeStrategy.cs",
    "content": "class FlatRateFeeStrategy : IFeeStrategy\n{\n    private const double RATE_PER_HOUR = 10.0;\n\n    public double CalculateFee(ParkingTicket parkingTicket)\n    {\n        long duration = parkingTicket.GetExitTimestamp() - parkingTicket.GetEntryTimestamp();\n        long hours = (duration / (1000 * 60 * 60)) + 1;\n        return hours * RATE_PER_HOUR;\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Fee/IFeeStrategy.cs",
    "content": "interface IFeeStrategy\n{\n    double CalculateFee(ParkingTicket parkingTicket);\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Fee/VehicleBasedFeeStrategy.cs",
    "content": "class VehicleBasedFeeStrategy : IFeeStrategy\n{\n    private static readonly Dictionary<VehicleSize, double> HOURLY_RATES = new Dictionary<VehicleSize, double>\n    {\n        { VehicleSize.SMALL, 10.0 },\n        { VehicleSize.MEDIUM, 20.0 },\n        { VehicleSize.LARGE, 30.0 }\n    };\n\n    public double CalculateFee(ParkingTicket parkingTicket)\n    {\n        long duration = parkingTicket.GetExitTimestamp() - parkingTicket.GetEntryTimestamp();\n        long hours = (duration / (1000 * 60 * 60)) + 1;\n        return hours * HOURLY_RATES[parkingTicket.GetVehicle().GetSize()];\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Parking/BestFitStrategy.cs",
    "content": "class BestFitStrategy : IParkingStrategy\n{\n    public ParkingSpot FindSpot(List<ParkingFloor> floors, Vehicle vehicle)\n    {\n        ParkingSpot bestSpot = null;\n\n        foreach (var floor in floors)\n        {\n            var spotOnThisFloor = floor.FindAvailableSpot(vehicle);\n\n            if (spotOnThisFloor != null)\n            {\n                if (bestSpot == null)\n                {\n                    bestSpot = spotOnThisFloor;\n                }\n                else\n                {\n                    if ((int)spotOnThisFloor.GetSpotSize() < (int)bestSpot.GetSpotSize())\n                    {\n                        bestSpot = spotOnThisFloor;\n                    }\n                }\n            }\n        }\n        return bestSpot;\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Parking/FarthestFirstStrategy.cs",
    "content": "class FarthestFirstStrategy : IParkingStrategy\n{\n    public ParkingSpot FindSpot(List<ParkingFloor> floors, Vehicle vehicle)\n    {\n        var reversedFloors = floors.AsEnumerable().Reverse().ToList();\n        foreach (var floor in reversedFloors)\n        {\n            var spot = floor.FindAvailableSpot(vehicle);\n            if (spot != null)\n            {\n                return spot;\n            }\n        }\n        return null;\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Parking/IParkingStrategy.cs",
    "content": "interface IParkingStrategy\n{\n    ParkingSpot FindSpot(List<ParkingFloor> floors, Vehicle vehicle);\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/Strategies/Parking/NearestFirstStrategy.cs",
    "content": "class NearestFirstStrategy : IParkingStrategy\n{\n    public ParkingSpot FindSpot(List<ParkingFloor> floors, Vehicle vehicle)\n    {\n        foreach (var floor in floors)\n        {\n            var spot = floor.FindAvailableSpot(vehicle);\n            if (spot != null)\n            {\n                return spot;\n            }\n        }\n        return null;\n    }\n}"
  },
  {
    "path": "solutions/csharp/parkinglot/parkinglot.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/pubsubsystem/Models/Message.cs",
    "content": "class Message\n{\n    private readonly string payload;\n    private readonly DateTime timestamp;\n\n    public Message(string payload)\n    {\n        this.payload = payload;\n        this.timestamp = DateTime.Now;\n    }\n\n    public string GetPayload()\n    {\n        return payload;\n    }\n\n    public override string ToString()\n    {\n        return $\"Message{{payload='{payload}'}}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/Models/Topic.cs",
    "content": "class Topic\n{\n    private readonly string name;\n    private readonly HashSet<ISubscriber> subscribers;\n    private readonly object subscribersLock = new object();\n\n    public Topic(string name)\n    {\n        this.name = name;\n        this.subscribers = new HashSet<ISubscriber>();\n    }\n\n    public string GetName()\n    {\n        return name;\n    }\n\n    public void AddSubscriber(ISubscriber subscriber)\n    {\n        lock (subscribersLock)\n        {\n            subscribers.Add(subscriber);\n        }\n    }\n\n    public void RemoveSubscriber(ISubscriber subscriber)\n    {\n        lock (subscribersLock)\n        {\n            subscribers.Remove(subscriber);\n        }\n    }\n\n    public void Broadcast(Message message)\n    {\n        List<ISubscriber> currentSubscribers;\n        lock (subscribersLock)\n        {\n            currentSubscribers = new List<ISubscriber>(subscribers);\n        }\n\n        List<Task> deliveryTasks = new List<Task>();\n\n        foreach (ISubscriber subscriber in currentSubscribers)\n        {\n            deliveryTasks.Add(Task.Run(() =>\n            {\n                try\n                {\n                    subscriber.OnMessage(message);\n                }\n                catch (Exception e)\n                {\n                    Console.Error.WriteLine($\"Error delivering message to subscriber {subscriber.GetId()}: {e.Message}\");\n                }\n            }));\n        }\n\n        Task.WaitAll(deliveryTasks.ToArray());\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/PubSubDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\npublic class PubSubDemo\n{\n    public static void Main(string[] args)\n    {\n        PubSubService pubSubService = PubSubService.GetInstance();\n\n        // --- Create Subscribers ---\n        ISubscriber sportsFan1 = new NewsSubscriber(\"SportsFan1\");\n        ISubscriber sportsFan2 = new NewsSubscriber(\"SportsFan2\");\n        ISubscriber techie1 = new NewsSubscriber(\"Techie1\");\n        ISubscriber allNewsReader = new NewsSubscriber(\"AllNewsReader\");\n        ISubscriber systemAdmin = new AlertSubscriber(\"SystemAdmin\");\n\n        // --- Create Topics and Subscriptions ---\n        const string SPORTS_TOPIC = \"SPORTS\";\n        const string TECH_TOPIC = \"TECH\";\n        const string WEATHER_TOPIC = \"WEATHER\";\n\n        pubSubService.CreateTopic(SPORTS_TOPIC);\n        pubSubService.CreateTopic(TECH_TOPIC);\n        pubSubService.CreateTopic(WEATHER_TOPIC);\n\n        pubSubService.Subscribe(SPORTS_TOPIC, sportsFan1);\n        pubSubService.Subscribe(SPORTS_TOPIC, sportsFan2);\n        pubSubService.Subscribe(SPORTS_TOPIC, allNewsReader);\n        pubSubService.Subscribe(SPORTS_TOPIC, systemAdmin);\n\n        pubSubService.Subscribe(TECH_TOPIC, techie1);\n        pubSubService.Subscribe(TECH_TOPIC, allNewsReader);\n\n        Console.WriteLine(\"\\n--- Publishing Messages ---\");\n\n        // --- Publish to SPORTS topic ---\n        pubSubService.Publish(SPORTS_TOPIC, new Message(\"Team A wins the championship!\"));\n        // Expected: SportsFan1, SportsFan2, AllNewsReader, SystemAdmin receive this.\n\n        // --- Publish to TECH topic ---\n        pubSubService.Publish(TECH_TOPIC, new Message(\"New AI model released.\"));\n        // Expected: Techie1, AllNewsReader receive this.\n\n        // --- Publish to WEATHER topic (no subscribers) ---\n        pubSubService.Publish(WEATHER_TOPIC, new Message(\"Sunny with a high of 75°F.\"));\n        // Expected: Message is dropped.\n\n        // Allow some time for async messages to be processed\n        Thread.Sleep(500);\n\n        Console.WriteLine(\"\\n--- Unsubscribing a user and re-publishing ---\");\n\n        // SportsFan2 gets tired of sports news\n        pubSubService.Unsubscribe(SPORTS_TOPIC, sportsFan2);\n\n        // Publish another message to SPORTS\n        pubSubService.Publish(SPORTS_TOPIC, new Message(\"Major player traded to Team B.\"));\n        // Expected: SportsFan1, AllNewsReader, SystemAdmin receive this. SportsFan2 does NOT.\n\n        // Give messages time to be delivered\n        Thread.Sleep(500);\n\n        // --- Shutdown the service ---\n        pubSubService.Shutdown();\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/PubSubService.cs",
    "content": "using System.Collections.Concurrent;\n\nclass PubSubService\n{\n    private static PubSubService instance;\n    private static readonly object instanceLock = new object();\n\n    private readonly ConcurrentDictionary<string, Topic> topicRegistry;\n\n    private PubSubService()\n    {\n        topicRegistry = new ConcurrentDictionary<string, Topic>();\n    }\n\n    public static PubSubService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (instanceLock)\n            {\n                if (instance == null)\n                {\n                    instance = new PubSubService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void CreateTopic(string topicName)\n    {\n        topicRegistry.TryAdd(topicName, new Topic(topicName));\n        Console.WriteLine($\"Topic {topicName} created\");\n    }\n\n    public void Subscribe(string topicName, ISubscriber subscriber)\n    {\n        if (!topicRegistry.TryGetValue(topicName, out Topic topic))\n        {\n            throw new ArgumentException($\"Topic not found: {topicName}\");\n        }\n        topic.AddSubscriber(subscriber);\n        Console.WriteLine($\"Subscriber '{subscriber.GetId()}' subscribed to topic: {topicName}\");\n    }\n\n    public void Unsubscribe(string topicName, ISubscriber subscriber)\n    {\n        if (topicRegistry.TryGetValue(topicName, out Topic topic))\n        {\n            topic.RemoveSubscriber(subscriber);\n        }\n        Console.WriteLine($\"Subscriber '{subscriber.GetId()}' unsubscribed from topic: {topicName}\");\n    }\n\n    public void Publish(string topicName, Message message)\n    {\n        Console.WriteLine($\"Publishing message to topic: {topicName}\");\n        if (!topicRegistry.TryGetValue(topicName, out Topic topic))\n        {\n            throw new ArgumentException($\"Topic not found: {topicName}\");\n        }\n        topic.Broadcast(message);\n    }\n\n    public void Shutdown()\n    {\n        Console.WriteLine(\"PubSubService shutting down...\");\n        Console.WriteLine(\"PubSubService shutdown complete.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/README.md",
    "content": "# Designing a Pub-Sub System in Java\n\n## Requirements\n1. The Pub-Sub system should allow publishers to publish messages to specific topics.\n2. Subscribers should be able to subscribe to topics of interest and receive messages published to those topics.\n3. The system should support multiple publishers and subscribers.\n4. Messages should be delivered to all subscribers of a topic in real-time.\n5. The system should handle concurrent access and ensure thread safety.\n6. The Pub-Sub system should be scalable and efficient in terms of message delivery.\n\n## Classes, Interfaces and Enumerations\n1. The **Message** class represents a message that can be published and received by subscribers. It contains the message content.\n2. The **Topic** class represents a topic to which messages can be published. It maintains a set of subscribers and provides methods to add and remove subscribers, as well as publish messages to all subscribers.\n3. The **Subscriber** interface defines the contract for subscribers. It declares the onMessage method that is invoked when a subscriber receives a message.\n4. The **PrintSubscriber** class is a concrete implementation of the Subscriber interface. It receives messages and prints them to the console.\n5. The **Publisher** class represents a publisher that publishes messages to a specific topic.\n6. The **PubSubSystem** class is the main class that manages topics, subscribers, and message publishing. It uses a ConcurrentHashMap to store topics and an ExecutorService to handle concurrent message publishing.\n7. The **PubSubDemo** class demonstrates the usage of the Pub-Sub system by creating topics, subscribers, and publishers, and publishing messages."
  },
  {
    "path": "solutions/csharp/pubsubsystem/Subscribers/AlertSubscriber.cs",
    "content": "class AlertSubscriber : ISubscriber\n{\n    private readonly string id;\n\n    public AlertSubscriber(string id)\n    {\n        this.id = id;\n    }\n\n    public string GetId()\n    {\n        return id;\n    }\n\n    public void OnMessage(Message message)\n    {\n        Console.WriteLine($\"!!! [ALERT - {id}] : '{message.GetPayload()}' !!!\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/Subscribers/ISubscriber.cs",
    "content": "interface ISubscriber\n{\n    string GetId();\n    void OnMessage(Message message);\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/Subscribers/NewsSubscriber.cs",
    "content": "class NewsSubscriber : ISubscriber\n{\n    private readonly string id;\n\n    public NewsSubscriber(string id)\n    {\n        this.id = id;\n    }\n\n    public string GetId()\n    {\n        return id;\n    }\n\n    public void OnMessage(Message message)\n    {\n        Console.WriteLine($\"[Subscriber {id}] received message '{message.GetPayload()}'\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/pubsubsystem/pubsubsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Commands/ICommand.cs",
    "content": "interface ICommand\n{\n    void Execute();\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Commands/PrepareOrderCommand.cs",
    "content": "class PrepareOrderCommand : ICommand\n{\n    private readonly Order order;\n    private readonly Chef chef;\n\n    public PrepareOrderCommand(Order order, Chef chef)\n    {\n        this.order = order;\n        this.chef = chef;\n    }\n\n    public void Execute()\n    {\n        chef.PrepareOrder(order);\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Commands/ServeOrderCommand.cs",
    "content": "class ServeOrderCommand : ICommand\n{\n    private readonly Order order;\n    private readonly Waiter waiter;\n\n    public ServeOrderCommand(Order order, Waiter waiter)\n    {\n        this.order = order;\n        this.waiter = waiter;\n    }\n\n    public void Execute()\n    {\n        waiter.ServeOrder(order);\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Decorators/BillDecorator.cs",
    "content": "abstract class BillDecorator : IBillComponent\n{\n    protected IBillComponent wrapped;\n\n    public BillDecorator(IBillComponent component)\n    {\n        this.wrapped = component;\n    }\n\n    public virtual double CalculateTotal()\n    {\n        return wrapped.CalculateTotal();\n    }\n\n    public virtual string GetDescription()\n    {\n        return wrapped.GetDescription();\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Decorators/ServiceChargeDecorator.cs",
    "content": "class ServiceChargeDecorator : BillDecorator\n{\n    private readonly double serviceCharge;\n\n    public ServiceChargeDecorator(IBillComponent component, double charge) : base(component)\n    {\n        this.serviceCharge = charge;\n    }\n\n    public override double CalculateTotal()\n    {\n        return base.CalculateTotal() + serviceCharge;\n    }\n\n    public override string GetDescription()\n    {\n        return base.GetDescription() + \", Service Charge\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Decorators/TaxDecorator.cs",
    "content": "class TaxDecorator : BillDecorator\n{\n    private readonly double taxRate;\n\n    public TaxDecorator(IBillComponent component, double taxRate) : base(component)\n    {\n        this.taxRate = taxRate;\n    }\n\n    public override double CalculateTotal()\n    {\n        return base.CalculateTotal() * (1 + taxRate);\n    }\n\n    public override string GetDescription()\n    {\n        return base.GetDescription() + $\", Tax @{taxRate * 100}%\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Enum/TableStatus.cs",
    "content": "enum TableStatus\n{\n    AVAILABLE,\n    OCCUPIED,\n    RESERVED\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/BaseBill.cs",
    "content": "class BaseBill : IBillComponent\n{\n    private readonly Order order;\n\n    public BaseBill(Order order)\n    {\n        this.order = order;\n    }\n\n    public double CalculateTotal() => order.GetTotalPrice();\n    public string GetDescription() => \"Order Items\";\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Bill.cs",
    "content": "class Bill\n{\n    private readonly IBillComponent component;\n\n    public Bill(IBillComponent component)\n    {\n        this.component = component;\n    }\n\n    public void PrintBill()\n    {\n        Console.WriteLine(\"\\n--- BILL ---\");\n        Console.WriteLine($\"Description: {component.GetDescription()}\");\n        Console.WriteLine($\"Total: ${component.CalculateTotal():F2}\");\n        Console.WriteLine(\"------------\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Chef.cs",
    "content": "class Chef : Staff\n{\n    public Chef(string id, string name) : base(id, name) { }\n\n    public void PrepareOrder(Order order)\n    {\n        Console.WriteLine($\"Chef {name} received order {order.GetOrderId()} and is starting preparation.\");\n        foreach (var item in order.GetOrderItems())\n        {\n            item.ChangeState(new PreparingState());\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/IBillComponent.cs",
    "content": "interface IBillComponent\n{\n    double CalculateTotal();\n    string GetDescription();\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Menu.cs",
    "content": "class Menu\n{\n    private readonly Dictionary<string, MenuItem> items = new Dictionary<string, MenuItem>();\n\n    public void AddItem(MenuItem item)\n    {\n        items[item.GetId()] = item;\n    }\n\n    public MenuItem GetItem(string id)\n    {\n        if (!items.TryGetValue(id, out MenuItem item))\n        {\n            throw new ArgumentException($\"Menu item with ID {id} not found.\");\n        }\n        return item;\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/MenuItem.cs",
    "content": "class MenuItem\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly double price;\n\n    public MenuItem(string id, string name, double price)\n    {\n        this.id = id;\n        this.name = name;\n        this.price = price;\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n    public double GetPrice() => price;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Order.cs",
    "content": "class Order\n{\n    private readonly int orderId;\n    private readonly int tableId;\n    private readonly List<OrderItem> items = new List<OrderItem>();\n\n    public Order(int orderId, int tableId)\n    {\n        this.orderId = orderId;\n        this.tableId = tableId;\n    }\n\n    public void AddItem(OrderItem item)\n    {\n        items.Add(item);\n    }\n\n    public double GetTotalPrice()\n    {\n        return items.Sum(item => item.GetMenuItem().GetPrice());\n    }\n\n    public int GetOrderId() => orderId;\n    public int GetTableId() => tableId;\n    public List<OrderItem> GetOrderItems() => items;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/OrderItem.cs",
    "content": "class OrderItem\n{\n    private readonly MenuItem menuItem;\n    private readonly Order order;\n    private IOrderItemState state;\n    private readonly List<IOrderObserver> observers = new List<IOrderObserver>();\n\n    public OrderItem(MenuItem menuItem, Order order)\n    {\n        this.menuItem = menuItem;\n        this.order = order;\n        this.state = new OrderedState();\n    }\n\n    public void ChangeState(IOrderItemState newState)\n    {\n        this.state = newState;\n        Console.WriteLine($\"Item '{menuItem.GetName()}' state changed to: {newState.GetStatus()}\");\n    }\n\n    public void NextState()\n    {\n        state.Next(this);\n    }\n\n    public void SetState(IOrderItemState state)\n    {\n        this.state = state;\n    }\n\n    public void AddObserver(IOrderObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void NotifyObservers()\n    {\n        foreach (var observer in observers.ToList())\n        {\n            observer.Update(this);\n        }\n    }\n\n    public MenuItem GetMenuItem() => menuItem;\n    public Order GetOrder() => order;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Restaurant.cs",
    "content": "class Restaurant\n{\n    private static Restaurant instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<string, Waiter> waiters = new Dictionary<string, Waiter>();\n    private readonly Dictionary<string, Chef> chefs = new Dictionary<string, Chef>();\n    private readonly Dictionary<int, Table> tables = new Dictionary<int, Table>();\n    private readonly Menu menu = new Menu();\n\n    private Restaurant() { }\n\n    public static Restaurant GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new Restaurant();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void AddWaiter(Waiter waiter) => waiters[waiter.GetId()] = waiter;\n    public Waiter GetWaiter(string id) => waiters.TryGetValue(id, out Waiter waiter) ? waiter : null;\n\n    public void AddChef(Chef chef) => chefs[chef.GetId()] = chef;\n    public Chef GetChef(string id) => chefs.TryGetValue(id, out Chef chef) ? chef : null;\n\n    public List<Chef> GetChefs() => chefs.Values.ToList();\n    public List<Waiter> GetWaiters() => waiters.Values.ToList();\n\n    public void AddTable(Table table) => tables[table.GetId()] = table;\n    public Menu GetMenu() => menu;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Staff.cs",
    "content": "abstract class Staff\n{\n    protected string id;\n    protected string name;\n\n    public Staff(string id, string name)\n    {\n        this.id = id;\n        this.name = name;\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Table.cs",
    "content": "class Table\n{\n    private readonly int id;\n    private readonly int capacity;\n    private TableStatus status;\n\n    public Table(int id, int capacity)\n    {\n        this.id = id;\n        this.capacity = capacity;\n        this.status = TableStatus.AVAILABLE;\n    }\n\n    public int GetId() => id;\n    public int GetCapacity() => capacity;\n    public TableStatus GetStatus() => status;\n    public void SetStatus(TableStatus status) => this.status = status;\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Models/Waiter.cs",
    "content": "class Waiter : Staff, IOrderObserver\n{\n    public Waiter(string id, string name) : base(id, name) { }\n\n    public void ServeOrder(Order order)\n    {\n        Console.WriteLine($\"Waiter {name} is serving order {order.GetOrderId()}\");\n        foreach (var item in order.GetOrderItems())\n        {\n            item.ChangeState(new ServedState());\n        }\n    }\n\n    public void Update(OrderItem item)\n    {\n        Console.WriteLine($\">>> WAITER {name} NOTIFIED: Item '{item.GetMenuItem().GetName()}' \" +\n                         $\"for table {item.GetOrder().GetTableId()} is READY FOR PICKUP.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/Observer/IOrderObserver.cs",
    "content": "interface IOrderObserver\n{\n    void Update(OrderItem item);\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/README.md",
    "content": "# Designing Restaurant Management System\n\n## Requirements\n1. The restaurant management system should allow customers to place orders, view the menu, and make reservations.\n2. The system should manage the restaurant's inventory, including ingredients and menu items.\n3. The system should handle order processing, including order preparation, billing, and payment.\n4. The system should support multiple payment methods, such as cash, credit card, and mobile payments.\n5. The system should manage staff information, including roles, schedules, and performance tracking.\n6. The system should generate reports and analytics for management, such as sales reports and inventory analysis.\n7. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **MenuItem** class represents a menu item in the restaurant, with properties such as ID, name, description, price, and availability.\n2. The **Order** class represents an order placed by a customer, with properties such as ID, list of menu items, total amount, order status, and timestamp.\n3. The **OrderStatus** enum represents the different statuses an order can have, such as pending, preparing, ready, completed, or cancelled.\n4. The **Reservation** class represents a reservation made by a customer, with properties such as ID, customer name, contact number, party size, and reservation time.\n5. The **Payment** class represents a payment made for an order, with properties such as ID, amount, payment method, and payment status.\n6. The **PaymentMethod** enum represents the different payment methods supported by the restaurant, such as cash, credit card, or mobile payment.\n7. The **PaymentStatus** enum represents the status of a payment, which can be pending, completed, or failed.\n8. The Staff class represents a staff member of the restaurant, with properties such as ID, name, role, and contact number.\n9. The **Restaurant** class is the main class that manages the restaurant operations. It follows the Singleton pattern to ensure only one instance of the restaurant exists.\n10. The Restaurant class provides methods for managing menu items, placing orders, updating order status, making reservations, processing payments, and managing staff.\n11. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as orders and reservations.\n12. The notifyKitchen and notifyStaff methods are placeholders for notifying relevant staff about order updates and status changes.\n13. The **RestaurantManagementDemo** class demonstrates the usage of the restaurant management system by adding menu items, placing an order, making a reservation, processing a payment, updating order status, adding staff, and retrieving the menu."
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/RestaurantManagementSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class RestaurantManagementSystemDemo\n{\n    public static void Main(string[] args)\n    {\n        Console.WriteLine(\"=== Initializing Restaurant System ===\");\n        RestaurantManagementSystemFacade rmsFacade = RestaurantManagementSystemFacade.GetInstance();\n\n        Table table1 = rmsFacade.AddTable(1, 4);\n        Chef chef1 = rmsFacade.AddChef(\"CHEF01\", \"Gordon\");\n        Waiter waiter1 = rmsFacade.AddWaiter(\"W01\", \"Alice\");\n\n        MenuItem pizza = rmsFacade.AddMenuItem(\"PIZZA01\", \"Margherita Pizza\", 12.50);\n        MenuItem pasta = rmsFacade.AddMenuItem(\"PASTA01\", \"Carbonara Pasta\", 15.00);\n        MenuItem coke = rmsFacade.AddMenuItem(\"DRINK01\", \"Coke\", 2.50);\n        Console.WriteLine(\"Initialization Complete.\\n\");\n\n        Console.WriteLine(\"=== SCENARIO 1: Taking an order ===\");\n        Order order1 = rmsFacade.TakeOrder(table1.GetId(), waiter1.GetId(), \n            new List<string> { pizza.GetId(), coke.GetId() });\n        Console.WriteLine($\"Order taken successfully. Order ID: {order1.GetOrderId()}\");\n\n        Console.WriteLine(\"\\n=== SCENARIO 2: Chef prepares, Waiter gets notified ===\");\n        rmsFacade.MarkItemsAsReady(order1.GetOrderId());\n        rmsFacade.ServeOrder(waiter1.GetId(), order1.GetOrderId());\n\n        Console.WriteLine(\"\\n=== SCENARIO 3: Generating the bill ===\");\n        Bill finalBill = rmsFacade.GenerateBill(order1.GetOrderId());\n        finalBill.PrintBill();\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/RestaurantManagementSystemFacade.cs",
    "content": "class RestaurantManagementSystemFacade\n{\n    private static RestaurantManagementSystemFacade instance;\n    private static readonly object lockObject = new object();\n    private readonly Restaurant restaurant = Restaurant.GetInstance();\n    private int orderIdCounter = 1;\n    private readonly Dictionary<int, Order> orders = new Dictionary<int, Order>();\n\n    private RestaurantManagementSystemFacade() { }\n\n    public static RestaurantManagementSystemFacade GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new RestaurantManagementSystemFacade();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public Table AddTable(int id, int capacity)\n    {\n        Table table = new Table(id, capacity);\n        restaurant.AddTable(table);\n        return table;\n    }\n\n    public Waiter AddWaiter(string id, string name)\n    {\n        Waiter waiter = new Waiter(id, name);\n        restaurant.AddWaiter(waiter);\n        return waiter;\n    }\n\n    public Chef AddChef(string id, string name)\n    {\n        Chef chef = new Chef(id, name);\n        restaurant.AddChef(chef);\n        return chef;\n    }\n\n    public MenuItem AddMenuItem(string id, string name, double price)\n    {\n        MenuItem item = new MenuItem(id, name, price);\n        restaurant.GetMenu().AddItem(item);\n        return item;\n    }\n\n    public Order TakeOrder(int tableId, string waiterId, List<string> menuItemIds)\n    {\n        Waiter waiter = restaurant.GetWaiter(waiterId);\n        if (waiter == null)\n        {\n            throw new ArgumentException(\"Invalid waiter ID.\");\n        }\n\n        var chefs = restaurant.GetChefs();\n        if (!chefs.Any())\n        {\n            throw new InvalidOperationException(\"No chefs available.\");\n        }\n        Chef chef = chefs.First();\n\n        Order order = new Order(Interlocked.Increment(ref orderIdCounter) - 1, tableId);\n        foreach (string itemId in menuItemIds)\n        {\n            MenuItem menuItem = restaurant.GetMenu().GetItem(itemId);\n            OrderItem orderItem = new OrderItem(menuItem, order);\n            orderItem.AddObserver(waiter);\n            order.AddItem(orderItem);\n        }\n\n        ICommand prepareOrderCommand = new PrepareOrderCommand(order, chef);\n        prepareOrderCommand.Execute();\n\n        orders[order.GetOrderId()] = order;\n        return order;\n    }\n\n    public void MarkItemsAsReady(int orderId)\n    {\n        Order order = orders[orderId];\n        Console.WriteLine($\"\\nChef has finished preparing order {order.GetOrderId()}\");\n\n        foreach (var item in order.GetOrderItems())\n        {\n            item.NextState();\n            item.NextState();\n        }\n    }\n\n    public void ServeOrder(string waiterId, int orderId)\n    {\n        Order order = orders[orderId];\n        Waiter waiter = restaurant.GetWaiter(waiterId);\n\n        ICommand serveOrderCommand = new ServeOrderCommand(order, waiter);\n        serveOrderCommand.Execute();\n    }\n\n    public Bill GenerateBill(int orderId)\n    {\n        Order order = orders[orderId];\n        IBillComponent billComponent = new BaseBill(order);\n        billComponent = new TaxDecorator(billComponent, 0.08);\n        billComponent = new ServiceChargeDecorator(billComponent, 5.00);\n\n        return new Bill(billComponent);\n    }\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/States/IOrderItemState.cs",
    "content": "interface IOrderItemState\n{\n    void Next(OrderItem item);\n    void Prev(OrderItem item);\n    string GetStatus();\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/States/OrderedState.cs",
    "content": "class OrderedState : IOrderItemState\n{\n    public void Next(OrderItem item)\n    {\n        item.SetState(new PreparingState());\n    }\n\n    public void Prev(OrderItem item)\n    {\n        Console.WriteLine(\"This is the initial state.\");\n    }\n\n    public string GetStatus() => \"ORDERED\";\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/States/PreparingState.cs",
    "content": "class PreparingState : IOrderItemState\n{\n    public void Next(OrderItem item)\n    {\n        item.SetState(new ReadyForPickupState());\n    }\n\n    public void Prev(OrderItem item)\n    {\n        item.SetState(new OrderedState());\n    }\n\n    public string GetStatus() => \"PREPARING\";\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/States/ReadyForPickupState.cs",
    "content": "class ReadyForPickupState : IOrderItemState\n{\n    public void Next(OrderItem item)\n    {\n        item.NotifyObservers();\n    }\n\n    public void Prev(OrderItem item)\n    {\n        item.SetState(new PreparingState());\n    }\n\n    public string GetStatus() => \"READY_FOR_PICKUP\";\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/States/ServedState.cs",
    "content": "class ServedState : IOrderItemState\n{\n    public void Next(OrderItem item)\n    {\n        Console.WriteLine(\"This is the final state.\");\n    }\n\n    public void Prev(OrderItem item)\n    {\n        Console.WriteLine(\"Cannot revert a served item.\");\n    }\n\n    public string GetStatus() => \"SERVED\";\n}"
  },
  {
    "path": "solutions/csharp/restaurantmanagementsystem/restaurantmanagementsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Enums/DriverStatus.cs",
    "content": "enum DriverStatus\n{\n    ONLINE,\n    IN_TRIP,\n    OFFLINE\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Enums/RideType.cs",
    "content": "enum RideType\n{\n    SEDAN,\n    SUV,\n    AUTO\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Enums/TripStatus.cs",
    "content": "enum TripStatus\n{\n    REQUESTED,\n    ASSIGNED,\n    IN_PROGRESS,\n    COMPLETED,\n    CANCELLED\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/Driver.cs",
    "content": "class Driver : User\n{\n    private Vehicle vehicle;\n    private Location currentLocation;\n    private DriverStatus status;\n\n    public Driver(string name, string contact, Vehicle v, Location loc)\n        : base(name, contact)\n    {\n        vehicle = v;\n        currentLocation = loc;\n        status = DriverStatus.OFFLINE;\n    }\n\n    public Vehicle Vehicle => vehicle;\n    public DriverStatus Status => status;\n\n    public void SetStatus(DriverStatus s)\n    {\n        status = s;\n        Console.WriteLine($\"Driver {Name} is now {s}\");\n    }\n\n    public Location CurrentLocation => currentLocation;\n    \n    public void SetCurrentLocation(Location loc)\n    {\n        currentLocation = loc;\n    }\n\n    public override void OnUpdate(Trip trip)\n    {\n        Console.WriteLine($\"--- Notification for Driver {Name} ---\");\n        Console.WriteLine($\"  Trip {trip.Id} status: {trip.Status}.\");\n        if (trip.Status == TripStatus.REQUESTED)\n        {\n            Console.WriteLine(\"  A new ride is available for you to accept.\");\n        }\n        Console.WriteLine(\"--------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/Location.cs",
    "content": "class Location\n{\n    private readonly double latitude;\n    private readonly double longitude;\n\n    public Location(double lat, double lng)\n    {\n        latitude = lat;\n        longitude = lng;\n    }\n\n    public double DistanceTo(Location other)\n    {\n        double dx = latitude - other.latitude;\n        double dy = longitude - other.longitude;\n        return Math.Sqrt(dx * dx + dy * dy);\n    }\n\n    public double Latitude => latitude;\n    public double Longitude => longitude;\n\n    public override string ToString()\n    {\n        return $\"Location({latitude}, {longitude})\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/Rider.cs",
    "content": "class Rider : User\n{\n    public Rider(string name, string contact) : base(name, contact) { }\n\n    public override void OnUpdate(Trip trip)\n    {\n        Console.WriteLine($\"--- Notification for Rider {Name} ---\");\n        Console.WriteLine($\"  Trip {trip.Id} is now {trip.Status}.\");\n        if (trip.Driver != null)\n        {\n            Console.WriteLine($\"  Driver: {trip.Driver.Name} in a {trip.Driver.Vehicle.Model} ({trip.Driver.Vehicle.LicenseNumber})\");\n        }\n        Console.WriteLine(\"--------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/Trip.cs",
    "content": "class Trip\n{\n    private readonly string id;\n    private readonly Rider rider;\n    private Driver driver;\n    private readonly Location pickupLocation;\n    private readonly Location dropoffLocation;\n    private readonly double fare;\n    private TripStatus status;\n    private ITripState currentState;\n    private readonly List<ITripObserver> observers = new List<ITripObserver>();\n\n    public static int idCounter = 0;\n\n    public Trip(TripBuilder builder)\n    {\n        id = builder.Id;\n        rider = builder.Rider;\n        driver = null;\n        pickupLocation = builder.PickupLocation;\n        dropoffLocation = builder.DropoffLocation;\n        fare = builder.Fare;\n        status = TripStatus.REQUESTED;\n        currentState = new RequestedState();\n    }\n\n    public void AddObserver(ITripObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    private void NotifyObservers()\n    {\n        foreach (var obs in observers)\n        {\n            obs.OnUpdate(this);\n        }\n    }\n\n    public void AssignDriver(Driver d)\n    {\n        currentState.Assign(this, d);\n        AddObserver(d);\n        NotifyObservers();\n    }\n\n    public void StartTrip()\n    {\n        currentState.Start(this);\n        NotifyObservers();\n    }\n\n    public void EndTrip()\n    {\n        currentState.End(this);\n        NotifyObservers();\n    }\n\n    // Getters\n    public string Id => id;\n    public Rider Rider => rider;\n    public Driver Driver => driver;\n    public Location PickupLocation => pickupLocation;\n    public Location DropoffLocation => dropoffLocation;\n    public double Fare => fare;\n    public TripStatus Status => status;\n\n    // Setters (internal, only to be called by State objects)\n    public void SetState(ITripState state)\n    {\n        currentState = state;\n    }\n\n    public void SetStatus(TripStatus s)\n    {\n        status = s;\n    }\n\n    public void SetDriver(Driver d)\n    {\n        driver = d;\n    }\n\n    public override string ToString()\n    {\n        return $\"Trip [id={id}, status={status}, fare=${fare:F2}]\";\n    }\n}\n\nclass TripBuilder\n{\n    private readonly string id;\n    private Rider rider;\n    private Location pickupLocation;\n    private Location dropoffLocation;\n    private double fare;\n\n    public TripBuilder()\n    {\n        id = $\"trip_{++Trip.idCounter}\";\n    }\n\n    public TripBuilder WithRider(Rider r)\n    {\n        rider = r;\n        return this;\n    }\n\n    public TripBuilder WithPickupLocation(Location loc)\n    {\n        pickupLocation = loc;\n        return this;\n    }\n\n    public TripBuilder WithDropoffLocation(Location loc)\n    {\n        dropoffLocation = loc;\n        return this;\n    }\n\n    public TripBuilder WithFare(double f)\n    {\n        fare = f;\n        return this;\n    }\n\n    public Trip Build()\n    {\n        if (rider == null || pickupLocation == null || dropoffLocation == null)\n        {\n            throw new InvalidOperationException(\"Rider, pickup, and dropoff locations are required to build a trip.\");\n        }\n        return new Trip(this);\n    }\n\n    internal string Id => id;\n    internal Rider Rider => rider;\n    internal Location PickupLocation => pickupLocation;\n    internal Location DropoffLocation => dropoffLocation;\n    internal double Fare => fare;\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/User.cs",
    "content": "abstract class User : ITripObserver\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string contact;\n    private readonly List<Trip> tripHistory;\n\n    private static int idCounter = 0;\n\n    public User(string n, string c)\n    {\n        id = $\"user_{++idCounter}\";\n        name = n;\n        contact = c;\n        tripHistory = new List<Trip>();\n    }\n\n    public void AddTripToHistory(Trip trip)\n    {\n        tripHistory.Add(trip);\n    }\n\n    public List<Trip> TripHistory => tripHistory;\n    public string Id => id;\n    public string Name => name;\n    public string Contact => contact;\n\n    public abstract void OnUpdate(Trip trip);\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Models/Vehicle.cs",
    "content": "class Vehicle\n{\n    private readonly string licenseNumber;\n    private readonly string model;\n    private readonly RideType type;\n\n    public Vehicle(string license, string m, RideType t)\n    {\n        licenseNumber = license;\n        model = m;\n        type = t;\n    }\n\n    public string LicenseNumber => licenseNumber;\n    public string Model => model;\n    public RideType Type => type;\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Observer/ITripObserver.cs",
    "content": "interface ITripObserver\n{\n    void OnUpdate(Trip trip);\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/README.md",
    "content": "# Designing a Ride-Sharing Service Like Uber\n\n## Requirements\n1. The ride sharing service should allow passengers to request rides and drivers to accept and fulfill those ride requests.\n2. Passengers should be able to specify their pickup location, destination, and desired ride type (e.g., regular, premium).\n3. Drivers should be able to see available ride requests and choose to accept or decline them.\n4. The system should match ride requests with available drivers based on proximity and other factors.\n5. The system should calculate the fare for each ride based on distance, time, and ride type.\n6. The system should handle payments and process transactions between passengers and drivers.\n7. The system should provide real-time tracking of ongoing rides and notify passengers and drivers about ride status updates.\n8. The system should handle concurrent requests and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Passenger** class represents a passenger in the ride sharing service, with properties such as ID, name, contact information, and location.\n2. The **Driver** class represents a driver in the ride sharing service, with properties such as ID, name, contact information, license plate, location, and status (available or busy).\n3. The **Ride** class represents a ride requested by a passenger and accepted by a driver, with properties such as ID, passenger, driver, source location, destination location, status, and fare.\n4. The **Location** class represents a geographical location with latitude and longitude coordinates.\n5. The **Payment** class represents a payment made for a ride, with properties such as ID, ride, amount, and payment status.\n6. The **RideService** class is the main class that manages the ride sharing service. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The RideService class provides methods for adding passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides.\n8. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and ConcurrentLinkedQueue) to handle concurrent access to shared data, such as ride requests and driver availability.\n9. The notifyDrivers, notifyPassenger, and notifyDriver methods are placeholders for notifying relevant parties about ride status updates.\n10. The calculateFare and processPayment methods are placeholders for calculating ride fares and processing payments, respectively.\n11. The **RideSharingDemo** class demonstrates the usage of the ride sharing service by creating passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides."
  },
  {
    "path": "solutions/csharp/ridesharingservice/RideSharingService.cs",
    "content": "class RideSharingService\n{\n    private static volatile RideSharingService instance;\n    private static readonly object lockObject = new object();\n    \n    private readonly Dictionary<string, Rider> riders = new Dictionary<string, Rider>();\n    private readonly Dictionary<string, Driver> drivers = new Dictionary<string, Driver>();\n    private readonly Dictionary<string, Trip> trips = new Dictionary<string, Trip>();\n    private IPricingStrategy pricingStrategy;\n    private IDriverMatchingStrategy driverMatchingStrategy;\n\n    private RideSharingService() { }\n\n    public static RideSharingService Instance\n    {\n        get\n        {\n            if (instance == null)\n            {\n                lock (lockObject)\n                {\n                    if (instance == null)\n                    {\n                        instance = new RideSharingService();\n                    }\n                }\n            }\n            return instance;\n        }\n    }\n\n    public void SetPricingStrategy(IPricingStrategy strategy)\n    {\n        pricingStrategy = strategy;\n    }\n\n    public void SetDriverMatchingStrategy(IDriverMatchingStrategy strategy)\n    {\n        driverMatchingStrategy = strategy;\n    }\n\n    public Rider RegisterRider(string name, string contact)\n    {\n        var rider = new Rider(name, contact);\n        riders[rider.Id] = rider;\n        return rider;\n    }\n\n    public Driver RegisterDriver(string name, string contact, Vehicle vehicle, Location initialLocation)\n    {\n        var driver = new Driver(name, contact, vehicle, initialLocation);\n        drivers[driver.Id] = driver;\n        return driver;\n    }\n\n    public Trip RequestRide(string riderId, Location pickup, Location dropoff, RideType rideType)\n    {\n        if (!riders.TryGetValue(riderId, out Rider rider))\n        {\n            throw new ArgumentException(\"Rider not found\");\n        }\n\n        Console.WriteLine($\"\\n--- New Ride Request from {rider.Name} ---\");\n\n        // 1. Find available drivers\n        var availableDrivers = driverMatchingStrategy.FindDrivers(drivers.Values.ToList(), pickup, rideType);\n\n        if (!availableDrivers.Any())\n        {\n            Console.WriteLine(\"No drivers available for your request. Please try again later.\");\n            return null;\n        }\n\n        Console.WriteLine($\"Found {availableDrivers.Count} available driver(s).\");\n\n        // 2. Calculate fare\n        double fare = pricingStrategy.CalculateFare(pickup, dropoff, rideType);\n        Console.WriteLine($\"Estimated fare: ${fare:F2}\");\n\n        // 3. Create a trip using the Builder\n        var trip = new TripBuilder()\n            .WithRider(rider)\n            .WithPickupLocation(pickup)\n            .WithDropoffLocation(dropoff)\n            .WithFare(fare)\n            .Build();\n\n        trips[trip.Id] = trip;\n\n        // 4. Notify nearby drivers\n        Console.WriteLine(\"Notifying nearby drivers of the new ride request...\");\n        foreach (var driver in availableDrivers)\n        {\n            Console.WriteLine($\" > Notifying {driver.Name} at {driver.CurrentLocation}\");\n            driver.OnUpdate(trip);\n        }\n\n        return trip;\n    }\n\n    public void AcceptRide(string driverId, string tripId)\n    {\n        if (!drivers.TryGetValue(driverId, out Driver driver) || !trips.TryGetValue(tripId, out Trip trip))\n        {\n            throw new ArgumentException(\"Driver or Trip not found\");\n        }\n\n        Console.WriteLine($\"\\n--- Driver {driver.Name} accepted the ride ---\");\n\n        driver.SetStatus(DriverStatus.IN_TRIP);\n        trip.AssignDriver(driver);\n    }\n\n    public void StartTrip(string tripId)\n    {\n        if (!trips.TryGetValue(tripId, out Trip trip))\n        {\n            throw new ArgumentException(\"Trip not found\");\n        }\n        Console.WriteLine($\"\\n--- Trip {trip.Id} is starting ---\");\n        trip.StartTrip();\n    }\n\n    public void EndTrip(string tripId)\n    {\n        if (!trips.TryGetValue(tripId, out Trip trip))\n        {\n            throw new ArgumentException(\"Trip not found\");\n        }\n        Console.WriteLine($\"\\n--- Trip {trip.Id} is ending ---\");\n        trip.EndTrip();\n\n        // Update statuses and history\n        var driver = trip.Driver;\n        driver.SetStatus(DriverStatus.ONLINE);\n        driver.SetCurrentLocation(trip.DropoffLocation);\n\n        var rider = trip.Rider;\n        driver.AddTripToHistory(trip);\n        rider.AddTripToHistory(trip);\n\n        Console.WriteLine($\"Driver {driver.Name} is now back online at {driver.CurrentLocation}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/RideSharingServiceDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class RideSharingServiceDemo\n{\n    public static void Main()\n    {\n        // 1. Setup the system using singleton instance\n        var service = RideSharingService.Instance;\n        service.SetDriverMatchingStrategy(new NearestDriverMatchingStrategy());\n        service.SetPricingStrategy(new VehicleBasedPricingStrategy());\n\n        // 2. Register riders and drivers\n        var alice = service.RegisterRider(\"Alice\", \"123-456-7890\");\n\n        var bobVehicle = new Vehicle(\"KA01-1234\", \"Toyota Prius\", RideType.SEDAN);\n        var bob = service.RegisterDriver(\"Bob\", \"243-987-2860\", bobVehicle, new Location(1.0, 1.0));\n\n        var charlieVehicle = new Vehicle(\"KA02-5678\", \"Honda CRV\", RideType.SUV);\n        var charlie = service.RegisterDriver(\"Charlie\", \"313-486-2691\", charlieVehicle, new Location(2.0, 2.0));\n\n        var davidVehicle = new Vehicle(\"KA03-9012\", \"Honda CRV\", RideType.SEDAN);\n        var david = service.RegisterDriver(\"David\", \"613-586-3241\", davidVehicle, new Location(1.2, 1.2));\n\n        // 3. Drivers go online\n        bob.SetStatus(DriverStatus.ONLINE);\n        charlie.SetStatus(DriverStatus.ONLINE);\n        david.SetStatus(DriverStatus.ONLINE);\n\n        // David is online but will be too far for the first request\n        david.SetCurrentLocation(new Location(10.0, 10.0));\n\n        // 4. Alice requests a ride\n        var pickupLocation = new Location(0.0, 0.0);\n        var dropoffLocation = new Location(5.0, 5.0);\n\n        // Rider wants a SEDAN\n        var trip1 = service.RequestRide(alice.Id, pickupLocation, dropoffLocation, RideType.SEDAN);\n\n        if (trip1 != null)\n        {\n            // 5. One of the nearby drivers accepts the ride\n            service.AcceptRide(bob.Id, trip1.Id);\n\n            // 6. The trip progresses\n            service.StartTrip(trip1.Id);\n            service.EndTrip(trip1.Id);\n        }\n\n        Console.WriteLine(\"\\n--- Checking Trip History ---\");\n        Console.WriteLine($\"Alice's trip history: {alice.TripHistory.Count} trips\");\n        Console.WriteLine($\"Bob's trip history: {bob.TripHistory.Count} trips\");\n\n        // --- Second ride request ---\n        Console.WriteLine(\"\\n=============================================\");\n        var harry = service.RegisterRider(\"Harry\", \"167-342-7834\");\n\n        // Harry requests an SUV\n        var trip2 = service.RequestRide(harry.Id,\n            new Location(2.5, 2.5),\n            new Location(8.0, 8.0),\n            RideType.SUV);\n\n        if (trip2 != null)\n        {\n            // Only Charlie is available for an SUV ride\n            service.AcceptRide(charlie.Id, trip2.Id);\n            service.StartTrip(trip2.Id);\n            service.EndTrip(trip2.Id);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/States/AssignedState.cs",
    "content": "class AssignedState : ITripState\n{\n    public void Request(Trip trip)\n    {\n        Console.WriteLine(\"Trip has already been requested and assigned.\");\n    }\n\n    public void Assign(Trip trip, Driver driver)\n    {\n        Console.WriteLine(\"Trip is already assigned. To re-assign, cancel first.\");\n    }\n\n    public void Start(Trip trip)\n    {\n        trip.SetStatus(TripStatus.IN_PROGRESS);\n        trip.SetState(new InProgressState());\n    }\n\n    public void End(Trip trip)\n    {\n        Console.WriteLine(\"Cannot end a trip that has not started.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/States/CompletedState.cs",
    "content": "class CompletedState : ITripState\n{\n    public void Request(Trip trip)\n    {\n        Console.WriteLine(\"Cannot request a trip that is already completed.\");\n    }\n\n    public void Assign(Trip trip, Driver driver)\n    {\n        Console.WriteLine(\"Cannot assign a driver to a completed trip.\");\n    }\n\n    public void Start(Trip trip)\n    {\n        Console.WriteLine(\"Cannot start a completed trip.\");\n    }\n\n    public void End(Trip trip)\n    {\n        Console.WriteLine(\"Trip is already completed.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/States/ITripState.cs",
    "content": "interface ITripState\n{\n    void Request(Trip trip);\n    void Assign(Trip trip, Driver driver);\n    void Start(Trip trip);\n    void End(Trip trip);\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/States/InProgressState.cs",
    "content": "class InProgressState : ITripState\n{\n    public void Request(Trip trip)\n    {\n        Console.WriteLine(\"Trip is already in progress.\");\n    }\n\n    public void Assign(Trip trip, Driver driver)\n    {\n        Console.WriteLine(\"Cannot assign a new driver while trip is in progress.\");\n    }\n\n    public void Start(Trip trip)\n    {\n        Console.WriteLine(\"Trip is already in progress.\");\n    }\n\n    public void End(Trip trip)\n    {\n        trip.SetStatus(TripStatus.COMPLETED);\n        trip.SetState(new CompletedState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/States/RequestedState.cs",
    "content": "class RequestedState : ITripState\n{\n    public void Request(Trip trip)\n    {\n        Console.WriteLine(\"Trip is already in requested state.\");\n    }\n\n    public void Assign(Trip trip, Driver driver)\n    {\n        trip.SetDriver(driver);\n        trip.SetStatus(TripStatus.ASSIGNED);\n        trip.SetState(new AssignedState());\n    }\n\n    public void Start(Trip trip)\n    {\n        Console.WriteLine(\"Cannot start a trip that has not been assigned a driver.\");\n    }\n\n    public void End(Trip trip)\n    {\n        Console.WriteLine(\"Cannot end a trip that has not been assigned a driver.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Strategies/Matching/IDriverMatchingStrategy.cs",
    "content": "interface IDriverMatchingStrategy\n{\n    List<Driver> FindDrivers(List<Driver> allDrivers, Location pickupLocation, RideType rideType);\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Strategies/Matching/NearestDriverMatchingStrategy.cs",
    "content": "class NearestDriverMatchingStrategy : IDriverMatchingStrategy\n{\n    private const double MAX_DISTANCE_KM = 5.0;\n\n    public List<Driver> FindDrivers(List<Driver> allDrivers, Location pickupLocation, RideType rideType)\n    {\n        Console.WriteLine($\"Finding nearest drivers for ride type: {rideType}\");\n\n        return allDrivers\n            .Where(driver => driver.Status == DriverStatus.ONLINE)\n            .Where(driver => driver.Vehicle.Type == rideType)\n            .Where(driver => pickupLocation.DistanceTo(driver.CurrentLocation) <= MAX_DISTANCE_KM)\n            .OrderBy(driver => pickupLocation.DistanceTo(driver.CurrentLocation))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Strategies/Pricing/FlatRatePricingStrategy.cs",
    "content": "class FlatRatePricingStrategy : IPricingStrategy\n{\n    private const double BASE_FARE = 5.0;\n    private const double FLAT_RATE = 1.5;\n\n    public double CalculateFare(Location pickup, Location dropoff, RideType rideType)\n    {\n        double distance = pickup.DistanceTo(dropoff);\n        return BASE_FARE + distance * FLAT_RATE;\n    }\n}\n"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Strategies/Pricing/IPricingStrategy.cs",
    "content": "interface IPricingStrategy\n{\n    double CalculateFare(Location pickup, Location dropoff, RideType rideType);\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/Strategies/Pricing/VehicleBasedPricingStrategy.cs",
    "content": "class VehicleBasedPricingStrategy : IPricingStrategy\n{\n    private const double BASE_FARE = 2.50;\n    private readonly Dictionary<RideType, double> ratePerKm = new Dictionary<RideType, double>\n    {\n        { RideType.SEDAN, 1.50 },\n        { RideType.SUV, 2.00 },\n        { RideType.AUTO, 1.00 }\n    };\n\n    public double CalculateFare(Location pickup, Location dropoff, RideType rideType)\n    {\n        return BASE_FARE + ratePerKm[rideType] * pickup.DistanceTo(dropoff);\n    }\n}"
  },
  {
    "path": "solutions/csharp/ridesharingservice/ridesharingservice.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Enums/GameStatus.cs",
    "content": "enum GameStatus\n{\n    NOT_STARTED,\n    RUNNING,\n    FINISHED\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Game.cs",
    "content": "class Game\n{\n    private readonly Board board;\n    private readonly Queue<Player> players;\n    private readonly Dice dice;\n    private GameStatus status;\n    private Player winner;\n\n    public Game(Board board, Queue<Player> players, Dice dice)\n    {\n        this.board = board;\n        this.players = new Queue<Player>(players);\n        this.dice = dice;\n        this.status = GameStatus.NOT_STARTED;\n        this.winner = null;\n    }\n\n    public void Play()\n    {\n        if (players.Count < 2)\n        {\n            Console.WriteLine(\"Cannot start game. At least 2 players are required.\");\n            return;\n        }\n\n        this.status = GameStatus.RUNNING;\n        Console.WriteLine(\"Game started!\");\n\n        while (status == GameStatus.RUNNING)\n        {\n            Player currentPlayer = players.Dequeue();\n            TakeTurn(currentPlayer);\n\n            if (status == GameStatus.RUNNING)\n            {\n                players.Enqueue(currentPlayer);\n            }\n        }\n\n        Console.WriteLine(\"Game Finished!\");\n        if (winner != null)\n        {\n            Console.WriteLine(\"The winner is \" + winner.GetName() + \"!\");\n        }\n    }\n\n    private void TakeTurn(Player player)\n    {\n        int roll = dice.Roll();\n        Console.WriteLine();\n        Console.WriteLine(player.GetName() + \"'s turn. Rolled a \" + roll + \".\");\n\n        int currentPosition = player.GetPosition();\n        int nextPosition = currentPosition + roll;\n\n        if (nextPosition > board.GetSize())\n        {\n            Console.WriteLine(\"Oops, \" + player.GetName() + \" needs to land exactly on \" + board.GetSize() + \". Turn skipped.\");\n            return;\n        }\n\n        if (nextPosition == board.GetSize())\n        {\n            player.SetPosition(nextPosition);\n            this.winner = player;\n            this.status = GameStatus.FINISHED;\n            Console.WriteLine(\"Hooray! \" + player.GetName() + \" reached the final square \" + board.GetSize() + \" and won!\");\n            return;\n        }\n\n        int finalPosition = board.GetFinalPosition(nextPosition);\n\n        if (finalPosition > nextPosition) // Ladder\n        {\n            Console.WriteLine(\"Wow! \" + player.GetName() + \" found a ladder 🪜 at \" + nextPosition + \" and climbed to \" + finalPosition + \".\");\n        }\n        else if (finalPosition < nextPosition) // Snake\n        {\n            Console.WriteLine(\"Oh no! \" + player.GetName() + \" was bitten by a snake 🐍 at \" + nextPosition + \" and slid down to \" + finalPosition + \".\");\n        }\n        else\n        {\n            Console.WriteLine(player.GetName() + \" moved from \" + currentPosition + \" to \" + finalPosition + \".\");\n        }\n\n        player.SetPosition(finalPosition);\n\n        if (roll == 6)\n        {\n            Console.WriteLine(player.GetName() + \" rolled a 6 and gets another turn!\");\n            TakeTurn(player);\n        }\n    }\n}\n\nclass GameBuilder\n{\n    private Board board;\n    private Queue<Player> players;\n    private Dice dice;\n\n    public GameBuilder SetBoard(int boardSize, List<BoardEntity> boardEntities)\n    {\n        this.board = new Board(boardSize, boardEntities);\n        return this;\n    }\n\n    public GameBuilder SetPlayers(List<string> playerNames)\n    {\n        this.players = new Queue<Player>();\n        foreach (string name in playerNames)\n        {\n            players.Enqueue(new Player(name));\n        }\n        return this;\n    }\n\n    public GameBuilder SetDice(Dice dice)\n    {\n        this.dice = dice;\n        return this;\n    }\n\n    public Game Build()\n    {\n        if (board == null || players == null || dice == null)\n        {\n            throw new InvalidOperationException(\"Board, Players, and Dice must be set.\");\n        }\n        return new Game(board, players, dice);\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/Board.cs",
    "content": "class Board\n{\n    private readonly int size;\n    private readonly Dictionary<int, int> snakesAndLadders;\n\n    public Board(int size, List<BoardEntity> entities)\n    {\n        this.size = size;\n        this.snakesAndLadders = new Dictionary<int, int>();\n\n        foreach (BoardEntity entity in entities)\n        {\n            snakesAndLadders[entity.GetStart()] = entity.GetEnd();\n        }\n    }\n\n    public int GetSize()\n    {\n        return size;\n    }\n\n    public int GetFinalPosition(int position)\n    {\n        if (snakesAndLadders.ContainsKey(position))\n        {\n            return snakesAndLadders[position];\n        }\n        return position;\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/BoardEntity.cs",
    "content": "abstract class BoardEntity\n{\n    protected readonly int start;\n    protected readonly int end;\n\n    public BoardEntity(int start, int end)\n    {\n        this.start = start;\n        this.end = end;\n    }\n\n    public int GetStart()\n    {\n        return start;\n    }\n\n    public int GetEnd()\n    {\n        return end;\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/Dice.cs",
    "content": "class Dice\n{\n    private readonly int minValue;\n    private readonly int maxValue;\n    private readonly Random random = new Random();\n\n    public Dice(int minValue, int maxValue)\n    {\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n    }\n\n    public int Roll()\n    {\n        return (int)(random.NextDouble() * (maxValue - minValue + 1) + minValue);\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/Ladder.cs",
    "content": "class Ladder : BoardEntity\n{\n    public Ladder(int start, int end) : base(start, end)\n    {\n        if (start >= end)\n        {\n            throw new ArgumentException(\"Ladder bottom must be at a lower position than its top.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/Player.cs",
    "content": "class Player\n{\n    private readonly string name;\n    private int position;\n\n    public Player(string name)\n    {\n        this.name = name;\n        this.position = 0;\n    }\n\n    public string GetName()\n    {\n        return name;\n    }\n\n    public int GetPosition()\n    {\n        return position;\n    }\n\n    public void SetPosition(int position)\n    {\n        this.position = position;\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/Models/Snake.cs",
    "content": "class Snake : BoardEntity\n{\n    public Snake(int start, int end) : base(start, end)\n    {\n        if (start <= end)\n        {\n            throw new ArgumentException(\"Snake head must be at a higher position than its tail.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/README.md",
    "content": "# Designing Snake and Ladder Game\n\n## Requirements\n1. The game should be played on a board with numbered cells, typically with 100 cells.\n2. The board should have a predefined set of snakes and ladders, connecting certain cells.\n3. The game should support multiple players, each represented by a unique game piece.\n4. Players should take turns rolling a dice to determine the number of cells to move forward.\n5. If a player lands on a cell with the head of a snake, they should slide down to the cell with the tail of the snake.\n6. If a player lands on a cell with the base of a ladder, they should climb up to the cell at the top of the ladder.\n7. The game should continue until one of the players reaches the final cell on the board.\n8. The game should handle multiple game sessions concurrently, allowing different groups of players to play independently.\n\n## Classes, Interfaces and Enumerations\n1. The **Board** class represents the game board with a fixed size (e.g., 100 cells). It contains the positions of snakes and ladders and provides methods to initialize them and retrieve the new position after encountering a snake or ladder.\n2. The **Player** class represents a player in the game, with properties such as name and current position on the board.\n3. The **Snake** class represents a snake on the board, with properties for the start and end positions.\n4. The **Ladder** class represents a ladder on the board, with properties for the start and end positions.\n5. The **Dice** class represents a dice used in the game, with a method to roll the dice and return a random value between 1 and 6.\n6. The **SnakeAndLadderGame** class represents a single game session. It initializes the game with a board, a list of players, and a dice. The play method handles the game loop, where players take turns rolling the dice and moving their positions on the board. It checks for snakes and ladders and updates the player's position accordingly. The game continues until a player reaches the final position on the board.\n7. The **GameManager** class is a singleton that manages multiple game sessions. It maintains a list of active games and provides a method to start a new game with a list of player names. Each game is started in a separate thread to allow concurrent game sessions.\n8. The **SnakeAndLadderDemo** class demonstrates the usage of the game by creating an instance of the GameManager and starting two separate game sessions with different sets of players."
  },
  {
    "path": "solutions/csharp/snakeandladdergame/SnakeAndLadderDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\npublic class SnakeAndLadderDemo\n{\n    public static void Main()\n    {\n        List<BoardEntity> boardEntities = new List<BoardEntity>\n        {\n            new Snake(17, 7), new Snake(54, 34),\n            new Snake(62, 19), new Snake(98, 79),\n            new Ladder(3, 38), new Ladder(24, 33),\n            new Ladder(42, 93), new Ladder(72, 84)\n        };\n\n        List<string> players = new List<string> { \"Alice\", \"Bob\", \"Charlie\" };\n\n        Game game = new GameBuilder()\n            .SetBoard(100, boardEntities)\n            .SetPlayers(players)\n            .SetDice(new Dice(1, 6))\n            .Build();            \n\n        game.Play();\n    }\n}"
  },
  {
    "path": "solutions/csharp/snakeandladdergame/snakeandladdergame.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Models/Comment.cs",
    "content": "class Comment : CommentableEntity\n{\n    public Comment(User author, string content) : base(author, content) { }\n\n    public List<Comment> GetReplies()\n    {\n        return GetComments();\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Models/CommentableEntity.cs",
    "content": "abstract class CommentableEntity\n{\n    protected readonly string id;\n    protected readonly User author;\n    protected readonly string content;\n    protected readonly DateTime timestamp;\n    private readonly HashSet<User> likes = new HashSet<User>();\n    protected readonly List<Comment> comments = new List<Comment>();\n\n    public CommentableEntity(User author, string content)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.author = author;\n        this.content = content;\n        this.timestamp = DateTime.Now;\n    }\n\n    public void AddLike(User user)\n    {\n        likes.Add(user);\n    }\n\n    public void AddComment(Comment comment)\n    {\n        comments.Add(comment);\n    }\n\n    public string GetId() { return id; }\n    public User GetAuthor() { return author; }\n    public string GetContent() { return content; }\n    public DateTime GetTimestamp() { return timestamp; }\n    public List<Comment> GetComments() { return comments; }\n    public HashSet<User> GetLikes() { return likes; }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Models/Post.cs",
    "content": "class Post : CommentableEntity\n{\n    public Post(User author, string content) : base(author, content) { }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Models/User.cs",
    "content": "class User\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n    private readonly HashSet<User> friends = new HashSet<User>();\n    private readonly List<Post> posts = new List<Post>();\n\n    public User(string name, string email)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public void AddFriend(User friend)\n    {\n        friends.Add(friend);\n    }\n\n    public void AddPost(Post post)\n    {\n        posts.Add(post);\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public HashSet<User> GetFriends() { return friends; }\n    public List<Post> GetPosts() { return posts; }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Observer/IPostObserver.cs",
    "content": "interface IPostObserver\n{\n    void OnPostCreated(Post post);\n    void OnLike(Post post, User user);\n    void OnComment(Post post, Comment comment);\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Observer/UserNotifier.cs",
    "content": "class UserNotifier : IPostObserver\n{\n    public void OnPostCreated(Post post)\n    {\n        User author = post.GetAuthor();\n        foreach (User friend in author.GetFriends())\n        {\n            Console.WriteLine($\"Notification for {friend.GetName()}: {author.GetName()} created a new post: {post.GetContent()}\");\n        }\n    }\n\n    public void OnLike(Post post, User user)\n    {\n        User author = post.GetAuthor();\n        Console.WriteLine($\"Notification for {author.GetName()}: {user.GetName()} liked your post\");\n    }\n\n    public void OnComment(Post post, Comment comment)\n    {\n        User author = post.GetAuthor();\n        Console.WriteLine($\"Notification for {author.GetName()}: {comment.GetAuthor().GetName()} commented on your post\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/README.md",
    "content": "# Designing a Social Network Like Facebook\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their personal information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their information, such as profile picture, bio, and interests.\n- Users should be able to update their profile information.\n#### Friend Connections:\n- Users should be able to send friend requests to other users.\n- Users should be able to accept or decline friend requests.\n- Users should be able to view their list of friends.\n#### Posts and Newsfeed:\n- Users should be able to create posts with text, images, or videos.\n- Users should be able to view a newsfeed consisting of posts from their friends and their own posts.\n- The newsfeed should be sorted in reverse chronological order.\n#### Likes and Comments:\n- Users should be able to like and comment on posts.\n- Users should be able to view the list of likes and comments on a post.\n#### Privacy and Security:\n- Users should be able to control the visibility of their posts and profile information.\n- The system should enforce secure access control to ensure data privacy.\n#### Notifications:\n- Users should receive notifications for events such as friend requests, likes, comments, and mentions.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the social networking system, containing properties such as ID, name, email, password, profile picture, bio, list of friends, and list of posts.\n2. The **Post** class represents a post created by a user, containing properties such as ID, user ID, content, image URLs, video URLs, timestamp, likes, and comments.\n3. The **Comment** class represents a comment made by a user on a post, containing properties such as ID, user ID, post ID, content, and timestamp.\n4. The **Notification** class represents a notification generated for a user, containing properties such as ID, user ID, notification type, content, and timestamp.\n5. The **NotificationType** enum defines the different types of notifications, such as friend request, friend request accepted, like, comment, and mention.\n6. The **SocialNetworkingService** class is the main class that manages the social networking system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SocialNetworkingService class provides methods for user registration, login, profile updates, friend requests, post creation, newsfeed generation, likes, comments, and notifications.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SocialNetworkingDemo** class demonstrates the usage of the social networking system by registering users, logging in, sending friend requests, creating posts, liking posts, commenting on posts, and retrieving newsfeed and notifications."
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Repositories/PostRepository.cs",
    "content": "class PostRepository\n{\n    private static readonly PostRepository INSTANCE = new PostRepository();\n    private readonly Dictionary<string, Post> posts = new Dictionary<string, Post>();\n\n    private PostRepository() { }\n\n    public static PostRepository GetInstance()\n    {\n        return INSTANCE;\n    }\n\n    public void Save(Post post)\n    {\n        posts[post.GetId()] = post;\n    }\n\n    public Post FindById(string id)\n    {\n        posts.TryGetValue(id, out Post post);\n        return post;\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Repositories/UserRepository.cs",
    "content": "class UserRepository\n{\n    private static readonly UserRepository INSTANCE = new UserRepository();\n    private readonly Dictionary<string, User> users = new Dictionary<string, User>();\n\n    private UserRepository() { }\n\n    public static UserRepository GetInstance()\n    {\n        return INSTANCE;\n    }\n\n    public void Save(User user)\n    {\n        users[user.GetId()] = user;\n    }\n\n    public User FindById(string id)\n    {\n        users.TryGetValue(id, out User user);\n        return user;\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Services/NewsFeedService.cs",
    "content": "class NewsFeedService\n{\n    private INewsFeedGenerationStrategy strategy;\n\n    public NewsFeedService()\n    {\n        this.strategy = new ChronologicalStrategy(); // Default strategy\n    }\n\n    public void SetStrategy(INewsFeedGenerationStrategy strategy)\n    {\n        this.strategy = strategy;\n    }\n\n    public List<Post> GetNewsFeed(User user)\n    {\n        return strategy.GenerateFeed(user);\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Services/PostService.cs",
    "content": "class PostService\n{\n    private readonly PostRepository postRepository = PostRepository.GetInstance();\n    private readonly List<IPostObserver> observers = new List<IPostObserver>();\n\n    public void AddObserver(IPostObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public Post CreatePost(User author, string content)\n    {\n        Post post = new Post(author, content);\n        postRepository.Save(post);\n        author.AddPost(post);\n        foreach (var observer in observers)\n        {\n            observer.OnPostCreated(post);\n        }\n        return post;\n    }\n\n    public void LikePost(User user, string postId)\n    {\n        Post post = postRepository.FindById(postId);\n        post.AddLike(user);\n        foreach (var observer in observers)\n        {\n            observer.OnLike(post, user);\n        }\n    }\n\n    public void AddComment(User author, string commentableId, string content)\n    {\n        Comment comment = new Comment(author, content);\n        Post post = postRepository.FindById(commentableId);\n        post.AddComment(comment);\n        foreach (var observer in observers)\n        {\n            observer.OnComment(post, comment);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Services/UserService.cs",
    "content": "class UserService\n{\n    private readonly UserRepository userRepository = UserRepository.GetInstance();\n\n    public User CreateUser(string name, string email)\n    {\n        User user = new User(name, email);\n        userRepository.Save(user);\n        return user;\n    }\n\n    public void AddFriend(string userId1, string userId2)\n    {\n        User user1 = userRepository.FindById(userId1);\n        User user2 = userRepository.FindById(userId2);\n\n        user1.AddFriend(user2);\n        user2.AddFriend(user1);\n    }\n\n    public User GetUserById(string userId)\n    {\n        return userRepository.FindById(userId);\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/SocialNetworkFacade.cs",
    "content": "class SocialNetworkFacade\n{\n    private readonly UserService userService;\n    private readonly PostService postService;\n    private readonly NewsFeedService newsFeedService;\n\n    public SocialNetworkFacade()\n    {\n        this.userService = new UserService();\n        this.postService = new PostService();\n        this.newsFeedService = new NewsFeedService();\n        // Wire up the observer\n        postService.AddObserver(new UserNotifier());\n    }\n\n    public User CreateUser(string name, string email)\n    {\n        return userService.CreateUser(name, email);\n    }\n\n    public void AddFriend(string userId1, string userId2)\n    {\n        userService.AddFriend(userId1, userId2);\n    }\n\n    public Post CreatePost(string authorId, string content)\n    {\n        User author = userService.GetUserById(authorId);\n        return postService.CreatePost(author, content);\n    }\n\n    public void AddComment(string userId, string postId, string content)\n    {\n        User user = userService.GetUserById(userId);\n        postService.AddComment(user, postId, content);\n    }\n\n    public void LikePost(string userId, string postId)\n    {\n        User user = userService.GetUserById(userId);\n        postService.LikePost(user, postId);\n    }\n\n    public List<Post> GetNewsFeed(string userId)\n    {\n        User user = userService.GetUserById(userId);\n        return newsFeedService.GetNewsFeed(user);\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/SocialNetworkingDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\npublic class SocialNetworkDemo\n{\n    private static void PrintFeed(List<Post> feed)\n    {\n        if (feed.Count == 0)\n        {\n            Console.WriteLine(\"  No posts in the feed.\");\n            return;\n        }\n\n        foreach (Post post in feed)\n        {\n            Console.WriteLine($\"  Post by {post.GetAuthor().GetName()} at {post.GetTimestamp()}\");\n            Console.WriteLine($\"    \\\"{post.GetContent()}\\\"\");\n            Console.WriteLine($\"    Likes: {post.GetLikes().Count}, Comments: {post.GetComments().Count}\");\n        }\n    }\n\n    public static void Main(string[] args)\n    {\n        SocialNetworkFacade socialNetwork = new SocialNetworkFacade();\n\n        Console.WriteLine(\"----------- 1. Creating Users -----------\");\n        User alice = socialNetwork.CreateUser(\"Alice\", \"alice@example.com\");\n        User bob = socialNetwork.CreateUser(\"Bob\", \"bob@example.com\");\n        User charlie = socialNetwork.CreateUser(\"Charlie\", \"charlie@example.com\");\n        Console.WriteLine($\"Created users: {alice.GetName()}, {bob.GetName()}, {charlie.GetName()}\");\n\n        Console.WriteLine(\"\\n----------- 2. Building Friendships -----------\");\n        socialNetwork.AddFriend(alice.GetId(), bob.GetId());\n        socialNetwork.AddFriend(bob.GetId(), charlie.GetId());\n        Console.WriteLine($\"{alice.GetName()} and {bob.GetName()} are now friends.\");\n        Console.WriteLine($\"{bob.GetName()} and {charlie.GetName()} are now friends.\");\n\n        Console.WriteLine(\"\\n----------- 3. Users Create Posts -----------\");\n        Post alicePost = socialNetwork.CreatePost(alice.GetId(), \"Hello from Alice!\");\n        Post bobPost = socialNetwork.CreatePost(bob.GetId(), \"It's a beautiful day!\");\n        Post charliePost = socialNetwork.CreatePost(charlie.GetId(), \"Thinking about design patterns.\");\n\n        Console.WriteLine(\"\\n----------- 4. Users Interact with Posts -----------\");\n        socialNetwork.AddComment(bob.GetId(), alicePost.GetId(), \"Hey Alice, nice to see you here!\");\n        socialNetwork.LikePost(charlie.GetId(), alicePost.GetId());\n\n        Console.WriteLine(\"\\n----------- 5. Viewing News Feeds (Strategy Pattern) -----------\");\n\n        Console.WriteLine(\"\\n--- Alice's News Feed (should see Bob's post) ---\");\n        List<Post> alicesFeed = socialNetwork.GetNewsFeed(alice.GetId());\n        PrintFeed(alicesFeed);\n\n        Console.WriteLine(\"\\n--- Bob's News Feed (should see Alice's, and Charlie's post) ---\");\n        List<Post> bobsFeed = socialNetwork.GetNewsFeed(bob.GetId());\n        PrintFeed(bobsFeed);\n\n        Console.WriteLine(\"\\n--- Charlie's News Feed (should see Bob's post) ---\");\n        List<Post> charliesFeed = socialNetwork.GetNewsFeed(charlie.GetId());\n        PrintFeed(charliesFeed);\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Strategy/ChronologicalStrategy.cs",
    "content": "class ChronologicalStrategy : INewsFeedGenerationStrategy\n{\n    public List<Post> GenerateFeed(User user)\n    {\n        HashSet<User> friends = user.GetFriends();\n        List<Post> feed = new List<Post>();\n\n        foreach (User friend in friends)\n        {\n            feed.AddRange(friend.GetPosts());\n        }\n\n        // Sort posts by timestamp in reverse (most recent first)\n        feed.Sort((p1, p2) => p2.GetTimestamp().CompareTo(p1.GetTimestamp()));\n\n        return feed;\n    }\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/Strategy/INewsFeedGenerationStrategy.cs",
    "content": "interface INewsFeedGenerationStrategy\n{\n    List<Post> GenerateFeed(User user);\n}"
  },
  {
    "path": "solutions/csharp/socialnetworkingservice/socialnetworkingservice.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/splitwise/Models/BalanceSheet.cs",
    "content": "class BalanceSheet\n{\n    private readonly User owner;\n    private readonly Dictionary<User, double> balances = new Dictionary<User, double>();\n    private readonly object balanceLock = new object();\n\n    public BalanceSheet(User owner)\n    {\n        this.owner = owner;\n    }\n\n    public Dictionary<User, double> GetBalances() => balances;\n\n    public void AdjustBalance(User otherUser, double amount)\n    {\n        lock (balanceLock)\n        {\n            if (owner.Equals(otherUser))\n            {\n                return; // Cannot owe yourself\n            }\n\n            if (balances.ContainsKey(otherUser))\n            {\n                balances[otherUser] += amount;\n            }\n            else\n            {\n                balances[otherUser] = amount;\n            }\n        }\n    }\n\n    public void ShowBalances()\n    {\n        Console.WriteLine($\"--- Balance Sheet for {owner.GetName()} ---\");\n        if (balances.Count == 0)\n        {\n            Console.WriteLine(\"All settled up!\");\n            return;\n        }\n\n        double totalOwedToMe = 0;\n        double totalIOwe = 0;\n\n        foreach (var entry in balances)\n        {\n            User otherUser = entry.Key;\n            double amount = entry.Value;\n\n            if (amount > 0.01)\n            {\n                Console.WriteLine($\"{otherUser.GetName()} owes {owner.GetName()} ${amount:F2}\");\n                totalOwedToMe += amount;\n            }\n            else if (amount < -0.01)\n            {\n                Console.WriteLine($\"{owner.GetName()} owes {otherUser.GetName()} ${-amount:F2}\");\n                totalIOwe += (-amount);\n            }\n        }\n\n        Console.WriteLine($\"Total Owed to {owner.GetName()}: ${totalOwedToMe:F2}\");\n        Console.WriteLine($\"Total {owner.GetName()} Owes: ${totalIOwe:F2}\");\n        Console.WriteLine(\"---------------------------------\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Models/Expense.cs",
    "content": "class Expense\n{\n    private readonly string id;\n    private readonly string description;\n    private readonly double amount;\n    private readonly User paidBy;\n    private readonly List<Split> splits;\n    private readonly DateTime timestamp;\n\n    public Expense(ExpenseBuilder builder)\n    {\n        this.id = builder.Id;\n        this.description = builder.Description;\n        this.amount = builder.Amount;\n        this.paidBy = builder.PaidBy;\n        this.timestamp = DateTime.Now;\n\n        // Use the strategy to calculate splits\n        this.splits = builder.SplitStrategy.CalculateSplits(\n            builder.Amount, builder.PaidBy, builder.Participants, builder.SplitValues);\n    }\n\n    public string GetId() => id;\n    public string GetDescription() => description;\n    public double GetAmount() => amount;\n    public User GetPaidBy() => paidBy;\n    public List<Split> GetSplits() => splits;\n}\n\nclass ExpenseBuilder\n{\n    public string Id { get; set; }\n    public string Description { get; set; }\n    public double Amount { get; set; }\n    public User PaidBy { get; set; }\n    public List<User> Participants { get; set; }\n    public SplitStrategy SplitStrategy { get; set; }\n    public List<double> SplitValues { get; set; }\n\n    public ExpenseBuilder SetId(string id)\n    {\n        this.Id = id;\n        return this;\n    }\n\n    public ExpenseBuilder SetDescription(string description)\n    {\n        this.Description = description;\n        return this;\n    }\n\n    public ExpenseBuilder SetAmount(double amount)\n    {\n        this.Amount = amount;\n        return this;\n    }\n\n    public ExpenseBuilder SetPaidBy(User paidBy)\n    {\n        this.PaidBy = paidBy;\n        return this;\n    }\n\n    public ExpenseBuilder SetParticipants(List<User> participants)\n    {\n        this.Participants = participants;\n        return this;\n    }\n\n    public ExpenseBuilder SetSplitStrategy(SplitStrategy splitStrategy)\n    {\n        this.SplitStrategy = splitStrategy;\n        return this;\n    }\n\n    public ExpenseBuilder SetSplitValues(List<double> splitValues)\n    {\n        this.SplitValues = splitValues;\n        return this;\n    }\n\n    public Expense Build()\n    {\n        if (SplitStrategy == null)\n        {\n            throw new InvalidOperationException(\"Split strategy is required.\");\n        }\n        return new Expense(this);\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Models/Group.cs",
    "content": "class Group\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly List<User> members;\n\n    public Group(string name, List<User> members)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.members = members;\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n    public List<User> GetMembers() => new List<User>(members);\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Models/Split.cs",
    "content": "class Split\n{\n    private readonly User user;\n    private readonly double amount;\n\n    public Split(User user, double amount)\n    {\n        this.user = user;\n        this.amount = amount;\n    }\n\n    public User GetUser() => user;\n    public double GetAmount() => amount;\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Models/Transaction.cs",
    "content": "class Transaction\n{\n    private readonly User from;\n    private readonly User to;\n    private readonly double amount;\n\n    public Transaction(User from, User to, double amount)\n    {\n        this.from = from;\n        this.to = to;\n        this.amount = amount;\n    }\n\n    public override string ToString()\n    {\n        return $\"{from.GetName()} should pay {to.GetName()} ${amount:F2}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Models/User.cs",
    "content": "class User\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n    private readonly BalanceSheet balanceSheet;\n\n    public User(string name, string email)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n        this.balanceSheet = new BalanceSheet(this);\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n    public BalanceSheet GetBalanceSheet() => balanceSheet;\n}"
  },
  {
    "path": "solutions/csharp/splitwise/README.md",
    "content": "# Designing Splitwise\n\n## Requirements\n1. The system should allow users to create accounts and manage their profile information.\n2. Users should be able to create groups and add other users to the groups.\n3. Users should be able to add expenses within a group, specifying the amount, description, and participants.\n4. The system should automatically split the expenses among the participants based on their share.\n5. Users should be able to view their individual balances with other users and settle up the balances.\n6. The system should support different split methods, such as equal split, percentage split, and exact amounts.\n7. Users should be able to view their transaction history and group expenses.\n8. The system should handle concurrent transactions and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the Splitwise system, with properties such as ID, name, email, and a map to store balances with other users.\n2. The **Group** class represents a group in Splitwise, containing a list of member users and a list of expenses.\n3. The **Expense** class represents an expense within a group, with properties such as ID, amount, description, the user who paid, and a list of splits.\n4. The **Split** class is an abstract class representing the split of an expense. It is extended by EqualSplit, PercentSplit, and ExactSplit classes to handle different split methods.\n5. The **Transaction** class represents a transaction between two users, with properties such as ID, sender, receiver, and amount.\n6. The **SplitwiseService** class is the main class that manages the Splitwise system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SplitwiseService class provides methods for adding users, groups, and expenses, splitting expenses, updating balances, settling balances, and creating transactions.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SplitwiseDemo** class demonstrates the usage of the Splitwise system by creating users, a group, adding an expense, settling balances, and printing user balances."
  },
  {
    "path": "solutions/csharp/splitwise/SplitwiseDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class SplitwiseDemo\n{\n    public static void Main(string[] args)\n    {\n        // 1. Setup the service\n        SplitwiseService service = SplitwiseService.GetInstance();\n\n        // 2. Create users and groups\n        User alice = service.AddUser(\"Alice\", \"alice@a.com\");\n        User bob = service.AddUser(\"Bob\", \"bob@b.com\");\n        User charlie = service.AddUser(\"Charlie\", \"charlie@c.com\");\n        User david = service.AddUser(\"David\", \"david@d.com\");\n\n        Group friendsGroup = service.AddGroup(\"Friends Trip\", new List<User> { alice, bob, charlie, david });\n\n        Console.WriteLine(\"--- System Setup Complete ---\\n\");\n\n        // 3. Use Case 1: Equal Split\n        Console.WriteLine(\"--- Use Case 1: Equal Split ---\");\n        service.CreateExpense(new ExpenseBuilder()\n                              .SetDescription(\"Dinner\")\n                              .SetAmount(1000)\n                              .SetPaidBy(alice)\n                              .SetParticipants(new List<User> { alice, bob, charlie, david })\n                              .SetSplitStrategy(new EqualSplitStrategy()));\n\n        service.ShowBalanceSheet(alice.GetId());\n        service.ShowBalanceSheet(bob.GetId());\n        Console.WriteLine();\n\n        // 4. Use Case 2: Exact Split\n        Console.WriteLine(\"--- Use Case 2: Exact Split ---\");\n        service.CreateExpense(new ExpenseBuilder()\n                              .SetDescription(\"Movie Tickets\")\n                              .SetAmount(370)\n                              .SetPaidBy(alice)\n                              .SetParticipants(new List<User> { bob, charlie })\n                              .SetSplitStrategy(new ExactSplitStrategy())\n                              .SetSplitValues(new List<double> { 120.0, 250.0 }));\n\n        service.ShowBalanceSheet(alice.GetId());\n        service.ShowBalanceSheet(bob.GetId());\n        Console.WriteLine();\n\n        // 5. Use Case 3: Percentage Split\n        Console.WriteLine(\"--- Use Case 3: Percentage Split ---\");\n        service.CreateExpense(new ExpenseBuilder()\n                              .SetDescription(\"Groceries\")\n                              .SetAmount(500)\n                              .SetPaidBy(david)\n                              .SetParticipants(new List<User> { alice, bob, charlie })\n                              .SetSplitStrategy(new PercentageSplitStrategy())\n                              .SetSplitValues(new List<double> { 40.0, 30.0, 30.0 })); // 40%, 30%, 30%\n\n        Console.WriteLine(\"--- Balances After All Expenses ---\");\n        service.ShowBalanceSheet(alice.GetId());\n        service.ShowBalanceSheet(bob.GetId());\n        service.ShowBalanceSheet(charlie.GetId());\n        service.ShowBalanceSheet(david.GetId());\n        Console.WriteLine();\n\n        // 6. Use Case 4: Simplify Group Debts\n        Console.WriteLine(\"--- Use Case 4: Simplify Group Debts for 'Friends Trip' ---\");\n        List<Transaction> simplifiedDebts = service.SimplifyGroupDebts(friendsGroup.GetId());\n        if (simplifiedDebts.Count == 0)\n        {\n            Console.WriteLine(\"All debts are settled within the group!\");\n        }\n        else\n        {\n            foreach (Transaction debt in simplifiedDebts)\n            {\n                Console.WriteLine(debt.ToString());\n            }\n        }\n        Console.WriteLine();\n\n        service.ShowBalanceSheet(bob.GetId());\n\n        // 7. Use Case 5: Partial Settlement\n        Console.WriteLine(\"--- Use Case 5: Partial Settlement ---\");\n        // From the simplified debts, we see Bob should pay Alice. Let's say Bob pays 100.\n        service.SettleUp(bob.GetId(), alice.GetId(), 100);\n\n        Console.WriteLine(\"--- Balances After Partial Settlement ---\");\n        service.ShowBalanceSheet(alice.GetId());\n        service.ShowBalanceSheet(bob.GetId());\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/SplitwiseService.cs",
    "content": "class SplitwiseService\n{\n    private static SplitwiseService instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<string, User> users = new Dictionary<string, User>();\n    private readonly Dictionary<string, Group> groups = new Dictionary<string, Group>();\n\n    private SplitwiseService() { }\n\n    public static SplitwiseService GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new SplitwiseService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public User AddUser(string name, string email)\n    {\n        User user = new User(name, email);\n        users[user.GetId()] = user;\n        return user;\n    }\n\n    public Group AddGroup(string name, List<User> members)\n    {\n        Group group = new Group(name, members);\n        groups[group.GetId()] = group;\n        return group;\n    }\n\n    public User GetUser(string id)\n    {\n        return users.TryGetValue(id, out User user) ? user : null;\n    }\n\n    public Group GetGroup(string id)\n    {\n        return groups.TryGetValue(id, out Group group) ? group : null;\n    }\n\n    public void CreateExpense(ExpenseBuilder builder)\n    {\n        lock (lockObject)\n        {\n            Expense expense = builder.Build();\n            User paidBy = expense.GetPaidBy();\n\n            foreach (Split split in expense.GetSplits())\n            {\n                User participant = split.GetUser();\n                double amount = split.GetAmount();\n\n                if (!paidBy.Equals(participant))\n                {\n                    paidBy.GetBalanceSheet().AdjustBalance(participant, amount);\n                    participant.GetBalanceSheet().AdjustBalance(paidBy, -amount);\n                }\n            }\n\n            Console.WriteLine($\"Expense '{expense.GetDescription()}' of amount {expense.GetAmount()} created.\");\n        }\n    }\n\n    public void SettleUp(string payerId, string payeeId, double amount)\n    {\n        lock (lockObject)\n        {\n            User payer = users[payerId];\n            User payee = users[payeeId];\n            Console.WriteLine($\"{payer.GetName()} is settling up {amount} with {payee.GetName()}\");\n\n            // Settlement is like a reverse expense. payer owes less to payee.\n            payee.GetBalanceSheet().AdjustBalance(payer, -amount);\n            payer.GetBalanceSheet().AdjustBalance(payee, amount);\n        }\n    }\n\n    public void ShowBalanceSheet(string userId)\n    {\n        User user = users[userId];\n        user.GetBalanceSheet().ShowBalances();\n    }\n\n    public List<Transaction> SimplifyGroupDebts(string groupId)\n    {\n        Group group = groups[groupId];\n        if (group == null)\n        {\n            throw new ArgumentException(\"Group not found\");\n        }\n\n        // Calculate net balance for each member within the group context\n        Dictionary<User, double> netBalances = new Dictionary<User, double>();\n        foreach (User member in group.GetMembers())\n        {\n            double balance = 0;\n            foreach (var entry in member.GetBalanceSheet().GetBalances())\n            {\n                // Consider only balances with other group members\n                if (group.GetMembers().Contains(entry.Key))\n                {\n                    balance += entry.Value;\n                }\n            }\n            netBalances[member] = balance;\n        }\n\n        // Separate into creditors and debtors\n        var creditors = netBalances.Where(e => e.Value > 0).OrderByDescending(e => e.Value).ToList();\n        var debtors = netBalances.Where(e => e.Value < 0).OrderBy(e => e.Value).ToList();\n\n        List<Transaction> transactions = new List<Transaction>();\n        int i = 0, j = 0;\n\n        while (i < creditors.Count && j < debtors.Count)\n        {\n            var creditor = creditors[i];\n            var debtor = debtors[j];\n\n            double amountToSettle = Math.Min(creditor.Value, -debtor.Value);\n            transactions.Add(new Transaction(debtor.Key, creditor.Key, amountToSettle));\n\n            // Update the values\n            creditors[i] = new KeyValuePair<User, double>(creditor.Key, creditor.Value - amountToSettle);\n            debtors[j] = new KeyValuePair<User, double>(debtor.Key, debtor.Value + amountToSettle);\n\n            if (Math.Abs(creditors[i].Value) < 0.01) i++;\n            if (Math.Abs(debtors[j].Value) < 0.01) j++;\n        }\n\n        return transactions;\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Strategy/EqualSplitStrategy.cs",
    "content": "class EqualSplitStrategy : SplitStrategy\n{\n    public override List<Split> CalculateSplits(double totalAmount, User paidBy, List<User> participants, List<double> splitValues)\n    {\n        List<Split> splits = new List<Split>();\n        double amountPerPerson = totalAmount / participants.Count;\n        foreach (User participant in participants)\n        {\n            splits.Add(new Split(participant, amountPerPerson));\n        }\n        return splits;\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Strategy/ExactSplitStrategy.cs",
    "content": "class ExactSplitStrategy : SplitStrategy\n{\n    public override List<Split> CalculateSplits(double totalAmount, User paidBy, List<User> participants, List<double> splitValues)\n    {\n        if (participants.Count != splitValues.Count)\n        {\n            throw new ArgumentException(\"Number of participants and split values must match.\");\n        }\n\n        if (Math.Abs(splitValues.Sum() - totalAmount) > 0.01)\n        {\n            throw new ArgumentException(\"Sum of exact amounts must equal the total expense amount.\");\n        }\n\n        List<Split> splits = new List<Split>();\n        for (int i = 0; i < participants.Count; i++)\n        {\n            splits.Add(new Split(participants[i], splitValues[i]));\n        }\n        return splits;\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Strategy/PercentageSplitStrategy.cs",
    "content": "class PercentageSplitStrategy : SplitStrategy\n{\n    public override List<Split> CalculateSplits(double totalAmount, User paidBy, List<User> participants, List<double> splitValues)\n    {\n        if (participants.Count != splitValues.Count)\n        {\n            throw new ArgumentException(\"Number of participants and split values must match.\");\n        }\n\n        if (Math.Abs(splitValues.Sum() - 100.0) > 0.01)\n        {\n            throw new ArgumentException(\"Sum of percentages must be 100.\");\n        }\n\n        List<Split> splits = new List<Split>();\n        for (int i = 0; i < participants.Count; i++)\n        {\n            double amount = (totalAmount * splitValues[i]) / 100.0;\n            splits.Add(new Split(participants[i], amount));\n        }\n        return splits;\n    }\n}"
  },
  {
    "path": "solutions/csharp/splitwise/Strategy/SplitStrategy.cs",
    "content": "abstract class SplitStrategy\n{\n    public abstract List<Split> CalculateSplits(double totalAmount, User paidBy, List<User> participants, List<double> splitValues);\n}"
  },
  {
    "path": "solutions/csharp/splitwise/splitwise.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/stackoverflow/Enums/EventType.cs",
    "content": "enum EventType\n{\n    UPVOTE_QUESTION,\n    DOWNVOTE_QUESTION,\n    UPVOTE_ANSWER,\n    DOWNVOTE_ANSWER,\n    ACCEPT_ANSWER\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Enums/VoteType.cs",
    "content": "enum VoteType\n{\n    UPVOTE,\n    DOWNVOTE\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Answer.cs",
    "content": "class Answer : Post\n{\n    private bool isAccepted = false;\n\n    public Answer(string body, User author)\n        : base(Guid.NewGuid().ToString(), body, author)\n    {\n    }\n\n    public void SetAccepted(bool accepted)\n    {\n        isAccepted = accepted;\n    }\n\n    public bool IsAcceptedAnswer() { return isAccepted; }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Comment.cs",
    "content": "class Comment : Content\n{\n    public Comment(string body, User author)\n        : base(Guid.NewGuid().ToString(), body, author)\n    {\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Content.cs",
    "content": "abstract class Content\n{\n    protected readonly string id;\n    protected readonly string body;\n    protected readonly User author;\n    protected readonly DateTime creationTime;\n\n    public Content(string id, string body, User author)\n    {\n        this.id = id;\n        this.body = body;\n        this.author = author;\n        this.creationTime = DateTime.Now;\n    }\n\n    public string GetId() { return id; }\n    public string GetBody() { return body; }\n    public User GetAuthor() { return author; }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Post.cs",
    "content": "using System.Collections.Concurrent;\n\nabstract class Post : Content\n{\n    private int voteCount = 0;\n    private readonly ConcurrentDictionary<string, VoteType> voters = new ConcurrentDictionary<string, VoteType>();\n    private readonly List<Comment> comments = new List<Comment>();\n    private readonly List<IPostObserver> observers = new List<IPostObserver>();\n    private readonly object postLock = new object();\n\n    public Post(string id, string body, User author) : base(id, body, author)\n    {\n    }\n\n    public void AddObserver(IPostObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    protected void NotifyObservers(Event eventObj)\n    {\n        foreach (var observer in observers)\n        {\n            observer.OnPostEvent(eventObj);\n        }\n    }\n\n    public void Vote(User user, VoteType voteType)\n    {\n        lock (postLock)\n        {\n            string userId = user.GetId();\n            if (voters.TryGetValue(userId, out VoteType existingVote) && existingVote == voteType)\n                return; // Already voted\n\n            int scoreChange = 0;\n            if (voters.ContainsKey(userId)) // User is changing their vote\n            {\n                scoreChange = (voteType == VoteType.UPVOTE) ? 2 : -2;\n            }\n            else // New vote\n            {\n                scoreChange = (voteType == VoteType.UPVOTE) ? 1 : -1;\n            }\n\n            voters[userId] = voteType;\n            voteCount += scoreChange;\n\n            EventType eventType;\n            if (this is Question)\n            {\n                eventType = (voteType == VoteType.UPVOTE) ? EventType.UPVOTE_QUESTION : EventType.DOWNVOTE_QUESTION;\n            }\n            else\n            {\n                eventType = (voteType == VoteType.UPVOTE) ? EventType.UPVOTE_ANSWER : EventType.DOWNVOTE_ANSWER;\n            }\n\n            NotifyObservers(new Event(eventType, user, this));\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Question.cs",
    "content": "class Question : Post\n{\n    private readonly string title;\n    private readonly HashSet<Tag> tags;\n    private readonly List<Answer> answers = new List<Answer>();\n    private Answer acceptedAnswer;\n\n    public Question(string title, string body, User author, HashSet<Tag> tags)\n        : base(Guid.NewGuid().ToString(), body, author)\n    {\n        this.title = title;\n        this.tags = tags;\n    }\n\n    public void AddAnswer(Answer answer)\n    {\n        answers.Add(answer);\n    }\n\n    public void AcceptAnswer(Answer answer)\n    {\n        lock (this)\n        {\n            if (!author.GetId().Equals(answer.GetAuthor().GetId()) && acceptedAnswer == null)\n            {\n                acceptedAnswer = answer;\n                answer.SetAccepted(true);\n                NotifyObservers(new Event(EventType.ACCEPT_ANSWER, answer.GetAuthor(), answer));\n            }\n        }\n    }\n\n    public string GetTitle() { return title; }\n    public HashSet<Tag> GetTags() { return tags; }\n    public List<Answer> GetAnswers() { return answers; }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/Tag.cs",
    "content": "class Tag : IComparable<Tag>\n{\n    private readonly string name;\n\n    public Tag(string name)\n    {\n        this.name = name;\n    }\n\n    public string GetName() { return name; }\n\n    public int CompareTo(Tag other)\n    {\n        return string.Compare(name, other.name, StringComparison.Ordinal);\n    }\n\n    public override bool Equals(object obj)\n    {\n        if (obj is Tag other)\n        {\n            return name.Equals(other.name, StringComparison.OrdinalIgnoreCase);\n        }\n        return false;\n    }\n\n    public override int GetHashCode()\n    {\n        return name.ToLower().GetHashCode();\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Models/User.cs",
    "content": "class User\n{\n    private readonly string id;\n    private readonly string name;\n    private int reputation;\n    private readonly object reputationLock = new object();\n\n    public User(string name)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.reputation = 0;\n    }\n\n    public void UpdateReputation(int change)\n    {\n        lock (reputationLock)\n        {\n            reputation += change;\n        }\n    }\n\n    public string GetId() { return id; }\n    public string GetName() { return name; }\n    public int GetReputation() \n    { \n        lock (reputationLock)\n        {\n            return reputation;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Observer/Event.cs",
    "content": "class Event\n{\n    private readonly EventType type;\n    private readonly User actor;\n    private readonly Post targetPost;\n\n    public Event(EventType type, User actor, Post targetPost)\n    {\n        this.type = type;\n        this.actor = actor;\n        this.targetPost = targetPost;\n    }\n\n    public EventType GetEventType() { return type; }\n    public User GetActor() { return actor; }\n    public Post GetTargetPost() { return targetPost; }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Observer/IPostObserver.cs",
    "content": "interface IPostObserver\n{\n    void OnPostEvent(Event eventObj);\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Observer/ReputationManager.cs",
    "content": "class ReputationManager : IPostObserver\n{\n    private const int QUESTION_UPVOTE_REP = 5;\n    private const int ANSWER_UPVOTE_REP = 10;\n    private const int ACCEPTED_ANSWER_REP = 15;\n    private const int DOWNVOTE_REP_PENALTY = -1;\n    private const int POST_DOWNVOTED_REP_PENALTY = -2;\n\n    public void OnPostEvent(Event eventObj)\n    {\n        User postAuthor = eventObj.GetTargetPost().GetAuthor();\n\n        switch (eventObj.GetEventType())\n        {\n            case EventType.UPVOTE_QUESTION:\n                postAuthor.UpdateReputation(QUESTION_UPVOTE_REP);\n                break;\n            case EventType.DOWNVOTE_QUESTION:\n                postAuthor.UpdateReputation(DOWNVOTE_REP_PENALTY);\n                eventObj.GetActor().UpdateReputation(POST_DOWNVOTED_REP_PENALTY);\n                break;\n            case EventType.UPVOTE_ANSWER:\n                postAuthor.UpdateReputation(ANSWER_UPVOTE_REP);\n                break;\n            case EventType.DOWNVOTE_ANSWER:\n                postAuthor.UpdateReputation(DOWNVOTE_REP_PENALTY);\n                eventObj.GetActor().UpdateReputation(POST_DOWNVOTED_REP_PENALTY);\n                break;\n            case EventType.ACCEPT_ANSWER:\n                postAuthor.UpdateReputation(ACCEPTED_ANSWER_REP);\n                break;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/README.md",
    "content": "# Designing Stack Overflow\n\n## Requirements\n1. Users can post questions, answer questions, and comment on questions and answers.\n2. Users can vote on questions and answers.\n3. Questions should have tags associated with them.\n4. Users can search for questions based on keywords, tags, or user profiles.\n5. The system should assign reputation score to users based on their activity and the quality of their contributions.\n6. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the Stack Overflow system, with properties such as id, username, email, and reputation.\n2. The **Question** class represents a question posted by a user, with properties such as id, title, content, author, answers, comments, tags, votes and creation date.\n3. The **Answer** class represents an answer to a question, with properties such as id, content, author, associated question, comments, votes and creation date.\n4. The **Comment** class represents a comment on a question or an answer, with properties such as id, content, author, and creation date.\n5. The **Tag** class represents a tag associated with a question, with properties such as id and name.\n6. The **Vote** class represents vote associated with a question/answer.\n7. The **StackOverflow** class is the main class that manages the Stack Overflow system. It provides methods for creating user, posting questions, answers, and comments, voting on questions and answers, searching for questions, and retrieving questions by tags and users.\n8.  The **StackOverflowDemo** class demonstrates the usage of the Stack Overflow system by creating users, posting questions and answers, voting, searching for questions, and retrieving questions by tags and users."
  },
  {
    "path": "solutions/csharp/stackoverflow/StackOverflowDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class StackOverflowDemo\n{\n    public static void Main(string[] args)\n    {\n        StackOverflowService service = new StackOverflowService();\n\n        // 1. Create Users\n        User alice = service.CreateUser(\"Alice\");\n        User bob = service.CreateUser(\"Bob\");\n        User charlie = service.CreateUser(\"Charlie\");\n\n        // 2. Alice posts a question\n        Console.WriteLine(\"--- Alice posts a question ---\");\n        Tag javaTag = new Tag(\"java\");\n        Tag designPatternsTag = new Tag(\"design-patterns\");\n        HashSet<Tag> tags = new HashSet<Tag> { javaTag, designPatternsTag };\n        Question question = service.PostQuestion(alice.GetId(), \"How to implement Observer Pattern?\", \"Details about Observer Pattern...\", tags);\n        PrintReputations(alice, bob, charlie);\n\n        // 3. Bob and Charlie post answers\n        Console.WriteLine(\"\\n--- Bob and Charlie post answers ---\");\n        Answer bobAnswer = service.PostAnswer(bob.GetId(), question.GetId(), \"You can use the java.util.Observer interface.\");\n        Answer charlieAnswer = service.PostAnswer(charlie.GetId(), question.GetId(), \"A better way is to create your own Observer interface.\");\n        PrintReputations(alice, bob, charlie);\n\n        // 4. Voting happens\n        Console.WriteLine(\"\\n--- Voting Occurs ---\");\n        service.VoteOnPost(alice.GetId(), question.GetId(), VoteType.UPVOTE);\n        service.VoteOnPost(bob.GetId(), charlieAnswer.GetId(), VoteType.UPVOTE);\n        service.VoteOnPost(alice.GetId(), bobAnswer.GetId(), VoteType.DOWNVOTE);\n        PrintReputations(alice, bob, charlie);\n\n        // 5. Alice accepts Charlie's answer\n        Console.WriteLine(\"\\n--- Alice accepts Charlie's answer ---\");\n        service.AcceptAnswer(question.GetId(), charlieAnswer.GetId());\n        PrintReputations(alice, bob, charlie);\n\n        // 6. Search for questions\n        Console.WriteLine(\"\\n--- (C) Combined Search: Questions by 'Alice' with tag 'java' ---\");\n        List<ISearchStrategy> filtersC = new List<ISearchStrategy>\n        {\n            new UserSearchStrategy(alice),\n            new TagSearchStrategy(javaTag)\n        };\n        List<Question> searchResults = service.SearchQuestions(filtersC);\n        foreach (var q in searchResults)\n        {\n            Console.WriteLine($\"  - Found: {q.GetTitle()}\");\n        }\n    }\n\n    private static void PrintReputations(params User[] users)\n    {\n        Console.WriteLine(\"--- Current Reputations ---\");\n        foreach (User user in users)\n        {\n            Console.WriteLine($\"{user.GetName()}: {user.GetReputation()}\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/StackOverflowService.cs",
    "content": "using System.Collections.Concurrent;\n\nclass StackOverflowService\n{\n    private readonly ConcurrentDictionary<string, User> users = new ConcurrentDictionary<string, User>();\n    private readonly ConcurrentDictionary<string, Question> questions = new ConcurrentDictionary<string, Question>();\n    private readonly ConcurrentDictionary<string, Answer> answers = new ConcurrentDictionary<string, Answer>();\n    private readonly IPostObserver reputationManager = new ReputationManager();\n\n    public User CreateUser(string name)\n    {\n        User user = new User(name);\n        users.TryAdd(user.GetId(), user);\n        return user;\n    }\n\n    public Question PostQuestion(string userId, string title, string body, HashSet<Tag> tags)\n    {\n        User author = users[userId];\n        Question question = new Question(title, body, author, tags);\n        question.AddObserver(reputationManager);\n        questions.TryAdd(question.GetId(), question);\n        return question;\n    }\n\n    public Answer PostAnswer(string userId, string questionId, string body)\n    {\n        User author = users[userId];\n        Question question = questions[questionId];\n        Answer answer = new Answer(body, author);\n        answer.AddObserver(reputationManager);\n        question.AddAnswer(answer);\n        answers.TryAdd(answer.GetId(), answer);\n        return answer;\n    }\n\n    public void VoteOnPost(string userId, string postId, VoteType voteType)\n    {\n        User user = users[userId];\n        Post post = FindPostById(postId);\n        post.Vote(user, voteType);\n    }\n\n    public void AcceptAnswer(string questionId, string answerId)\n    {\n        Question question = questions[questionId];\n        Answer answer = answers[answerId];\n        question.AcceptAnswer(answer);\n    }\n\n    public List<Question> SearchQuestions(List<ISearchStrategy> strategies)\n    {\n        List<Question> results = questions.Values.ToList();\n\n        foreach (var strategy in strategies)\n        {\n            results = strategy.Filter(results);\n        }\n\n        return results;\n    }\n\n    public User GetUser(string userId)\n    {\n        return users[userId];\n    }\n\n    private Post FindPostById(string postId)\n    {\n        if (questions.TryGetValue(postId, out Question question))\n        {\n            return question;\n        }\n        else if (answers.TryGetValue(postId, out Answer answer))\n        {\n            return answer;\n        }\n\n        throw new KeyNotFoundException(\"Post not found\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Strategy/ISearchStrategy.cs",
    "content": "interface ISearchStrategy\n{\n    List<Question> Filter(List<Question> questions);\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Strategy/KeywordSearchStrategy.cs",
    "content": "class KeywordSearchStrategy : ISearchStrategy\n{\n    private readonly string keyword;\n\n    public KeywordSearchStrategy(string keyword)\n    {\n        this.keyword = keyword.ToLower();\n    }\n\n    public List<Question> Filter(List<Question> questions)\n    {\n        return questions\n            .Where(q => q.GetTitle().ToLower().Contains(keyword) || q.GetBody().ToLower().Contains(keyword))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Strategy/TagSearchStrategy.cs",
    "content": "class TagSearchStrategy : ISearchStrategy\n{\n    private readonly Tag tag;\n\n    public TagSearchStrategy(Tag tag)\n    {\n        this.tag = tag;\n    }\n\n    public List<Question> Filter(List<Question> questions)\n    {\n        return questions\n            .Where(q => q.GetTags().Any(t => t.GetName().Equals(tag.GetName(), StringComparison.OrdinalIgnoreCase)))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/Strategy/UserSearchStrategy.cs",
    "content": "class UserSearchStrategy : ISearchStrategy\n{\n    private readonly User user;\n\n    public UserSearchStrategy(User user)\n    {\n        this.user = user;\n    }\n\n    public List<Question> Filter(List<Question> questions)\n    {\n        return questions\n            .Where(q => q.GetAuthor().GetId().Equals(user.GetId()))\n            .ToList();\n    }\n}"
  },
  {
    "path": "solutions/csharp/stackoverflow/stackoverflow.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Enums/TaskPriority.cs",
    "content": "enum TaskPriority\n{\n    LOW,\n    MEDIUM,\n    HIGH,\n    CRITICAL\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Enums/TaskStatus.cs",
    "content": "enum TaskStatus\n{\n    TODO,\n    IN_PROGRESS,\n    DONE,\n    BLOCKED\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/ActivityLog.cs",
    "content": "class ActivityLog\n{\n    private readonly string description;\n    private readonly DateTime timestamp;\n\n    public ActivityLog(string description)\n    {\n        this.description = description;\n        this.timestamp = DateTime.Now;\n    }\n\n    public override string ToString()\n    {\n        return $\"[{timestamp}] {description}\";\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/Comment.cs",
    "content": "class Comment\n{\n    private readonly string id;\n    private readonly string content;\n    private readonly User author;\n    private readonly DateTime timestamp;\n\n    public Comment(string content, User author)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.content = content;\n        this.author = author;\n        this.timestamp = DateTime.Now;\n    }\n\n    public User GetAuthor() => author;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/Tag.cs",
    "content": "class Tag\n{\n    private readonly string name;\n\n    public Tag(string name)\n    {\n        this.name = name;\n    }\n\n    public string GetName() => name;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/Task.cs",
    "content": "class Task\n{\n    private readonly string id;\n    private string title;\n    private string description;\n    private string dueDate;\n    private TaskPriority priority;\n    private readonly User createdBy;\n    private User assignee;\n    private TaskState currentState;\n    private readonly HashSet<Tag> tags;\n    private readonly List<Comment> comments;\n    private readonly List<Task> subtasks;\n    private readonly List<ActivityLog> activityLogs;\n    private readonly List<ITaskObserver> observers;\n    private readonly object taskLock = new object();\n\n    public Task(TaskBuilder builder)\n    {\n        this.id = builder.Id;\n        this.title = builder.Title;\n        this.description = builder.Description;\n        this.dueDate = builder.DueDate;\n        this.priority = builder.Priority;\n        this.createdBy = builder.CreatedBy;\n        this.assignee = builder.Assignee;\n        this.tags = builder.Tags;\n        this.currentState = new TodoState(); // Initial state\n        this.comments = new List<Comment>();\n        this.subtasks = new List<Task>();\n        this.activityLogs = new List<ActivityLog>();\n        this.observers = new List<ITaskObserver>();\n        AddLog($\"Task created with title: {title}\");\n    }\n\n    public void SetAssignee(User user)\n    {\n        lock (taskLock)\n        {\n            this.assignee = user;\n            AddLog($\"Assigned to {user.GetName()}\");\n            NotifyObservers(\"assignee\");\n        }\n    }\n\n    public void UpdatePriority(TaskPriority priority)\n    {\n        lock (taskLock)\n        {\n            this.priority = priority;\n            NotifyObservers(\"priority\");\n        }\n    }\n\n    public void AddComment(Comment comment)\n    {\n        lock (taskLock)\n        {\n            comments.Add(comment);\n            AddLog($\"Comment added by {comment.GetAuthor().GetName()}\");\n            NotifyObservers(\"comment\");\n        }\n    }\n\n    public void AddSubtask(Task subtask)\n    {\n        lock (taskLock)\n        {\n            subtasks.Add(subtask);\n            AddLog($\"Subtask added: {subtask.GetTitle()}\");\n            NotifyObservers(\"subtask_added\");\n        }\n    }\n\n    // State Pattern Methods\n    public void SetState(TaskState state)\n    {\n        this.currentState = state;\n        AddLog($\"Status changed to: {state.GetStatus()}\");\n        NotifyObservers(\"status\");\n    }\n\n    public void StartProgress() => currentState.StartProgress(this);\n    public void CompleteTask() => currentState.CompleteTask(this);\n    public void ReopenTask() => currentState.ReopenTask(this);\n\n    // Observer Pattern Methods\n    public void AddObserver(ITaskObserver observer) => observers.Add(observer);\n    public void RemoveObserver(ITaskObserver observer) => observers.Remove(observer);\n\n    public void NotifyObservers(string changeType)\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(this, changeType);\n        }\n    }\n\n    public void AddLog(string logDescription)\n    {\n        activityLogs.Add(new ActivityLog(logDescription));\n    }\n\n    public bool IsComposite() => subtasks.Count > 0;\n\n    public void Display(string indent = \"\")\n    {\n        Console.WriteLine($\"{indent}- {title} [{GetStatus()}, {priority}, Due: {dueDate}]\");\n        if (IsComposite())\n        {\n            foreach (var subtask in subtasks)\n            {\n                subtask.Display(indent + \"  \");\n            }\n        }\n    }\n\n    // Getters\n    public string GetId() => id;\n    public string GetTitle() => title;\n    public string GetDescription() => description;\n    public TaskPriority GetPriority() => priority;\n    public string GetDueDate() => dueDate;\n    public User GetAssignee() => assignee;\n    public TaskStatus GetStatus() => currentState.GetStatus();\n\n    public void SetTitle(string title) => this.title = title;\n    public void SetDescription(string description) => this.description = description;\n}\n\n// Builder Pattern\nclass TaskBuilder\n{\n    public string Id { get; private set; }\n    public string Title { get; private set; }\n    public string Description { get; private set; } = \"\";\n    public string DueDate { get; private set; }\n    public TaskPriority Priority { get; private set; }\n    public User CreatedBy { get; private set; }\n    public User Assignee { get; private set; }\n    public HashSet<Tag> Tags { get; private set; } = new HashSet<Tag>();\n\n    public TaskBuilder(string title)\n    {\n        this.Id = Guid.NewGuid().ToString();\n        this.Title = title;\n    }\n\n    public TaskBuilder SetDescription(string description)\n    {\n        this.Description = description;\n        return this;\n    }\n\n    public TaskBuilder SetDueDate(string dueDate)\n    {\n        this.DueDate = dueDate;\n        return this;\n    }\n\n    public TaskBuilder SetPriority(TaskPriority priority)\n    {\n        this.Priority = priority;\n        return this;\n    }\n\n    public TaskBuilder SetAssignee(User assignee)\n    {\n        this.Assignee = assignee;\n        return this;\n    }\n\n    public TaskBuilder SetCreatedBy(User createdBy)\n    {\n        this.CreatedBy = createdBy;\n        return this;\n    }\n\n    public TaskBuilder SetTags(HashSet<Tag> tags)\n    {\n        this.Tags = tags;\n        return this;\n    }\n\n    public Task Build()\n    {\n        return new Task(this);\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/TaskList.cs",
    "content": "class TaskList\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly List<Task> tasks;\n    private readonly object listLock = new object();\n\n    public TaskList(string name)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.tasks = new List<Task>();\n    }\n\n    public void AddTask(Task task)\n    {\n        lock (listLock)\n        {\n            tasks.Add(task);\n        }\n    }\n\n    public List<Task> GetTasks()\n    {\n        lock (listLock)\n        {\n            return new List<Task>(tasks); // Return copy\n        }\n    }\n\n    public string GetId() => id;\n    public string GetName() => name;\n\n    public void Display()\n    {\n        Console.WriteLine($\"--- Task List: {name} ---\");\n        foreach (var task in tasks)\n        {\n            task.Display(\"\");\n        }\n        Console.WriteLine(\"-----------------------------------\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Models/User.cs",
    "content": "class User\n{\n    private readonly string id;\n    private readonly string name;\n    private readonly string email;\n\n    public User(string name, string email)\n    {\n        this.id = Guid.NewGuid().ToString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public string GetId() => id;\n    public string GetEmail() => email;\n    public string GetName() => name;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Observer/ActivityLogger.cs",
    "content": "class ActivityLogger : ITaskObserver\n{\n    public void Update(Task task, string changeType)\n    {\n        Console.WriteLine($\"LOGGER: Task '{task.GetTitle()}' was updated. Change: {changeType}\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Observer/ITaskObserver.cs",
    "content": "interface ITaskObserver\n{\n    void Update(Task task, string changeType);\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/README.md",
    "content": "# Designing a Task Management System\n\n## Requirements\n1. The task management system should allow users to create, update, and delete tasks.\n2. Each task should have a title, description, due date, priority, and status (e.g., pending, in progress, completed).\n3. Users should be able to assign tasks to other users and set reminders for tasks.\n4. The system should support searching and filtering tasks based on various criteria (e.g., priority, due date, assigned user).\n5. Users should be able to mark tasks as completed and view their task history.\n6. The system should handle concurrent access to tasks and ensure data consistency.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the task management system, with properties such as id, name, and email.\n2. The **TaskStatus** enum defines the possible states of a task, such as pending, in progress, and completed.\n3. The **Task** class represents a task in the system, with properties like id, title, description, due date, priority, status, and assigned user.\n4. The **TaskManager** class is the core of the task management system and follows the Singleton pattern to ensure a single instance of the task manager.\n5. The TaskManager class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to tasks and ensure thread safety.\n6. The TaskManager class provides methods for creating, updating, deleting, searching, and filtering tasks, as well as marking tasks as completed and retrieving task history for a user.\n7. The **TaskManagementSystem** class serves as the entry point of the application and demonstrates the usage of the task management system."
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/State/DoneState.cs",
    "content": "class DoneState : TaskState\n{\n    public override void StartProgress(Task task)\n    {\n        Console.WriteLine(\"Cannot start a completed task. Reopen it first.\");\n    }\n\n    public override void CompleteTask(Task task)\n    {\n        Console.WriteLine(\"Task is already done.\");\n    }\n\n    public override void ReopenTask(Task task)\n    {\n        task.SetState(new TodoState());\n    }\n\n    public override TaskStatus GetStatus() => TaskStatus.DONE;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/State/InProgressState.cs",
    "content": "class InProgressState : TaskState\n{\n    public override void StartProgress(Task task)\n    {\n        Console.WriteLine(\"Task is already in progress.\");\n    }\n\n    public override void CompleteTask(Task task)\n    {\n        task.SetState(new DoneState());\n    }\n\n    public override void ReopenTask(Task task)\n    {\n        task.SetState(new TodoState());\n    }\n\n    public override TaskStatus GetStatus() => TaskStatus.IN_PROGRESS;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/State/TaskState.cs",
    "content": "abstract class TaskState\n{\n    public abstract void StartProgress(Task task);\n    public abstract void CompleteTask(Task task);\n    public abstract void ReopenTask(Task task);\n    public abstract TaskStatus GetStatus();\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/State/TodoState.cs",
    "content": "class TodoState : TaskState\n{\n    public override void StartProgress(Task task)\n    {\n        task.SetState(new InProgressState());\n    }\n\n    public override void CompleteTask(Task task)\n    {\n        Console.WriteLine(\"Cannot complete a task that is not in progress.\");\n    }\n\n    public override void ReopenTask(Task task)\n    {\n        Console.WriteLine(\"Task is already in TO-DO state.\");\n    }\n\n    public override TaskStatus GetStatus() => TaskStatus.TODO;\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Strategy/SortByDueDate.cs",
    "content": "class SortByDueDate : TaskSortStrategy\n{\n    public override void Sort(List<Task> tasks)\n    {\n        tasks.Sort((a, b) => string.Compare(a.GetDueDate(), b.GetDueDate(), StringComparison.Ordinal));\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Strategy/SortByPriority.cs",
    "content": "class SortByPriority : TaskSortStrategy\n{\n    public override void Sort(List<Task> tasks)\n    {\n        // Higher priority comes first\n        tasks.Sort((a, b) => b.GetPriority().CompareTo(a.GetPriority()));\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/Strategy/TaskSortStrategy.cs",
    "content": "abstract class TaskSortStrategy\n{\n    public abstract void Sort(List<Task> tasks);\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/TaskManagementSystem.cs",
    "content": "class TaskManagementSystem\n{\n    private static TaskManagementSystem instance;\n    private static readonly object lockObject = new object();\n    private readonly Dictionary<string, User> users = new Dictionary<string, User>();\n    private readonly Dictionary<string, Task> tasks = new Dictionary<string, Task>();\n    private readonly Dictionary<string, TaskList> taskLists = new Dictionary<string, TaskList>();\n\n    private TaskManagementSystem() { }\n\n    public static TaskManagementSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new TaskManagementSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public User CreateUser(string name, string email)\n    {\n        User user = new User(name, email);\n        users[user.GetId()] = user;\n        return user;\n    }\n\n    public TaskList CreateTaskList(string listName)\n    {\n        TaskList taskList = new TaskList(listName);\n        taskLists[taskList.GetId()] = taskList;\n        return taskList;\n    }\n\n    public Task CreateTask(string title, string description, string dueDate,\n                          TaskPriority priority, string createdByUserId)\n    {\n        if (!users.TryGetValue(createdByUserId, out User createdBy))\n        {\n            throw new ArgumentException(\"User not found.\");\n        }\n\n        Task task = new TaskBuilder(title)\n                .SetDescription(description)\n                .SetDueDate(dueDate)\n                .SetPriority(priority)\n                .SetCreatedBy(createdBy)\n                .Build();\n\n        task.AddObserver(new ActivityLogger());\n\n        tasks[task.GetId()] = task;\n        return task;\n    }\n\n    public List<Task> ListTasksByUser(string userId)\n    {\n        if (!users.TryGetValue(userId, out User user))\n        {\n            return new List<Task>();\n        }\n\n        return tasks.Values.Where(task => task.GetAssignee() == user).ToList();\n    }\n\n    public List<Task> ListTasksByStatus(TaskStatus status)\n    {\n        return tasks.Values.Where(task => task.GetStatus() == status).ToList();\n    }\n\n    public void DeleteTask(string taskId)\n    {\n        tasks.Remove(taskId);\n    }\n\n    public List<Task> SearchTasks(string keyword, TaskSortStrategy sortingStrategy)\n    {\n        List<Task> matchingTasks = new List<Task>();\n        foreach (var task in tasks.Values)\n        {\n            if (task.GetTitle().Contains(keyword) || task.GetDescription().Contains(keyword))\n            {\n                matchingTasks.Add(task);\n            }\n        }\n        sortingStrategy.Sort(matchingTasks);\n        return matchingTasks;\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/TaskManagementSystemDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\n\npublic class TaskManagementSystemDemo\n{\n    public static void Main()\n    {\n        TaskManagementSystem taskManagementSystem = TaskManagementSystem.GetInstance();\n\n        // Create users\n        User user1 = taskManagementSystem.CreateUser(\"John Doe\", \"john@example.com\");\n        User user2 = taskManagementSystem.CreateUser(\"Jane Smith\", \"jane@example.com\");\n\n        // Create task lists\n        TaskList taskList1 = taskManagementSystem.CreateTaskList(\"Enhancements\");\n        TaskList taskList2 = taskManagementSystem.CreateTaskList(\"Bug Fix\");\n\n        // Create tasks\n        Task task1 = taskManagementSystem.CreateTask(\"Enhancement Task\", \"Launch New Feature\",\n                \"2024-02-15\", TaskPriority.LOW, user1.GetId());\n        Task subtask1 = taskManagementSystem.CreateTask(\"Enhancement sub task\", \"Design UI/UX\",\n                \"2024-02-14\", TaskPriority.MEDIUM, user1.GetId());\n        Task task2 = taskManagementSystem.CreateTask(\"Bug Fix Task\", \"Fix API Bug\",\n                \"2024-02-16\", TaskPriority.HIGH, user2.GetId());\n\n        task1.AddSubtask(subtask1);\n\n        taskList1.AddTask(task1);\n        taskList2.AddTask(task2);\n\n        taskList1.Display();\n\n        // Update task status\n        subtask1.StartProgress();\n\n        // Assign task\n        subtask1.SetAssignee(user2);\n\n        taskList1.Display();\n\n        // Search tasks\n        List<Task> searchResults = taskManagementSystem.SearchTasks(\"Task\", new SortByDueDate());\n        Console.WriteLine(\"\\nTasks with keyword Task:\");\n        foreach (Task task in searchResults)\n        {\n            Console.WriteLine(task.GetTitle());\n        }\n\n        // Filter tasks by status\n        List<Task> filteredTasks = taskManagementSystem.ListTasksByStatus(TaskStatus.TODO);\n        Console.WriteLine(\"\\nTODO Tasks:\");\n        foreach (Task task in filteredTasks)\n        {\n            Console.WriteLine(task.GetTitle());\n        }\n\n        // Mark a task as done\n        subtask1.CompleteTask();\n\n        // Get tasks assigned to a user\n        List<Task> userTaskList = taskManagementSystem.ListTasksByUser(user2.GetId());\n        Console.WriteLine($\"\\nTask for {user2.GetName()}:\");\n        foreach (Task task in userTaskList)\n        {\n            Console.WriteLine(task.GetTitle());\n        }\n\n        taskList1.Display();\n\n        // Delete a task\n        taskManagementSystem.DeleteTask(task2.GetId());\n    }\n}"
  },
  {
    "path": "solutions/csharp/taskmanagementsystem/taskmanagementsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/tictactoe/Enums/GameStatus.cs",
    "content": "enum GameStatus\n{\n    IN_PROGRESS,\n    WINNER_X,\n    WINNER_O,\n    DRAW\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Enums/Symbol.cs",
    "content": "enum Symbol\n{\n    X,\n    O,\n    EMPTY\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Exceptions/InvalidMoveException.cs",
    "content": "class InvalidMoveException : Exception\n{\n    public InvalidMoveException(string message) : base(message) { }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Models/Board.cs",
    "content": "using System;\n\n\nclass Board\n{\n    private readonly int size;\n    private int movesCount;\n    private readonly Cell[,] board;\n\n    public Board(int size)\n    {\n        this.size = size;\n        this.board = new Cell[size, size];\n        movesCount = 0;\n        InitializeBoard();\n    }\n\n    private void InitializeBoard()\n    {\n        for (int row = 0; row < size; row++)\n        {\n            for (int col = 0; col < size; col++)\n            {\n                board[row, col] = new Cell();\n            }\n        }\n    }\n\n    public bool PlaceSymbol(int row, int col, Symbol symbol)\n    {\n        if (row < 0 || row >= size || col < 0 || col >= size)\n        {\n            throw new InvalidMoveException(\"Invalid position: out of bounds.\");\n        }\n        if (board[row, col].GetSymbol() != Symbol.EMPTY)\n        {\n            throw new InvalidMoveException(\"Invalid position: cell is already occupied.\");\n        }\n\n        board[row, col].SetSymbol(symbol);\n        movesCount++;\n        return true;\n    }\n\n    public Cell GetCell(int row, int col)\n    {\n        if (row < 0 || row >= size || col < 0 || col >= size)\n        {\n            return null;\n        }\n        return board[row, col];\n    }\n\n    public bool IsFull() { return movesCount == size * size; }\n\n    public void PrintBoard()\n    {\n        Console.WriteLine(\"-------------\");\n        for (int i = 0; i < size; i++)\n        {\n            Console.Write(\"| \");\n            for (int j = 0; j < size; j++)\n            {\n                Console.Write(board[i, j].GetSymbolChar() + \" | \");\n            }\n            Console.WriteLine();\n            Console.WriteLine(\"-------------\");\n        }\n    }\n\n    public int GetSize() => size;\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Models/Cell.cs",
    "content": "class Cell\n{\n    private Symbol symbol;\n\n    public Cell()\n    {\n        symbol = Symbol.EMPTY;\n    }\n\n    public Symbol GetSymbol() { return symbol; }\n    public void SetSymbol(Symbol symbol) { this.symbol = symbol; }\n\n    public char GetSymbolChar()\n    {\n        switch (symbol)\n        {\n            case Symbol.X: return 'X';\n            case Symbol.O: return 'O';\n            case Symbol.EMPTY: return '_';\n            default: return '_';\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Models/Game.cs",
    "content": "using System;\n\nclass Game : GameSubject\n{\n    private readonly Board board;\n    private readonly Player player1;\n    private readonly Player player2;\n    private Player currentPlayer;\n    private Player winner;\n    private GameStatus status;\n    private IGameState state;\n    private readonly List<IWinningStrategy> winningStrategies;\n\n    public Game(Player player1, Player player2)\n    {\n        board = new Board(3);\n        this.player1 = player1;\n        this.player2 = player2;\n        currentPlayer = player1; // Player 1 starts\n        winner = null;\n        status = GameStatus.IN_PROGRESS;\n        state = new InProgressState();\n        winningStrategies = new List<IWinningStrategy>\n        {\n            new RowWinningStrategy(),\n            new ColumnWinningStrategy(),\n            new DiagonalWinningStrategy()\n        };\n    }\n\n    public void MakeMove(Player player, int row, int col)\n    {\n        state.HandleMove(this, player, row, col);\n    }\n\n    public bool CheckWinner(Player player)\n    {\n        foreach (var strategy in winningStrategies)\n        {\n            if (strategy.CheckWinner(board, player))\n            {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public void SwitchPlayer()\n    {\n        if (currentPlayer == player1)\n        {\n            currentPlayer = player2;\n        }\n        else\n        {\n            currentPlayer = player1;\n        }        \n    }\n\n    public Board GetBoard() => board;\n    public Player GetCurrentPlayer() => currentPlayer;\n    public Player GetWinner() => winner;\n    public void SetWinner(Player winner) => this.winner = winner;\n    public GameStatus GetStatus() => status;\n    public void SetState(IGameState state) => this.state = state;\n    public void SetStatus(GameStatus status)\n    {\n        this.status = status;\n        // Notify observers when the status changes to a finished state\n        if (status != GameStatus.IN_PROGRESS)\n        {\n            NotifyObservers();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Models/Player.cs",
    "content": "class Player\n{\n    private readonly string name;\n    private readonly Symbol symbol;\n\n    public Player(string name, Symbol symbol)\n    {\n        this.name = name;\n        this.symbol = symbol;\n    }\n\n    public string GetName() { return name; }\n    public Symbol GetSymbol() { return symbol; }\n\n    public char GetSymbolChar()\n    {\n        switch (symbol)\n        {\n            case Symbol.X: return 'X';\n            case Symbol.O: return 'O';\n            case Symbol.EMPTY: return '_';\n            default: return '_';\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Observer/GameSubject.cs",
    "content": "abstract class GameSubject\n{\n    private readonly List<IGameObserver> observers = new List<IGameObserver>();\n\n    public void AddObserver(IGameObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(IGameObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    public void NotifyObservers()\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update((Game)this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Observer/IGameObserver.cs",
    "content": "interface IGameObserver\n{\n    void Update(Game game);\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Observer/Scoreboard.cs",
    "content": "using System.Collections.Concurrent;\n\nclass Scoreboard : IGameObserver\n{\n    private readonly ConcurrentDictionary<string, int> scores;\n\n    public Scoreboard()\n    {\n        scores = new ConcurrentDictionary<string, int>();\n    }\n\n    public void Update(Game game)\n    {\n        // The scoreboard only cares about finished games with a winner\n        if (game.GetWinner() != null)\n        {\n            string winnerName = game.GetWinner().GetName();\n            scores.AddOrUpdate(winnerName, 1, (key, value) => value + 1);\n            Console.WriteLine(\"[Scoreboard] \" + winnerName + \" wins! Their new score is \" + scores[winnerName] + \".\");\n        }\n    }\n\n    public void PrintScores()\n    {\n        Console.WriteLine(\"\\n--- Overall Scoreboard ---\");\n        if (scores.IsEmpty)\n        {\n            Console.WriteLine(\"No games with a winner have been played yet.\");\n            return;\n        }\n\n        foreach (var kvp in scores)\n        {\n            Console.WriteLine(\"Player: \" + kvp.Key + \" | Wins: \" + kvp.Value);\n        }\n        Console.WriteLine(\"--------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/README.md",
    "content": "# Designing a Tic Tac Toe Game\n\n## Requirements\n1. The Tic-Tac-Toe game should be played on a 3x3 grid.\n2. Two players take turns marking their symbols (X or O) on the grid.\n3. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game.\n4. If all the cells on the grid are filled and no player has won, the game ends in a draw.\n5. The game should have a user interface to display the grid and allow players to make their moves.\n6. The game should handle player turns and validate moves to ensure they are legal.\n7. The game should detect and announce the winner or a draw at the end of the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Player** class represents a player in the game, with a name and a symbol (X or O).\n2. The **Board** class represents the game board, which is a 3x3 grid. It provides methods to make moves, check for a winner, and check if the board is full.\n3. The **Game** class manages the game flow and player interactions. It handles player turns, validates moves, and determines the winner or a draw.\n4. The **TicTacToe** class is the entry point of the application and creates instances of the players and the game."
  },
  {
    "path": "solutions/csharp/tictactoe/States/DrawState.cs",
    "content": "class DrawState : IGameState\n{\n    public void HandleMove(Game game, Player player, int row, int col)\n    {\n        throw new InvalidMoveException(\"Game is already over. It was a draw.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/States/IGameState.cs",
    "content": "interface IGameState\n{\n    void HandleMove(Game game, Player player, int row, int col);\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/States/InProgressState.cs",
    "content": "class InProgressState : IGameState\n{\n    public void HandleMove(Game game, Player player, int row, int col)\n    {\n        if (game.GetCurrentPlayer() != player)\n        {\n            throw new InvalidMoveException(\"Not your turn!\");\n        }\n\n        // Place the piece on the board\n        game.GetBoard().PlaceSymbol(row, col, player.GetSymbol());\n\n        // Check for a winner or a draw\n        if (game.CheckWinner(player))\n        {\n            game.SetWinner(player);\n            if (player.GetSymbol() == Symbol.X)\n            {\n                game.SetStatus(GameStatus.WINNER_X);\n            }\n            else\n            {\n                game.SetStatus(GameStatus.WINNER_O);\n            }            \n            game.SetState(new WinnerState());\n        }\n        else if (game.GetBoard().IsFull())\n        {\n            game.SetStatus(GameStatus.DRAW);\n            game.SetState(new DrawState());\n        }\n        else\n        {\n            // If the game is still in progress, switch players\n            game.SwitchPlayer();\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/States/WinnerState.cs",
    "content": "class WinnerState : IGameState\n{\n    public void HandleMove(Game game, Player player, int row, int col)\n    {\n        throw new InvalidMoveException(\"Game is already over. \" + game.GetWinner().GetName() + \" has won.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Strategy/ColumnWinningStrategy.cs",
    "content": "class ColumnWinningStrategy : IWinningStrategy\n{\n    public bool CheckWinner(Board board, Player player)\n    {\n        for (int col = 0; col < board.GetSize(); col++)\n        {\n            bool colWin = true;\n            for (int row = 0; row < board.GetSize(); row++)\n            {\n                if (board.GetCell(row, col).GetSymbol() != player.GetSymbol())\n                {\n                    colWin = false;\n                    break;\n                }\n            }\n            if (colWin) return true;\n        }\n        return false;\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Strategy/DiagonalWinningStrategy.cs",
    "content": "class DiagonalWinningStrategy : IWinningStrategy\n{\n    public bool CheckWinner(Board board, Player player)\n    {\n        // Main diagonal\n        bool mainDiagWin = true;\n        for (int i = 0; i < board.GetSize(); i++)\n        {\n            if (board.GetCell(i, i).GetSymbol() != player.GetSymbol())\n            {\n                mainDiagWin = false;\n                break;\n            }\n        }\n        if (mainDiagWin) return true;\n\n        // Anti-diagonal\n        bool antiDiagWin = true;\n        for (int i = 0; i < board.GetSize(); i++)\n        {\n            if (board.GetCell(i, board.GetSize() - 1 - i).GetSymbol() != player.GetSymbol())\n            {\n                antiDiagWin = false;\n                break;\n            }\n        }\n        return antiDiagWin;\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Strategy/IWinningStrategy.cs",
    "content": "interface IWinningStrategy\n{\n    bool CheckWinner(Board board, Player player);\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/Strategy/RowWinningStrategy.cs",
    "content": "class RowWinningStrategy : IWinningStrategy\n{\n    public bool CheckWinner(Board board, Player player)\n    {\n        for (int row = 0; row < board.GetSize(); row++)\n        {\n            bool rowWin = true;\n            for (int col = 0; col < board.GetSize(); col++)\n            {\n                if (board.GetCell(row, col).GetSymbol() != player.GetSymbol())\n                {\n                    rowWin = false;\n                    break;\n                }\n            }\n            if (rowWin) return true;\n        }\n        return false;\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/TicTacToeDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\npublic class TicTacToeDemo\n{\n    public static void Main()\n    {\n        TicTacToeSystem system = TicTacToeSystem.GetInstance();\n\n        Player alice = new Player(\"Alice\", Symbol.X);\n        Player bob = new Player(\"Bob\", Symbol.O);\n\n        // --- GAME 1: Alice wins ---\n        Console.WriteLine(\"--- GAME 1: Alice (X) vs. Bob (O) ---\");\n        system.CreateGame(alice, bob);\n        system.PrintBoard();\n\n        system.MakeMove(alice, 0, 0);\n        system.MakeMove(bob, 1, 0);\n        system.MakeMove(alice, 0, 1);\n        system.MakeMove(bob, 1, 1);\n        system.MakeMove(alice, 0, 2); // Alice wins, scoreboard is notified\n        Console.WriteLine(\"----------------------------------------\\n\");\n\n        // --- GAME 2: Bob wins ---\n        Console.WriteLine(\"--- GAME 2: Alice (X) vs. Bob (O) ---\");\n        system.CreateGame(alice, bob); // A new game instance\n        system.PrintBoard();\n\n        system.MakeMove(alice, 0, 0);\n        system.MakeMove(bob, 1, 0);\n        system.MakeMove(alice, 0, 1);\n        system.MakeMove(bob, 1, 1);\n        system.MakeMove(alice, 2, 2);\n        system.MakeMove(bob, 1, 2); // Bob wins, scoreboard is notified\n        Console.WriteLine(\"----------------------------------------\\n\");\n\n        // --- GAME 3: A Draw ---\n        Console.WriteLine(\"--- GAME 3: Alice (X) vs. Bob (O) - Draw ---\");\n        system.CreateGame(alice, bob);\n        system.PrintBoard();\n\n        system.MakeMove(alice, 0, 0);\n        system.MakeMove(bob, 0, 1);\n        system.MakeMove(alice, 0, 2);\n        system.MakeMove(bob, 1, 1);\n        system.MakeMove(alice, 1, 0);\n        system.MakeMove(bob, 1, 2);\n        system.MakeMove(alice, 2, 1);\n        system.MakeMove(bob, 2, 0);\n        system.MakeMove(alice, 2, 2); // Draw, scoreboard is not notified of a winner\n        Console.WriteLine(\"----------------------------------------\\n\");\n\n        // --- Final Scoreboard ---\n        // We get the scoreboard from the system and print its final state\n        system.PrintScoreBoard();\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/TicTacToeSystem.cs",
    "content": "class TicTacToeSystem\n{\n    private static volatile TicTacToeSystem instance;\n    private static readonly object lockObject = new object();\n    private Game game;\n    private readonly Scoreboard scoreboard; // The system now manages a scoreboard\n\n    private TicTacToeSystem()\n    {\n        scoreboard = new Scoreboard(); // Create the scoreboard on initialization\n    }\n\n    public static TicTacToeSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new TicTacToeSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void CreateGame(Player player1, Player player2)\n    {\n        game = new Game(player1, player2);\n        // Register the scoreboard as an observer for this new game\n        game.AddObserver(scoreboard);\n\n        Console.WriteLine(\"Game started between \" + player1.GetName() + \" (X) and \" + player2.GetName() + \" (O).\");\n    }\n\n    public void MakeMove(Player player, int row, int col)\n    {\n        if (game == null)\n        {\n            Console.WriteLine(\"No game in progress. Please create a game first.\");\n            return;\n        }\n\n        try\n        {\n            Console.WriteLine(player.GetName() + \" plays at (\" + row + \", \" + col + \")\");\n            game.MakeMove(player, row, col);\n            PrintBoard();\n            Console.WriteLine(\"Game Status: \" + game.GetStatus());\n            if (game.GetWinner() != null)\n            {\n                Console.WriteLine(\"Winner: \" + game.GetWinner().GetName());\n            }\n        }\n        catch (InvalidMoveException e)\n        {\n            Console.WriteLine(\"Error: \" + e.Message);\n        }\n    }\n\n    public void PrintBoard()\n    {\n        game.GetBoard().PrintBoard();\n    }\n\n    public void PrintScoreBoard()\n    {\n        scoreboard.PrintScores();\n    }\n}"
  },
  {
    "path": "solutions/csharp/tictactoe/tictactoe.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/Enums/Direction.cs",
    "content": "enum Direction\n{\n    NORTH,\n    SOUTH,\n    EAST,\n    WEST\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/Enums/LightColor.cs",
    "content": "enum LightColor\n{\n    GREEN,\n    YELLOW,\n    RED\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/IntersectionController.cs",
    "content": "class IntersectionController\n{\n    private readonly int id;\n    private readonly Dictionary<Direction, TrafficLight> trafficLights;\n    private IIntersectionState currentState;\n    private readonly long greenDuration;\n    private readonly long yellowDuration;\n    private volatile bool running = true;\n\n    public IntersectionController(int id, Dictionary<Direction, TrafficLight> trafficLights, \n                                  long greenDuration, long yellowDuration)\n    {\n        this.id = id;\n        this.trafficLights = trafficLights;\n        this.greenDuration = greenDuration;\n        this.yellowDuration = yellowDuration;\n        this.currentState = new NorthSouthGreenState(); // Initial state for the intersection\n    }\n\n    public int GetId() => id;\n    public long GetGreenDuration() => greenDuration;\n    public long GetYellowDuration() => yellowDuration;\n    public TrafficLight GetLight(Direction direction) => trafficLights[direction];\n\n    public void SetState(IIntersectionState state)\n    {\n        this.currentState = state;\n    }\n\n    public void Start()\n    {\n        Task.Run(() => Run());\n    }\n\n    public void Stop()\n    {\n        this.running = false;\n    }\n\n    public void Run()\n    {\n        while (running)\n        {\n            try\n            {\n                currentState.Handle(this);\n            }\n            catch (Exception e)\n            {\n                Console.WriteLine($\"Intersection {id} encountered an error: {e.Message}\");\n                running = false;\n            }\n        }\n    }\n}\n\n// Builder Pattern\nclass IntersectionControllerBuilder\n{\n    private readonly int id;\n    private long greenDuration = 5000; // default 5s\n    private long yellowDuration = 2000; // default 2s\n    private readonly List<ITrafficObserver> observers = new List<ITrafficObserver>();\n\n    public IntersectionControllerBuilder(int id)\n    {\n        this.id = id;\n    }\n\n    public IntersectionControllerBuilder WithDurations(long green, long yellow)\n    {\n        this.greenDuration = green;\n        this.yellowDuration = yellow;\n        return this;\n    }\n\n    public IntersectionControllerBuilder AddObserver(ITrafficObserver observer)\n    {\n        this.observers.Add(observer);\n        return this;\n    }\n\n    public IntersectionController Build()\n    {\n        var lights = new Dictionary<Direction, TrafficLight>();\n        foreach (Direction dir in Enum.GetValues(typeof(Direction)).Cast<Direction>())\n        {\n            TrafficLight light = new TrafficLight(id, dir);\n            // Attach all registered observers to each light\n            foreach (var observer in observers)\n            {\n                light.AddObserver(observer);\n            }\n            lights[dir] = light;\n        }\n        return new IntersectionController(id, lights, greenDuration, yellowDuration);\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/Observer/CentralMonitor.cs",
    "content": "class CentralMonitor : ITrafficObserver\n{\n    public void Update(int intersectionId, Direction direction, LightColor color)\n    {\n        Console.WriteLine($\"[MONITOR] Intersection {intersectionId}: Light for {direction} direction changed to {color}.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/Observer/ITrafficObserver.cs",
    "content": "interface ITrafficObserver\n{\n    void Update(int intersectionId, Direction direction, LightColor color);\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/README.md",
    "content": "# Designing a Traffic Signal Control System\n\n## Requirements\n1. The traffic signal system should control the flow of traffic at an intersection with multiple roads.\n2. The system should support different types of signals, such as red, yellow, and green.\n3. The duration of each signal should be configurable and adjustable based on traffic conditions.\n4. The system should handle the transition between signals smoothly, ensuring safe and efficient traffic flow.\n5. The system should be able to detect and handle emergency situations, such as an ambulance or fire truck approaching the intersection.\n6. The system should be scalable and extensible to support additional features and functionality.\n\n## Classes, Interfaces and Enumerations\n1. The **Signal** enum represents the different states of a traffic light: red, yellow, and green.\n2. The **Road** class represents a road in the traffic signal system, with properties such as ID, name, and an associated traffic light.\n3. The **TrafficLight** class represents a traffic light, with properties such as ID, current signal, and durations for each signal state. It provides methods to change the signal and notify observers (e.g., roads) about signal changes.\n4. The **TrafficController** class serves as the central controller for the traffic signal system. It follows the Singleton pattern to ensure a single instance of the controller. It manages the roads and their associated traffic lights, starts the traffic control process, and handles emergency situations.\n5. The **TrafficSignalSystemDemo** class is the main entry point of the application. It demonstrates the usage of the traffic signal system by creating roads, traffic lights, assigning traffic lights to roads, and starting the traffic control process."
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Intersection/EastWestGreenState.cs",
    "content": "class EastWestGreenState : IIntersectionState\n{\n    public void Handle(IntersectionController context)\n    {\n        Console.WriteLine($\"\\n--- INTERSECTION {context.GetId()}: Cycle -> East-West GREEN ---\");\n\n        // Turn East and West green, ensure North and South are red\n        context.GetLight(Direction.EAST).StartGreen();\n        context.GetLight(Direction.WEST).StartGreen();\n        context.GetLight(Direction.NORTH).SetColor(LightColor.RED);\n        context.GetLight(Direction.SOUTH).SetColor(LightColor.RED);\n\n        // Wait for green light duration\n        Thread.Sleep((int)context.GetGreenDuration());\n\n        // Transition East and West to Yellow\n        context.GetLight(Direction.EAST).Transition();\n        context.GetLight(Direction.WEST).Transition();\n\n        // Wait for yellow light duration\n        Thread.Sleep((int)context.GetYellowDuration());\n\n        // Transition East and West to Red\n        context.GetLight(Direction.EAST).Transition();\n        context.GetLight(Direction.WEST).Transition();\n\n        // Change the intersection's state back to let North-South go\n        context.SetState(new NorthSouthGreenState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Intersection/IIntersectionState.cs",
    "content": "interface IIntersectionState\n{\n    void Handle(IntersectionController context);\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Intersection/NorthSouthGreenState.cs",
    "content": "class NorthSouthGreenState : IIntersectionState\n{\n    public void Handle(IntersectionController context)\n    {\n        Console.WriteLine($\"\\n--- INTERSECTION {context.GetId()}: Cycle Start -> North-South GREEN ---\");\n\n        // Turn North and South green, ensure East and West are red\n        context.GetLight(Direction.NORTH).StartGreen();\n        context.GetLight(Direction.SOUTH).StartGreen();\n        context.GetLight(Direction.EAST).SetColor(LightColor.RED);\n        context.GetLight(Direction.WEST).SetColor(LightColor.RED);\n\n        // Wait for green light duration\n        Thread.Sleep((int)context.GetGreenDuration());\n\n        // Transition North and South to Yellow\n        context.GetLight(Direction.NORTH).Transition();\n        context.GetLight(Direction.SOUTH).Transition();\n\n        // Wait for yellow light duration\n        Thread.Sleep((int)context.GetYellowDuration());\n\n        // Transition North and South to Red\n        context.GetLight(Direction.NORTH).Transition();\n        context.GetLight(Direction.SOUTH).Transition();\n\n        // Change the intersection's state to let East-West go\n        context.SetState(new EastWestGreenState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Light/GreenState.cs",
    "content": "class GreenState : ISignalState\n{\n    public void Handle(TrafficLight context)\n    {\n        context.SetColor(LightColor.GREEN);\n        // After being green, the next state is yellow.\n        context.SetNextState(new YellowState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Light/ISignalState.cs",
    "content": "interface ISignalState\n{\n    void Handle(TrafficLight context);\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Light/RedState.cs",
    "content": "class RedState : ISignalState\n{\n    public void Handle(TrafficLight context)\n    {\n        context.SetColor(LightColor.RED);\n        // Red is a stable state, it transitions to green only when the intersection controller commands it.\n        // So, the next state is self.\n        context.SetNextState(new RedState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/States/Light/YellowState.cs",
    "content": "class YellowState : ISignalState\n{\n    public void Handle(TrafficLight context)\n    {\n        context.SetColor(LightColor.YELLOW);\n        // After being yellow, the next state is red.\n        context.SetNextState(new RedState());\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/TrafficControlSystem.cs",
    "content": "class TrafficControlSystem\n{\n    private static TrafficControlSystem instance;\n    private static readonly object lockObject = new object();\n    private readonly List<IntersectionController> intersections = new List<IntersectionController>();\n    private readonly List<Task> tasks = new List<Task>();\n\n    private TrafficControlSystem() { }\n\n    public static TrafficControlSystem GetInstance()\n    {\n        if (instance == null)\n        {\n            lock (lockObject)\n            {\n                if (instance == null)\n                {\n                    instance = new TrafficControlSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void AddIntersection(int intersectionId, int greenDuration, int yellowDuration)\n    {\n        IntersectionController intersection = new IntersectionControllerBuilder(intersectionId)\n                .WithDurations(greenDuration, yellowDuration)\n                .AddObserver(new CentralMonitor())\n                .Build();\n        intersections.Add(intersection);\n    }\n\n    public void StartSystem()\n    {\n        if (intersections.Count == 0)\n        {\n            Console.WriteLine(\"No intersections to manage. System not starting.\");\n            return;\n        }\n\n        Console.WriteLine(\"--- Starting Traffic Control System ---\");\n\n        foreach (var intersection in intersections)\n        {\n            Task task = Task.Run(() => intersection.Run());\n            tasks.Add(task);\n        }\n    }\n\n    public void StopSystem()\n    {\n        Console.WriteLine(\"\\n--- Shutting Down Traffic Control System ---\");\n\n        foreach (var intersection in intersections)\n        {\n            intersection.Stop();\n        }\n\n        Task.WaitAll(tasks.ToArray(), TimeSpan.FromSeconds(5));\n\n        Console.WriteLine(\"All intersections stopped. System shut down.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/TrafficLight.cs",
    "content": "class TrafficLight\n{\n    private readonly int intersectionId;\n    private readonly Direction direction;\n    private LightColor currentColor;\n    private ISignalState currentState;\n    private ISignalState nextState;\n    private readonly List<ITrafficObserver> observers = new List<ITrafficObserver>();\n\n    public TrafficLight(int intersectionId, Direction direction)\n    {\n        this.intersectionId = intersectionId;\n        this.direction = direction;\n        this.currentState = new RedState(); // Default state is Red\n        this.currentState.Handle(this);\n    }\n\n    // This is called by the IntersectionController to initiate a G-Y-R cycle\n    public void StartGreen()\n    {\n        this.currentState = new GreenState();\n        this.currentState.Handle(this);\n    }\n\n    // This is called by the IntersectionController to transition from G->Y or Y->R\n    public void Transition()\n    {\n        this.currentState = this.nextState;\n        this.currentState.Handle(this);\n    }\n\n    public void SetColor(LightColor color)\n    {\n        if (this.currentColor != color)\n        {\n            this.currentColor = color;\n            NotifyObservers();\n        }\n    }\n\n    public void SetNextState(ISignalState state)\n    {\n        this.nextState = state;\n    }\n\n    public LightColor GetCurrentColor() => currentColor;\n    public Direction GetDirection() => direction;\n\n    // Observer pattern methods\n    public void AddObserver(ITrafficObserver observer)\n    {\n        observers.Add(observer);\n    }\n\n    public void RemoveObserver(ITrafficObserver observer)\n    {\n        observers.Remove(observer);\n    }\n\n    private void NotifyObservers()\n    {\n        foreach (var observer in observers)\n        {\n            observer.Update(intersectionId, direction, currentColor);\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/TrafficSystemDemo.cs",
    "content": "using System;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Collections.Generic;\n\npublic class TrafficSystemDemo\n{\n    public static void Main(string[] args)\n    {\n        // 1. Get the singleton TrafficControlSystem instance\n        TrafficControlSystem system = TrafficControlSystem.GetInstance();\n\n        // 2. Add intersections to the system\n        system.AddIntersection(1, 500, 200);\n        system.AddIntersection(2, 700, 150);\n\n        // 3. Start the system\n        system.StartSystem();\n\n        // 4. Let the simulation run for a while (e.g., 5 seconds)\n        try\n        {\n            Thread.Sleep(5000);\n        }\n        catch (ThreadInterruptedException)\n        {\n            Thread.CurrentThread.Interrupt();\n        }\n\n        // 5. Stop the system gracefully\n        system.StopSystem();\n    }\n}"
  },
  {
    "path": "solutions/csharp/trafficsignalsystem/trafficsignalsystem.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/vendingmachine/Enum/Coin.cs",
    "content": "enum Coin\n{\n    PENNY = 1,\n    NICKEL = 5,\n    DIME = 10,\n    QUARTER = 25\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/Models/Inventory.cs",
    "content": "class Inventory\n{\n    private readonly Dictionary<string, Item> itemMap = new Dictionary<string, Item>();\n    private readonly Dictionary<string, int> stockMap = new Dictionary<string, int>();\n\n    public void AddItem(string code, Item item, int quantity)\n    {\n        itemMap[code] = item;\n        stockMap[code] = quantity;\n    }\n\n    public Item GetItem(string code)\n    {\n        return itemMap.GetValueOrDefault(code);\n    }\n\n    public bool IsAvailable(string code)\n    {\n        return stockMap.GetValueOrDefault(code, 0) > 0;\n    }\n\n    public void ReduceStock(string code)\n    {\n        if (stockMap.ContainsKey(code))\n        {\n            stockMap[code] = stockMap[code] - 1;\n        }\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/Models/Item.cs",
    "content": "class Item\n{\n    private string code;\n    private string name;\n    private int price;\n\n    public Item(string code, string name, int price)\n    {\n        this.code = code;\n        this.name = name;\n        this.price = price;\n    }\n\n    public string GetName()\n    {\n        return name;\n    }\n\n    public int GetPrice()\n    {\n        return price;\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/README.md",
    "content": "# Designing a Vending Machine\n\n## Requirements\n1. The vending machine should support multiple products with different prices and quantities.\n1. The machine should accept coins and notes of different denominations.\n1. The machine should dispense the selected product and return change if necessary.\n1. The machine should keep track of the available products and their quantities.\n1. The machine should handle multiple transactions concurrently and ensure data consistency.\n1. The machine should provide an interface for restocking products and collecting money.\n1. The machine should handle exceptional scenarios, such as insufficient funds or out-of-stock products.\n\n## Classes, Interfaces and Enumerations\n1. The **Product** class represents a product in the vending machine, with properties such as name and price.\n2. The **Coin** and **Note** enums represent the different denominations of coins and notes accepted by the vending machine.\n3. The **Inventory** class manages the available products and their quantities in the vending machine. It uses a concurrent hash map to ensure thread safety.\n4. The **VendingMachineState** interface defines the behavior of the vending machine in different states, such as idle, ready, and dispense.\n5. The **IdleState**, **ReadyState**, and **DispenseState** classes implement the VendingMachineState interface and define the specific behaviors for each state.\n6. The **VendingMachine** class is the main class that represents the vending machine. It follows the Singleton pattern to ensure only one instance of the vending machine exists.\n7. The VendingMachine class maintains the current state, selected product, total payment, and provides methods for state transitions and payment handling.\n8. The **VendingMachineDemo** class demonstrates the usage of the vending machine by adding products to the inventory, selecting products, inserting coins and notes, dispensing products, and returning change."
  },
  {
    "path": "solutions/csharp/vendingmachine/States/DispensingState.cs",
    "content": "class DispensingState : VendingMachineState\n{\n    public DispensingState(VendingMachine machine) : base(machine)\n    {\n    }\n\n    public override void InsertCoin(Coin coin)\n    {\n        Console.WriteLine(\"Currently dispensing. Please wait.\");\n    }\n\n    public override void SelectItem(string code)\n    {\n        Console.WriteLine(\"Currently dispensing. Please wait.\");\n    }\n\n    public override void Dispense()\n    {\n        // already triggered by HasMoneyState\n    }\n\n    public override void Refund()\n    {\n        Console.WriteLine(\"Dispensing in progress. Refund not allowed.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/States/HasMoneyState.cs",
    "content": "class HasMoneyState : VendingMachineState\n{\n    public HasMoneyState(VendingMachine machine) : base(machine)\n    {\n    }\n\n    public override void InsertCoin(Coin coin)\n    {\n        Console.WriteLine(\"Already received full amount.\");\n    }\n\n    public override void SelectItem(string code)\n    {\n        Console.WriteLine(\"Item already selected.\");\n    }\n\n    public override void Dispense()\n    {\n        machine.SetState(new DispensingState(machine));\n        machine.DispenseItem();\n    }\n\n    public override void Refund()\n    {\n        machine.RefundBalance();\n        machine.Reset();\n        machine.SetState(new IdleState(machine));\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/States/IdleState.cs",
    "content": "class IdleState : VendingMachineState\n{\n    public IdleState(VendingMachine machine) : base(machine)\n    {\n    }\n\n    public override void InsertCoin(Coin coin)\n    {\n        Console.WriteLine(\"Please select an item before inserting money.\");\n    }\n\n    public override void SelectItem(string code)\n    {\n        if (!machine.GetInventory().IsAvailable(code))\n        {\n            Console.WriteLine(\"Item not available.\");\n            return;\n        }\n        machine.SetSelectedItemCode(code);\n        machine.SetState(new ItemSelectedState(machine));\n        Console.WriteLine(\"Item selected: \" + code);\n    }\n\n    public override void Dispense()\n    {\n        Console.WriteLine(\"No item selected.\");\n    }\n\n    public override void Refund()\n    {\n        Console.WriteLine(\"No money to refund.\");\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/States/ItemSelectedState.cs",
    "content": "class ItemSelectedState : VendingMachineState\n{\n    public ItemSelectedState(VendingMachine machine) : base(machine)\n    {\n    }\n\n    public override void InsertCoin(Coin coin)\n    {\n        machine.AddBalance((int)coin);\n        Console.WriteLine(\"Coin Inserted: \" + (int)coin);\n        int price = machine.GetSelectedItem().GetPrice();\n        if (machine.GetBalance() >= price)\n        {\n            Console.WriteLine(\"Sufficient money received.\");\n            machine.SetState(new HasMoneyState(machine));\n        }\n    }\n\n    public override void SelectItem(string code)\n    {\n        Console.WriteLine(\"Item already selected.\");\n    }\n\n    public override void Dispense()\n    {\n        Console.WriteLine(\"Please insert sufficient money.\");\n    }\n\n    public override void Refund()\n    {\n        machine.Reset();\n        machine.SetState(new IdleState(machine));\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/States/VendingMachineState.cs",
    "content": "abstract class VendingMachineState\n{\n    protected VendingMachine machine;\n\n    public VendingMachineState(VendingMachine machine)\n    {\n        this.machine = machine;\n    }\n\n    public abstract void InsertCoin(Coin coin);\n    public abstract void SelectItem(string code);\n    public abstract void Dispense();\n    public abstract void Refund();\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/VendingMachine.cs",
    "content": "class VendingMachine\n{\n    private static readonly VendingMachine INSTANCE = new VendingMachine();\n    private readonly Inventory inventory = new Inventory();\n    private VendingMachineState currentState;\n    private int balance = 0;\n    private string selectedItemCode;\n\n    public VendingMachine()\n    {\n        currentState = new IdleState(this);\n    }\n\n    public static VendingMachine GetInstance()\n    {\n        return INSTANCE;\n    }\n\n    public void InsertCoin(Coin coin)\n    {\n        currentState.InsertCoin(coin);\n    }\n\n    public Item AddItem(string code, string name, int price, int quantity)\n    {\n        Item item = new Item(code, name, price);\n        inventory.AddItem(code, item, quantity);\n        return item;\n    }\n\n    public void SelectItem(string code)\n    {\n        currentState.SelectItem(code);\n    }\n\n    public void Dispense()\n    {\n        currentState.Dispense();\n    }\n\n    public void DispenseItem()\n    {\n        Item item = inventory.GetItem(selectedItemCode);\n        if (balance >= item.GetPrice())\n        {\n            inventory.ReduceStock(selectedItemCode);\n            balance -= item.GetPrice();\n            Console.WriteLine(\"Dispensed: \" + item.GetName());\n            if (balance > 0)\n            {\n                Console.WriteLine(\"Returning change: \" + balance);\n            }\n        }\n        Reset();\n        SetState(new IdleState(this));\n    }\n\n    public void RefundBalance()\n    {\n        Console.WriteLine(\"Refunding: \" + balance);\n        balance = 0;\n    }\n\n    public void Reset()\n    {\n        selectedItemCode = null;\n        balance = 0;\n    }\n\n    public void AddBalance(int value)\n    {\n        balance += value;\n    }\n\n    public Item GetSelectedItem()\n    {\n        return inventory.GetItem(selectedItemCode);\n    }\n\n    public void SetSelectedItemCode(string code)\n    {\n        this.selectedItemCode = code;\n    }\n\n    public void SetState(VendingMachineState state)\n    {\n        this.currentState = state;\n    }\n\n    public Inventory GetInventory() { return inventory; }\n    public int GetBalance() { return balance; }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/VendingMachineDemo.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\npublic class VendingMachineDemo\n{\n    public static void Main()\n    {\n        VendingMachine vendingMachine = VendingMachine.GetInstance();\n\n        // Add products to the inventory\n        vendingMachine.AddItem(\"A1\", \"Coke\", 25, 3);\n        vendingMachine.AddItem(\"A2\", \"Pepsi\", 25, 2);\n        vendingMachine.AddItem(\"B1\", \"Water\", 10, 5);\n\n        // Select a product\n        Console.WriteLine(\"\\n--- Step 1: Select an item ---\");\n        vendingMachine.SelectItem(\"A1\");\n\n        // Insert coins\n        Console.WriteLine(\"\\n--- Step 2: Insert coins ---\");\n        vendingMachine.InsertCoin(Coin.DIME); // 10\n        vendingMachine.InsertCoin(Coin.DIME); // 10\n        vendingMachine.InsertCoin(Coin.NICKEL); // 5\n\n        // Dispense the product\n        Console.WriteLine(\"\\n--- Step 3: Dispense item ---\");\n        vendingMachine.Dispense(); // Should dispense Coke\n\n        // Select another item\n        Console.WriteLine(\"\\n--- Step 4: Select another item ---\");\n        vendingMachine.SelectItem(\"B1\");\n\n        // Insert more amount\n        Console.WriteLine(\"\\n--- Step 5: Insert more than needed ---\");\n        vendingMachine.InsertCoin(Coin.QUARTER); // 25\n\n        // Try to dispense the product\n        Console.WriteLine(\"\\n--- Step 6: Dispense and return change ---\");\n        vendingMachine.Dispense();\n    }\n}"
  },
  {
    "path": "solutions/csharp/vendingmachine/vendingmachine.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\r\n\r\n  <PropertyGroup>\r\n    <OutputType>Exe</OutputType>\r\n    <TargetFramework>net8.0</TargetFramework>\r\n    <ImplicitUsings>enable</ImplicitUsings>\r\n    <Nullable>enable</Nullable>\r\n  </PropertyGroup>\r\n\r\n</Project>\r\n"
  },
  {
    "path": "solutions/csharp/votingsystem/README.md",
    "content": "### Airline Management System\n\nThis is a simple airline management system that allows you to manage flights, passengers, and bookings."
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/README.md",
    "content": "# Designing an Airline Management System\n\n## Requirements\n1. The airline management system should allow users to search for flights based on source, destination, and date.\n2. Users should be able to book flights, select seats, and make payments.\n3. The system should manage flight schedules, aircraft assignments, and crew assignments.\n4. The system should handle passenger information, including personal details and baggage information.\n5. The system should support different types of users, such as passengers, airline staff, and administrators.\n6. The system should be able to handle cancellations, refunds, and flight changes.\n7. The system should ensure data consistency and handle concurrent access to shared resources.\n8. The system should be scalable and extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Flight** class represents a flight in the airline management system, with properties such as flight number, source, destination, departure time, arrival time, and available seats.\n2. The **Aircraft** class represents an aircraft, with properties like tail number, model, and total seats.\n3. The **Passenger** class represents a passenger, with properties such as ID, name, email, and phone number.\n4. The **Booking** class represents a booking made by a passenger for a specific flight and seat, with properties such as booking number, flight, passenger, seat, price, and booking status.\n5. The **Seat** class represents a seat on a flight, with properties like seat number, seat type, and seat status.\n6. The **Payment** class represents a payment made for a booking, with properties such as payment ID, payment method, amount, and payment status.\n7. The **FlightSearch** class provides functionality to search for flights based on source, destination, and date.\n8. The **BookingManager** class manages the creation and cancellation of bookings. It follows the Singleton pattern to ensure a single instance of the booking manager.\n9. The **PaymentProcessor** class handles the processing of payments. It follows the Singleton pattern to ensure a single instance of the payment processor.\n10. The **AirlineManagementSystem** class serves as the main entry point of the system, combining all the components and providing methods for flight management, booking, payment processing, and other operations."
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/aircraft.go",
    "content": "package airlinemanagementsystem\n\ntype Aircraft struct {\n\tTailNumber string\n\tModel      string\n\tTotalSeats int\n}\n\nfunc NewAircraft(tailNumber, model string, totalSeats int) *Aircraft {\n\treturn &Aircraft{\n\t\tTailNumber: tailNumber,\n\t\tModel:      model,\n\t\tTotalSeats: totalSeats,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/airline_management_system.go",
    "content": "package airlinemanagementsystem\n\nimport (\n    \"sync\"\n    \"time\"\n)\n\ntype AirlineManagementSystem struct {\n    flights         []*Flight\n    aircrafts       []*Aircraft\n    flightSearch    *FlightSearch\n    bookingManager  *BookingManager\n    paymentProcessor *PaymentProcessor\n    mu              sync.RWMutex\n}\n\nfunc NewAirlineManagementSystem() *AirlineManagementSystem {\n    system := &AirlineManagementSystem{\n        flights:          make([]*Flight, 0),\n        aircrafts:        make([]*Aircraft, 0),\n        bookingManager:   GetBookingManager(),\n        paymentProcessor: GetPaymentProcessor(),\n    }\n    system.flightSearch = NewFlightSearch(system.flights)\n    return system\n}\n\nfunc (ams *AirlineManagementSystem) AddFlight(flight *Flight) {\n    ams.mu.Lock()\n    defer ams.mu.Unlock()\n    ams.flights = append(ams.flights, flight)\n}\n\nfunc (ams *AirlineManagementSystem) AddAircraft(aircraft *Aircraft) {\n    ams.mu.Lock()\n    defer ams.mu.Unlock()\n    ams.aircrafts = append(ams.aircrafts, aircraft)\n}\n\nfunc (ams *AirlineManagementSystem) SearchFlights(source, destination string, date time.Time) []*Flight {\n    return ams.flightSearch.SearchFlights(source, destination, date)\n}\n\nfunc (ams *AirlineManagementSystem) BookFlight(flight *Flight, passenger *Passenger, seat *Seat, price float64) *Booking {\n    return ams.bookingManager.CreateBooking(flight, passenger, seat, price)\n}\n\nfunc (ams *AirlineManagementSystem) CancelBooking(bookingNumber string) {\n    ams.bookingManager.CancelBooking(bookingNumber)\n}\n\nfunc (ams *AirlineManagementSystem) ProcessPayment(payment *Payment) {\n    ams.paymentProcessor.ProcessPayment(payment)\n}"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/airline_management_system_demo.go",
    "content": "package airlinemanagementsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype Demo struct {\n\tsystem *AirlineManagementSystem\n}\n\nfunc NewDemo() *Demo {\n\treturn &Demo{\n\t\tsystem: NewAirlineManagementSystem(),\n\t}\n}\n\nfunc Run() {\n\tsystem := NewAirlineManagementSystem()\n\n\t// Create users\n\tpassenger1 := NewPassenger(\n\t\t\"U001\",\n\t\t\"John Doe\",\n\t\t\"john@example.com\",\n\t\t\"1234567890\",\n\t)\n\n\t// Create flights\n\tdepartureTime1 := time.Now().AddDate(0, 0, 1)\n\tarrivalTime1 := departureTime1.Add(2 * time.Hour)\n\tflight1 := NewFlight(\n\t\t\"F001\",\n\t\t\"New York\",\n\t\t\"London\",\n\t\tdepartureTime1,\n\t\tarrivalTime1,\n\t)\n\n\tdepartureTime2 := time.Now().AddDate(0, 0, 3)\n\tarrivalTime2 := departureTime2.Add(5 * time.Hour)\n\tflight2 := NewFlight(\n\t\t\"F002\",\n\t\t\"Paris\",\n\t\t\"Tokyo\",\n\t\tdepartureTime2,\n\t\tarrivalTime2,\n\t)\n\n\tsystem.AddFlight(flight1)\n\tsystem.AddFlight(flight2)\n\n\t// Create aircrafts\n\taircraft1 := NewAircraft(\"A001\", \"Boeing 747\", 300)\n\taircraft2 := NewAircraft(\"A002\", \"Airbus A380\", 500)\n\n\tsystem.AddAircraft(aircraft1)\n\tsystem.AddAircraft(aircraft2)\n\n\t// Search flights\n\tsearchDate := time.Now().AddDate(0, 0, 1)\n\tsearchResults := system.SearchFlights(\"New York\", \"London\", searchDate)\n\n\tfmt.Println(\"Search Results:\")\n\tfor _, flight := range searchResults {\n\t\tfmt.Printf(\"Flight: %s - %s to %s\\n\",\n\t\t\tflight.FlightNumber,\n\t\t\tflight.Source,\n\t\t\tflight.Destination,\n\t\t)\n\t}\n\n\t// Create seat\n\tseat := NewSeat(\"25A\", SeatTypeEconomy)\n\n\t// Book a flight\n\tbooking := system.BookFlight(flight1, passenger1, seat, 100.0)\n\tif booking != nil {\n\t\tfmt.Printf(\"Booking successful. Booking ID: %s\\n\", booking.BookingNumber)\n\t} else {\n\t\tfmt.Println(\"Booking failed.\")\n\t}\n\n\t// Cancel the booking\n\tsystem.CancelBooking(booking.BookingNumber)\n\tfmt.Println(\"Booking cancelled.\")\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/booking.go",
    "content": "package airlinemanagementsystem\n\nimport \"sync\"\n\ntype Booking struct {\n\tBookingNumber string\n\tFlight        *Flight\n\tPassenger     *Passenger\n\tSeat          *Seat\n\tPrice         float64\n\tStatus        BookingStatus\n\tmu            sync.RWMutex\n}\n\nfunc NewBooking(bookingNumber string, flight *Flight, passenger *Passenger, seat *Seat, price float64) *Booking {\n\treturn &Booking{\n\t\tBookingNumber: bookingNumber,\n\t\tFlight:        flight,\n\t\tPassenger:     passenger,\n\t\tSeat:          seat,\n\t\tPrice:         price,\n\t\tStatus:        BookingStatusConfirmed,\n\t}\n}\n\nfunc (b *Booking) Cancel() {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.Status = BookingStatusCancelled\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/booking_manager.go",
    "content": "package airlinemanagementsystem\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\ntype BookingManager struct {\n\tbookings       map[string]*Booking\n\tbookingCounter int64\n\tmu             sync.RWMutex\n}\n\nvar (\n\tbookingManager *BookingManager\n\tbookingOnce    sync.Once\n)\n\nfunc GetBookingManager() *BookingManager {\n\tbookingOnce.Do(func() {\n\t\tbookingManager = &BookingManager{\n\t\t\tbookings: make(map[string]*Booking),\n\t\t}\n\t})\n\treturn bookingManager\n}\n\nfunc (bm *BookingManager) CreateBooking(flight *Flight, passenger *Passenger, seat *Seat, price float64) *Booking {\n\tbm.mu.Lock()\n\tdefer bm.mu.Unlock()\n\n\tbookingNumber := bm.generateBookingNumber()\n\tbooking := NewBooking(bookingNumber, flight, passenger, seat, price)\n\tbm.bookings[bookingNumber] = booking\n\treturn booking\n}\n\nfunc (bm *BookingManager) CancelBooking(bookingNumber string) {\n\tbm.mu.Lock()\n\tdefer bm.mu.Unlock()\n\n\tif booking, exists := bm.bookings[bookingNumber]; exists {\n\t\tbooking.Cancel()\n\t}\n}\n\nfunc (bm *BookingManager) generateBookingNumber() string {\n\tcounter := atomic.AddInt64(&bm.bookingCounter, 1)\n\treturn fmt.Sprintf(\"BKG%s%06d\",\n\t\ttime.Now().Format(\"20060102150405\"),\n\t\tcounter)\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/flight.go",
    "content": "package airlinemanagementsystem\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Flight struct {\n\tFlightNumber   string\n\tSource         string\n\tDestination    string\n\tDepartureTime  time.Time\n\tArrivalTime    time.Time\n\tAvailableSeats []*Seat\n\tmu             sync.RWMutex\n}\n\nfunc NewFlight(flightNumber, source, destination string, departureTime, arrivalTime time.Time) *Flight {\n\treturn &Flight{\n\t\tFlightNumber:   flightNumber,\n\t\tSource:         source,\n\t\tDestination:    destination,\n\t\tDepartureTime:  departureTime,\n\t\tArrivalTime:    arrivalTime,\n\t\tAvailableSeats: make([]*Seat, 0),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/flight_search.go",
    "content": "package airlinemanagementsystem\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype FlightSearch struct {\n\tflights []*Flight\n\tmu      sync.RWMutex\n}\n\nfunc NewFlightSearch(flights []*Flight) *FlightSearch {\n\treturn &FlightSearch{\n\t\tflights: flights,\n\t}\n}\n\nfunc (fs *FlightSearch) SearchFlights(source, destination string, date time.Time) []*Flight {\n\tfs.mu.RLock()\n\tdefer fs.mu.RUnlock()\n\n\tvar results []*Flight\n\tsource = strings.ToLower(source)\n\tdestination = strings.ToLower(destination)\n\n\tfor _, flight := range fs.flights {\n\t\tif strings.ToLower(flight.Source) == source &&\n\t\t\tstrings.ToLower(flight.Destination) == destination &&\n\t\t\tflight.DepartureTime.Year() == date.Year() &&\n\t\t\tflight.DepartureTime.Month() == date.Month() &&\n\t\t\tflight.DepartureTime.Day() == date.Day() {\n\t\t\tresults = append(results, flight)\n\t\t}\n\t}\n\treturn results\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/passenger.go",
    "content": "package airlinemanagementsystem\n\ntype Passenger struct {\n\tID    string\n\tName  string\n\tEmail string\n\tPhone string\n}\n\nfunc NewPassenger(id, name, email, phone string) *Passenger {\n\treturn &Passenger{\n\t\tID:    id,\n\t\tName:  name,\n\t\tEmail: email,\n\t\tPhone: phone,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/payment.go",
    "content": "package airlinemanagementsystem\n\nimport \"sync\"\n\ntype Payment struct {\n\tPaymentID     string\n\tPaymentMethod string\n\tAmount        float64\n\tstatus        PaymentStatus\n\tmu            sync.RWMutex\n}\n\nfunc NewPayment(paymentID, paymentMethod string, amount float64) *Payment {\n\treturn &Payment{\n\t\tPaymentID:     paymentID,\n\t\tPaymentMethod: paymentMethod,\n\t\tAmount:        amount,\n\t\tstatus:        PaymentStatusPending,\n\t}\n}\n\nfunc (p *Payment) ProcessPayment() {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.status = PaymentStatusCompleted\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/payment_processor.go",
    "content": "package airlinemanagementsystem\n\nimport \"sync\"\n\ntype PaymentProcessor struct {\n\tmu sync.Mutex\n}\n\nvar (\n\tpaymentProcessor *PaymentProcessor\n\tpaymentOnce      sync.Once\n)\n\nfunc GetPaymentProcessor() *PaymentProcessor {\n\tpaymentOnce.Do(func() {\n\t\tpaymentProcessor = &PaymentProcessor{}\n\t})\n\treturn paymentProcessor\n}\n\nfunc (p *PaymentProcessor) ProcessPayment(payment *Payment) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tpayment.ProcessPayment()\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/seat.go",
    "content": "package airlinemanagementsystem\n\nimport \"sync\"\n\ntype Seat struct {\n\tSeatNumber string\n\tType       SeatType\n\tstatus     SeatStatus\n\tmu         sync.RWMutex\n}\n\nfunc NewSeat(seatNumber string, seatType SeatType) *Seat {\n\treturn &Seat{\n\t\tSeatNumber: seatNumber,\n\t\tType:       seatType,\n\t\tstatus:     SeatStatusAvailable,\n\t}\n}\n\nfunc (s *Seat) Reserve() {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.status = SeatStatusReserved\n}\n\nfunc (s *Seat) Release() {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.status = SeatStatusAvailable\n}\n\nfunc (s *Seat) GetStatus() SeatStatus {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn s.status\n}\n"
  },
  {
    "path": "solutions/golang/airlinemanagementsystem/types.go",
    "content": "package airlinemanagementsystem\n\ntype SeatType int\ntype SeatStatus int\ntype BookingStatus int\ntype PaymentStatus int\n\nconst (\n\tSeatTypeEconomy SeatType = iota\n\tSeatTypePremiumEconomy\n\tSeatTypeBusiness\n\tSeatTypeFirstClass\n)\n\nconst (\n\tSeatStatusAvailable SeatStatus = iota\n\tSeatStatusReserved\n\tSeatStatusOccupied\n)\n\nconst (\n\tBookingStatusConfirmed BookingStatus = iota\n\tBookingStatusCancelled\n\tBookingStatusPending\n\tBookingStatusExpired\n)\n\nconst (\n\tPaymentStatusPending PaymentStatus = iota\n\tPaymentStatusCompleted\n\tPaymentStatusFailed\n\tPaymentStatusRefunded\n)\n"
  },
  {
    "path": "solutions/golang/app.log",
    "content": "[DEBUG] 1730056952254 - This is a debug message\n[INFO] 1730056952255 - This is an information message\n[DEBUG] 1730091879648 - This is a debug message\n[INFO] 1730091879648 - This is an information message\n"
  },
  {
    "path": "solutions/golang/atm/README.md",
    "content": "# Designing an ATM System\n\n## Requirements\n1. The ATM system should support basic operations such as balance inquiry, cash withdrawal, and cash deposit.\n2. Users should be able to authenticate themselves using a card and a PIN (Personal Identification Number).\n3. The system should interact with a bank's backend system to validate user accounts and perform transactions.\n4. The ATM should have a cash dispenser to dispense cash to users.\n5. The system should handle concurrent access and ensure data consistency.\n6. The ATM should have a user-friendly interface for users to interact with.\n\n## Classes, Interfaces and Enumerations\n1. The **Card** class represents an ATM card with a card number and PIN.\n2. The **Account** class represents a bank account with an account number and balance. It provides methods to debit and credit the account balance.\n3. The **Transaction** class is an abstract base class for different types of transactions, such as withdrawal and deposit. It is extended by WithdrawalTransaction and DepositTransaction classes.\n4. The **BankingService** class manages the bank accounts and processes transactions. It uses a thread-safe ConcurrentHashMap to store and retrieve account information.\n5. The **CashDispenser** class represents the ATM's cash dispenser and handles the dispensing of cash. It uses synchronization to ensure thread safety when dispensing cash.\n6. The **ATM** class serves as the main interface for ATM operations. It interacts with the BankingService and CashDispenser to perform user authentication, balance inquiry, cash withdrawal, and cash deposit.\n7. The **ATMDriver** class demonstrates the usage of the ATM system by creating sample accounts and performing ATM operations."
  },
  {
    "path": "solutions/golang/atm/account.go",
    "content": "package atm\n\nimport \"sync\"\n\ntype Account struct {\n\taccountNumber string\n\tbalance       float64\n\tmu            sync.Mutex\n}\n\nfunc NewAccount(accountNumber string, balance float64) *Account {\n\treturn &Account{\n\t\taccountNumber: accountNumber,\n\t\tbalance:       balance,\n\t}\n}\n\nfunc (a *Account) GetAccountNumber() string {\n\treturn a.accountNumber\n}\n\nfunc (a *Account) GetBalance() float64 {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\treturn a.balance\n}\n\nfunc (a *Account) Debit(amount float64) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\tif a.balance < amount {\n\t\treturn ErrInsufficientFunds\n\t}\n\ta.balance -= amount\n\treturn nil\n}\n\nfunc (a *Account) Credit(amount float64) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\ta.balance += amount\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/atm/atm.go",
    "content": "package atm\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\ntype ATM struct {\n\tbankingService *BankingService\n\tcashDispenser  *CashDispenser\n\ttxnCounter     int64\n}\n\nfunc NewATM(bankingService *BankingService, cashDispenser *CashDispenser) *ATM {\n\treturn &ATM{\n\t\tbankingService: bankingService,\n\t\tcashDispenser:  cashDispenser,\n\t}\n}\n\nfunc (a *ATM) AuthenticateUser(card *Card) error {\n\t// Authentication logic would go here\n\treturn nil\n}\n\nfunc (a *ATM) CheckBalance(accountNumber string) (float64, error) {\n\taccount := a.bankingService.GetAccount(accountNumber)\n\tif account == nil {\n\t\treturn 0, errors.New(\"account not found\")\n\t}\n\treturn account.GetBalance(), nil\n}\n\nfunc (a *ATM) WithdrawCash(accountNumber string, amount float64) error {\n\taccount := a.bankingService.GetAccount(accountNumber)\n\tif account == nil {\n\t\treturn errors.New(\"account not found\")\n\t}\n\n\ttransaction := NewWithdrawalTransaction(a.generateTransactionID(), account, amount)\n\tif err := a.bankingService.ProcessTransaction(transaction); err != nil {\n\t\treturn err\n\t}\n\n\treturn a.cashDispenser.DispenseCash(int(amount))\n}\n\nfunc (a *ATM) DepositCash(accountNumber string, amount float64) error {\n\taccount := a.bankingService.GetAccount(accountNumber)\n\tif account == nil {\n\t\treturn errors.New(\"account not found\")\n\t}\n\n\ttransaction := NewDepositTransaction(a.generateTransactionID(), account, amount)\n\treturn a.bankingService.ProcessTransaction(transaction)\n}\n\nfunc (a *ATM) generateTransactionID() string {\n\ttxnNumber := atomic.AddInt64(&a.txnCounter, 1)\n\ttimestamp := time.Now().Format(\"20060102150405\")\n\treturn fmt.Sprintf(\"TXN%s%010d\", timestamp, txnNumber)\n}\n"
  },
  {
    "path": "solutions/golang/atm/atm_demo.go",
    "content": "package atm\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tbankingService := NewBankingService()\n\tcashDispenser := NewCashDispenser(10000)\n\tatmMachine := NewATM(bankingService, cashDispenser)\n\n\t// Create sample accounts\n\tbankingService.CreateAccount(\"1234567890\", 1000.0)\n\tbankingService.CreateAccount(\"9876543210\", 500.0)\n\n\t// Create card and authenticate\n\tcard := NewCard(\"1234567890\", \"1234\")\n\tif err := atmMachine.AuthenticateUser(card); err != nil {\n\t\tfmt.Printf(\"Authentication failed: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Check balance\n\tif balance, err := atmMachine.CheckBalance(\"1234567890\"); err == nil {\n\t\tfmt.Printf(\"Account balance: %.2f\\n\", balance)\n\t} else {\n\t\tfmt.Printf(\"Error checking balance: %v\\n\", err)\n\t}\n\n\t// Withdraw cash\n\tif err := atmMachine.WithdrawCash(\"1234567890\", 500.0); err == nil {\n\t\tfmt.Println(\"Successfully withdrew $500\")\n\t} else {\n\t\tfmt.Printf(\"Error withdrawing cash: %v\\n\", err)\n\t}\n\n\t// Deposit cash\n\tif err := atmMachine.DepositCash(\"9876543210\", 200.0); err == nil {\n\t\tfmt.Println(\"Successfully deposited $200\")\n\t} else {\n\t\tfmt.Printf(\"Error depositing cash: %v\\n\", err)\n\t}\n\n\t// Check updated balance\n\tif balance, err := atmMachine.CheckBalance(\"1234567890\"); err == nil {\n\t\tfmt.Printf(\"Updated account balance: %.2f\\n\", balance)\n\t} else {\n\t\tfmt.Printf(\"Error checking balance: %v\\n\", err)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/atm/banking_service.go",
    "content": "package atm\n\nimport (\n\t\"sync\"\n)\n\ntype BankingService struct {\n\taccounts map[string]*Account\n\tmu       sync.RWMutex\n}\n\nfunc NewBankingService() *BankingService {\n\treturn &BankingService{\n\t\taccounts: make(map[string]*Account),\n\t}\n}\n\nfunc (bs *BankingService) CreateAccount(accountNumber string, initialBalance float64) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\tbs.accounts[accountNumber] = NewAccount(accountNumber, initialBalance)\n}\n\nfunc (bs *BankingService) GetAccount(accountNumber string) *Account {\n\tbs.mu.RLock()\n\tdefer bs.mu.RUnlock()\n\treturn bs.accounts[accountNumber]\n}\n\nfunc (bs *BankingService) ProcessTransaction(transaction Transaction) error {\n\treturn transaction.Execute()\n}\n"
  },
  {
    "path": "solutions/golang/atm/card.go",
    "content": "package atm\n\ntype Card struct {\n\tCardNumber string\n\tPIN        string\n}\n\nfunc NewCard(cardNumber, pin string) *Card {\n\treturn &Card{\n\t\tCardNumber: cardNumber,\n\t\tPIN:        pin,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/atm/cash_dispenser.go",
    "content": "package atm\n\nimport (\n\t\"sync\"\n)\n\ntype CashDispenser struct {\n\tcashAvailable int\n\tmu            sync.Mutex\n}\n\nfunc NewCashDispenser(initialCash int) *CashDispenser {\n\treturn &CashDispenser{\n\t\tcashAvailable: initialCash,\n\t}\n}\n\nfunc (cd *CashDispenser) DispenseCash(amount int) error {\n\tcd.mu.Lock()\n\tdefer cd.mu.Unlock()\n\n\tif amount > cd.cashAvailable {\n\t\treturn ErrInsufficientCashInATM\n\t}\n\tcd.cashAvailable -= amount\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/atm/deposit_transaction.go",
    "content": "package atm\n\ntype DepositTransaction struct {\n\tBaseTransaction\n}\n\nfunc NewDepositTransaction(transactionID string, account *Account, amount float64) *DepositTransaction {\n\treturn &DepositTransaction{\n\t\tBaseTransaction: BaseTransaction{\n\t\t\tTransactionID: transactionID,\n\t\t\tAccount:       account,\n\t\t\tAmount:        amount,\n\t\t},\n\t}\n}\n\nfunc (t *DepositTransaction) Execute() error {\n\treturn t.Account.Credit(t.Amount)\n}\n"
  },
  {
    "path": "solutions/golang/atm/errors.go",
    "content": "package atm\n\nimport \"errors\"\n\nvar (\n\tErrInsufficientFunds     = errors.New(\"insufficient funds in account\")\n\tErrInsufficientCashInATM = errors.New(\"insufficient cash available in ATM\")\n\tErrInvalidCard           = errors.New(\"invalid card\")\n\tErrInvalidPIN            = errors.New(\"invalid PIN\")\n)\n"
  },
  {
    "path": "solutions/golang/atm/transaction.go",
    "content": "package atm\n\ntype Transaction interface {\n\tExecute() error\n}\n\ntype BaseTransaction struct {\n\tTransactionID string\n\tAccount       *Account\n\tAmount        float64\n}\n"
  },
  {
    "path": "solutions/golang/atm/withdrawal_transaction.go",
    "content": "package atm\n\ntype WithdrawalTransaction struct {\n\tBaseTransaction\n}\n\nfunc NewWithdrawalTransaction(transactionID string, account *Account, amount float64) *WithdrawalTransaction {\n\treturn &WithdrawalTransaction{\n\t\tBaseTransaction: BaseTransaction{\n\t\t\tTransactionID: transactionID,\n\t\t\tAccount:       account,\n\t\t\tAmount:        amount,\n\t\t},\n\t}\n}\n\nfunc (t *WithdrawalTransaction) Execute() error {\n\treturn t.Account.Debit(t.Amount)\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/README.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "solutions/golang/carrentalsystem/car.go",
    "content": "package carrentalsystem\n\nimport \"sync\"\n\ntype Car struct {\n\tMake              string\n\tModel             string\n\tYear              int\n\tLicensePlate      string\n\tRentalPricePerDay float64\n\tavailable         bool\n\tmu                sync.Mutex\n}\n\nfunc NewCar(make, model string, year int, licensePlate string, rentalPricePerDay float64) *Car {\n\treturn &Car{\n\t\tMake:              make,\n\t\tModel:             model,\n\t\tYear:              year,\n\t\tLicensePlate:      licensePlate,\n\t\tRentalPricePerDay: rentalPricePerDay,\n\t\tavailable:         true,\n\t}\n}\n\nfunc (c *Car) IsAvailable() bool {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\treturn c.available\n}\n\nfunc (c *Car) SetAvailable(available bool) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tc.available = available\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/car_rental_system_demo.go",
    "content": "package carrentalsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\trentalSystem := GetRentalSystem()\n\n\t// Add cars to the rental system\n\trentalSystem.AddCar(NewCar(\"Toyota\", \"Camry\", 2022, \"ABC123\", 50.0))\n\trentalSystem.AddCar(NewCar(\"Honda\", \"Civic\", 2021, \"XYZ789\", 45.0))\n\trentalSystem.AddCar(NewCar(\"Ford\", \"Mustang\", 2023, \"DEF456\", 80.0))\n\n\t// Create customer\n\tcustomer := NewCustomer(\"John Doe\", \"john@example.com\", \"DL1234\")\n\n\t// Make reservation\n\tstartDate := time.Now()\n\tendDate := startDate.AddDate(0, 0, 3)\n\n\tavailableCars := rentalSystem.SearchCars(\"Toyota\", \"Camry\", startDate, endDate)\n\tif len(availableCars) > 0 {\n\t\tselectedCar := availableCars[0]\n\t\treservation, err := rentalSystem.MakeReservation(customer, selectedCar, startDate, endDate)\n\t\tif err == nil {\n\t\t\tif rentalSystem.ProcessPayment(reservation) {\n\t\t\t\tfmt.Printf(\"Reservation successful. Reservation ID: %s\\n\", reservation.ReservationID)\n\t\t\t} else {\n\t\t\t\tfmt.Println(\"Payment failed. Reservation canceled.\")\n\t\t\t\trentalSystem.CancelReservation(reservation.ReservationID)\n\t\t\t}\n\t\t} else {\n\t\t\tfmt.Printf(\"Reservation failed: %v\\n\", err)\n\t\t}\n\t} else {\n\t\tfmt.Println(\"No available cars found for the given criteria.\")\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/credit_card_processor.go",
    "content": "package carrentalsystem\n\ntype CreditCardPaymentProcessor struct{}\n\nfunc NewCreditCardPaymentProcessor() *CreditCardPaymentProcessor {\n\treturn &CreditCardPaymentProcessor{}\n}\n\nfunc (p *CreditCardPaymentProcessor) ProcessPayment(amount float64) bool {\n\t// Process credit card payment\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/customer.go",
    "content": "package carrentalsystem\n\ntype Customer struct {\n\tName                 string\n\tContactInfo          string\n\tDriversLicenseNumber string\n}\n\nfunc NewCustomer(name, contactInfo, driversLicenseNumber string) *Customer {\n\treturn &Customer{\n\t\tName:                 name,\n\t\tContactInfo:          contactInfo,\n\t\tDriversLicenseNumber: driversLicenseNumber,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/payment_processor.go",
    "content": "package carrentalsystem\n\ntype PaymentProcessor interface {\n\tProcessPayment(amount float64) bool\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/paypal_processor.go",
    "content": "package carrentalsystem\n\ntype PayPalPaymentProcessor struct{}\n\nfunc NewPayPalPaymentProcessor() *PayPalPaymentProcessor {\n\treturn &PayPalPaymentProcessor{}\n}\n\nfunc (p *PayPalPaymentProcessor) ProcessPayment(amount float64) bool {\n\t// Process PayPal payment\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/rental_system.go",
    "content": "package carrentalsystem\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype RentalSystem struct {\n\tcars         map[string]*Car\n\treservations map[string]*Reservation\n\tprocessor    PaymentProcessor\n\tmu           sync.RWMutex\n}\n\nvar (\n\tinstance *RentalSystem\n\tonce     sync.Once\n)\n\nfunc GetRentalSystem() *RentalSystem {\n\tonce.Do(func() {\n\t\tinstance = &RentalSystem{\n\t\t\tcars:         make(map[string]*Car),\n\t\t\treservations: make(map[string]*Reservation),\n\t\t\tprocessor:    NewCreditCardPaymentProcessor(),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (rs *RentalSystem) AddCar(car *Car) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\trs.cars[car.LicensePlate] = car\n}\n\nfunc (rs *RentalSystem) RemoveCar(licensePlate string) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\tdelete(rs.cars, licensePlate)\n}\n\nfunc (rs *RentalSystem) SearchCars(make, model string, startDate, endDate time.Time) []*Car {\n\trs.mu.RLock()\n\tdefer rs.mu.RUnlock()\n\n\tvar availableCars []*Car\n\tfor _, car := range rs.cars {\n\t\tif strings.EqualFold(car.Make, make) &&\n\t\t\tstrings.EqualFold(car.Model, model) &&\n\t\t\tcar.IsAvailable() &&\n\t\t\trs.isCarAvailable(car, startDate, endDate) {\n\t\t\tavailableCars = append(availableCars, car)\n\t\t}\n\t}\n\treturn availableCars\n}\n\nfunc (rs *RentalSystem) isCarAvailable(car *Car, startDate, endDate time.Time) bool {\n\tfor _, reservation := range rs.reservations {\n\t\tif reservation.Car == car {\n\t\t\tif !startDate.After(reservation.EndDate) && !endDate.Before(reservation.StartDate) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (rs *RentalSystem) MakeReservation(customer *Customer, car *Car, startDate, endDate time.Time) (*Reservation, error) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\n\tif !rs.isCarAvailable(car, startDate, endDate) {\n\t\treturn nil, fmt.Errorf(\"car is not available for the selected dates\")\n\t}\n\n\treservationID := rs.generateReservationID()\n\treservation := NewReservation(reservationID, customer, car, startDate, endDate)\n\trs.reservations[reservationID] = reservation\n\tcar.SetAvailable(false)\n\n\treturn reservation, nil\n}\n\nfunc (rs *RentalSystem) CancelReservation(reservationID string) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\n\tif reservation, exists := rs.reservations[reservationID]; exists {\n\t\treservation.Car.SetAvailable(true)\n\t\tdelete(rs.reservations, reservationID)\n\t}\n}\n\nfunc (rs *RentalSystem) ProcessPayment(reservation *Reservation) bool {\n\treturn rs.processor.ProcessPayment(reservation.TotalPrice)\n}\n\nfunc (rs *RentalSystem) generateReservationID() string {\n\tbytes := make([]byte, 4)\n\trand.Read(bytes)\n\treturn fmt.Sprintf(\"RES%s\", hex.EncodeToString(bytes))\n}\n"
  },
  {
    "path": "solutions/golang/carrentalsystem/reservation.go",
    "content": "package carrentalsystem\n\nimport (\n\t\"time\"\n)\n\ntype Reservation struct {\n\tReservationID string\n\tCustomer      *Customer\n\tCar           *Car\n\tStartDate     time.Time\n\tEndDate       time.Time\n\tTotalPrice    float64\n}\n\nfunc NewReservation(reservationID string, customer *Customer, car *Car, startDate, endDate time.Time) *Reservation {\n\tres := &Reservation{\n\t\tReservationID: reservationID,\n\t\tCustomer:      customer,\n\t\tCar:           car,\n\t\tStartDate:     startDate,\n\t\tEndDate:       endDate,\n\t}\n\tres.TotalPrice = res.calculateTotalPrice()\n\treturn res\n}\n\nfunc (r *Reservation) calculateTotalPrice() float64 {\n\tdays := r.EndDate.Sub(r.StartDate).Hours() / 24\n\treturn r.Car.RentalPricePerDay * days\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/README.md",
    "content": "# Designing a Chess Game\n\n## Requirements\n1. The chess game should follow the standard rules of chess.\n2. The game should support two players, each controlling their own set of pieces.\n3. The game board should be represented as an 8x8 grid, with alternating black and white squares.\n4. Each player should have 16 pieces: 1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.\n5. The game should validate legal moves for each piece and prevent illegal moves.\n6. The game should detect checkmate and stalemate conditions.\n7. The game should handle player turns and allow players to make moves alternately.\n8. The game should provide a user interface for players to interact with the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Piece** class is an abstract base class representing a chess piece. It contains common attributes such as color, row, and column, and declares an abstract method canMove to be implemented by each specific piece class.\n2. The **King**, **Queen**, **Rook**, **Bishop**, **Knight**, and **Pawn** classes extend the Piece class and implement their respective movement logic in the canMove method.\n3. The **Board** class represents the chess board and manages the placement of pieces. It provides methods to get and set pieces on the board, check the validity of moves, and determine checkmate and stalemate conditions.\n4. The **Player** class represents a player in the game and has a method to make a move on the board.\n5. The Move class represents a move made by a player, containing the piece being moved and the destination coordinates.\n6. The **Game** class orchestrates the overall game flow. It initializes the board, handles player turns, and determines the game result.\n7. The **ChessGame** class is the entry point of the application and starts the game."
  },
  {
    "path": "solutions/golang/chessgame/board.go",
    "content": "package chessgame\n\ntype Board struct {\n\tpieces [][]Piece\n}\n\nfunc NewBoard() *Board {\n\tboard := &Board{\n\t\tpieces: make([][]Piece, 8),\n\t}\n\tfor i := range board.pieces {\n\t\tboard.pieces[i] = make([]Piece, 8)\n\t}\n\tboard.initializeBoard()\n\treturn board\n}\n\nfunc (b *Board) initializeBoard() {\n\t// Initialize white pieces\n\tb.pieces[0][0] = NewRook(White, 0, 0)\n\tb.pieces[0][1] = NewKnight(White, 0, 1)\n\tb.pieces[0][2] = NewBishop(White, 0, 2)\n\tb.pieces[0][3] = NewQueen(White, 0, 3)\n\tb.pieces[0][4] = NewKing(White, 0, 4)\n\tb.pieces[0][5] = NewBishop(White, 0, 5)\n\tb.pieces[0][6] = NewKnight(White, 0, 6)\n\tb.pieces[0][7] = NewRook(White, 0, 7)\n\tfor i := 0; i < 8; i++ {\n\t\tb.pieces[1][i] = NewPawn(White, 1, i)\n\t}\n\n\t// Initialize black pieces\n\tb.pieces[7][0] = NewRook(Black, 7, 0)\n\tb.pieces[7][1] = NewKnight(Black, 7, 1)\n\tb.pieces[7][2] = NewBishop(Black, 7, 2)\n\tb.pieces[7][3] = NewQueen(Black, 7, 3)\n\tb.pieces[7][4] = NewKing(Black, 7, 4)\n\tb.pieces[7][5] = NewBishop(Black, 7, 5)\n\tb.pieces[7][6] = NewKnight(Black, 7, 6)\n\tb.pieces[7][7] = NewRook(Black, 7, 7)\n\tfor i := 0; i < 8; i++ {\n\t\tb.pieces[6][i] = NewPawn(Black, 6, i)\n\t}\n}\n\nfunc (b *Board) GetPiece(row, col int) Piece {\n\tif row < 0 || row > 7 || col < 0 || col > 7 {\n\t\treturn nil\n\t}\n\treturn b.pieces[row][col]\n}\n\nfunc (b *Board) SetPiece(row, col int, piece Piece) {\n\tif row >= 0 && row < 8 && col >= 0 && col < 8 {\n\t\tb.pieces[row][col] = piece\n\t}\n}\n\nfunc (b *Board) IsValidMove(piece Piece, destRow, destCol int) bool {\n\tif piece == nil || destRow < 0 || destRow > 7 || destCol < 0 || destCol > 7 {\n\t\treturn false\n\t}\n\tdestPiece := b.GetPiece(destRow, destCol)\n\treturn (destPiece == nil || destPiece.GetColor() != piece.GetColor()) &&\n\t\tpiece.CanMove(b, destRow, destCol)\n}\n\nfunc (b *Board) IsCheckmate(color Color) bool {\n\t// TODO: Implement checkmate logic\n\treturn false\n}\n\nfunc (b *Board) IsStalemate(color Color) bool {\n\t// TODO: Implement stalemate logic\n\treturn false\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/chess_game.go",
    "content": "package chessgame\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n)\n\ntype ChessGame struct {\n\tboard         *Board\n\tplayers       []*Player\n\tcurrentPlayer int\n}\n\nfunc NewChessGame() *ChessGame {\n\treturn &ChessGame{\n\t\tboard:         NewBoard(),\n\t\tplayers:       []*Player{NewPlayer(White), NewPlayer(Black)},\n\t\tcurrentPlayer: 0,\n\t}\n}\n\nfunc (g *ChessGame) Start() {\n\treader := bufio.NewReader(os.Stdin)\n\n\tfor !g.isGameOver() {\n\t\tplayer := g.players[g.currentPlayer]\n\t\tfmt.Printf(\"%s's turn.\\n\", player.color)\n\n\t\tmove, err := g.getPlayerMove(player, reader)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error: %v\\nTry again!\\n\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\terr = player.MakeMove(g.board, move)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Error: %v\\nTry again!\\n\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tg.currentPlayer = (g.currentPlayer + 1) % 2\n\t}\n\n\tg.displayResult()\n}\n\nfunc (g *ChessGame) isGameOver() bool {\n\treturn g.board.IsCheckmate(White) || g.board.IsCheckmate(Black) ||\n\t\tg.board.IsStalemate(White) || g.board.IsStalemate(Black)\n}\n\nfunc (g *ChessGame) getPlayerMove(player *Player, reader *bufio.Reader) (*Move, error) {\n\tfmt.Print(\"Enter source row: \")\n\tsourceRow, _ := strconv.Atoi(readLine(reader))\n\tfmt.Print(\"Enter source column: \")\n\tsourceCol, _ := strconv.Atoi(readLine(reader))\n\tfmt.Print(\"Enter destination row: \")\n\tdestRow, _ := strconv.Atoi(readLine(reader))\n\tfmt.Print(\"Enter destination column: \")\n\tdestCol, _ := strconv.Atoi(readLine(reader))\n\n\tpiece := g.board.GetPiece(sourceRow, sourceCol)\n\tif piece == nil || piece.GetColor() != player.color {\n\t\treturn nil, fmt.Errorf(\"invalid piece selection\")\n\t}\n\n\treturn NewMove(piece, destRow, destCol), nil\n}\n\nfunc (g *ChessGame) displayResult() {\n\tif g.board.IsCheckmate(White) {\n\t\tfmt.Println(\"Black wins by checkmate!\")\n\t} else if g.board.IsCheckmate(Black) {\n\t\tfmt.Println(\"White wins by checkmate!\")\n\t} else if g.board.IsStalemate(White) || g.board.IsStalemate(Black) {\n\t\tfmt.Println(\"The game ends in a stalemate!\")\n\t}\n}\n\nfunc readLine(reader *bufio.Reader) string {\n\ttext, _ := reader.ReadString('\\n')\n\treturn text[:len(text)-1]\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/chess_game_demo.go",
    "content": "package chessgame\n\nfunc Run() {\n\tgame := NewChessGame()\n\tgame.Start()\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/color.go",
    "content": "package chessgame\n\ntype Color int\n\nconst (\n\tWhite Color = iota\n\tBlack\n)\n\nfunc (c Color) String() string {\n\tif c == White {\n\t\treturn \"White\"\n\t}\n\treturn \"Black\"\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/errors.go",
    "content": "package chessgame\n\ntype InvalidMoveError struct {\n\tmessage string\n}\n\nfunc NewInvalidMoveError(message string) *InvalidMoveError {\n\treturn &InvalidMoveError{message: message}\n}\n\nfunc (e *InvalidMoveError) Error() string {\n\treturn e.message\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/move.go",
    "content": "package chessgame\n\ntype Move struct {\n\tpiece   Piece\n\tdestRow int\n\tdestCol int\n}\n\nfunc NewMove(piece Piece, destRow, destCol int) *Move {\n\treturn &Move{\n\t\tpiece:   piece,\n\t\tdestRow: destRow,\n\t\tdestCol: destCol,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/piece.go",
    "content": "package chessgame\n\ntype Piece interface {\n\tCanMove(board *Board, destRow, destCol int) bool\n\tGetColor() Color\n\tGetRow() int\n\tGetCol() int\n\tSetPosition(row, col int)\n}\n\ntype BasePiece struct {\n\tcolor Color\n\trow   int\n\tcol   int\n}\n\nfunc (p *BasePiece) GetColor() Color { return p.color }\nfunc (p *BasePiece) GetRow() int     { return p.row }\nfunc (p *BasePiece) GetCol() int     { return p.col }\nfunc (p *BasePiece) SetPosition(row, col int) {\n\tp.row = row\n\tp.col = col\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/pieces.go",
    "content": "package chessgame\n\nimport \"math\"\n\ntype Pawn struct {\n\tBasePiece\n}\n\nfunc NewPawn(color Color, row, col int) *Pawn {\n\treturn &Pawn{BasePiece{color, row, col}}\n}\n\nfunc (p *Pawn) CanMove(board *Board, destRow, destCol int) bool {\n\trowDiff := destRow - p.row\n\tcolDiff := math.Abs(float64(destCol - p.col))\n\n\tif p.color == White {\n\t\treturn (rowDiff == 1 && colDiff == 0) ||\n\t\t\t(p.row == 1 && rowDiff == 2 && colDiff == 0) ||\n\t\t\t(rowDiff == 1 && colDiff == 1 && board.GetPiece(destRow, destCol) != nil)\n\t}\n\treturn (rowDiff == -1 && colDiff == 0) ||\n\t\t(p.row == 6 && rowDiff == -2 && colDiff == 0) ||\n\t\t(rowDiff == -1 && colDiff == 1 && board.GetPiece(destRow, destCol) != nil)\n}\n\ntype Rook struct {\n\tBasePiece\n}\n\nfunc NewRook(color Color, row, col int) *Rook {\n\treturn &Rook{BasePiece{color, row, col}}\n}\n\nfunc (r *Rook) CanMove(board *Board, destRow, destCol int) bool {\n\treturn r.row == destRow || r.col == destCol\n}\n\ntype Knight struct {\n\tBasePiece\n}\n\nfunc NewKnight(color Color, row, col int) *Knight {\n\treturn &Knight{BasePiece{color, row, col}}\n}\n\nfunc (k *Knight) CanMove(board *Board, destRow, destCol int) bool {\n\trowDiff := math.Abs(float64(destRow - k.row))\n\tcolDiff := math.Abs(float64(destCol - k.col))\n\treturn (rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2)\n}\n\ntype Bishop struct {\n\tBasePiece\n}\n\nfunc NewBishop(color Color, row, col int) *Bishop {\n\treturn &Bishop{BasePiece{color, row, col}}\n}\n\nfunc (b *Bishop) CanMove(board *Board, destRow, destCol int) bool {\n\trowDiff := math.Abs(float64(destRow - b.row))\n\tcolDiff := math.Abs(float64(destCol - b.col))\n\treturn rowDiff == colDiff\n}\n\ntype Queen struct {\n\tBasePiece\n}\n\nfunc NewQueen(color Color, row, col int) *Queen {\n\treturn &Queen{BasePiece{color, row, col}}\n}\n\nfunc (q *Queen) CanMove(board *Board, destRow, destCol int) bool {\n\trowDiff := math.Abs(float64(destRow - q.row))\n\tcolDiff := math.Abs(float64(destCol - q.col))\n\treturn (rowDiff == colDiff) || (q.row == destRow || q.col == destCol)\n}\n\ntype King struct {\n\tBasePiece\n}\n\nfunc NewKing(color Color, row, col int) *King {\n\treturn &King{BasePiece{color, row, col}}\n}\n\nfunc (k *King) CanMove(board *Board, destRow, destCol int) bool {\n\trowDiff := math.Abs(float64(destRow - k.row))\n\tcolDiff := math.Abs(float64(destCol - k.col))\n\treturn rowDiff <= 1 && colDiff <= 1\n}\n"
  },
  {
    "path": "solutions/golang/chessgame/player.go",
    "content": "package chessgame\n\ntype Player struct {\n\tcolor Color\n}\n\nfunc NewPlayer(color Color) *Player {\n\treturn &Player{color: color}\n}\n\nfunc (p *Player) MakeMove(board *Board, move *Move) error {\n\tif !board.IsValidMove(move.piece, move.destRow, move.destCol) {\n\t\treturn NewInvalidMoveError(\"Invalid move!\")\n\t}\n\n\tsourceRow := move.piece.GetRow()\n\tsourceCol := move.piece.GetCol()\n\tboard.SetPiece(sourceRow, sourceCol, nil)\n\tboard.SetPiece(move.destRow, move.destCol, move.piece)\n\tmove.piece.SetPosition(move.destRow, move.destCol)\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/coffeevendingmachine/README.md",
    "content": "# Designing a Coffee Vending Machine\n\n## Requirements\n1. The coffee vending machine should support different types of coffee, such as espresso, cappuccino, and latte.\n2. Each type of coffee should have a specific price and recipe (ingredients and their quantities).\n3. The machine should have a menu to display the available coffee options and their prices.\n4. Users should be able to select a coffee type and make a payment.\n5. The machine should dispense the selected coffee and provide change if necessary.\n6. The machine should track the inventory of ingredients and notify when they are running low.\n7. The machine should handle multiple user requests concurrently and ensure thread safety.\n\n## Classes, Interfaces and Enumerations\n1. The **Coffee** class represents a coffee type with its name, price, and recipe (ingredients and their quantities).\n2. The **Ingredient** class represents an ingredient used in making coffee, with its name and quantity. It provides a synchronized method to update the quantity.\n3. The **Payment** class represents a payment made by a user, with the amount paid.\n4. The **CoffeeMachine** class is the main class that manages the coffee vending machine. It follows the Singleton pattern to ensure a single instance of the machine.\n5. The **CoffeeMachine** class initializes the coffee menu and ingredients in its constructor. It provides methods to display the menu, select a coffee, dispense coffee, and update ingredient quantities.\n6. The hasEnoughIngredients method checks if there are sufficient ingredients to make a selected coffee, while the updateIngredients method updates the ingredient quantities after dispensing a coffee.\n7. The **CoffeeVendingMachine** class is the entry point of the application and demonstrates the usage of the coffee vending machine. It creates an instance of the machine, displays the menu, and simulates concurrent user requests using an ExecutorService."
  },
  {
    "path": "solutions/golang/coffeevendingmachine/coffee.go",
    "content": "package coffeevendingmachine\n\ntype Coffee struct {\n\tname   string\n\tprice  float64\n\trecipe map[*Ingredient]int\n}\n\nfunc NewCoffee(name string, price float64, recipe map[*Ingredient]int) *Coffee {\n\treturn &Coffee{\n\t\tname:   name,\n\t\tprice:  price,\n\t\trecipe: recipe,\n\t}\n}\n\nfunc (c *Coffee) GetName() string {\n\treturn c.name\n}\n\nfunc (c *Coffee) GetPrice() float64 {\n\treturn c.price\n}\n\nfunc (c *Coffee) GetRecipe() map[*Ingredient]int {\n\treturn c.recipe\n}\n"
  },
  {
    "path": "solutions/golang/coffeevendingmachine/coffee_machine.go",
    "content": "package coffeevendingmachine\n\nimport (\n    \"fmt\"\n    \"sync\"\n)\n\ntype CoffeeMachine struct {\n    coffeeMenu   []*Coffee\n    ingredients  map[string]*Ingredient\n    mu          sync.Mutex\n}\n\nvar (\n    instance *CoffeeMachine\n    once     sync.Once\n)\n\nfunc GetCoffeeMachine() *CoffeeMachine {\n    once.Do(func() {\n        instance = &CoffeeMachine{\n            coffeeMenu:  make([]*Coffee, 0),\n            ingredients: make(map[string]*Ingredient),\n        }\n        instance.initializeIngredients()\n        instance.initializeCoffeeMenu()\n    })\n    return instance\n}\n\nfunc (cm *CoffeeMachine) initializeIngredients() {\n    cm.ingredients[\"Coffee\"] = NewIngredient(\"Coffee\", 10)\n    cm.ingredients[\"Water\"] = NewIngredient(\"Water\", 10)\n    cm.ingredients[\"Milk\"] = NewIngredient(\"Milk\", 10)\n}\n\nfunc (cm *CoffeeMachine) initializeCoffeeMenu() {\n    // Espresso Recipe\n    espressoRecipe := make(map[*Ingredient]int)\n    espressoRecipe[cm.ingredients[\"Coffee\"]] = 1\n    espressoRecipe[cm.ingredients[\"Water\"]] = 1\n    cm.coffeeMenu = append(cm.coffeeMenu, NewCoffee(\"Espresso\", 2.5, espressoRecipe))\n\n    // Cappuccino Recipe\n    cappuccinoRecipe := make(map[*Ingredient]int)\n    cappuccinoRecipe[cm.ingredients[\"Coffee\"]] = 1\n    cappuccinoRecipe[cm.ingredients[\"Water\"]] = 1\n    cappuccinoRecipe[cm.ingredients[\"Milk\"]] = 1\n    cm.coffeeMenu = append(cm.coffeeMenu, NewCoffee(\"Cappuccino\", 3.5, cappuccinoRecipe))\n\n    // Latte Recipe\n    latteRecipe := make(map[*Ingredient]int)\n    latteRecipe[cm.ingredients[\"Coffee\"]] = 1\n    latteRecipe[cm.ingredients[\"Water\"]] = 1\n    latteRecipe[cm.ingredients[\"Milk\"]] = 2\n    cm.coffeeMenu = append(cm.coffeeMenu, NewCoffee(\"Latte\", 4.0, latteRecipe))\n}\n\nfunc (cm *CoffeeMachine) DisplayMenu() {\n    fmt.Println(\"Coffee Menu:\")\n    for _, coffee := range cm.coffeeMenu {\n        fmt.Printf(\"%s - $%.2f\\n\", coffee.GetName(), coffee.GetPrice())\n    }\n}\n\nfunc (cm *CoffeeMachine) SelectCoffee(coffeeName string) *Coffee {\n    cm.mu.Lock()\n    defer cm.mu.Unlock()\n\n    for _, coffee := range cm.coffeeMenu {\n        if coffee.GetName() == coffeeName {\n            return coffee\n        }\n    }\n    return nil\n}\n\nfunc (cm *CoffeeMachine) DispenseCoffee(coffee *Coffee, payment *Payment) error {\n    cm.mu.Lock()\n    defer cm.mu.Unlock()\n\n    if coffee == nil {\n        return fmt.Errorf(\"invalid coffee selection\")\n    }\n\n    if payment.amount < coffee.GetPrice() {\n        return fmt.Errorf(\"insufficient payment for %s\", coffee.GetName())\n    }\n\n    if !cm.hasEnoughIngredients(coffee) {\n        return fmt.Errorf(\"insufficient ingredients to make %s\", coffee.GetName())\n    }\n\n    cm.updateIngredients(coffee)\n    fmt.Printf(\"Dispensing %s...\\n\", coffee.GetName())\n\n    change := payment.amount - coffee.GetPrice()\n    if change > 0 {\n        fmt.Printf(\"Please collect your change: $%.2f\\n\", change)\n    }\n\n    return nil\n}\n\nfunc (cm *CoffeeMachine) hasEnoughIngredients(coffee *Coffee) bool {\n    for ingredient, requiredQuantity := range coffee.GetRecipe() {\n        if ingredient.GetQuantity() < requiredQuantity {\n            return false\n        }\n    }\n    return true\n}\n\nfunc (cm *CoffeeMachine) updateIngredients(coffee *Coffee) {\n    for ingredient, requiredQuantity := range coffee.GetRecipe() {\n        ingredient.UpdateQuantity(-requiredQuantity)\n        if ingredient.GetQuantity() < 3 {\n            fmt.Printf(\"Low inventory alert: %s\\n\", ingredient.GetName())\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/golang/coffeevendingmachine/coffee_vending_machine_demo.go",
    "content": "package coffeevendingmachine\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tcoffeeMachine := GetCoffeeMachine()\n\n\t// Display coffee menu\n\tcoffeeMachine.DisplayMenu()\n\n\t// Simulate user requests\n\tcoffeeTypes := []string{\"Espresso\", \"Cappuccino\", \"Latte\"}\n\tpayments := []float64{3.0, 3.5, 4.0}\n\n\tfor i, coffeeType := range coffeeTypes {\n\t\tselectedCoffee := coffeeMachine.SelectCoffee(coffeeType)\n\t\tpayment := NewPayment(payments[i])\n\n\t\tfmt.Printf(\"\\nOrdering %s...\\n\", coffeeType)\n\t\tif err := coffeeMachine.DispenseCoffee(selectedCoffee, payment); err != nil {\n\t\t\tfmt.Printf(\"Error: %v\\n\", err)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/coffeevendingmachine/ingredient.go",
    "content": "package coffeevendingmachine\n\nimport \"sync\"\n\ntype Ingredient struct {\n\tname     string\n\tquantity int\n\tmu       sync.Mutex\n}\n\nfunc NewIngredient(name string, quantity int) *Ingredient {\n\treturn &Ingredient{\n\t\tname:     name,\n\t\tquantity: quantity,\n\t}\n}\n\nfunc (i *Ingredient) GetName() string {\n\treturn i.name\n}\n\nfunc (i *Ingredient) GetQuantity() int {\n\ti.mu.Lock()\n\tdefer i.mu.Unlock()\n\treturn i.quantity\n}\n\nfunc (i *Ingredient) UpdateQuantity(amount int) {\n\ti.mu.Lock()\n\tdefer i.mu.Unlock()\n\ti.quantity += amount\n}\n"
  },
  {
    "path": "solutions/golang/coffeevendingmachine/payment.go",
    "content": "package coffeevendingmachine\n\ntype Payment struct {\n\tamount float64\n}\n\nfunc NewPayment(amount float64) *Payment {\n\treturn &Payment{amount: amount}\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/README.md",
    "content": "# Designing a Concert Ticket Booking System\n\n## Requirements\n1. The concert ticket booking system should allow users to view available concerts and their seating arrangements.\n2. Users should be able to search for concerts based on various criteria such as artist, venue, date, and time.\n3. Users should be able to select seats and purchase tickets for a specific concert.\n4. The system should handle concurrent booking requests to avoid double-booking of seats.\n5. The system should ensure fair booking opportunities for all users.\n6. The system should handle payment processing securely.\n7. The system should generate booking confirmations and send them to users via email or SMS.\n8. The system should provide a waiting list functionality for sold-out concerts.\n\n## Classes, Interfaces and Enumerations\n1. The **Concert** class represents a concert event, with properties such as ID, artist, venue, date and time, and a list of seats.\n2. The **Seat** class represents a seat in a concert, with properties like ID, seat number, seat type, price, and status. It provides methods to book and release a seat.\n3. The **SeatType** enum represents the different types of seats available, such as regular, premium, and VIP.\n4. The **SeatStatus** enum represents the status of a seat, which can be available, booked, or reserved.\n5. The **Booking** class represents a booking made by a user for a specific concert and seats. It contains properties such as ID, user, concert, seats, total price, and status. It provides methods to confirm and cancel a booking.\n6. The **BookingStatus** enum represents the status of a booking, which can be pending, confirmed, or cancelled.\n7. The **User** class represents a user of the concert ticket booking system, with properties like ID, name, and email.\n8. The **ConcertTicketBookingSystem** class is the central component of the system. It follows the Singleton pattern to ensure a single instance of the system. It manages concerts, bookings, and provides methods to add concerts, search concerts, book tickets, and cancel bookings.\n9. The **SeatNotAvailableException** is a custom exception used to handle cases where a seat is not available for booking."
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/booking.go",
    "content": "package concertbookingsystem\n\ntype Booking struct {\n\tID         string\n\tUser       *User\n\tConcert    *Concert\n\tSeats      []*Seat\n\tTotalPrice float64\n\tStatus     BookingStatus\n}\n\nfunc NewBooking(id string, user *User, concert *Concert, seats []*Seat) *Booking {\n\ttotalPrice := calculateTotalPrice(seats)\n\treturn &Booking{\n\t\tID:         id,\n\t\tUser:       user,\n\t\tConcert:    concert,\n\t\tSeats:      seats,\n\t\tTotalPrice: totalPrice,\n\t\tStatus:     BookingStatusPending,\n\t}\n}\n\nfunc (b *Booking) ConfirmBooking() {\n\tif b.Status == BookingStatusPending {\n\t\tb.Status = BookingStatusConfirmed\n\t\t// TODO: Send booking confirmation to user\n\t}\n}\n\nfunc (b *Booking) CancelBooking() {\n\tif b.Status == BookingStatusConfirmed {\n\t\tb.Status = BookingStatusCancelled\n\t\tfor _, seat := range b.Seats {\n\t\t\tseat.Release()\n\t\t}\n\t\t// TODO: Send cancellation notification to user\n\t}\n}\n\nfunc calculateTotalPrice(seats []*Seat) float64 {\n\tvar total float64\n\tfor _, seat := range seats {\n\t\ttotal += seat.Price\n\t}\n\treturn total\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/concert.go",
    "content": "package concertbookingsystem\n\nimport \"time\"\n\ntype Concert struct {\n\tID       string\n\tArtist   string\n\tVenue    string\n\tDateTime time.Time\n\tSeats    []*Seat\n}\n\nfunc NewConcert(id, artist, venue string, dateTime time.Time, seats []*Seat) *Concert {\n\treturn &Concert{\n\t\tID:       id,\n\t\tArtist:   artist,\n\t\tVenue:    venue,\n\t\tDateTime: dateTime,\n\t\tSeats:    seats,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/concert_booking_system.go",
    "content": "package concertbookingsystem\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype ConcertTicketBookingSystem struct {\n\tconcerts map[string]*Concert\n\tbookings map[string]*Booking\n\tmu       sync.Mutex\n}\n\nvar (\n\tinstance *ConcertTicketBookingSystem\n\tonce     sync.Once\n)\n\nfunc GetBookingSystem() *ConcertTicketBookingSystem {\n\tonce.Do(func() {\n\t\tinstance = &ConcertTicketBookingSystem{\n\t\t\tconcerts: make(map[string]*Concert),\n\t\t\tbookings: make(map[string]*Booking),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (bs *ConcertTicketBookingSystem) AddConcert(concert *Concert) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\tbs.concerts[concert.ID] = concert\n}\n\nfunc (bs *ConcertTicketBookingSystem) GetConcert(concertID string) *Concert {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\treturn bs.concerts[concertID]\n}\n\nfunc (bs *ConcertTicketBookingSystem) SearchConcerts(artist, venue string, dateTime time.Time) []*Concert {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\tvar results []*Concert\n\tfor _, concert := range bs.concerts {\n\t\tif concert.Artist == artist &&\n\t\t\tconcert.Venue == venue &&\n\t\t\tconcert.DateTime.Equal(dateTime) {\n\t\t\tresults = append(results, concert)\n\t\t}\n\t}\n\treturn results\n}\n\nfunc (bs *ConcertTicketBookingSystem) BookTickets(user *User, concert *Concert, seats []*Seat) (*Booking, error) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\t// Check seat availability\n\tfor _, seat := range seats {\n\t\tif seat.GetStatus() != StatusAvailable {\n\t\t\treturn nil, NewSeatNotAvailableError(fmt.Sprintf(\"Seat %s is not available\", seat.SeatNumber))\n\t\t}\n\t}\n\n\t// Book seats\n\tfor _, seat := range seats {\n\t\tif err := seat.Book(); err != nil {\n\t\t\t// Rollback previous bookings\n\t\t\tfor _, s := range seats {\n\t\t\t\tif s == seat {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ts.Release()\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// Create booking\n\tbookingID := fmt.Sprintf(\"BKG-%d\", time.Now().UnixNano())\n\tbooking := NewBooking(bookingID, user, concert, seats)\n\n\t// Process payment (mock)\n\tbs.processPayment(booking)\n\n\t// Confirm booking\n\tbooking.ConfirmBooking()\n\tbs.bookings[bookingID] = booking\n\n\tfmt.Printf(\"Booking %s - %d seats booked\\n\", booking.ID, len(booking.Seats))\n\treturn booking, nil\n}\n\nfunc (bs *ConcertTicketBookingSystem) CancelBooking(bookingID string) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\tif booking, exists := bs.bookings[bookingID]; exists {\n\t\tbooking.CancelBooking()\n\t\tdelete(bs.bookings, bookingID)\n\t\tfmt.Printf(\"Booking %s cancelled\\n\", bookingID)\n\t}\n}\n\nfunc (bs *ConcertTicketBookingSystem) processPayment(booking *Booking) {\n\t// Mock payment processing\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/concert_booking_system_demo.go",
    "content": "package concertbookingsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\tbookingSystem := GetBookingSystem()\n\n\t// Create concerts\n\tconcert1Seats := GenerateSeats(100)\n\tconcert1 := NewConcert(\"C001\", \"Artist 1\", \"Venue 1\",\n\t\ttime.Now().Add(30*24*time.Hour), concert1Seats)\n\tbookingSystem.AddConcert(concert1)\n\n\tconcert2Seats := GenerateSeats(50)\n\tconcert2 := NewConcert(\"C002\", \"Artist 2\", \"Venue 2\",\n\t\ttime.Now().Add(60*24*time.Hour), concert2Seats)\n\tbookingSystem.AddConcert(concert2)\n\n\t// Create users\n\tuser1 := NewUser(\"U001\", \"John Doe\", \"john@example.com\")\n\tuser2 := NewUser(\"U002\", \"Jane Smith\", \"jane@example.com\")\n\n\t// Search concerts\n\tsearchResults := bookingSystem.SearchConcerts(\"Artist 1\", \"Venue 1\",\n\t\ttime.Now().Add(30*24*time.Hour))\n\n\tfmt.Println(\"Search Results:\")\n\tfor _, concert := range searchResults {\n\t\tfmt.Printf(\"Concert: %s at %s\\n\", concert.Artist, concert.Venue)\n\t}\n\n\t// Book tickets\n\tselectedSeats1 := concert1.Seats[:3] // Select first 3 seats\n\tbooking1, err := bookingSystem.BookTickets(user1, concert1, selectedSeats1)\n\tif err != nil {\n\t\tfmt.Printf(\"Booking error: %v\\n\", err)\n\t}\n\n\tselectedSeats2 := concert2.Seats[:2] // Select first 2 seats\n\tbooking2, err := bookingSystem.BookTickets(user2, concert2, selectedSeats2)\n\tif err != nil {\n\t\tfmt.Printf(\"Booking error: %v\\n\", err)\n\t}\n\n\tif booking2 != nil {\n\t\tfmt.Printf(\"Booking Successful\\n\")\n\t}\n\n\t// Cancel booking\n\tif booking1 != nil {\n\t\tbookingSystem.CancelBooking(booking1.ID)\n\t}\n\n\t// Book tickets again\n\tselectedSeats3 := concert1.Seats[3:5] // Select next 2 seats\n\tbooking3, err := bookingSystem.BookTickets(user2, concert1, selectedSeats3)\n\tif err != nil {\n\t\tfmt.Printf(\"Booking error: %v\\n\", err)\n\t}\n\n\tif booking3 != nil {\n\t\tfmt.Printf(\"Booking Successful\\n\")\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/errors.go",
    "content": "package concertbookingsystem\n\ntype SeatNotAvailableError struct {\n\tmessage string\n}\n\nfunc NewSeatNotAvailableError(message string) *SeatNotAvailableError {\n\treturn &SeatNotAvailableError{message: message}\n}\n\nfunc (e *SeatNotAvailableError) Error() string {\n\treturn e.message\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/seat.go",
    "content": "package concertbookingsystem\n\nimport \"sync\"\n\ntype Seat struct {\n\tID         string\n\tSeatNumber string\n\tType       SeatType\n\tPrice      float64\n\tstatus     SeatStatus\n\tmu         sync.Mutex\n}\n\nfunc NewSeat(id, seatNumber string, seatType SeatType, price float64) *Seat {\n\treturn &Seat{\n\t\tID:         id,\n\t\tSeatNumber: seatNumber,\n\t\tType:       seatType,\n\t\tPrice:      price,\n\t\tstatus:     StatusAvailable,\n\t}\n}\n\nfunc (s *Seat) Book() error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.status != StatusAvailable {\n\t\treturn NewSeatNotAvailableError(\"Seat is already booked or reserved\")\n\t}\n\ts.status = StatusBooked\n\treturn nil\n}\n\nfunc (s *Seat) Release() {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tif s.status == StatusBooked {\n\t\ts.status = StatusAvailable\n\t}\n}\n\nfunc (s *Seat) GetStatus() SeatStatus {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\treturn s.status\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/types.go",
    "content": "package concertbookingsystem\n\ntype SeatType int\ntype SeatStatus int\ntype BookingStatus int\n\nconst (\n\tSeatTypeRegular SeatType = iota\n\tSeatTypePremium\n\tSeatTypeVIP\n)\n\nconst (\n\tStatusAvailable SeatStatus = iota\n\tStatusBooked\n\tStatusReserved\n)\n\nconst (\n\tBookingStatusPending BookingStatus = iota\n\tBookingStatusConfirmed\n\tBookingStatusCancelled\n)\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/user.go",
    "content": "package concertbookingsystem\n\ntype User struct {\n\tID    string\n\tName  string\n\tEmail string\n}\n\nfunc NewUser(id, name, email string) *User {\n\treturn &User{\n\t\tID:    id,\n\t\tName:  name,\n\t\tEmail: email,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/concertticketbookingsystem/utils.go",
    "content": "package concertbookingsystem\n\nimport \"fmt\"\n\nfunc GenerateSeats(numberOfSeats int) []*Seat {\n\tseats := make([]*Seat, 0, numberOfSeats)\n\tfor i := 1; i <= numberOfSeats; i++ {\n\t\tseatNumber := fmt.Sprintf(\"S%d\", i)\n\t\tvar seatType SeatType\n\t\tvar price float64\n\n\t\tswitch {\n\t\tcase i <= 10:\n\t\t\tseatType = SeatTypeVIP\n\t\t\tprice = 100.0\n\t\tcase i <= 30:\n\t\t\tseatType = SeatTypePremium\n\t\t\tprice = 75.0\n\t\tdefault:\n\t\t\tseatType = SeatTypeRegular\n\t\t\tprice = 50.0\n\t\t}\n\n\t\tseats = append(seats, NewSeat(seatNumber, seatNumber, seatType, price))\n\t}\n\treturn seats\n}\n"
  },
  {
    "path": "solutions/golang/courseregistrationsystem/README.md",
    "content": "# Designing a University Course Registration System\n\n## Requirements\n1. The course registration system should allow students to register for courses and view their registered courses.\n2. Each course should have a course code, name, instructor, and maximum enrollment capacity.\n3. Students should be able to search for courses based on course code or name.\n4. The system should prevent students from registering for courses that have reached their maximum enrollment capacity.\n5. The system should handle concurrent registration requests from multiple students.\n6. The system should ensure data consistency and prevent race conditions.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Student** class represents a student in the course registration system, with properties such as ID, name, email, and a list of registered courses.\n2. The **Course** class represents a course offered in the system, with properties such as code, name, instructor, maximum capacity, and the number of enrolled students.\n3. The **Registration** class represents a registration record, associating a student with a course and capturing the registration timestamp.\n4. The **CourseRegistrationSystem** class is the main class that manages the course registration system. It follows the Singleton pattern to ensure only one instance of the system exists.\n5. The CourseRegistrationSystem class provides methods for adding courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student.\n6. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as courses and registrations.\n7. The registerCourse method is synchronized to ensure thread safety when multiple students are registering for courses simultaneously.\n8. The notifyObservers method is a placeholder for notifying observers (e.g., UI components) about updates to course enrollment.\n9. The **CourseRegistrationDemo** class demonstrates the usage of the course registration system by creating courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student."
  },
  {
    "path": "solutions/golang/courseregistrationsystem/course.go",
    "content": "package courseregistrationsystem\n\nimport \"sync\"\n\ntype Course struct {\n\tCode             string\n\tName             string\n\tInstructor       string\n\tMaxCapacity      int\n\tenrolledStudents int\n\tmu               sync.Mutex\n}\n\nfunc NewCourse(code, name, instructor string, maxCapacity int) *Course {\n\treturn &Course{\n\t\tCode:        code,\n\t\tName:        name,\n\t\tInstructor:  instructor,\n\t\tMaxCapacity: maxCapacity,\n\t}\n}\n\nfunc (c *Course) GetEnrolledStudents() int {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\treturn c.enrolledStudents\n}\n\nfunc (c *Course) IncrementEnrolled() {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\tc.enrolledStudents++\n}\n"
  },
  {
    "path": "solutions/golang/courseregistrationsystem/course_registration_system.go",
    "content": "package courseregistrationsystem\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype CourseRegistrationSystem struct {\n\tcourses       map[string]*Course\n\tstudents      map[int]*Student\n\tregistrations []*Registration\n\tmu            sync.RWMutex\n}\n\nvar (\n\tinstance *CourseRegistrationSystem\n\tonce     sync.Once\n)\n\nfunc GetRegistrationSystem() *CourseRegistrationSystem {\n\tonce.Do(func() {\n\t\tinstance = &CourseRegistrationSystem{\n\t\t\tcourses:       make(map[string]*Course),\n\t\t\tstudents:      make(map[int]*Student),\n\t\t\tregistrations: make([]*Registration, 0),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (rs *CourseRegistrationSystem) AddCourse(course *Course) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\trs.courses[course.Code] = course\n}\n\nfunc (rs *CourseRegistrationSystem) AddStudent(student *Student) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\trs.students[student.ID] = student\n}\n\nfunc (rs *CourseRegistrationSystem) SearchCourses(query string) []*Course {\n\trs.mu.RLock()\n\tdefer rs.mu.RUnlock()\n\n\tvar result []*Course\n\tquery = strings.ToLower(query)\n\n\tfor _, course := range rs.courses {\n\t\tif strings.Contains(strings.ToLower(course.Code), query) ||\n\t\t\tstrings.Contains(strings.ToLower(course.Name), query) {\n\t\t\tresult = append(result, course)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc (rs *CourseRegistrationSystem) RegisterCourse(student *Student, course *Course) error {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\n\t// Check if course exists\n\tif _, exists := rs.courses[course.Code]; !exists {\n\t\treturn fmt.Errorf(\"course %s does not exist\", course.Code)\n\t}\n\n\t// Check if student exists\n\tif _, exists := rs.students[student.ID]; !exists {\n\t\treturn fmt.Errorf(\"student with ID %d does not exist\", student.ID)\n\t}\n\n\t// Check capacity\n\tif course.GetEnrolledStudents() >= course.MaxCapacity {\n\t\treturn fmt.Errorf(\"course %s is full\", course.Code)\n\t}\n\n\t// Check if student is already registered\n\tfor _, c := range student.RegisteredCourses {\n\t\tif c.Code == course.Code {\n\t\t\treturn fmt.Errorf(\"student is already registered for course %s\", course.Code)\n\t\t}\n\t}\n\n\t// Create registration\n\tregistration := NewRegistration(student, course)\n\trs.registrations = append(rs.registrations, registration)\n\n\t// Update course and student\n\tcourse.IncrementEnrolled()\n\tstudent.AddCourse(course)\n\n\trs.notifyObservers(course)\n\treturn nil\n}\n\nfunc (rs *CourseRegistrationSystem) GetRegisteredCourses(student *Student) []*Course {\n\trs.mu.RLock()\n\tdefer rs.mu.RUnlock()\n\n\tif _, exists := rs.students[student.ID]; !exists {\n\t\treturn nil\n\t}\n\n\treturn student.RegisteredCourses\n}\n\nfunc (rs *CourseRegistrationSystem) notifyObservers(course *Course) {\n\t// TODO: Implement observer pattern for notifications\n\tfmt.Printf(\"Course %s updated: %d/%d students enrolled\\n\",\n\t\tcourse.Code, course.GetEnrolledStudents(), course.MaxCapacity)\n}\n"
  },
  {
    "path": "solutions/golang/courseregistrationsystem/course_registration_system_demo.go",
    "content": "package courseregistrationsystem\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tregistrationSystem := GetRegistrationSystem()\n\n\t// Create courses\n\tcourse1 := NewCourse(\"CS101\", \"Introduction to Programming\", \"John Doe\", 50)\n\tcourse2 := NewCourse(\"CS201\", \"Data Structures and Algorithms\", \"Jane Smith\", 30)\n\n\tregistrationSystem.AddCourse(course1)\n\tregistrationSystem.AddCourse(course2)\n\n\t// Create students\n\tstudent1 := NewStudent(1, \"Alice\", \"alice@example.com\")\n\tstudent2 := NewStudent(2, \"Bob\", \"bob@example.com\")\n\n\tregistrationSystem.AddStudent(student1)\n\tregistrationSystem.AddStudent(student2)\n\n\t// Search for courses\n\tsearchResults := registrationSystem.SearchCourses(\"CS\")\n\tfmt.Println(\"Search Results:\")\n\tfor _, course := range searchResults {\n\t\tfmt.Printf(\"%s - %s\\n\", course.Code, course.Name)\n\t}\n\n\t// Register courses for students\n\tfmt.Println(\"\\nRegistration Results:\")\n\n\terr := registrationSystem.RegisterCourse(student1, course1)\n\tfmt.Printf(\"Student 1 - Course 1: %v\\n\", err == nil)\n\n\terr = registrationSystem.RegisterCourse(student2, course1)\n\tfmt.Printf(\"Student 2 - Course 1: %v\\n\", err == nil)\n\n\terr = registrationSystem.RegisterCourse(student1, course2)\n\tfmt.Printf(\"Student 1 - Course 2: %v\\n\", err == nil)\n\n\t// Get registered courses for a student\n\tregisteredCourses := registrationSystem.GetRegisteredCourses(student1)\n\tfmt.Println(\"\\nRegistered Courses for Student 1:\")\n\tfor _, course := range registeredCourses {\n\t\tfmt.Printf(\"%s - %s\\n\", course.Code, course.Name)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/courseregistrationsystem/registration.go",
    "content": "package courseregistrationsystem\n\nimport \"time\"\n\ntype Registration struct {\n\tStudent          *Student\n\tCourse           *Course\n\tRegistrationTime time.Time\n}\n\nfunc NewRegistration(student *Student, course *Course) *Registration {\n\treturn &Registration{\n\t\tStudent:          student,\n\t\tCourse:           course,\n\t\tRegistrationTime: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/courseregistrationsystem/student.go",
    "content": "package courseregistrationsystem\n\nimport \"sync\"\n\ntype Student struct {\n\tID                int\n\tName              string\n\tEmail             string\n\tRegisteredCourses []*Course\n\tmu                sync.Mutex\n}\n\nfunc NewStudent(id int, name, email string) *Student {\n\treturn &Student{\n\t\tID:                id,\n\t\tName:              name,\n\t\tEmail:             email,\n\t\tRegisteredCourses: make([]*Course, 0),\n\t}\n}\n\nfunc (s *Student) AddCourse(course *Course) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.RegisteredCourses = append(s.RegisteredCourses, course)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/README.md",
    "content": "# Designing a Cricket Information System like CricInfo\n\n## Requirements\n1. The Cricinfo system should provide information about cricket matches, teams, players, and live scores.\n2. Users should be able to view the schedule of upcoming matches and the results of completed matches.\n3. The system should allow users to search for specific matches, teams, or players.\n4. Users should be able to view detailed information about a particular match, including the scorecard, commentary, and statistics.\n5. The system should support real-time updates of live scores and match information.\n6. The system should handle concurrent access to match data and ensure data consistency.\n7. The system should be scalable and able to handle a large volume of user requests.\n8. The system should be extensible to accommodate new features and enhancements in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **Match** class represents a cricket match, with properties such as ID, title, venue, start time, teams, status, and scorecard.\n2. The **Team** class represents a cricket team, with properties like ID, name, and a list of players.\n3. The **Player** class represents a cricket player, with properties such as ID, name, and role.\n4. The **Scorecard** class represents the scorecard of a match, containing team scores and a list of innings.\n5. The **Innings** class represents an innings in a match, with properties like ID, batting team, bowling team, and a list of overs.\n6. The **Over** class represents an over in an innings, containing a list of balls.\n7. The **Ball** class represents a ball bowled in an over, with properties such as ball number, bowler, batsman, and result.\n8. The **MatchStatus** enum represents the different statuses of a match, such as scheduled, in progress, completed, or abandoned.\n9. The **MatchService** class manages the matches in the system, providing methods to add, retrieve, and update match information. It follows the Singleton pattern to ensure a single instance of the service.\n10. The **ScorecardService** class manages the scorecards of matches, allowing the creation, retrieval, and update of scorecards and their associated data, such as innings and scores. It also follows the Singleton pattern.\n11. The **CricinfoSystem** class serves as the main entry point of the system, integrating the match and scorecard services and providing high-level methods for interacting with the system."
  },
  {
    "path": "solutions/golang/cricinfo/ball.go",
    "content": "package cricinfo\n\ntype Ball struct {\n\tBallNumber int\n\tBowler     string\n\tBatsman    string\n\tResult     string\n}\n\nfunc NewBall(ballNumber int, bowler, batsman, result string) *Ball {\n\treturn &Ball{\n\t\tBallNumber: ballNumber,\n\t\tBowler:     bowler,\n\t\tBatsman:    batsman,\n\t\tResult:     result,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/cricinfo.go",
    "content": "package cricinfo\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\t// Create teams\n\tteam1Players := []*Player{\n\t\tNewPlayer(\"P101\", \"Player 1\", \"Batsman\"),\n\t\tNewPlayer(\"P102\", \"Player 2\", \"Bowler\"),\n\t\tNewPlayer(\"P103\", \"Player 3\", \"All-rounder\"),\n\t}\n\tteam2Players := []*Player{\n\t\tNewPlayer(\"P201\", \"Player 4\", \"Batsman\"),\n\t\tNewPlayer(\"P202\", \"Player 5\", \"Bowler\"),\n\t\tNewPlayer(\"P203\", \"Player 6\", \"All-rounder\"),\n\t}\n\n\tteam1 := NewTeam(\"T1\", \"Team 1\", team1Players)\n\tteam2 := NewTeam(\"T2\", \"Team 2\", team2Players)\n\tteams := []*Team{team1, team2}\n\n\t// Create match\n\tmatch := NewMatch(\"M001\", \"Match 1\", \"Venue 1\", time.Now(), teams)\n\n\t// Create Cricinfo system\n\tcricinfoSystem := NewCricinfoSystem()\n\n\t// Add match\n\tcricinfoSystem.AddMatch(match)\n\n\t// Create scorecard\n\tscorecardID := cricinfoSystem.CreateScorecard(match)\n\n\t// Update scores\n\tcricinfoSystem.UpdateScore(scorecardID, \"T1\", 100)\n\tcricinfoSystem.UpdateScore(scorecardID, \"T2\", 75)\n\n\t// Create innings\n\tinnings1 := NewInnings(\"I1\", \"T1\", \"T2\")\n\tinnings2 := NewInnings(\"I2\", \"T2\", \"T1\")\n\n\t// Add overs\n\tover1 := NewOver(1)\n\tover1.AddBall(NewBall(1, \"P202\", \"P101\", \"4\"))\n\tover1.AddBall(NewBall(2, \"P202\", \"P101\", \"6\"))\n\tinnings1.AddOver(over1)\n\n\tover2 := NewOver(2)\n\tover2.AddBall(NewBall(1, \"P102\", \"P201\", \"1\"))\n\tover2.AddBall(NewBall(2, \"P102\", \"P201\", \"0\"))\n\tinnings1.AddOver(over2)\n\n\t// Add innings\n\tcricinfoSystem.AddInnings(scorecardID, innings1)\n\tcricinfoSystem.AddInnings(scorecardID, innings2)\n\n\t// Display scorecard\n\tscorecard := cricinfoSystem.GetScorecard(scorecardID)\n\tdisplayScorecard(scorecard)\n}\n\nfunc displayScorecard(scorecard *Scorecard) {\n\tfmt.Printf(\"Scorecard ID: %s\\n\", scorecard.ID)\n\tfmt.Printf(\"Match: %s\\n\", scorecard.Match.Title)\n\n\tfmt.Println(\"Team Scores:\")\n\tfor teamID, score := range scorecard.TeamScores {\n\t\tfmt.Printf(\"%s: %d\\n\", teamID, score)\n\t}\n\n\tfmt.Println(\"\\nInnings:\")\n\tfor _, innings := range scorecard.Innings {\n\t\tfmt.Printf(\"Innings ID: %s\\n\", innings.ID)\n\t\tfmt.Printf(\"Batting Team: %s\\n\", innings.BattingTeamID)\n\t\tfmt.Printf(\"Bowling Team: %s\\n\", innings.BowlingTeamID)\n\t\tfmt.Println(\"Overs:\")\n\t\tfor _, over := range innings.Overs {\n\t\t\tfmt.Printf(\"Over %d\\n\", over.OverNumber)\n\t\t\tfor _, ball := range over.Balls {\n\t\t\t\tfmt.Printf(\"Ball %d: %s to %s - %s\\n\",\n\t\t\t\t\tball.BallNumber, ball.Bowler, ball.Batsman, ball.Result)\n\t\t\t}\n\t\t}\n\t\tfmt.Println()\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/cricinfo_system.go",
    "content": "package cricinfo\n\ntype CricinfoSystem struct {\n\tmatchService     *MatchService\n\tscorecardService *ScorecardService\n}\n\nfunc NewCricinfoSystem() *CricinfoSystem {\n\treturn &CricinfoSystem{\n\t\tmatchService:     GetMatchService(),\n\t\tscorecardService: GetScorecardService(),\n\t}\n}\n\nfunc (cs *CricinfoSystem) AddMatch(match *Match) {\n\tcs.matchService.AddMatch(match)\n}\n\nfunc (cs *CricinfoSystem) GetMatch(matchID string) *Match {\n\treturn cs.matchService.GetMatch(matchID)\n}\n\nfunc (cs *CricinfoSystem) GetAllMatches() []*Match {\n\treturn cs.matchService.GetAllMatches()\n}\n\nfunc (cs *CricinfoSystem) UpdateMatchStatus(matchID string, status MatchStatus) {\n\tcs.matchService.UpdateMatchStatus(matchID, status)\n}\n\nfunc (cs *CricinfoSystem) CreateScorecard(match *Match) string {\n\treturn cs.scorecardService.CreateScorecard(match)\n}\n\nfunc (cs *CricinfoSystem) GetScorecard(scorecardID string) *Scorecard {\n\treturn cs.scorecardService.GetScorecard(scorecardID)\n}\n\nfunc (cs *CricinfoSystem) UpdateScore(scorecardID string, teamID string, score int) {\n\tcs.scorecardService.UpdateScore(scorecardID, teamID, score)\n}\n\nfunc (cs *CricinfoSystem) AddInnings(scorecardID string, innings *Innings) {\n\tcs.scorecardService.AddInnings(scorecardID, innings)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/innings.go",
    "content": "package cricinfo\n\ntype Innings struct {\n\tID            string\n\tBattingTeamID string\n\tBowlingTeamID string\n\tOvers         []*Over\n}\n\nfunc NewInnings(id, battingTeamID, bowlingTeamID string) *Innings {\n\treturn &Innings{\n\t\tID:            id,\n\t\tBattingTeamID: battingTeamID,\n\t\tBowlingTeamID: bowlingTeamID,\n\t\tOvers:         make([]*Over, 0),\n\t}\n}\n\nfunc (i *Innings) AddOver(over *Over) {\n\ti.Overs = append(i.Overs, over)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/match.go",
    "content": "package cricinfo\n\nimport \"time\"\n\ntype Match struct {\n\tID        string\n\tTitle     string\n\tVenue     string\n\tStartTime time.Time\n\tTeams     []*Team\n\tStatus    MatchStatus\n\tScorecard *Scorecard\n}\n\nfunc NewMatch(id, title, venue string, startTime time.Time, teams []*Team) *Match {\n\treturn &Match{\n\t\tID:        id,\n\t\tTitle:     title,\n\t\tVenue:     venue,\n\t\tStartTime: startTime,\n\t\tTeams:     teams,\n\t\tStatus:    MatchStatusScheduled,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/match_service.go",
    "content": "package cricinfo\n\nimport (\n\t\"sync\"\n)\n\ntype MatchService struct {\n\tmatches map[string]*Match\n\tmu      sync.RWMutex\n}\n\nvar (\n\tmatchServiceInstance *MatchService\n\tmatchServiceOnce     sync.Once\n)\n\nfunc GetMatchService() *MatchService {\n\tmatchServiceOnce.Do(func() {\n\t\tmatchServiceInstance = &MatchService{\n\t\t\tmatches: make(map[string]*Match),\n\t\t}\n\t})\n\treturn matchServiceInstance\n}\n\nfunc (ms *MatchService) AddMatch(match *Match) {\n\tms.mu.Lock()\n\tdefer ms.mu.Unlock()\n\tms.matches[match.ID] = match\n}\n\nfunc (ms *MatchService) GetMatch(matchID string) *Match {\n\tms.mu.RLock()\n\tdefer ms.mu.RUnlock()\n\treturn ms.matches[matchID]\n}\n\nfunc (ms *MatchService) GetAllMatches() []*Match {\n\tms.mu.RLock()\n\tdefer ms.mu.RUnlock()\n\n\tmatches := make([]*Match, 0, len(ms.matches))\n\tfor _, match := range ms.matches {\n\t\tmatches = append(matches, match)\n\t}\n\treturn matches\n}\n\nfunc (ms *MatchService) UpdateMatchStatus(matchID string, status MatchStatus) {\n\tms.mu.Lock()\n\tdefer ms.mu.Unlock()\n\tif match, exists := ms.matches[matchID]; exists {\n\t\tmatch.Status = status\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/over.go",
    "content": "package cricinfo\n\ntype Over struct {\n\tOverNumber int\n\tBalls      []*Ball\n}\n\nfunc NewOver(overNumber int) *Over {\n\treturn &Over{\n\t\tOverNumber: overNumber,\n\t\tBalls:      make([]*Ball, 0),\n\t}\n}\n\nfunc (o *Over) AddBall(ball *Ball) {\n\to.Balls = append(o.Balls, ball)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/player.go",
    "content": "package cricinfo\n\ntype Player struct {\n\tID   string\n\tName string\n\tRole string\n}\n\nfunc NewPlayer(id, name, role string) *Player {\n\treturn &Player{\n\t\tID:   id,\n\t\tName: name,\n\t\tRole: role,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/scorecard.go",
    "content": "package cricinfo\n\nimport \"sync\"\n\ntype Scorecard struct {\n\tID         string\n\tMatch      *Match\n\tTeamScores map[string]int\n\tInnings    []*Innings\n\tmu         sync.RWMutex\n}\n\nfunc NewScorecard(id string, match *Match) *Scorecard {\n\treturn &Scorecard{\n\t\tID:         id,\n\t\tMatch:      match,\n\t\tTeamScores: make(map[string]int),\n\t\tInnings:    make([]*Innings, 0),\n\t}\n}\n\nfunc (s *Scorecard) UpdateScore(teamID string, score int) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.TeamScores[teamID] = score\n}\n\nfunc (s *Scorecard) AddInnings(innings *Innings) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.Innings = append(s.Innings, innings)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/scorecard_service.go",
    "content": "package cricinfo\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype ScorecardService struct {\n\tscorecards       map[string]*Scorecard\n\tscorecardCounter int64\n\tmu               sync.RWMutex\n}\n\nvar (\n\tscorecardServiceInstance *ScorecardService\n\tscorecardServiceOnce     sync.Once\n)\n\nfunc GetScorecardService() *ScorecardService {\n\tscorecardServiceOnce.Do(func() {\n\t\tscorecardServiceInstance = &ScorecardService{\n\t\t\tscorecards: make(map[string]*Scorecard),\n\t\t}\n\t})\n\treturn scorecardServiceInstance\n}\n\nfunc (ss *ScorecardService) CreateScorecard(match *Match) string {\n\tss.mu.Lock()\n\tdefer ss.mu.Unlock()\n\n\tscorecardID := ss.generateScorecardID(match.ID)\n\tscorecard := NewScorecard(scorecardID, match)\n\tss.scorecards[scorecardID] = scorecard\n\treturn scorecardID\n}\n\nfunc (ss *ScorecardService) GetScorecard(scorecardID string) *Scorecard {\n\tss.mu.RLock()\n\tdefer ss.mu.RUnlock()\n\treturn ss.scorecards[scorecardID]\n}\n\nfunc (ss *ScorecardService) UpdateScore(scorecardID string, teamID string, score int) {\n\tss.mu.RLock()\n\tscorecard := ss.scorecards[scorecardID]\n\tss.mu.RUnlock()\n\n\tif scorecard != nil {\n\t\tscorecard.UpdateScore(teamID, score)\n\t}\n}\n\nfunc (ss *ScorecardService) AddInnings(scorecardID string, innings *Innings) {\n\tss.mu.RLock()\n\tscorecard := ss.scorecards[scorecardID]\n\tss.mu.RUnlock()\n\n\tif scorecard != nil {\n\t\tscorecard.AddInnings(innings)\n\t}\n}\n\nfunc (ss *ScorecardService) generateScorecardID(matchID string) string {\n\tcounter := atomic.AddInt64(&ss.scorecardCounter, 1)\n\treturn fmt.Sprintf(\"SC-%s-%04d\", matchID, counter)\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/team.go",
    "content": "package cricinfo\n\ntype Team struct {\n\tID      string\n\tName    string\n\tPlayers []*Player\n}\n\nfunc NewTeam(id, name string, players []*Player) *Team {\n\treturn &Team{\n\t\tID:      id,\n\t\tName:    name,\n\t\tPlayers: players,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/cricinfo/types.go",
    "content": "package cricinfo\n\ntype MatchStatus int\n\nconst (\n\tMatchStatusScheduled MatchStatus = iota\n\tMatchStatusInProgress\n\tMatchStatusCompleted\n\tMatchStatusAbandoned\n)\n\nfunc (s MatchStatus) String() string {\n\treturn [...]string{\"SCHEDULED\", \"IN_PROGRESS\", \"COMPLETED\", \"ABANDONED\"}[s]\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/README.md",
    "content": "# Designing a Digital Wallet System\n\n## Requirements\n1. The digital wallet should allow users to create an account and manage their personal information.\n2. Users should be able to add and remove payment methods, such as credit cards or bank accounts.\n3. The digital wallet should support fund transfers between users and to external accounts.\n4. The system should handle transaction history and provide a statement of transactions.\n5. The digital wallet should support multiple currencies and perform currency conversions.\n6. The system should ensure the security of user information and transactions.\n7. The digital wallet should handle concurrent transactions and ensure data consistency.\n8. The system should be scalable to handle a large number of users and transactions.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the digital wallet, with properties such as ID, name, email, password, and a list of accounts.\n2. The **Account** class represents a user's account within the digital wallet, with properties like ID, user, account number, currency, balance, and a list of transactions. It provides methods to deposit and withdraw funds.\n3. The **Transaction** class represents a financial transaction between two accounts, containing properties such as ID, source account, destination account, amount, currency, and timestamp.\n4. The **PaymentMethod** class is an abstract base class for different payment methods, such as credit cards and bank accounts. It defines the common properties and methods for processing payments.\n5. The **CreditCard** and **BankAccount** classes are concrete implementations of the PaymentMethod class, representing specific payment methods.\n6. The **Currency** enum represents different currencies supported by the digital wallet.\n7. The **CurrencyConverter** class provides a static method to convert amounts between different currencies based on predefined exchange rates.\n8. The **DigitalWallet** class is the central component of the digital wallet system. It follows the Singleton pattern to ensure only one instance of the digital wallet exists. It provides methods to create users, accounts, add payment methods, transfer funds, and retrieve transaction history. It handles concurrent access to shared resources using synchronization.\n9. The **DigitalWalletDemo** class demonstrates the usage of the digital wallet system by creating users, accounts, adding payment methods, depositing funds, transferring funds, and retrieving transaction history."
  },
  {
    "path": "solutions/golang/digitalwalletservice/account.go",
    "content": "package digitalwallet\n\nimport (\n\t\"math/big\"\n\t\"sync\"\n)\n\ntype Account struct {\n\tID            string\n\tUser          *User\n\tAccountNumber string\n\tCurrency      Currency\n\tbalance       *big.Float\n\ttransactions  []*Transaction\n\tmu            sync.RWMutex\n}\n\nfunc NewAccount(id string, user *User, accountNumber string, currency Currency) *Account {\n\treturn &Account{\n\t\tID:            id,\n\t\tUser:          user,\n\t\tAccountNumber: accountNumber,\n\t\tCurrency:      currency,\n\t\tbalance:       big.NewFloat(0),\n\t\ttransactions:  make([]*Transaction, 0),\n\t}\n}\n\nfunc (a *Account) Deposit(amount *big.Float) {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\ta.balance.Add(a.balance, amount)\n}\n\nfunc (a *Account) Withdraw(amount *big.Float) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.balance.Cmp(amount) >= 0 {\n\t\ta.balance.Sub(a.balance, amount)\n\t\treturn nil\n\t}\n\treturn NewInsufficientFundsError(\"Insufficient funds in the account\")\n}\n\nfunc (a *Account) AddTransaction(transaction *Transaction) {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\ta.transactions = append(a.transactions, transaction)\n}\n\nfunc (a *Account) GetBalance() *big.Float {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\treturn new(big.Float).Copy(a.balance)\n}\n\nfunc (a *Account) GetTransactions() []*Transaction {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\treturn append([]*Transaction{}, a.transactions...)\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/bank_account.go",
    "content": "package digitalwallet\n\nimport \"math/big\"\n\ntype BankAccount struct {\n\tBasePaymentMethod\n\tAccountNumber string\n\tRoutingNumber string\n}\n\nfunc NewBankAccount(id string, user *User, accountNumber, routingNumber string) *BankAccount {\n\treturn &BankAccount{\n\t\tBasePaymentMethod: BasePaymentMethod{ID: id, User: user},\n\t\tAccountNumber:     accountNumber,\n\t\tRoutingNumber:     routingNumber,\n\t}\n}\n\nfunc (b *BankAccount) ProcessPayment(amount *big.Float, currency Currency) bool {\n\t// Process bank account payment\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/credit_card.go",
    "content": "package digitalwallet\n\nimport \"math/big\"\n\ntype CreditCard struct {\n\tBasePaymentMethod\n\tCardNumber     string\n\tExpirationDate string\n\tCVV            string\n}\n\nfunc NewCreditCard(id string, user *User, cardNumber, expirationDate, cvv string) *CreditCard {\n\treturn &CreditCard{\n\t\tBasePaymentMethod: BasePaymentMethod{ID: id, User: user},\n\t\tCardNumber:        cardNumber,\n\t\tExpirationDate:    expirationDate,\n\t\tCVV:               cvv,\n\t}\n}\n\nfunc (c *CreditCard) ProcessPayment(amount *big.Float, currency Currency) bool {\n\t// Process credit card payment\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/currency_converter.go",
    "content": "package digitalwallet\n\nimport (\n\t\"math/big\"\n\t\"sync\"\n)\n\ntype CurrencyConverter struct {\n\texchangeRates map[Currency]*big.Float\n\tmu            sync.RWMutex\n}\n\nvar (\n\tcurrencyConverter *CurrencyConverter\n\tconverterOnce     sync.Once\n)\n\nfunc GetCurrencyConverter() *CurrencyConverter {\n\tconverterOnce.Do(func() {\n\t\tcurrencyConverter = &CurrencyConverter{\n\t\t\texchangeRates: make(map[Currency]*big.Float),\n\t\t}\n\t\tcurrencyConverter.initializeRates()\n\t})\n\treturn currencyConverter\n}\n\nfunc (cc *CurrencyConverter) initializeRates() {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\tone := big.NewFloat(1)\n\tcc.exchangeRates[USD] = one\n\tcc.exchangeRates[EUR] = big.NewFloat(0.85)\n\tcc.exchangeRates[GBP] = big.NewFloat(0.72)\n\tcc.exchangeRates[JPY] = big.NewFloat(110.00)\n}\n\nfunc (cc *CurrencyConverter) Convert(amount *big.Float, sourceCurrency, targetCurrency Currency) *big.Float {\n\tcc.mu.RLock()\n\tdefer cc.mu.RUnlock()\n\n\tsourceRate := cc.exchangeRates[sourceCurrency]\n\ttargetRate := cc.exchangeRates[targetCurrency]\n\n\tresult := new(big.Float).Mul(amount, sourceRate)\n\treturn new(big.Float).Quo(result, targetRate)\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/digital_wallet.go",
    "content": "package digitalwallet\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype DigitalWallet struct {\n\tusers          map[string]*User\n\taccounts       map[string]*Account\n\tpaymentMethods map[string]PaymentMethod\n\tmu             sync.RWMutex\n}\n\nvar (\n\tinstance *DigitalWallet\n\tonce     sync.Once\n)\n\nfunc GetDigitalWallet() *DigitalWallet {\n\tonce.Do(func() {\n\t\tinstance = &DigitalWallet{\n\t\t\tusers:          make(map[string]*User),\n\t\t\taccounts:       make(map[string]*Account),\n\t\t\tpaymentMethods: make(map[string]PaymentMethod),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (dw *DigitalWallet) CreateUser(user *User) {\n\tdw.mu.Lock()\n\tdefer dw.mu.Unlock()\n\tdw.users[user.ID] = user\n}\n\nfunc (dw *DigitalWallet) CreateAccount(account *Account) {\n\tdw.mu.Lock()\n\tdefer dw.mu.Unlock()\n\tdw.accounts[account.ID] = account\n\taccount.User.AddAccount(account)\n}\n\nfunc (dw *DigitalWallet) AddPaymentMethod(method PaymentMethod) {\n\tdw.mu.Lock()\n\tdefer dw.mu.Unlock()\n\tdw.paymentMethods[method.GetID()] = method\n}\n\nfunc (dw *DigitalWallet) TransferFunds(sourceAccount, destinationAccount *Account, amount *big.Float, currency Currency) error {\n\tdw.mu.Lock()\n\tdefer dw.mu.Unlock()\n\n\tconverter := GetCurrencyConverter()\n\n\t// Convert amount to source account currency\n\tsourceAmount := amount\n\tif sourceAccount.Currency != currency {\n\t\tsourceAmount = converter.Convert(amount, currency, sourceAccount.Currency)\n\t}\n\n\t// Withdraw from source account\n\tif err := sourceAccount.Withdraw(sourceAmount); err != nil {\n\t\treturn err\n\t}\n\n\t// Convert amount to destination account currency\n\tdestAmount := amount\n\tif destinationAccount.Currency != currency {\n\t\tdestAmount = converter.Convert(amount, currency, destinationAccount.Currency)\n\t}\n\n\t// Deposit to destination account\n\tdestinationAccount.Deposit(destAmount)\n\n\t// Create and record transaction\n\ttransactionID := fmt.Sprintf(\"TXN%d\", time.Now().UnixNano())\n\ttransaction := NewTransaction(transactionID, sourceAccount, destinationAccount, amount, currency)\n\tsourceAccount.AddTransaction(transaction)\n\tdestinationAccount.AddTransaction(transaction)\n\n\treturn nil\n}\n\nfunc (dw *DigitalWallet) GetTransactionHistory(account *Account) []*Transaction {\n\treturn account.GetTransactions()\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/digital_wallet_demo.go",
    "content": "package digitalwallet\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n)\n\nfunc Run() {\n\tdigitalWallet := GetDigitalWallet()\n\n\t// Create users\n\tuser1 := NewUser(\"U001\", \"John Doe\", \"john@example.com\", \"password123\")\n\tuser2 := NewUser(\"U002\", \"Jane Smith\", \"jane@example.com\", \"password456\")\n\tdigitalWallet.CreateUser(user1)\n\tdigitalWallet.CreateUser(user2)\n\n\t// Create accounts\n\taccount1 := NewAccount(\"A001\", user1, \"1234567890\", USD)\n\taccount2 := NewAccount(\"A002\", user2, \"9876543210\", EUR)\n\tdigitalWallet.CreateAccount(account1)\n\tdigitalWallet.CreateAccount(account2)\n\n\t// Add payment methods\n\tcreditCard := NewCreditCard(\"PM001\", user1, \"1234567890123456\", \"12/25\", \"123\")\n\tbankAccount := NewBankAccount(\"PM002\", user2, \"9876543210\", \"987654321\")\n\tdigitalWallet.AddPaymentMethod(creditCard)\n\tdigitalWallet.AddPaymentMethod(bankAccount)\n\n\t// Deposit funds\n\taccount1.Deposit(big.NewFloat(1000.00))\n\taccount2.Deposit(big.NewFloat(500.00))\n\n\t// Transfer funds\n\tamount := big.NewFloat(100.00)\n\tif err := digitalWallet.TransferFunds(account1, account2, amount, USD); err != nil {\n\t\tfmt.Printf(\"Transfer failed: %v\\n\", err)\n\t}\n\n\t// Print transaction history\n\tfmt.Println(\"Transaction History for Account 1:\")\n\tfor _, transaction := range digitalWallet.GetTransactionHistory(account1) {\n\t\tfmt.Printf(\"Transaction ID: %s\\n\", transaction.ID)\n\t\tfmt.Printf(\"Amount: %v %s\\n\", transaction.Amount, transaction.Currency)\n\t\tfmt.Printf(\"Timestamp: %v\\n\\n\", transaction.Timestamp)\n\t}\n\n\tfmt.Println(\"Transaction History for Account 2:\")\n\tfor _, transaction := range digitalWallet.GetTransactionHistory(account2) {\n\t\tfmt.Printf(\"Transaction ID: %s\\n\", transaction.ID)\n\t\tfmt.Printf(\"Amount: %v %s\\n\", transaction.Amount, transaction.Currency)\n\t\tfmt.Printf(\"Timestamp: %v\\n\\n\", transaction.Timestamp)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/errors.go",
    "content": "package digitalwallet\n\ntype InsufficientFundsError struct {\n\tmessage string\n}\n\nfunc NewInsufficientFundsError(message string) *InsufficientFundsError {\n\treturn &InsufficientFundsError{message: message}\n}\n\nfunc (e *InsufficientFundsError) Error() string {\n\treturn e.message\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/payment_method.go",
    "content": "package digitalwallet\n\nimport \"math/big\"\n\ntype PaymentMethod interface {\n\tProcessPayment(amount *big.Float, currency Currency) bool\n\tGetID() string\n\tGetUser() *User\n}\n\ntype BasePaymentMethod struct {\n\tID   string\n\tUser *User\n}\n\nfunc (b *BasePaymentMethod) GetID() string {\n\treturn b.ID\n}\n\nfunc (b *BasePaymentMethod) GetUser() *User {\n\treturn b.User\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/transaction.go",
    "content": "package digitalwallet\n\nimport (\n\t\"math/big\"\n\t\"time\"\n)\n\ntype Transaction struct {\n\tID                 string\n\tSourceAccount      *Account\n\tDestinationAccount *Account\n\tAmount             *big.Float\n\tCurrency           Currency\n\tTimestamp          time.Time\n}\n\nfunc NewTransaction(id string, sourceAccount, destinationAccount *Account, amount *big.Float, currency Currency) *Transaction {\n\treturn &Transaction{\n\t\tID:                 id,\n\t\tSourceAccount:      sourceAccount,\n\t\tDestinationAccount: destinationAccount,\n\t\tAmount:             amount,\n\t\tCurrency:           currency,\n\t\tTimestamp:          time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/types.go",
    "content": "package digitalwallet\n\ntype Currency string\n\nconst (\n\tUSD Currency = \"USD\"\n\tEUR Currency = \"EUR\"\n\tGBP Currency = \"GBP\"\n\tJPY Currency = \"JPY\"\n)\n"
  },
  {
    "path": "solutions/golang/digitalwalletservice/user.go",
    "content": "package digitalwallet\n\nimport \"sync\"\n\ntype User struct {\n\tID       string\n\tName     string\n\tEmail    string\n\tPassword string\n\taccounts []*Account\n\tmu       sync.RWMutex\n}\n\nfunc NewUser(id, name, email, password string) *User {\n\treturn &User{\n\t\tID:       id,\n\t\tName:     name,\n\t\tEmail:    email,\n\t\tPassword: password,\n\t\taccounts: make([]*Account, 0),\n\t}\n}\n\nfunc (u *User) AddAccount(account *Account) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.accounts = append(u.accounts, account)\n}\n\nfunc (u *User) RemoveAccount(account *Account) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tfor i, acc := range u.accounts {\n\t\tif acc == account {\n\t\t\tu.accounts = append(u.accounts[:i], u.accounts[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/elevatorsystem/README.md",
    "content": "# Designing an Elevator System\n\n## Requirements\n1. The elevator system should consist of multiple elevators serving multiple floors.\n2. Each elevator should have a capacity limit and should not exceed it.\n3. Users should be able to request an elevator from any floor and select a destination floor.\n4. The elevator system should efficiently handle user requests and optimize the movement of elevators to minimize waiting time.\n5. The system should prioritize requests based on the direction of travel and the proximity of the elevators to the requested floor.\n6. The elevators should be able to handle multiple requests concurrently and process them in an optimal order.\n7. The system should ensure thread safety and prevent race conditions when multiple threads interact with the elevators.\n\n## Classes, Interfaces and Enumerations\n1. The **Direction** enum represents the possible directions of elevator movement (UP or DOWN).\n2. The **Request** class represents a user request for an elevator, containing the source floor and destination floor.\n3. The **Elevator** class represents an individual elevator in the system. It has a capacity limit and maintains a list of 4. requests. The elevator processes requests concurrently and moves between floors based on the requests.\n4. The **ElevatorController** class manages multiple elevators and handles user requests. It finds the optimal elevator to serve a request based on the proximity of the elevators to the requested floor.\n5. The **ElevatorSystem** class is the entry point of the application and demonstrates the usage of the elevator system."
  },
  {
    "path": "solutions/golang/elevatorsystem/direction.go",
    "content": "package elevatorsystem\n\ntype Direction int\n\nconst (\n\tDirectionUp Direction = iota\n\tDirectionDown\n)\n\nfunc (d Direction) String() string {\n\treturn [...]string{\"UP\", \"DOWN\"}[d]\n}\n"
  },
  {
    "path": "solutions/golang/elevatorsystem/elevator.go",
    "content": "package elevatorsystem\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype Elevator struct {\n\tid               int\n\tcapacity         int\n\tcurrentFloor     int\n\tcurrentDirection Direction\n\trequests         chan *Request\n\tstopChan         chan struct{}\n\tmu               sync.RWMutex\n}\n\nfunc NewElevator(id, capacity int) *Elevator {\n\treturn &Elevator{\n\t\tid:               id,\n\t\tcapacity:         capacity,\n\t\tcurrentFloor:     1,\n\t\tcurrentDirection: DirectionUp,\n\t\trequests:         make(chan *Request, capacity),\n\t\tstopChan:         make(chan struct{}),\n\t}\n}\n\nfunc (e *Elevator) AddRequest(request *Request) bool {\n\tselect {\n\tcase e.requests <- request:\n\t\tfmt.Printf(\"Elevator %d added request: Floor %d to %d\\n\",\n\t\t\te.id, request.SourceFloor, request.DestinationFloor)\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (e *Elevator) getCurrentFloor() int {\n\te.mu.RLock()\n\tdefer e.mu.RUnlock()\n\treturn e.currentFloor\n}\n\nfunc (e *Elevator) setCurrentFloor(floor int) {\n\te.mu.Lock()\n\tdefer e.mu.Unlock()\n\te.currentFloor = floor\n}\n\nfunc (e *Elevator) Run() {\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase request := <-e.requests:\n\t\t\t\te.processRequest(request)\n\t\t\tcase <-e.stopChan:\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (e *Elevator) Stop() {\n\tclose(e.stopChan)\n}\n\nfunc (e *Elevator) processRequest(request *Request) {\n\tstartFloor := e.getCurrentFloor()\n\tendFloor := request.DestinationFloor\n\n\tif startFloor < endFloor {\n\t\te.currentDirection = DirectionUp\n\t\tfor i := startFloor; i <= endFloor; i++ {\n\t\t\te.setCurrentFloor(i)\n\t\t\tfmt.Printf(\"Elevator %d reached floor %d\\n\", e.id, i)\n\t\t\ttime.Sleep(time.Second) // Simulating elevator movement\n\t\t}\n\t} else if startFloor > endFloor {\n\t\te.currentDirection = DirectionDown\n\t\tfor i := startFloor; i >= endFloor; i-- {\n\t\t\te.setCurrentFloor(i)\n\t\t\tfmt.Printf(\"Elevator %d reached floor %d\\n\", e.id, i)\n\t\t\ttime.Sleep(time.Second) // Simulating elevator movement\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/elevatorsystem/elevator_controller.go",
    "content": "package elevatorsystem\n\nimport (\n\t\"math\"\n\t\"sync\"\n)\n\ntype ElevatorController struct {\n\televators []*Elevator\n\tmu        sync.RWMutex\n}\n\nfunc NewElevatorController(numElevators, capacity int) *ElevatorController {\n\tcontroller := &ElevatorController{\n\t\televators: make([]*Elevator, numElevators),\n\t}\n\n\tfor i := 0; i < numElevators; i++ {\n\t\televator := NewElevator(i+1, capacity)\n\t\tcontroller.elevators[i] = elevator\n\t\televator.Run()\n\t}\n\n\treturn controller\n}\n\nfunc (ec *ElevatorController) RequestElevator(sourceFloor, destinationFloor int) {\n\televator := ec.findOptimalElevator(sourceFloor, destinationFloor)\n\trequest := NewRequest(sourceFloor, destinationFloor)\n\televator.AddRequest(request)\n}\n\nfunc (ec *ElevatorController) findOptimalElevator(sourceFloor, destinationFloor int) *Elevator {\n\tec.mu.RLock()\n\tdefer ec.mu.RUnlock()\n\n\tvar optimalElevator *Elevator\n\tminDistance := math.MaxInt32\n\n\tfor _, elevator := range ec.elevators {\n\t\tdistance := int(math.Abs(float64(sourceFloor - elevator.getCurrentFloor())))\n\t\tif distance < minDistance {\n\t\t\tminDistance = distance\n\t\t\toptimalElevator = elevator\n\t\t}\n\t}\n\n\treturn optimalElevator\n}\n\nfunc (ec *ElevatorController) Stop() {\n\tec.mu.Lock()\n\tdefer ec.mu.Unlock()\n\n\tfor _, elevator := range ec.elevators {\n\t\televator.Stop()\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/elevatorsystem/elevator_controller_demo.go",
    "content": "package elevatorsystem\n\nimport (\n\t\"time\"\n)\n\nfunc Run() {\n\tcontroller := NewElevatorController(3, 5)\n\tdefer controller.Stop()\n\n\t// Simulate elevator requests\n\tcontroller.RequestElevator(5, 10)\n\tcontroller.RequestElevator(3, 7)\n\tcontroller.RequestElevator(8, 2)\n\tcontroller.RequestElevator(1, 9)\n\n\t// Wait for elevators to process requests\n\ttime.Sleep(30 * time.Second)\n}\n"
  },
  {
    "path": "solutions/golang/elevatorsystem/request.go",
    "content": "package elevatorsystem\n\ntype Request struct {\n\tSourceFloor      int\n\tDestinationFloor int\n}\n\nfunc NewRequest(sourceFloor, destinationFloor int) *Request {\n\treturn &Request{\n\t\tSourceFloor:      sourceFloor,\n\t\tDestinationFloor: destinationFloor,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/README.md",
    "content": "# Designing an Online Food Delivery Service Like Swiggy\n\n## Requirements\n1. The food delivery service should allow customers to browse restaurants, view menus, and place orders.\n2. Restaurants should be able to manage their menus, prices, and availability.\n3. Delivery agents should be able to accept and fulfill orders.\n4. The system should handle order tracking and status updates.\n5. The system should support multiple payment methods.\n6. The system should handle concurrent orders and ensure data consistency.\n7. The system should be scalable and handle a high volume of orders.\n8. The system should provide real-time notifications to customers, restaurants, and delivery agents.\n\n## Classes, Interfaces and Enumerations\n1. The **Customer** class represents a customer who can place orders. It contains customer details such as ID, name, email, and phone number.\n2. The **Restaurant** class represents a restaurant that offers menu items. It contains restaurant details such as ID, name, address, and a list of menu items. It provides methods to add and remove menu items.\n3. The **MenuItem** class represents an item on a restaurant's menu. It contains details such as ID, name, description, price, and availability status.\n4. The **Order** class represents an order placed by a customer. It contains order details such as ID, customer, restaurant, list of order items, status, and assigned delivery agent. It provides methods to add and remove order items, update order status, and assign a delivery agent.\n5. The **OrderItem** class represents an item within an order. It contains the selected menu item and the quantity ordered.\n6. The **OrderStatus** enum represents the different statuses an order can have, such as PENDING, CONFIRMED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.\n7. The **DeliveryAgent** class represents a delivery agent who fulfills orders. It contains details such as ID, name, phone number, and availability status.\n8. The **FoodDeliveryService** class is the main class that manages the food delivery service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register customers, restaurants, and delivery agents, retrieve available restaurants and menus, place orders, update order status, cancel orders, and assign delivery agents to orders. It also handles notifications to customers, restaurants, and delivery agents."
  },
  {
    "path": "solutions/golang/fooddeliveryservice/customer.go",
    "content": "package fooddeliveryservice\n\ntype Customer struct {\n\tID    string\n\tName  string\n\tEmail string\n\tPhone string\n}\n\nfunc NewCustomer(id, name, email, phone string) *Customer {\n\treturn &Customer{\n\t\tID:    id,\n\t\tName:  name,\n\t\tEmail: email,\n\t\tPhone: phone,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/delivery_agent.go",
    "content": "package fooddeliveryservice\n\nimport \"sync\"\n\ntype DeliveryAgent struct {\n\tID        string\n\tName      string\n\tPhone     string\n\tavailable bool\n\tmu        sync.RWMutex\n}\n\nfunc NewDeliveryAgent(id, name, phone string) *DeliveryAgent {\n\treturn &DeliveryAgent{\n\t\tID:        id,\n\t\tName:      name,\n\t\tPhone:     phone,\n\t\tavailable: true,\n\t}\n}\n\nfunc (d *DeliveryAgent) SetAvailable(available bool) {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\td.available = available\n}\n\nfunc (d *DeliveryAgent) IsAvailable() bool {\n\td.mu.RLock()\n\tdefer d.mu.RUnlock()\n\treturn d.available\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/food_delivery_service.go",
    "content": "package fooddeliveryservice\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype FoodDeliveryService struct {\n\tcustomers      map[string]*Customer\n\trestaurants    map[string]*Restaurant\n\torders         map[string]*Order\n\tdeliveryAgents map[string]*DeliveryAgent\n\tmu             sync.RWMutex\n}\n\nvar (\n\tinstance *FoodDeliveryService\n\tonce     sync.Once\n)\n\nfunc GetFoodDeliveryService() *FoodDeliveryService {\n\tonce.Do(func() {\n\t\tinstance = &FoodDeliveryService{\n\t\t\tcustomers:      make(map[string]*Customer),\n\t\t\trestaurants:    make(map[string]*Restaurant),\n\t\t\torders:         make(map[string]*Order),\n\t\t\tdeliveryAgents: make(map[string]*DeliveryAgent),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (s *FoodDeliveryService) RegisterCustomer(customer *Customer) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.customers[customer.ID] = customer\n}\n\nfunc (s *FoodDeliveryService) RegisterRestaurant(restaurant *Restaurant) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.restaurants[restaurant.ID] = restaurant\n}\n\nfunc (s *FoodDeliveryService) RegisterDeliveryAgent(agent *DeliveryAgent) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.deliveryAgents[agent.ID] = agent\n}\n\nfunc (s *FoodDeliveryService) GetAvailableRestaurants() []*Restaurant {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\trestaurants := make([]*Restaurant, 0, len(s.restaurants))\n\tfor _, restaurant := range s.restaurants {\n\t\trestaurants = append(restaurants, restaurant)\n\t}\n\treturn restaurants\n}\n\nfunc (s *FoodDeliveryService) GetRestaurantMenu(restaurantID string) []*MenuItem {\n\ts.mu.RLock()\n\trestaurant := s.restaurants[restaurantID]\n\ts.mu.RUnlock()\n\n\tif restaurant != nil {\n\t\treturn restaurant.GetMenu()\n\t}\n\treturn nil\n}\n\nfunc (s *FoodDeliveryService) PlaceOrder(customerID, restaurantID string, items []*OrderItem) (*Order, error) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tcustomer := s.customers[customerID]\n\trestaurant := s.restaurants[restaurantID]\n\n\tif customer == nil {\n\t\treturn nil, fmt.Errorf(\"customer not found\")\n\t}\n\tif restaurant == nil {\n\t\treturn nil, fmt.Errorf(\"restaurant not found\")\n\t}\n\n\torderID := fmt.Sprintf(\"ORD%d\", time.Now().UnixNano())\n\torder := NewOrder(orderID, customer, restaurant)\n\n\tfor _, item := range items {\n\t\torder.AddItem(item)\n\t}\n\n\ts.orders[order.ID] = order\n\ts.notifyRestaurant(order)\n\tfmt.Printf(\"Order placed: %s\\n\", order.ID)\n\treturn order, nil\n}\n\nfunc (s *FoodDeliveryService) UpdateOrderStatus(orderID string, status OrderStatus) error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\torder := s.orders[orderID]\n\tif order == nil {\n\t\treturn fmt.Errorf(\"order not found\")\n\t}\n\n\torder.SetStatus(status)\n\ts.notifyCustomer(order)\n\n\tif status == OrderStatusConfirmed {\n\t\ts.assignDeliveryAgent(order)\n\t}\n\treturn nil\n}\n\nfunc (s *FoodDeliveryService) CancelOrder(orderID string) error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\torder := s.orders[orderID]\n\tif order == nil {\n\t\treturn fmt.Errorf(\"order not found\")\n\t}\n\n\tif order.GetStatus() != OrderStatusPending {\n\t\treturn fmt.Errorf(\"cannot cancel order in current status\")\n\t}\n\n\torder.SetStatus(OrderStatusCancelled)\n\ts.notifyCustomer(order)\n\ts.notifyRestaurant(order)\n\tfmt.Printf(\"Order cancelled: %s\\n\", order.ID)\n\treturn nil\n}\n\nfunc (s *FoodDeliveryService) notifyCustomer(order *Order) {\n\t// TODO: Implement customer notification\n\tfmt.Printf(\"Notifying customer about order %s status: %s\\n\",\n\t\torder.ID, order.GetStatus())\n}\n\nfunc (s *FoodDeliveryService) notifyRestaurant(order *Order) {\n\t// TODO: Implement restaurant notification\n\tfmt.Printf(\"Notifying restaurant about order %s\\n\", order.ID)\n}\n\nfunc (s *FoodDeliveryService) notifyDeliveryAgent(order *Order) {\n\t// TODO: Implement delivery agent notification\n\tfmt.Printf(\"Notifying delivery agent about order %s\\n\", order.ID)\n}\n\nfunc (s *FoodDeliveryService) assignDeliveryAgent(order *Order) {\n\tfor _, agent := range s.deliveryAgents {\n\t\tif agent.IsAvailable() {\n\t\t\tagent.SetAvailable(false)\n\t\t\torder.AssignDeliveryAgent(agent)\n\t\t\ts.notifyDeliveryAgent(order)\n\t\t\tbreak\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/food_delivery_service_demo.go",
    "content": "package fooddeliveryservice\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tservice := GetFoodDeliveryService()\n\n\t// Register customers\n\tcustomer1 := NewCustomer(\"C001\", \"John Doe\", \"john@example.com\", \"1234567890\")\n\tcustomer2 := NewCustomer(\"C002\", \"Jane Smith\", \"jane@example.com\", \"9876543210\")\n\tservice.RegisterCustomer(customer1)\n\tservice.RegisterCustomer(customer2)\n\n\t// Create restaurant menus\n\trestaurant1Menu := []*MenuItem{\n\t\tNewMenuItem(\"M001\", \"Burger\", \"Delicious burger\", 9.99),\n\t\tNewMenuItem(\"M002\", \"Pizza\", \"Cheesy pizza\", 12.99),\n\t}\n\trestaurant2Menu := []*MenuItem{\n\t\tNewMenuItem(\"M003\", \"Sushi\", \"Fresh sushi\", 15.99),\n\t\tNewMenuItem(\"M004\", \"Ramen\", \"Delicious ramen\", 10.99),\n\t}\n\n\t// Register restaurants\n\trestaurant1 := NewRestaurant(\"R001\", \"Restaurant 1\", \"Address 1\", restaurant1Menu)\n\trestaurant2 := NewRestaurant(\"R002\", \"Restaurant 2\", \"Address 2\", restaurant2Menu)\n\tservice.RegisterRestaurant(restaurant1)\n\tservice.RegisterRestaurant(restaurant2)\n\n\t// Register delivery agents\n\tagent1 := NewDeliveryAgent(\"D001\", \"Agent 1\", \"9999999999\")\n\tagent2 := NewDeliveryAgent(\"D002\", \"Agent 2\", \"8888888888\")\n\tservice.RegisterDeliveryAgent(agent1)\n\tservice.RegisterDeliveryAgent(agent2)\n\n\t// Place orders\n\torderItems := []*OrderItem{\n\t\tNewOrderItem(restaurant1Menu[0], 2),\n\t\tNewOrderItem(restaurant1Menu[1], 1),\n\t}\n\n\torder1, err := service.PlaceOrder(customer1.ID, restaurant1.ID, orderItems)\n\tif err != nil {\n\t\tfmt.Printf(\"Error placing order: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Update order status\n\terr = service.UpdateOrderStatus(order1.ID, OrderStatusConfirmed)\n\tif err != nil {\n\t\tfmt.Printf(\"Error updating order status: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Order status updated: %s\\n\", order1.GetStatus())\n\n\t// Place and cancel another order\n\torder2Items := []*OrderItem{\n\t\tNewOrderItem(restaurant2Menu[0], 1),\n\t}\n\torder2, err := service.PlaceOrder(customer2.ID, restaurant2.ID, order2Items)\n\tif err != nil {\n\t\tfmt.Printf(\"Error placing order: %v\\n\", err)\n\t\treturn\n\t}\n\n\terr = service.CancelOrder(order2.ID)\n\tif err != nil {\n\t\tfmt.Printf(\"Error cancelling order: %v\\n\", err)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/menu_item.go",
    "content": "package fooddeliveryservice\n\nimport \"sync\"\n\ntype MenuItem struct {\n\tID          string\n\tName        string\n\tDescription string\n\tPrice       float64\n\tavailable   bool\n\tmu          sync.RWMutex\n}\n\nfunc NewMenuItem(id, name, description string, price float64) *MenuItem {\n\treturn &MenuItem{\n\t\tID:          id,\n\t\tName:        name,\n\t\tDescription: description,\n\t\tPrice:       price,\n\t\tavailable:   true,\n\t}\n}\n\nfunc (m *MenuItem) SetAvailable(available bool) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tm.available = available\n}\n\nfunc (m *MenuItem) IsAvailable() bool {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\treturn m.available\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/order.go",
    "content": "package fooddeliveryservice\n\nimport \"sync\"\n\ntype OrderItem struct {\n\tMenuItem *MenuItem\n\tQuantity int\n}\n\nfunc NewOrderItem(menuItem *MenuItem, quantity int) *OrderItem {\n\treturn &OrderItem{\n\t\tMenuItem: menuItem,\n\t\tQuantity: quantity,\n\t}\n}\n\ntype Order struct {\n\tID            string\n\tCustomer      *Customer\n\tRestaurant    *Restaurant\n\tItems         []*OrderItem\n\tStatus        OrderStatus\n\tDeliveryAgent *DeliveryAgent\n\tmu            sync.RWMutex\n}\n\nfunc NewOrder(id string, customer *Customer, restaurant *Restaurant) *Order {\n\treturn &Order{\n\t\tID:         id,\n\t\tCustomer:   customer,\n\t\tRestaurant: restaurant,\n\t\tItems:      make([]*OrderItem, 0),\n\t\tStatus:     OrderStatusPending,\n\t}\n}\n\nfunc (o *Order) AddItem(item *OrderItem) {\n\to.mu.Lock()\n\tdefer o.mu.Unlock()\n\to.Items = append(o.Items, item)\n}\n\nfunc (o *Order) RemoveItem(item *OrderItem) {\n\to.mu.Lock()\n\tdefer o.mu.Unlock()\n\tfor i, orderItem := range o.Items {\n\t\tif orderItem == item {\n\t\t\to.Items = append(o.Items[:i], o.Items[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (o *Order) SetStatus(status OrderStatus) {\n\to.mu.Lock()\n\tdefer o.mu.Unlock()\n\to.Status = status\n}\n\nfunc (o *Order) GetStatus() OrderStatus {\n\to.mu.RLock()\n\tdefer o.mu.RUnlock()\n\treturn o.Status\n}\n\nfunc (o *Order) AssignDeliveryAgent(agent *DeliveryAgent) {\n\to.mu.Lock()\n\tdefer o.mu.Unlock()\n\to.DeliveryAgent = agent\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/restaurant.go",
    "content": "package fooddeliveryservice\n\nimport \"sync\"\n\ntype Restaurant struct {\n\tID      string\n\tName    string\n\tAddress string\n\tMenu    []*MenuItem\n\tmu      sync.RWMutex\n}\n\nfunc NewRestaurant(id, name, address string, menu []*MenuItem) *Restaurant {\n\treturn &Restaurant{\n\t\tID:      id,\n\t\tName:    name,\n\t\tAddress: address,\n\t\tMenu:    menu,\n\t}\n}\n\nfunc (r *Restaurant) AddMenuItem(item *MenuItem) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.Menu = append(r.Menu, item)\n}\n\nfunc (r *Restaurant) RemoveMenuItem(item *MenuItem) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tfor i, menuItem := range r.Menu {\n\t\tif menuItem == item {\n\t\t\tr.Menu = append(r.Menu[:i], r.Menu[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (r *Restaurant) GetMenu() []*MenuItem {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\tmenuCopy := make([]*MenuItem, len(r.Menu))\n\tcopy(menuCopy, r.Menu)\n\treturn menuCopy\n}\n"
  },
  {
    "path": "solutions/golang/fooddeliveryservice/types.go",
    "content": "package fooddeliveryservice\n\ntype OrderStatus int\n\nconst (\n\tOrderStatusPending OrderStatus = iota\n\tOrderStatusConfirmed\n\tOrderStatusPreparing\n\tOrderStatusOutForDelivery\n\tOrderStatusDelivered\n\tOrderStatusCancelled\n)\n\nfunc (s OrderStatus) String() string {\n\treturn [...]string{\n\t\t\"PENDING\",\n\t\t\"CONFIRMED\",\n\t\t\"PREPARING\",\n\t\t\"OUT_FOR_DELIVERY\",\n\t\t\"DELIVERED\",\n\t\t\"CANCELLED\",\n\t}[s]\n}\n"
  },
  {
    "path": "solutions/golang/go.mod",
    "content": "module github.com/ashishps1/awesome-low-level-design/solutions/golang\n\ngo 1.23.2\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/README.md",
    "content": "# Designing a Hotel Management System\n\n## Requirements\n1. The hotel management system should allow guests to book rooms, check-in, and check-out.\n2. The system should manage different types of rooms, such as single, double, deluxe, and suite.\n3. The system should handle room availability and reservation status.\n4. The system should allow the hotel staff to manage guest information, room assignments, and billing.\n5. The system should support multiple payment methods, such as cash, credit card, and online payment.\n6. The system should handle concurrent bookings and ensure data consistency.\n7. The system should provide reporting and analytics features for hotel management.\n8. The system should be scalable and handle a large number of rooms and guests.\n\n## Classes, Interfaces and Enumerations\n1. The **Guest** class represents a guest of the hotel, with properties such as ID, name, email, and phone number.\n2. The **Room** class represents a room in the hotel, with properties like ID, room type, price, and status. It provides methods to book, check-in, and check-out a room.\n3. The **RoomType** enum represents the different types of rooms available in the hotel.\n4. The **RoomStatus** enum represents the status of a room, which can be available, booked, or occupied.\n5. The **Reservation** class represents a reservation made by a guest for a specific room and date range. It contains properties such as ID, guest, room, check-in date, check-out date, and status. It provides a method to cancel a reservation.\n6. The **ReservationStatus** enum represents the status of a reservation, which can be confirmed or cancelled.\n7. The **Payment** interface defines the contract for processing payments. It is implemented by concrete payment classes like CashPayment and CreditCardPayment.\n8. The **HotelManagementSystem** class is the central component of the hotel management system. It follows the Singleton pattern to ensure only one instance of the system exists. It provides methods to add guests and rooms, book rooms, cancel reservations, check-in, check-out, and process payments. It also handles concurrent access to shared resources using synchronization.\n9. The **HotelManagementSystemDemo** class demonstrates the usage of the hotel management system by creating guests, rooms, booking a room, checking in, checking out, and cancelling a reservation."
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/guest.go",
    "content": "package hotelmanagement\n\ntype Guest struct {\n\tID          string\n\tName        string\n\tEmail       string\n\tPhoneNumber string\n}\n\nfunc NewGuest(id, name, email, phoneNumber string) *Guest {\n\treturn &Guest{\n\t\tID:          id,\n\t\tName:        name,\n\t\tEmail:       email,\n\t\tPhoneNumber: phoneNumber,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/hotel_management.go",
    "content": "package hotelmanagement\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype HotelManagementSystem struct {\n\tguests       map[string]*Guest\n\trooms        map[string]*Room\n\treservations map[string]*Reservation\n\tmu           sync.RWMutex\n}\n\nvar (\n\tinstance *HotelManagementSystem\n\tonce     sync.Once\n)\n\nfunc GetHotelManagementSystem() *HotelManagementSystem {\n\tonce.Do(func() {\n\t\tinstance = &HotelManagementSystem{\n\t\t\tguests:       make(map[string]*Guest),\n\t\t\trooms:        make(map[string]*Room),\n\t\t\treservations: make(map[string]*Reservation),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (h *HotelManagementSystem) AddGuest(guest *Guest) {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\th.guests[guest.ID] = guest\n}\n\nfunc (h *HotelManagementSystem) GetGuest(guestID string) *Guest {\n\th.mu.RLock()\n\tdefer h.mu.RUnlock()\n\treturn h.guests[guestID]\n}\n\nfunc (h *HotelManagementSystem) AddRoom(room *Room) {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\th.rooms[room.ID] = room\n}\n\nfunc (h *HotelManagementSystem) GetRoom(roomID string) *Room {\n\th.mu.RLock()\n\tdefer h.mu.RUnlock()\n\treturn h.rooms[roomID]\n}\n\nfunc (h *HotelManagementSystem) BookRoom(guest *Guest, room *Room, checkInDate, checkOutDate time.Time) (*Reservation, error) {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\tif room.GetStatus() != RoomStatusAvailable {\n\t\treturn nil, fmt.Errorf(\"room is not available\")\n\t}\n\n\tif err := room.Book(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treservationID := fmt.Sprintf(\"RES%d\", time.Now().UnixNano())\n\treservation := NewReservation(reservationID, guest, room, checkInDate, checkOutDate)\n\th.reservations[reservationID] = reservation\n\n\treturn reservation, nil\n}\n\nfunc (h *HotelManagementSystem) CancelReservation(reservationID string) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\treservation, exists := h.reservations[reservationID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"reservation not found\")\n\t}\n\n\tif err := reservation.Cancel(); err != nil {\n\t\treturn err\n\t}\n\n\tdelete(h.reservations, reservationID)\n\treturn nil\n}\n\nfunc (h *HotelManagementSystem) CheckIn(reservationID string) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\treservation, exists := h.reservations[reservationID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"reservation not found\")\n\t}\n\n\tif reservation.Status != ReservationStatusConfirmed {\n\t\treturn fmt.Errorf(\"invalid reservation status\")\n\t}\n\n\treturn reservation.Room.CheckIn()\n}\n\nfunc (h *HotelManagementSystem) CheckOut(reservationID string, payment Payment) error {\n\th.mu.Lock()\n\tdefer h.mu.Unlock()\n\n\treservation, exists := h.reservations[reservationID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"reservation not found\")\n\t}\n\n\tif reservation.Status != ReservationStatusConfirmed {\n\t\treturn fmt.Errorf(\"invalid reservation status\")\n\t}\n\n\tdays := reservation.CheckOutDate.Sub(reservation.CheckInDate).Hours() / 24\n\tamount := reservation.Room.Price * days\n\n\tif !payment.ProcessPayment(amount) {\n\t\treturn fmt.Errorf(\"payment failed\")\n\t}\n\n\tif err := reservation.Room.CheckOut(); err != nil {\n\t\treturn err\n\t}\n\n\tdelete(h.reservations, reservationID)\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/hotel_management_demo.go",
    "content": "package hotelmanagement\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\thotelSystem := GetHotelManagementSystem()\n\n\t// Create guests\n\tguest1 := NewGuest(\"G001\", \"John Doe\", \"john@example.com\", \"1234567890\")\n\tguest2 := NewGuest(\"G002\", \"Jane Smith\", \"jane@example.com\", \"9876543210\")\n\thotelSystem.AddGuest(guest1)\n\thotelSystem.AddGuest(guest2)\n\n\t// Create rooms\n\troom1 := NewRoom(\"R001\", RoomTypeSingle, 100.0)\n\troom2 := NewRoom(\"R002\", RoomTypeDouble, 200.0)\n\thotelSystem.AddRoom(room1)\n\thotelSystem.AddRoom(room2)\n\n\t// Book a room\n\tcheckInDate := time.Now()\n\tcheckOutDate := checkInDate.AddDate(0, 0, 3)\n\n\treservation1, err := hotelSystem.BookRoom(guest1, room1, checkInDate, checkOutDate)\n\tif err != nil {\n\t\tfmt.Printf(\"Failed to book room: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Reservation created: %s\\n\", reservation1.ID)\n\n\t// Check-in\n\tif err := hotelSystem.CheckIn(reservation1.ID); err != nil {\n\t\tfmt.Printf(\"Failed to check in: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Checked in: %s\\n\", reservation1.ID)\n\n\t// Check-out and process payment\n\tpayment := NewCreditCardPayment()\n\tif err := hotelSystem.CheckOut(reservation1.ID, payment); err != nil {\n\t\tfmt.Printf(\"Failed to check out: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Checked out: %s\\n\", reservation1.ID)\n\n\t// Cancel a reservation\n\tif err := hotelSystem.CancelReservation(reservation1.ID); err != nil {\n\t\tfmt.Printf(\"Failed to cancel reservation: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Reservation cancelled: %s\\n\", reservation1.ID)\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/payment.go",
    "content": "package hotelmanagement\n\ntype Payment interface {\n\tProcessPayment(amount float64) bool\n}\n\ntype CreditCardPayment struct{}\n\nfunc NewCreditCardPayment() *CreditCardPayment {\n\treturn &CreditCardPayment{}\n}\n\nfunc (p *CreditCardPayment) ProcessPayment(amount float64) bool {\n\t// Process credit card payment\n\treturn true\n}\n\ntype CashPayment struct{}\n\nfunc NewCashPayment() *CashPayment {\n\treturn &CashPayment{}\n}\n\nfunc (p *CashPayment) ProcessPayment(amount float64) bool {\n\t// Process cash payment\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/reservation.go",
    "content": "package hotelmanagement\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype Reservation struct {\n\tID           string\n\tGuest        *Guest\n\tRoom         *Room\n\tCheckInDate  time.Time\n\tCheckOutDate time.Time\n\tStatus       ReservationStatus\n\tmu           sync.RWMutex\n}\n\nfunc NewReservation(id string, guest *Guest, room *Room, checkInDate, checkOutDate time.Time) *Reservation {\n\treturn &Reservation{\n\t\tID:           id,\n\t\tGuest:        guest,\n\t\tRoom:         room,\n\t\tCheckInDate:  checkInDate,\n\t\tCheckOutDate: checkOutDate,\n\t\tStatus:       ReservationStatusConfirmed,\n\t}\n}\n\nfunc (r *Reservation) Cancel() error {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\n\tif r.Status != ReservationStatusConfirmed {\n\t\treturn fmt.Errorf(\"reservation is not confirmed\")\n\t}\n\n\tr.Status = ReservationStatusCancelled\n\treturn r.Room.CheckOut()\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/room.go",
    "content": "package hotelmanagement\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype Room struct {\n\tID     string\n\tType   RoomType\n\tPrice  float64\n\tstatus RoomStatus\n\tmu     sync.RWMutex\n}\n\nfunc NewRoom(id string, roomType RoomType, price float64) *Room {\n\treturn &Room{\n\t\tID:     id,\n\t\tType:   roomType,\n\t\tPrice:  price,\n\t\tstatus: RoomStatusAvailable,\n\t}\n}\n\nfunc (r *Room) Book() error {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\n\tif r.status != RoomStatusAvailable {\n\t\treturn fmt.Errorf(\"room is not available for booking\")\n\t}\n\tr.status = RoomStatusBooked\n\treturn nil\n}\n\nfunc (r *Room) CheckIn() error {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\n\tif r.status != RoomStatusBooked {\n\t\treturn fmt.Errorf(\"room is not booked\")\n\t}\n\tr.status = RoomStatusOccupied\n\treturn nil\n}\n\nfunc (r *Room) CheckOut() error {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\n\tif r.status != RoomStatusOccupied {\n\t\treturn fmt.Errorf(\"room is not occupied\")\n\t}\n\tr.status = RoomStatusAvailable\n\treturn nil\n}\n\nfunc (r *Room) GetStatus() RoomStatus {\n\tr.mu.RLock()\n\tdefer r.mu.RUnlock()\n\treturn r.status\n}\n"
  },
  {
    "path": "solutions/golang/hotelmanagementsystem/types.go",
    "content": "package hotelmanagement\n\ntype RoomType int\ntype RoomStatus int\ntype ReservationStatus int\n\nconst (\n\tRoomTypeSingle RoomType = iota\n\tRoomTypeDouble\n\tRoomTypeDeluxe\n\tRoomTypeSuite\n)\n\nconst (\n\tRoomStatusAvailable RoomStatus = iota\n\tRoomStatusBooked\n\tRoomStatusOccupied\n)\n\nconst (\n\tReservationStatusConfirmed ReservationStatus = iota\n\tReservationStatusCancelled\n)\n"
  },
  {
    "path": "solutions/golang/librarymanagementsystem/README.md",
    "content": "# Designing a Library Management System\n\n## Requirements\n1. The library management system should allow librarians to manage books, members, and borrowing activities.\n2. The system should support adding, updating, and removing books from the library catalog.\n3. Each book should have details such as title, author, ISBN, publication year, and availability status.\n4. The system should allow members to borrow and return books.\n5. Each member should have details such as name, member ID, contact information, and borrowing history.\n6. The system should enforce borrowing rules, such as a maximum number of books that can be borrowed at a time and loan duration.\n7. The system should handle concurrent access to the library catalog and member records.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Book** class represents a book in the library catalog, with properties such as ISBN, title, author, publication year, and availability status.\n2. The **Member** class represents a library member, with properties like member ID, name, contact information, and a list of borrowed books.\n3. The **LibraryManager** class is the core of the library management system and follows the Singleton pattern to ensure a single instance of the library manager.\n4. The LibraryManager class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to the library catalog and member records.\n5. The LibraryManager class provides methods for adding and removing books, registering and unregistering members, borrowing and returning books, and searching for books based on keywords.\n6. The **LibraryManagementSystemDemo** class serves as the entry point of the application and demonstrates the usage of the library management system."
  },
  {
    "path": "solutions/golang/librarymanagementsystem/book.go",
    "content": "package librarymanagementsystem\n\nimport \"sync\"\n\ntype Book struct {\n\tISBN            string\n\tTitle           string\n\tAuthor          string\n\tPublicationYear int\n\tavailable       bool\n\tmu              sync.RWMutex\n}\n\nfunc NewBook(isbn, title, author string, publicationYear int) *Book {\n\treturn &Book{\n\t\tISBN:            isbn,\n\t\tTitle:           title,\n\t\tAuthor:          author,\n\t\tPublicationYear: publicationYear,\n\t\tavailable:       true,\n\t}\n}\n\nfunc (b *Book) IsAvailable() bool {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.available\n}\n\nfunc (b *Book) SetAvailable(available bool) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.available = available\n}\n"
  },
  {
    "path": "solutions/golang/librarymanagementsystem/library_management_system_demo.go",
    "content": "package librarymanagementsystem\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tlibraryManager := GetLibraryManager()\n\n\t// Add books to the catalog\n\tbook1 := NewBook(\"ISBN1\", \"Book 1\", \"Author 1\", 2020)\n\tbook2 := NewBook(\"ISBN2\", \"Book 2\", \"Author 2\", 2019)\n\tbook3 := NewBook(\"ISBN3\", \"Book 3\", \"Author 3\", 2021)\n\n\tlibraryManager.AddBook(book1)\n\tlibraryManager.AddBook(book2)\n\tlibraryManager.AddBook(book3)\n\n\t// Register members\n\tmember1 := NewMember(\"M1\", \"John Doe\", \"john@example.com\")\n\tmember2 := NewMember(\"M2\", \"Jane Smith\", \"jane@example.com\")\n\n\tlibraryManager.RegisterMember(member1)\n\tlibraryManager.RegisterMember(member2)\n\n\t// Borrow books\n\tif err := libraryManager.BorrowBook(\"M1\", \"ISBN1\"); err != nil {\n\t\tfmt.Printf(\"Error borrowing book: %v\\n\", err)\n\t}\n\n\tif err := libraryManager.BorrowBook(\"M2\", \"ISBN2\"); err != nil {\n\t\tfmt.Printf(\"Error borrowing book: %v\\n\", err)\n\t}\n\n\t// Return books\n\tif err := libraryManager.ReturnBook(\"M1\", \"ISBN1\"); err != nil {\n\t\tfmt.Printf(\"Error returning book: %v\\n\", err)\n\t}\n\n\t// Search books\n\tsearchResults := libraryManager.SearchBooks(\"Book\")\n\tfmt.Println(\"\\nSearch Results:\")\n\tfor _, book := range searchResults {\n\t\tfmt.Printf(\"%s by %s\\n\", book.Title, book.Author)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/librarymanagementsystem/library_manager.go",
    "content": "package librarymanagementsystem\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n)\n\nconst (\n\tmaxBooksPerMember = 5\n\tloanDurationDays  = 14\n)\n\ntype LibraryManager struct {\n\tcatalog map[string]*Book\n\tmembers map[string]*Member\n\tmu      sync.RWMutex\n}\n\nvar (\n\tinstance *LibraryManager\n\tonce     sync.Once\n)\n\nfunc GetLibraryManager() *LibraryManager {\n\tonce.Do(func() {\n\t\tinstance = &LibraryManager{\n\t\t\tcatalog: make(map[string]*Book),\n\t\t\tmembers: make(map[string]*Member),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (lm *LibraryManager) AddBook(book *Book) {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\tlm.catalog[book.ISBN] = book\n}\n\nfunc (lm *LibraryManager) RemoveBook(isbn string) {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\tdelete(lm.catalog, isbn)\n}\n\nfunc (lm *LibraryManager) GetBook(isbn string) *Book {\n\tlm.mu.RLock()\n\tdefer lm.mu.RUnlock()\n\treturn lm.catalog[isbn]\n}\n\nfunc (lm *LibraryManager) RegisterMember(member *Member) {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\tlm.members[member.MemberID] = member\n}\n\nfunc (lm *LibraryManager) UnregisterMember(memberID string) {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\tdelete(lm.members, memberID)\n}\n\nfunc (lm *LibraryManager) GetMember(memberID string) *Member {\n\tlm.mu.RLock()\n\tdefer lm.mu.RUnlock()\n\treturn lm.members[memberID]\n}\n\nfunc (lm *LibraryManager) BorrowBook(memberID, isbn string) error {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\n\tmember := lm.members[memberID]\n\tbook := lm.catalog[isbn]\n\n\tif member == nil || book == nil {\n\t\treturn fmt.Errorf(\"book or member not found\")\n\t}\n\n\tif !book.IsAvailable() {\n\t\treturn fmt.Errorf(\"book is not available\")\n\t}\n\n\tif len(member.GetBorrowedBooks()) >= maxBooksPerMember {\n\t\treturn fmt.Errorf(\"member %s has reached the maximum number of borrowed books\", member.Name)\n\t}\n\n\tmember.BorrowBook(book)\n\tbook.SetAvailable(false)\n\tfmt.Printf(\"Book borrowed: %s by %s\\n\", book.Title, member.Name)\n\treturn nil\n}\n\nfunc (lm *LibraryManager) ReturnBook(memberID, isbn string) error {\n\tlm.mu.Lock()\n\tdefer lm.mu.Unlock()\n\n\tmember := lm.members[memberID]\n\tbook := lm.catalog[isbn]\n\n\tif member == nil || book == nil {\n\t\treturn fmt.Errorf(\"book or member not found\")\n\t}\n\n\tmember.ReturnBook(book)\n\tbook.SetAvailable(true)\n\tfmt.Printf(\"Book returned: %s by %s\\n\", book.Title, member.Name)\n\treturn nil\n}\n\nfunc (lm *LibraryManager) SearchBooks(keyword string) []*Book {\n\tlm.mu.RLock()\n\tdefer lm.mu.RUnlock()\n\n\tkeyword = strings.ToLower(keyword)\n\tmatchingBooks := make([]*Book, 0)\n\n\tfor _, book := range lm.catalog {\n\t\tif strings.Contains(strings.ToLower(book.Title), keyword) ||\n\t\t\tstrings.Contains(strings.ToLower(book.Author), keyword) {\n\t\t\tmatchingBooks = append(matchingBooks, book)\n\t\t}\n\t}\n\treturn matchingBooks\n}\n"
  },
  {
    "path": "solutions/golang/librarymanagementsystem/member.go",
    "content": "package librarymanagementsystem\n\nimport \"sync\"\n\ntype Member struct {\n\tMemberID      string\n\tName          string\n\tContactInfo   string\n\tborrowedBooks map[string]*Book // Using map for O(1) lookups\n\tmu            sync.RWMutex\n}\n\nfunc NewMember(memberID, name, contactInfo string) *Member {\n\treturn &Member{\n\t\tMemberID:      memberID,\n\t\tName:          name,\n\t\tContactInfo:   contactInfo,\n\t\tborrowedBooks: make(map[string]*Book),\n\t}\n}\n\nfunc (m *Member) BorrowBook(book *Book) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tm.borrowedBooks[book.ISBN] = book\n}\n\nfunc (m *Member) ReturnBook(book *Book) {\n\tm.mu.Lock()\n\tdefer m.mu.Unlock()\n\tdelete(m.borrowedBooks, book.ISBN)\n}\n\nfunc (m *Member) GetBorrowedBooks() []*Book {\n\tm.mu.RLock()\n\tdefer m.mu.RUnlock()\n\tbooks := make([]*Book, 0, len(m.borrowedBooks))\n\tfor _, book := range m.borrowedBooks {\n\t\tbooks = append(books, book)\n\t}\n\treturn books\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/README.md",
    "content": "# Designing a Professional Networking Platform like LinkedIn\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their professional information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their professional information, such as profile picture, headline, summary, experience, education, and skills.\n- Users should be able to update their profile information.\n#### Connections:\n- Users should be able to send connection requests to other users.\n- Users should be able to accept or decline connection requests.\n- Users should be able to view their list of connections.\n#### Messaging:\n- Users should be able to send messages to their connections.\n- Users should be able to view their inbox and sent messages.\n#### Job Postings:\n- Employers should be able to post job listings with details such as title, description, requirements, and location.\n- Users should be able to view and apply for job postings.\n#### Search Functionality:\n- Users should be able to search for other users, companies, and job postings based on relevant criteria.\n- Search results should be ranked based on relevance and user preferences.\n#### Notifications:\n- Users should receive notifications for events such as connection requests, messages, and job postings.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the LinkedIn system, containing properties such as ID, name, email, password, profile, connections, inbox, and sent messages.\n2. The **Profile** class represents a user's profile, containing properties such as profile picture, headline, summary, experiences, educations, and skills.\n3. The **Experience**, **Education**, and **Skill** classes represent different components of a user's profile.\n4. The **Connection** class represents a connection between two users, containing the user and the connection date.\n5. The **Message** class represents a message sent between users, containing properties such as ID, sender, receiver, content, and timestamp.\n6. The **JobPosting** class represents a job listing posted by an employer, containing properties such as ID, title, description, requirements, location, and post date.\n7. The **Notification** class represents a notification generated for a user, containing properties such as ID, user, notification type, content, and timestamp.\n8. The **NotificationType** enum defines the different types of notifications, such as connection request, message, and job posting.\n9. The **LinkedInService** class is the main class that manages the LinkedIn system. It follows the Singleton pattern to ensure only one instance of the service exists.\n10. The **LinkedInService** class provides methods for user registration, login, profile updates, connection requests, job postings, user and job search, messaging, and notifications.\n11. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n12. The **LinkedInDemo** class demonstrates the usage of the LinkedIn system by registering users, logging in, updating profiles, sending connection requests, posting job listings, searching for users and jobs, sending messages, and retrieving notifications."
  },
  {
    "path": "solutions/golang/linkedin/connection.go",
    "content": "package linkedin\n\nimport \"time\"\n\ntype Connection struct {\n\tUser           *User\n\tConnectionDate time.Time\n}\n\nfunc NewConnection(user *User) *Connection {\n\treturn &Connection{\n\t\tUser:           user,\n\t\tConnectionDate: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/education.go",
    "content": "package linkedin\n\ntype Education struct {\n\tSchool       string\n\tDegree       string\n\tFieldOfStudy string\n\tStartDate    string\n\tEndDate      string\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/experience.go",
    "content": "package linkedin\n\ntype Experience struct {\n\tTitle       string\n\tCompany     string\n\tStartDate   string\n\tEndDate     string\n\tDescription string\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/job_posting.go",
    "content": "package linkedin\n\nimport \"time\"\n\ntype JobPosting struct {\n\tID           string\n\tTitle        string\n\tDescription  string\n\tRequirements []string\n\tLocation     string\n\tPostDate     time.Time\n}\n\nfunc NewJobPosting(id, title, description string, requirements []string, location string) *JobPosting {\n\treturn &JobPosting{\n\t\tID:           id,\n\t\tTitle:        title,\n\t\tDescription:  description,\n\t\tRequirements: requirements,\n\t\tLocation:     location,\n\t\tPostDate:     time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/linkedin_service.go",
    "content": "package linkedin\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype LinkedInService struct {\n\tusers         map[string]*User\n\tjobPostings   map[string]*JobPosting\n\tnotifications map[string][]*Notification\n\tmu            sync.RWMutex\n}\n\nvar (\n\tinstance *LinkedInService\n\tonce     sync.Once\n)\n\nfunc GetLinkedInService() *LinkedInService {\n\tonce.Do(func() {\n\t\tinstance = &LinkedInService{\n\t\t\tusers:         make(map[string]*User),\n\t\t\tjobPostings:   make(map[string]*JobPosting),\n\t\t\tnotifications: make(map[string][]*Notification),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (s *LinkedInService) RegisterUser(user *User) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.users[user.ID] = user\n}\n\nfunc (s *LinkedInService) LoginUser(email, password string) (*User, error) {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\n\tfor _, user := range s.users {\n\t\tif user.Email == email && user.Password == password {\n\t\t\treturn user, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"invalid email or password\")\n}\n\nfunc (s *LinkedInService) UpdateUserProfile(user *User) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.users[user.ID] = user\n}\n\nfunc (s *LinkedInService) SendConnectionRequest(sender, receiver *User) {\n\tconnection := NewConnection(sender)\n\treceiver.AddConnection(connection)\n\n\tnotification := NewNotification(\n\t\tfmt.Sprintf(\"NOTIF-%d\", time.Now().UnixNano()),\n\t\treceiver,\n\t\tNotificationTypeConnectionRequest,\n\t\tfmt.Sprintf(\"New connection request from %s\", sender.Name),\n\t)\n\ts.addNotification(receiver.ID, notification)\n}\n\nfunc (s *LinkedInService) AcceptConnectionRequest(user, connectionUser *User) {\n\tuser.AddConnection(NewConnection(connectionUser))\n}\n\nfunc (s *LinkedInService) SearchUsers(keyword string) []*User {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\n\tvar results []*User\n\tkeyword = strings.ToLower(keyword)\n\n\tfor _, user := range s.users {\n\t\tif strings.Contains(strings.ToLower(user.Name), keyword) {\n\t\t\tresults = append(results, user)\n\t\t}\n\t}\n\treturn results\n}\n\nfunc (s *LinkedInService) PostJobListing(jobPosting *JobPosting) {\n\ts.mu.Lock()\n\ts.jobPostings[jobPosting.ID] = jobPosting\n\ts.mu.Unlock()\n\n\t// Notify all users about new job posting\n\tfor _, user := range s.users {\n\t\tnotification := NewNotification(\n\t\t\tfmt.Sprintf(\"NOTIF-%d\", time.Now().UnixNano()),\n\t\t\tuser,\n\t\t\tNotificationTypeJobPosting,\n\t\t\tfmt.Sprintf(\"New job posting: %s\", jobPosting.Title),\n\t\t)\n\t\ts.addNotification(user.ID, notification)\n\t}\n}\n\nfunc (s *LinkedInService) SearchJobPostings(keyword string) []*JobPosting {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\n\tvar results []*JobPosting\n\tkeyword = strings.ToLower(keyword)\n\n\tfor _, posting := range s.jobPostings {\n\t\tif strings.Contains(strings.ToLower(posting.Title), keyword) ||\n\t\t\tstrings.Contains(strings.ToLower(posting.Description), keyword) {\n\t\t\tresults = append(results, posting)\n\t\t}\n\t}\n\treturn results\n}\n\nfunc (s *LinkedInService) SendMessage(sender, receiver *User, content string) {\n\tmessage := NewMessage(\n\t\tfmt.Sprintf(\"MSG-%d\", time.Now().UnixNano()),\n\t\tsender,\n\t\treceiver,\n\t\tcontent,\n\t)\n\n\treceiver.AddMessage(message, false)\n\tsender.AddMessage(message, true)\n\n\tnotification := NewNotification(\n\t\tfmt.Sprintf(\"NOTIF-%d\", time.Now().UnixNano()),\n\t\treceiver,\n\t\tNotificationTypeMessage,\n\t\tfmt.Sprintf(\"New message from %s\", sender.Name),\n\t)\n\ts.addNotification(receiver.ID, notification)\n}\n\nfunc (s *LinkedInService) addNotification(userID string, notification *Notification) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.notifications[userID] = append(s.notifications[userID], notification)\n}\n\nfunc (s *LinkedInService) GetNotifications(userID string) []*Notification {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn s.notifications[userID]\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/linkedin_service_demo.go",
    "content": "package linkedin\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tservice := GetLinkedInService()\n\n\t// Create users\n\tuser1 := NewUser(\"1\", \"John Doe\", \"john@example.com\", \"password\")\n\tuser2 := NewUser(\"2\", \"Jane Smith\", \"jane@example.com\", \"password\")\n\n\tservice.RegisterUser(user1)\n\tservice.RegisterUser(user2)\n\n\t// Login\n\tloggedInUser, err := service.LoginUser(\"john@example.com\", \"password\")\n\tif err != nil {\n\t\tfmt.Printf(\"Login failed: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"User logged in: %s\\n\", loggedInUser.Name)\n\n\t// Update profile\n\tloggedInUser.Profile.SetHeadline(\"Software Engineer\")\n\tloggedInUser.Profile.SetSummary(\"Passionate about coding and problem-solving.\")\n\tservice.UpdateUserProfile(loggedInUser)\n\n\t// Send connection request\n\tservice.SendConnectionRequest(user1, user2)\n\n\t// Accept connection request\n\tservice.AcceptConnectionRequest(user2, user1)\n\n\t// Post job listing\n\tjobPosting := NewJobPosting(\n\t\t\"1\",\n\t\t\"Software Developer\",\n\t\t\"We are hiring!\",\n\t\t[]string{\"Java\", \"Python\"},\n\t\t\"San Francisco\",\n\t)\n\tservice.PostJobListing(jobPosting)\n\n\t// Search users\n\tsearchResults := service.SearchUsers(\"John\")\n\tfmt.Println(\"\\nSearch Results:\")\n\tfor _, user := range searchResults {\n\t\tfmt.Printf(\"Name: %s\\n\", user.Name)\n\t\tfmt.Printf(\"Headline: %s\\n\\n\", user.Profile.Headline)\n\t}\n\n\t// Search job postings\n\tjobResults := service.SearchJobPostings(\"Software\")\n\tfmt.Println(\"Job Posting Results:\")\n\tfor _, posting := range jobResults {\n\t\tfmt.Printf(\"Title: %s\\n\", posting.Title)\n\t\tfmt.Printf(\"Description: %s\\n\\n\", posting.Description)\n\t}\n\n\t// Send message\n\tservice.SendMessage(user1, user2, \"Hi Jane, hope you're doing well!\")\n\n\t// Get notifications\n\tnotifications := service.GetNotifications(user2.ID)\n\tfmt.Println(\"Notifications:\")\n\tfor _, notification := range notifications {\n\t\tfmt.Printf(\"Type: %v\\n\", notification.Type)\n\t\tfmt.Printf(\"Content: %s\\n\\n\", notification.Content)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/message.go",
    "content": "package linkedin\n\nimport \"time\"\n\ntype Message struct {\n\tID        string\n\tSender    *User\n\tReceiver  *User\n\tContent   string\n\tTimestamp time.Time\n}\n\nfunc NewMessage(id string, sender, receiver *User, content string) *Message {\n\treturn &Message{\n\t\tID:        id,\n\t\tSender:    sender,\n\t\tReceiver:  receiver,\n\t\tContent:   content,\n\t\tTimestamp: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/notification.go",
    "content": "package linkedin\n\nimport \"time\"\n\ntype Notification struct {\n\tID        string\n\tUser      *User\n\tType      NotificationType\n\tContent   string\n\tTimestamp time.Time\n}\n\nfunc NewNotification(id string, user *User, notifType NotificationType, content string) *Notification {\n\treturn &Notification{\n\t\tID:        id,\n\t\tUser:      user,\n\t\tType:      notifType,\n\t\tContent:   content,\n\t\tTimestamp: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/profile.go",
    "content": "package linkedin\n\nimport \"sync\"\n\ntype Profile struct {\n\tProfilePicture string\n\tHeadline       string\n\tSummary        string\n\tExperiences    []*Experience\n\tEducations     []*Education\n\tSkills         []*Skill\n\tmu             sync.RWMutex\n}\n\nfunc NewProfile() *Profile {\n\treturn &Profile{\n\t\tExperiences: make([]*Experience, 0),\n\t\tEducations:  make([]*Education, 0),\n\t\tSkills:      make([]*Skill, 0),\n\t}\n}\n\nfunc (p *Profile) SetSummary(summary string) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.Summary = summary\n}\n\nfunc (p *Profile) SetHeadline(headline string) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.Headline = headline\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/skill.go",
    "content": "package linkedin\n\ntype Skill struct {\n\tName string\n}\n"
  },
  {
    "path": "solutions/golang/linkedin/types.go",
    "content": "package linkedin\n\ntype NotificationType int\n\nconst (\n\tNotificationTypeConnectionRequest NotificationType = iota\n\tNotificationTypeMessage\n\tNotificationTypeJobPosting\n)"
  },
  {
    "path": "solutions/golang/linkedin/user.go",
    "content": "package linkedin\n\nimport \"sync\"\n\ntype User struct {\n\tID           string\n\tName         string\n\tEmail        string\n\tPassword     string\n\tProfile      *Profile\n\tconnections  []*Connection\n\tinbox        []*Message\n\tsentMessages []*Message\n\tmu           sync.RWMutex\n}\n\nfunc NewUser(id, name, email, password string) *User {\n\treturn &User{\n\t\tID:           id,\n\t\tName:         name,\n\t\tEmail:        email,\n\t\tPassword:     password,\n\t\tProfile:      NewProfile(),\n\t\tconnections:  make([]*Connection, 0),\n\t\tinbox:        make([]*Message, 0),\n\t\tsentMessages: make([]*Message, 0),\n\t}\n}\n\nfunc (u *User) AddConnection(connection *Connection) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.connections = append(u.connections, connection)\n}\n\nfunc (u *User) AddMessage(message *Message, isSent bool) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tif isSent {\n\t\tu.sentMessages = append(u.sentMessages, message)\n\t} else {\n\t\tu.inbox = append(u.inbox, message)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/README.md",
    "content": "# Designing a Logging Framework\n\n## Requirements\n1. The logging framework should support different log levels, such as DEBUG, INFO, WARNING, ERROR, and FATAL.\n2. It should allow logging messages with a timestamp, log level, and message content.\n3. The framework should support multiple output destinations, such as console, file, and database.\n4. It should provide a configuration mechanism to set the log level and output destination.\n5. The logging framework should be thread-safe to handle concurrent logging from multiple threads.\n6. It should be extensible to accommodate new log levels and output destinations in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **LogLevel** enum defines the different log levels supported by the logging framework.\n2. The **LogMessage** class represents a log message with a timestamp, log level, and message content.\n3. The **LogAppender** interface defines the contract for appending log messages to different output destinations.\n4. The **ConsoleAppender**, **FileAppender**, and **DatabaseAppender** classes are concrete implementations of the LogAppender interface, supporting logging to the console, file, and database, respectively.\n5. The **LoggerConfig** class holds the configuration settings for the logger, including the log level and the selected log appender.\n6. The **Logger** class is a singleton that provides the main logging functionality. It allows setting the configuration, logging messages at different levels, and provides convenience methods for each log level.\n7. The **LoggingExample** class demonstrates the usage of the logging framework, showcasing different log levels, changing the configuration, and logging from multiple threads."
  },
  {
    "path": "solutions/golang/loggingframework/console_appender.go",
    "content": "package loggingframework\n\nimport \"fmt\"\n\ntype ConsoleAppender struct{}\n\nfunc NewConsoleAppender() *ConsoleAppender {\n\treturn &ConsoleAppender{}\n}\n\nfunc (a *ConsoleAppender) Append(message *LogMessage) error {\n\tfmt.Println(message.String())\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/database_appender.go",
    "content": "package loggingframework\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n)\n\ntype DatabaseAppender struct {\n\tdb *sql.DB\n}\n\nfunc NewDatabaseAppender(jdbcURL, username, password string) (*DatabaseAppender, error) {\n\tdb, err := sql.Open(\"mysql\", fmt.Sprintf(\"%s:%s@%s\", username, password, jdbcURL))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &DatabaseAppender{\n\t\tdb: db,\n\t}, nil\n}\n\nfunc (a *DatabaseAppender) Append(message *LogMessage) error {\n\tstmt, err := a.db.Prepare(\"INSERT INTO logs (level, message, timestamp) VALUES (?, ?, ?)\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer stmt.Close()\n\n\t_, err = stmt.Exec(message.Level.String(), message.Message, message.Timestamp)\n\treturn err\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/file_appender.go",
    "content": "package loggingframework\n\nimport (\n\t\"os\"\n)\n\ntype FileAppender struct {\n\tfilePath string\n}\n\nfunc NewFileAppender(filePath string) *FileAppender {\n\treturn &FileAppender{\n\t\tfilePath: filePath,\n\t}\n}\n\nfunc (a *FileAppender) Append(message *LogMessage) error {\n\tf, err := os.OpenFile(a.filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\t_, err = f.WriteString(message.String() + \"\\n\")\n\treturn err\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/log_appender.go",
    "content": "package loggingframework\n\ntype LogAppender interface {\n\tAppend(message *LogMessage) error\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/log_level.go",
    "content": "package loggingframework\n\ntype LogLevel int\n\nconst (\n\tLogLevelDebug LogLevel = iota\n\tLogLevelInfo\n\tLogLevelWarning\n\tLogLevelError\n\tLogLevelFatal\n)\n\nfunc (l LogLevel) String() string {\n\treturn [...]string{\"DEBUG\", \"INFO\", \"WARNING\", \"ERROR\", \"FATAL\"}[l]\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/log_message.go",
    "content": "package loggingframework\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\ntype LogMessage struct {\n\tLevel     LogLevel\n\tMessage   string\n\tTimestamp int64\n}\n\nfunc NewLogMessage(level LogLevel, message string) *LogMessage {\n\treturn &LogMessage{\n\t\tLevel:     level,\n\t\tMessage:   message,\n\t\tTimestamp: time.Now().UnixMilli(),\n\t}\n}\n\nfunc (m *LogMessage) String() string {\n\treturn fmt.Sprintf(\"[%s] %d - %s\", m.Level, m.Timestamp, m.Message)\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/logger.go",
    "content": "package loggingframework\n\nimport (\n\t\"sync\"\n)\n\ntype Logger struct {\n\tconfig *LoggerConfig\n\tmu     sync.RWMutex\n}\n\nvar (\n\tinstance *Logger\n\tonce     sync.Once\n)\n\nfunc GetLogger() *Logger {\n\tonce.Do(func() {\n\t\tinstance = &Logger{\n\t\t\tconfig: NewLoggerConfig(LogLevelInfo, NewConsoleAppender()),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (l *Logger) SetConfig(config *LoggerConfig) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.config = config\n}\n\nfunc (l *Logger) log(level LogLevel, message string) error {\n\tl.mu.RLock()\n\tif level < l.config.Level {\n\t\tl.mu.RUnlock()\n\t\treturn nil\n\t}\n\tappender := l.config.Appender\n\tl.mu.RUnlock()\n\n\tlogMessage := NewLogMessage(level, message)\n\treturn appender.Append(logMessage)\n}\n\nfunc (l *Logger) Debug(message string) error {\n\treturn l.log(LogLevelDebug, message)\n}\n\nfunc (l *Logger) Info(message string) error {\n\treturn l.log(LogLevelInfo, message)\n}\n\nfunc (l *Logger) Warning(message string) error {\n\treturn l.log(LogLevelWarning, message)\n}\n\nfunc (l *Logger) Error(message string) error {\n\treturn l.log(LogLevelError, message)\n}\n\nfunc (l *Logger) Fatal(message string) error {\n\treturn l.log(LogLevelFatal, message)\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/logger_config.go",
    "content": "package loggingframework\n\ntype LoggerConfig struct {\n\tLevel    LogLevel\n\tAppender LogAppender\n}\n\nfunc NewLoggerConfig(level LogLevel, appender LogAppender) *LoggerConfig {\n\treturn &LoggerConfig{\n\t\tLevel:    level,\n\t\tAppender: appender,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/loggingframework/logging_framework_demo.go",
    "content": "package loggingframework\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tlogger := GetLogger()\n\n\t// Logging with default configuration\n\tlogger.Info(\"This is an information message\")\n\tlogger.Warning(\"This is a warning message\")\n\tlogger.Error(\"This is an error message\")\n\n\t// Changing log level and appender\n\tfileAppender := NewFileAppender(\"app.log\")\n\tconfig := NewLoggerConfig(LogLevelDebug, fileAppender)\n\tlogger.SetConfig(config)\n\n\tif err := logger.Debug(\"This is a debug message\"); err != nil {\n\t\tfmt.Printf(\"Error logging debug message: %v\\n\", err)\n\t}\n\n\tif err := logger.Info(\"This is an information message\"); err != nil {\n\t\tfmt.Printf(\"Error logging info message: %v\\n\", err)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/lrucache/README.md",
    "content": "# Designing a LRU Cache\n\n## Requirements\n1. The LRU cache should support the following operations:\n- put(key, value): Insert a key-value pair into the cache. If the cache is at capacity, remove the least recently used item before inserting the new item.\n- get(key): Get the value associated with the given key. If the key exists in the cache, move it to the front of the cache (most recently used) and return its value. If the key does not exist, return -1.\n2. The cache should have a fixed capacity, specified during initialization.\n3. The cache should be thread-safe, allowing concurrent access from multiple threads.\n4. The cache should be efficient in terms of time complexity for both put and get operations, ideally O(1).\n\n## Classes, Interfaces and Enumerations\n1. The **Node** class represents a node in the doubly linked list, containing the key, value, and references to the previous and next nodes.\n2. The **LRUCache** class implements the LRU cache functionality using a combination of a hash map (cache) and a doubly linked list (head and tail).\n3. The get method retrieves the value associated with a given key. If the key exists in the cache, it is moved to the head of the linked list (most recently used) and its value is returned. If the key does not exist, null is returned.\n4. The put method inserts a key-value pair into the cache. If the key already exists, its value is updated, and the node is moved to the head of the linked list. If the key does not exist and the cache is at capacity, the least recently used item (at the tail of the linked list) is removed, and the new item is inserted at the head.\n5. The addToHead, removeNode, moveToHead, and removeTail methods are helper methods to manipulate the doubly linked list.\n6. The synchronized keyword is used on the get and put methods to ensure thread safety, allowing concurrent access from multiple threads.\n7. The **LRUCacheDemo** class demonstrates the usage of the LRU cache by creating an instance of LRUCache with a capacity of 3, performing various put and get operations, and printing the results."
  },
  {
    "path": "solutions/golang/lrucache/lru_cache.go",
    "content": "package lrucache\n\nimport (\n\t\"sync\"\n)\n\n// Node represents a node in the doubly linked list\ntype Node[K comparable, V any] struct {\n\tkey   K\n\tvalue V\n\tprev  *Node[K, V]\n\tnext  *Node[K, V]\n}\n\n// LRUCache represents a thread-safe LRU cache implementation\ntype LRUCache[K comparable, V any] struct {\n\tcapacity int\n\tcache    map[K]*Node[K, V]\n\thead     *Node[K, V]\n\ttail     *Node[K, V]\n\tmu       sync.RWMutex\n}\n\n// NewLRUCache creates a new LRU cache with the specified capacity\nfunc NewLRUCache[K comparable, V any](capacity int) *LRUCache[K, V] {\n\tcache := &LRUCache[K, V]{\n\t\tcapacity: capacity,\n\t\tcache:    make(map[K]*Node[K, V]),\n\t}\n\t// Initialize dummy head and tail nodes\n\tcache.head = &Node[K, V]{}\n\tcache.tail = &Node[K, V]{}\n\tcache.head.next = cache.tail\n\tcache.tail.prev = cache.head\n\treturn cache\n}\n\n// Get retrieves a value from the cache\nfunc (c *LRUCache[K, V]) Get(key K) (V, bool) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tif node, exists := c.cache[key]; exists {\n\t\tc.moveToHead(node)\n\t\treturn node.value, true\n\t}\n\n\tvar zero V\n\treturn zero, false\n}\n\n// Put adds or updates a value in the cache\nfunc (c *LRUCache[K, V]) Put(key K, value V) {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tif node, exists := c.cache[key]; exists {\n\t\tnode.value = value\n\t\tc.moveToHead(node)\n\t\treturn\n\t}\n\n\tnewNode := &Node[K, V]{\n\t\tkey:   key,\n\t\tvalue: value,\n\t}\n\tc.cache[key] = newNode\n\tc.addToHead(newNode)\n\n\tif len(c.cache) > c.capacity {\n\t\tlastNode := c.removeTail()\n\t\tdelete(c.cache, lastNode.key)\n\t}\n}\n\n// addToHead adds a node right after the head\nfunc (c *LRUCache[K, V]) addToHead(node *Node[K, V]) {\n\tnode.prev = c.head\n\tnode.next = c.head.next\n\tc.head.next.prev = node\n\tc.head.next = node\n}\n\n// removeNode removes a node from the list\nfunc (c *LRUCache[K, V]) removeNode(node *Node[K, V]) {\n\tnode.prev.next = node.next\n\tnode.next.prev = node.prev\n}\n\n// moveToHead moves an existing node to the front of the list\nfunc (c *LRUCache[K, V]) moveToHead(node *Node[K, V]) {\n\tc.removeNode(node)\n\tc.addToHead(node)\n}\n\n// removeTail removes and returns the last node before the tail\nfunc (c *LRUCache[K, V]) removeTail() *Node[K, V] {\n\tnode := c.tail.prev\n\tc.removeNode(node)\n\treturn node\n}\n\n// Size returns the current number of items in the cache\nfunc (c *LRUCache[K, V]) Size() int {\n\tc.mu.RLock()\n\tdefer c.mu.RUnlock()\n\treturn len(c.cache)\n}\n\n// Clear removes all items from the cache\nfunc (c *LRUCache[K, V]) Clear() {\n\tc.mu.Lock()\n\tdefer c.mu.Unlock()\n\n\tc.cache = make(map[K]*Node[K, V])\n\tc.head.next = c.tail\n\tc.tail.prev = c.head\n}\n"
  },
  {
    "path": "solutions/golang/lrucache/lru_cache_demo.go",
    "content": "package lrucache\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\t// Create a new cache with capacity 3\n\tlruCache := NewLRUCache[int, string](3)\n\n\t// Add some values\n\tlruCache.Put(1, \"Value 1\")\n\tlruCache.Put(2, \"Value 2\")\n\tlruCache.Put(3, \"Value 3\")\n\n\t// Get values and print them\n\tif val, exists := lruCache.Get(1); exists {\n\t\tfmt.Println(val) // Output: Value 1\n\t}\n\tif val, exists := lruCache.Get(2); exists {\n\t\tfmt.Println(val) // Output: Value 2\n\t}\n\n\t// Add a new value that should evict the least recently used one\n\tlruCache.Put(4, \"Value 4\")\n\n\t// Try to get the evicted value\n\tif val, exists := lruCache.Get(3); exists {\n\t\tfmt.Println(val)\n\t} else {\n\t\tfmt.Println(\"Value 3 was evicted\") // Output: Value 3 was evicted\n\t}\n\n\t// Get the newly added value\n\tif val, exists := lruCache.Get(4); exists {\n\t\tfmt.Println(val) // Output: Value 4\n\t}\n\n\t// Update an existing value\n\tlruCache.Put(2, \"Updated Value 2\")\n\n\t// Get the values again\n\tif val, exists := lruCache.Get(1); exists {\n\t\tfmt.Println(val) // Output: Value 1\n\t}\n\tif val, exists := lruCache.Get(2); exists {\n\t\tfmt.Println(val) // Output: Updated Value 2\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/movieticketbookingsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/airlinemanagementsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/linkedin\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/librarymanagementsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/fooddeliveryservice\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/elevatorsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/digitalwallet\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/courseregistrationsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/coffeevendingmachine\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/chessgame\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/carrentalsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/atm\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/lrucache\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/loggingframework\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/music_streaming_service\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/onlineauctionsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/onlineshopping\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/onlinestockbrokeragesystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/parkinglot\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/pubsubsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/restaurantmanagementsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/ridesharingservice\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/snake_and_ladder_game\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/social_networking_service\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/splitwise\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/stackoverflow\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/taskmanagementsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/tictactoe\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/trafficsignalsystem\"\n\t// \"github.com/ashishps1/awesome-low-level-design/solutions/golang/vending_machine\"\n)\n\nfunc main() {\n\tfmt.Println(\"Starting Projects\")\n\n\t// airlinemanagementsystem.Run()\n\t// atm.Run()\n\t// carrentalsystem.Run()\n\t// chessgame.Run()\n\t// coffeevendingmachine.Run()\n\t// concertbookingsystem.Run()\n\t// courseregistrationsystem.Run()\n\t// cricinfo.Run()\n\t// digitalwallet.Run()\n\t// elevatorsystem.Run()\n\t// fooddeliveryservice.Run()\n\t// hotelmanagement.Run()\n\t// librarymanagementsystem.Run()\n\t// linkedin.Run()\n\t// loggingframework.Run()\n\t// lrucache.Run()\n\t// movieticketbookingsystem.Run()\n\t// musicstreamingservice.Run()\n\t// onlineauctionsystem.Run()\n\t// onlineshopping.Run()\n\t// onlinestockbrokeragesystem.Run()\n\t// parkinglot.Run()\n\t// pubsubsystem.Run()\n\t// restaurantmanagementsystem.Run()\n\t// ridesharingservice.Run()\n\t// snakeandladdergame.Run()\n\t// socialnetworkingservice.Run()\n\t// splitwise.Run()\n\t// stackoverflow.Run()\n\t// taskmanagementsystem.Run()\n\t// tictactoe.Run()\n\t// trafficsignalsystem.Run()\n\t// vending_machine.Run()\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/README.md",
    "content": "# Designing a Movie Ticket Booking System like BookMyShow\n\n## Requirements\n1. The system should allow users to view the list of movies playing in different theaters.\n2. Users should be able to select a movie, theater, and show timing to book tickets.\n3. The system should display the seating arrangement of the selected show and allow users to choose seats.\n4. Users should be able to make payments and confirm their booking.\n5. The system should handle concurrent bookings and ensure seat availability is updated in real-time.\n6. The system should support different types of seats (e.g., normal, premium) and pricing.\n7. The system should allow theater administrators to add, update, and remove movies, shows, and seating arrangements.\n8. The system should be scalable to handle a large number of concurrent users and bookings.\n\n## Classes, Interfaces and Enumerations\n1. The **Movie** class represents a movie with properties such as ID, title, description, and duration.\n2. The **Theater** class represents a theater with properties such as ID, name, location, and a list of shows.\n3. The **Show** class represents a movie show in a theater, with properties such as ID, movie, theater, start time, end time, and a map of seats.\n4. The **Seat** class represents a seat in a show, with properties such as ID, row, column, type, price, and status.\n5. The **SeatType** enum defines the different types of seats (normal or premium).\n6. The **SeatStatus** enum defines the different statuses of a seat (available or booked).\n7. The **Booking** class represents a booking made by a user, with properties such as ID, user, show, selected seats, total price, and status.\n8. The **BookingStatus** enum defines the different statuses of a booking (pending, confirmed, or cancelled).\n9. The **User** class represents a user of the booking system, with properties such as ID, name, and email.\n10. The **MovieTicketBookingSystem** class is the main class that manages the movie ticket booking system. It follows the Singleton pattern to ensure only one instance of the system exists.\n11. The MovieTicketBookingSystem class provides methods for adding movies, theaters, and shows, as well as booking tickets, confirming bookings, and cancelling bookings.\n12. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap to handle concurrent access to shared resources like shows and bookings.\n13. The **MovieTicketBookingDemo** class demonstrates the usage of the movie ticket booking system by adding movies, theaters, shows, booking tickets, and confirming or cancelling bookings."
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/booking.go",
    "content": "package movieticketbookingsystem\n\nimport \"sync\"\n\ntype Booking struct {\n\tID         string\n\tUser       *User\n\tShow       *Show\n\tSeats      []*Seat\n\tTotalPrice float64\n\tStatus     BookingStatus\n\tmu         sync.RWMutex\n}\n\nfunc NewBooking(id string, user *User, show *Show, seats []*Seat, totalPrice float64, status BookingStatus) *Booking {\n\treturn &Booking{\n\t\tID:         id,\n\t\tUser:       user,\n\t\tShow:       show,\n\t\tSeats:      seats,\n\t\tTotalPrice: totalPrice,\n\t\tStatus:     status,\n\t}\n}\n\nfunc (b *Booking) GetStatus() BookingStatus {\n\tb.mu.RLock()\n\tdefer b.mu.RUnlock()\n\treturn b.Status\n}\n\nfunc (b *Booking) SetStatus(status BookingStatus) {\n\tb.mu.Lock()\n\tdefer b.mu.Unlock()\n\tb.Status = status\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/movie.go",
    "content": "package movieticketbookingsystem\n\ntype Movie struct {\n\tID              string\n\tTitle           string\n\tDescription     string\n\tDurationMinutes int\n}\n\nfunc NewMovie(id, title, description string, durationMinutes int) *Movie {\n\treturn &Movie{\n\t\tID:              id,\n\t\tTitle:           title,\n\t\tDescription:     description,\n\t\tDurationMinutes: durationMinutes,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/movie_ticket_booking_system.go",
    "content": "package movieticketbookingsystem\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\ntype MovieTicketBookingSystem struct {\n\tmovies       []*Movie\n\ttheaters     []*Theater\n\tshows        map[string]*Show\n\tbookings     map[string]*Booking\n\tmu           sync.RWMutex\n\tbookingCount int64\n}\n\nvar (\n\tinstance *MovieTicketBookingSystem\n\tonce     sync.Once\n)\n\nfunc GetBookingSystem() *MovieTicketBookingSystem {\n\tonce.Do(func() {\n\t\tinstance = &MovieTicketBookingSystem{\n\t\t\tmovies:   make([]*Movie, 0),\n\t\t\ttheaters: make([]*Theater, 0),\n\t\t\tshows:    make(map[string]*Show),\n\t\t\tbookings: make(map[string]*Booking),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (bs *MovieTicketBookingSystem) AddMovie(movie *Movie) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\tbs.movies = append(bs.movies, movie)\n}\n\nfunc (bs *MovieTicketBookingSystem) AddTheater(theater *Theater) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\tbs.theaters = append(bs.theaters, theater)\n}\n\nfunc (bs *MovieTicketBookingSystem) AddShow(show *Show) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\tbs.shows[show.ID] = show\n}\n\nfunc (bs *MovieTicketBookingSystem) GetShow(showID string) *Show {\n\tbs.mu.RLock()\n\tdefer bs.mu.RUnlock()\n\treturn bs.shows[showID]\n}\n\nfunc (bs *MovieTicketBookingSystem) BookTickets(user *User, show *Show, selectedSeats []*Seat) (*Booking, error) {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\t// Check seat availability\n\tfor _, seat := range selectedSeats {\n\t\tshowSeat, exists := show.Seats[seat.ID]\n\t\tif !exists || showSeat.GetStatus() != SeatStatusAvailable {\n\t\t\treturn nil, fmt.Errorf(\"seat %s is not available\", seat.ID)\n\t\t}\n\t}\n\n\t// Mark seats as booked\n\tfor _, seat := range selectedSeats {\n\t\tshow.Seats[seat.ID].SetStatus(SeatStatusBooked)\n\t}\n\n\t// Calculate total price\n\tvar totalPrice float64\n\tfor _, seat := range selectedSeats {\n\t\ttotalPrice += seat.GetPrice()\n\t}\n\n\t// Generate booking ID\n\tbookingID := bs.generateBookingID()\n\n\t// Create booking\n\tbooking := NewBooking(bookingID, user, show, selectedSeats, totalPrice, BookingStatusPending)\n\tbs.bookings[bookingID] = booking\n\n\treturn booking, nil\n}\n\nfunc (bs *MovieTicketBookingSystem) ConfirmBooking(bookingID string) error {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\tbooking, exists := bs.bookings[bookingID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"booking not found\")\n\t}\n\n\tif booking.GetStatus() != BookingStatusPending {\n\t\treturn fmt.Errorf(\"booking is not in pending state\")\n\t}\n\n\tbooking.SetStatus(BookingStatusConfirmed)\n\treturn nil\n}\n\nfunc (bs *MovieTicketBookingSystem) CancelBooking(bookingID string) error {\n\tbs.mu.Lock()\n\tdefer bs.mu.Unlock()\n\n\tbooking, exists := bs.bookings[bookingID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"booking not found\")\n\t}\n\n\tif booking.GetStatus() == BookingStatusCancelled {\n\t\treturn fmt.Errorf(\"booking is already cancelled\")\n\t}\n\n\tbooking.SetStatus(BookingStatusCancelled)\n\n\t// Release seats\n\tfor _, seat := range booking.Seats {\n\t\tbooking.Show.Seats[seat.ID].SetStatus(SeatStatusAvailable)\n\t}\n\n\treturn nil\n}\n\nfunc (bs *MovieTicketBookingSystem) generateBookingID() string {\n\tcount := atomic.AddInt64(&bs.bookingCount, 1)\n\treturn fmt.Sprintf(\"BKG%s%06d\", time.Now().Format(\"20060102150405\"), count)\n}\n\n// Create utility function for demo\nfunc CreateSeats(rows, columns int) map[string]*Seat {\n\tseats := make(map[string]*Seat)\n\tfor row := 1; row <= rows; row++ {\n\t\tfor col := 1; col <= columns; col++ {\n\t\t\tseatID := fmt.Sprintf(\"%d-%d\", row, col)\n\t\t\tseatType := SeatTypeNormal\n\t\t\tprice := 100.0\n\n\t\t\tif row <= 2 {\n\t\t\t\tseatType = SeatTypePremium\n\t\t\t\tprice = 150.0\n\t\t\t}\n\n\t\t\tseats[seatID] = NewSeat(\n\t\t\t\tseatID,\n\t\t\t\trow,\n\t\t\t\tcol,\n\t\t\t\tseatType,\n\t\t\t\tprice,\n\t\t\t\tSeatStatusAvailable,\n\t\t\t)\n\t\t}\n\t}\n\treturn seats\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/movie_ticket_booking_system_demo.go",
    "content": "package movieticketbookingsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\tbookingSystem := GetBookingSystem()\n\n\t// Add movies\n\tmovie1 := NewMovie(\"M1\", \"Movie 1\", \"Description 1\", 120)\n\tmovie2 := NewMovie(\"M2\", \"Movie 2\", \"Description 2\", 135)\n\tbookingSystem.AddMovie(movie1)\n\tbookingSystem.AddMovie(movie2)\n\n\t// Add theaters\n\ttheater1 := NewTheater(\"T1\", \"Theater 1\", \"Location 1\")\n\ttheater2 := NewTheater(\"T2\", \"Theater 2\", \"Location 2\")\n\tbookingSystem.AddTheater(theater1)\n\tbookingSystem.AddTheater(theater2)\n\n\t// Add shows\n\tshow1 := NewShow(\n\t\t\"S1\",\n\t\tmovie1,\n\t\ttheater1,\n\t\ttime.Now(),\n\t\ttime.Now().Add(time.Duration(movie1.DurationMinutes)*time.Minute),\n\t\tCreateSeats(10, 10),\n\t)\n\tshow2 := NewShow(\n\t\t\"S2\",\n\t\tmovie2,\n\t\ttheater2,\n\t\ttime.Now(),\n\t\ttime.Now().Add(time.Duration(movie2.DurationMinutes)*time.Minute),\n\t\tCreateSeats(8, 8),\n\t)\n\n\tbookingSystem.AddShow(show1)\n\tbookingSystem.AddShow(show2)\n\n\t// Create user\n\tuser := NewUser(\"U1\", \"John Doe\", \"john@example.com\")\n\n\t// Select seats\n\tselectedSeats := []*Seat{\n\t\tshow1.Seats[\"1-5\"],\n\t\tshow1.Seats[\"1-6\"],\n\t}\n\n\t// Book tickets\n\tbooking, err := bookingSystem.BookTickets(user, show1, selectedSeats)\n\tif err != nil {\n\t\tfmt.Printf(\"Booking failed: %v\\n\", err)\n\t\treturn\n\t}\n\n\tfmt.Printf(\"Booking successful. Booking ID: %s\\n\", booking.ID)\n\n\t// Confirm booking\n\tif err := bookingSystem.ConfirmBooking(booking.ID); err != nil {\n\t\tfmt.Printf(\"Failed to confirm booking: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(\"Booking confirmed\")\n\n\t// Cancel booking\n\tif err := bookingSystem.CancelBooking(booking.ID); err != nil {\n\t\tfmt.Printf(\"Failed to cancel booking: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"Booking canceled. Booking ID: %s\\n\", booking.ID)\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/seat.go",
    "content": "package movieticketbookingsystem\n\nimport \"sync\"\n\ntype Seat struct {\n\tID     string\n\tRow    int\n\tColumn int\n\tType   SeatType\n\tPrice  float64\n\tstatus SeatStatus\n\tmu     sync.RWMutex\n}\n\nfunc NewSeat(id string, row, column int, seatType SeatType, price float64, status SeatStatus) *Seat {\n\treturn &Seat{\n\t\tID:     id,\n\t\tRow:    row,\n\t\tColumn: column,\n\t\tType:   seatType,\n\t\tPrice:  price,\n\t\tstatus: status,\n\t}\n}\n\nfunc (s *Seat) GetStatus() SeatStatus {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn s.status\n}\n\nfunc (s *Seat) SetStatus(status SeatStatus) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.status = status\n}\n\nfunc (s *Seat) GetPrice() float64 {\n\treturn s.Price\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/show.go",
    "content": "package movieticketbookingsystem\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Show struct {\n\tID        string\n\tMovie     *Movie\n\tTheater   *Theater\n\tStartTime time.Time\n\tEndTime   time.Time\n\tSeats     map[string]*Seat\n\tmu        sync.RWMutex\n}\n\nfunc NewShow(id string, movie *Movie, theater *Theater, startTime, endTime time.Time, seats map[string]*Seat) *Show {\n\treturn &Show{\n\t\tID:        id,\n\t\tMovie:     movie,\n\t\tTheater:   theater,\n\t\tStartTime: startTime,\n\t\tEndTime:   endTime,\n\t\tSeats:     seats,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/theater.go",
    "content": "package movieticketbookingsystem\n\ntype Theater struct {\n\tID       string\n\tName     string\n\tLocation string\n\tShows    []*Show\n}\n\nfunc NewTheater(id, name, location string) *Theater {\n\treturn &Theater{\n\t\tID:       id,\n\t\tName:     name,\n\t\tLocation: location,\n\t\tShows:    make([]*Show, 0),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/types.go",
    "content": "package movieticketbookingsystem\n\ntype SeatType int\ntype SeatStatus int\ntype BookingStatus int\n\nconst (\n\tSeatTypeNormal SeatType = iota\n\tSeatTypePremium\n)\n\nconst (\n\tSeatStatusAvailable SeatStatus = iota\n\tSeatStatusBooked\n)\n\nconst (\n\tBookingStatusPending BookingStatus = iota\n\tBookingStatusConfirmed\n\tBookingStatusCancelled\n)\n"
  },
  {
    "path": "solutions/golang/movieticketbookingsystem/user.go",
    "content": "package movieticketbookingsystem\n\ntype User struct {\n\tID    string\n\tName  string\n\tEmail string\n}\n\nfunc NewUser(id, name, email string) *User {\n\treturn &User{\n\t\tID:    id,\n\t\tName:  name,\n\t\tEmail: email,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/README.md",
    "content": "# Designing an Online Music Streaming Service Like Spotify\n\n## Requirements\n1. The music streaming service should allow users to browse and search for songs, albums, and artists.\n2. Users should be able to create and manage playlists.\n3. The system should support user authentication and authorization.\n4. Users should be able to play, pause, skip, and seek within songs.\n5. The system should recommend songs and playlists based on user preferences and listening history.\n6. The system should handle concurrent requests and ensure smooth streaming experience for multiple users.\n7. The system should be scalable and handle a large volume of songs and users.\n8. The system should be extensible to support additional features such as social sharing and offline playback.\n\n## Classes, Interfaces and Enumerations\n1. The **Song**, **Album**, and **Artist** classes represent the basic entities in the music streaming service, with properties such as ID, title, artist, album, duration, and relationships between them.\n2. The **User** class represents a user of the music streaming service, with properties like ID, username, password, and a list of playlists.\n3. The **Playlist** class represents a user-created playlist, containing a list of songs.\n4. The **MusicLibrary** class serves as a central repository for storing and managing songs, albums, and artists. It follows the Singleton pattern to ensure a single instance of the music library.\n5. The **UserManager** class handles user registration, login, and other user-related operations. It also follows the Singleton pattern.\n6. The **MusicPlayer** class represents the music playback functionality, allowing users to play, pause, skip, and seek within songs.\n7. The **MusicRecommender** class generates song recommendations based on user preferences and listening history. It follows the Singleton pattern.\n8. The **MusicStreamingService** class is the main entry point of the music streaming service. It initializes the necessary components, handles user requests, and manages the overall functionality of the service."
  },
  {
    "path": "solutions/golang/musicstreamingservice/album.go",
    "content": "package musicstreamingservice\n\ntype Album struct {\n\tID     string\n\tTitle  string\n\tArtist string\n\tSongs  []*Song\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/artist.go",
    "content": "package musicstreamingservice\n\ntype Artist struct {\n\tID     string\n\tName   string\n\tAlbums []*Album\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/music_library.go",
    "content": "package musicstreamingservice\n\nimport (\n\t\"strings\"\n\t\"sync\"\n)\n\ntype MusicLibrary struct {\n\tsongs   map[string]*Song\n\talbums  map[string]*Album\n\tartists map[string]*Artist\n\tmu      sync.RWMutex\n}\n\nvar (\n\tlibraryInstance *MusicLibrary\n\tlibraryOnce     sync.Once\n)\n\nfunc GetMusicLibrary() *MusicLibrary {\n\tlibraryOnce.Do(func() {\n\t\tlibraryInstance = &MusicLibrary{\n\t\t\tsongs:   make(map[string]*Song),\n\t\t\talbums:  make(map[string]*Album),\n\t\t\tartists: make(map[string]*Artist),\n\t\t}\n\t})\n\treturn libraryInstance\n}\n\nfunc (ml *MusicLibrary) AddSong(song *Song) {\n\tml.mu.Lock()\n\tdefer ml.mu.Unlock()\n\tml.songs[song.ID] = song\n}\n\nfunc (ml *MusicLibrary) AddAlbum(album *Album) {\n\tml.mu.Lock()\n\tdefer ml.mu.Unlock()\n\tml.albums[album.ID] = album\n\tfor _, song := range album.Songs {\n\t\tml.songs[song.ID] = song\n\t}\n}\n\nfunc (ml *MusicLibrary) AddArtist(artist *Artist) {\n\tml.mu.Lock()\n\tdefer ml.mu.Unlock()\n\tml.artists[artist.ID] = artist\n\tfor _, album := range artist.Albums {\n\t\tml.albums[album.ID] = album\n\t\tfor _, song := range album.Songs {\n\t\t\tml.songs[song.ID] = song\n\t\t}\n\t}\n}\n\nfunc (ml *MusicLibrary) SearchSongs(query string) []*Song {\n\tml.mu.RLock()\n\tdefer ml.mu.RUnlock()\n\n\tquery = strings.ToLower(query)\n\tvar results []*Song\n\n\tfor _, song := range ml.songs {\n\t\tif strings.Contains(strings.ToLower(song.Title), query) ||\n\t\t\tstrings.Contains(strings.ToLower(song.Artist), query) ||\n\t\t\tstrings.Contains(strings.ToLower(song.Album), query) {\n\t\t\tresults = append(results, song)\n\t\t}\n\t}\n\treturn results\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/music_player.go",
    "content": "package musicstreamingservice\n\nimport \"sync\"\n\ntype MusicPlayer struct {\n\tCurrentSong *Song\n\tIsPlaying   bool\n\tCurrentTime int\n\tmu          sync.Mutex\n}\n\nfunc NewMusicPlayer() *MusicPlayer {\n\treturn &MusicPlayer{}\n}\n\nfunc (p *MusicPlayer) PlaySong(song *Song) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.CurrentSong = song\n\tp.IsPlaying = true\n\tp.CurrentTime = 0\n\t// Implement actual playback logic here\n}\n\nfunc (p *MusicPlayer) PauseSong() {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.IsPlaying = false\n\t// Implement actual pause logic here\n}\n\nfunc (p *MusicPlayer) SeekTo(time int) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.CurrentTime = time\n\t// Implement actual seek logic here\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/music_recommender.go",
    "content": "package musicstreamingservice\n\nimport (\n\t\"sync\"\n)\n\ntype MusicRecommender struct {\n\tuserRecommendations map[string][]*Song\n\tmu                  sync.RWMutex\n}\n\nvar (\n\trecommenderInstance *MusicRecommender\n\trecommenderOnce     sync.Once\n)\n\nfunc GetMusicRecommender() *MusicRecommender {\n\trecommenderOnce.Do(func() {\n\t\trecommenderInstance = &MusicRecommender{\n\t\t\tuserRecommendations: make(map[string][]*Song),\n\t\t}\n\t})\n\treturn recommenderInstance\n}\n\nfunc (mr *MusicRecommender) RecommendSongs(user *User) []*Song {\n\tmr.mu.RLock()\n\tdefer mr.mu.RUnlock()\n\n\tif recommendations, exists := mr.userRecommendations[user.ID]; exists {\n\t\treturn recommendations\n\t}\n\treturn make([]*Song, 0)\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/music_streaming_service.go",
    "content": "package musicstreamingservice\n\ntype MusicStreamingService struct {\n\tMusicLibrary     *MusicLibrary\n\tUserManager      *UserManager\n\tMusicRecommender *MusicRecommender\n}\n\nfunc NewMusicStreamingService() *MusicStreamingService {\n\treturn &MusicStreamingService{\n\t\tMusicLibrary:     GetMusicLibrary(),\n\t\tUserManager:      GetUserManager(),\n\t\tMusicRecommender: GetMusicRecommender(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/music_streaming_service_demo.go",
    "content": "package musicstreamingservice\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tservice := NewMusicStreamingService()\n\n\t// Create users\n\tuser1 := NewUser(\"1\", \"john@example.com\", \"password123\")\n\tuser2 := NewUser(\"2\", \"jane@example.com\", \"password456\")\n\n\t// Create songs\n\tsong1 := &Song{ID: \"1\", Title: \"Song 1\", Artist: \"Artist 1\", Album: \"Album 1\", Duration: 180}\n\tsong2 := &Song{ID: \"2\", Title: \"Song 2\", Artist: \"Artist 2\", Album: \"Album 2\", Duration: 200}\n\tsong3 := &Song{ID: \"3\", Title: \"Song 3\", Artist: \"Artist 3\", Album: \"Album 3\", Duration: 210}\n\n\t// Create albums\n\talbum1 := &Album{ID: \"1\", Title: \"Album 1\", Artist: \"Artist 1\", Songs: []*Song{song1}}\n\talbum2 := &Album{ID: \"2\", Title: \"Album 2\", Artist: \"Artist 2\", Songs: []*Song{song2}}\n\talbum3 := &Album{ID: \"3\", Title: \"Album 3\", Artist: \"Artist 3\", Songs: []*Song{song3}}\n\n\t// Create artists\n\tartist1 := &Artist{ID: \"1\", Name: \"Artist 1\", Albums: []*Album{album1}}\n\tartist2 := &Artist{ID: \"2\", Name: \"Artist 2\", Albums: []*Album{album2}}\n\tartist3 := &Artist{ID: \"3\", Name: \"Artist 3\", Albums: []*Album{album3}}\n\n\t// Add artists to library\n\tservice.MusicLibrary.AddArtist(artist1)\n\tservice.MusicLibrary.AddArtist(artist2)\n\tservice.MusicLibrary.AddArtist(artist3)\n\n\t// Register users\n\tservice.UserManager.RegisterUser(user1)\n\tservice.UserManager.RegisterUser(user2)\n\n\t// Login user\n\tloggedInUser := service.UserManager.LoginUser(\"john@example.com\", \"password123\")\n\tif loggedInUser != nil {\n\t\tfmt.Printf(\"User logged in: %s\\n\", loggedInUser.Username)\n\t} else {\n\t\tfmt.Println(\"Invalid username or password.\")\n\t}\n\n\t// Search songs\n\tsearchResults := service.MusicLibrary.SearchSongs(\"Song\")\n\tfmt.Println(\"\\nSearch Results:\")\n\tfor _, song := range searchResults {\n\t\tfmt.Printf(\"Song: %s - %s\\n\", song.Title, song.Artist)\n\t}\n\n\t// Create playlist\n\tplaylist := NewPlaylist(\"1\", \"My Playlist\", loggedInUser)\n\tplaylist.AddSong(song1)\n\tplaylist.AddSong(song2)\n\tloggedInUser.AddPlaylist(playlist)\n\n\t// Get recommendations\n\trecommendations := service.MusicRecommender.RecommendSongs(loggedInUser)\n\tfmt.Println(\"\\nRecommended Songs:\")\n\tfor _, song := range recommendations {\n\t\tfmt.Printf(\"Song: %s - %s\\n\", song.Title, song.Artist)\n\t}\n\n\t// Create and use music player\n\tplayer := NewMusicPlayer()\n\tplayer.PlaySong(song1)\n\tplayer.PauseSong()\n\tplayer.SeekTo(60)\n\n\t// Display user playlists\n\tfmt.Println(\"\\nUser Playlists:\")\n\tfor _, p := range loggedInUser.Playlists {\n\t\tfmt.Printf(\"Playlist: %s\\n\", p.Name)\n\t\tfmt.Println(\"Songs:\")\n\t\tfor _, s := range p.Songs {\n\t\t\tfmt.Printf(\"- %s\\n\", s.Title)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/playlist.go",
    "content": "package musicstreamingservice\n\ntype Playlist struct {\n\tID    string\n\tName  string\n\tOwner *User\n\tSongs []*Song\n}\n\nfunc NewPlaylist(id, name string, owner *User) *Playlist {\n\treturn &Playlist{\n\t\tID:    id,\n\t\tName:  name,\n\t\tOwner: owner,\n\t\tSongs: make([]*Song, 0),\n\t}\n}\n\nfunc (p *Playlist) AddSong(song *Song) {\n\tp.Songs = append(p.Songs, song)\n}\n\nfunc (p *Playlist) RemoveSong(song *Song) {\n\tfor i, s := range p.Songs {\n\t\tif s.ID == song.ID {\n\t\t\tp.Songs = append(p.Songs[:i], p.Songs[i+1:]...)\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/song.go",
    "content": "package musicstreamingservice\n\ntype Song struct {\n\tID       string\n\tTitle    string\n\tArtist   string\n\tAlbum    string\n\tDuration int\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/user.go",
    "content": "package musicstreamingservice\n\nimport \"sync\"\n\ntype User struct {\n\tID        string\n\tUsername  string\n\tPassword  string\n\tPlaylists []*Playlist\n\tmu        sync.RWMutex\n}\n\nfunc NewUser(id, username, password string) *User {\n\treturn &User{\n\t\tID:        id,\n\t\tUsername:  username,\n\t\tPassword:  password,\n\t\tPlaylists: make([]*Playlist, 0),\n\t}\n}\n\nfunc (u *User) AddPlaylist(playlist *Playlist) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.Playlists = append(u.Playlists, playlist)\n}\n\nfunc (u *User) RemovePlaylist(playlist *Playlist) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tfor i, p := range u.Playlists {\n\t\tif p.ID == playlist.ID {\n\t\t\tu.Playlists = append(u.Playlists[:i], u.Playlists[i+1:]...)\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/musicstreamingservice/userManager.go",
    "content": "package musicstreamingservice\n\nimport (\n\t\"sync\"\n)\n\ntype UserManager struct {\n\tusers map[string]*User\n\tmu    sync.RWMutex\n}\n\nvar (\n\tuserManagerInstance *UserManager\n\tuserManagerOnce     sync.Once\n)\n\nfunc GetUserManager() *UserManager {\n\tuserManagerOnce.Do(func() {\n\t\tuserManagerInstance = &UserManager{\n\t\t\tusers: make(map[string]*User),\n\t\t}\n\t})\n\treturn userManagerInstance\n}\n\nfunc (um *UserManager) RegisterUser(user *User) {\n\tum.mu.Lock()\n\tdefer um.mu.Unlock()\n\tum.users[user.ID] = user\n}\n\nfunc (um *UserManager) LoginUser(username, password string) *User {\n\tum.mu.RLock()\n\tdefer um.mu.RUnlock()\n\n\tfor _, user := range um.users {\n\t\tif user.Username == username && user.Password == password {\n\t\t\treturn user\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/README.md",
    "content": "# Designing an Online Auction System\nIn this article, we delve into the object-oriented design and implementation of an Online Auction System using Java. \n\nThis system allows for the creation and management of auctions, user participation in bidding, and handling transactions.\n\n## Requirements\n1. The online auction system should allow users to register and log in to their accounts.\n2. Users should be able to create new auction listings with details such as item name, description, starting price, and auction duration.\n3. Users should be able to browse and search for auction listings based on various criteria (e.g., item name, category, price range).\n4. Users should be able to place bids on active auction listings.\n5. The system should automatically update the current highest bid and notify the bidders accordingly.\n6. The auction should end when the specified duration is reached, and the highest bidder should be declared the winner.\n7. The system should handle concurrent access to auction listings and ensure data consistency.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online auction system, with properties such as id, username, and email.\n2. The **AuctionStatus** enum defines the possible states of an auction listing, such as active and closed.\n3. The **AuctionListing** class represents an auction listing in the system, with properties like id, item name, description, starting price, duration, seller, current highest bid, and a list of bids.\n4. The **Bid** class represents a bid placed by a user on an auction listing, with properties such as id, bidder, amount, and timestamp.\n5. The **AuctionSystem** class is the core of the online auction system and follows the Singleton pattern to ensure a single instance of the auction system.\n6. The AuctionSystem class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to auction listings and ensure thread safety.\n7. The AuctionSystem class provides methods for registering users, creating auction listings, searching auction listings, and placing bids.\n8. The **AuctionSystemDemo** class serves as the entry point of the application and demonstrates the usage of the online auction system."
  },
  {
    "path": "solutions/golang/onlineauctionsystem/auction_listing.go",
    "content": "package onlineauctionsystem\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype AuctionListing struct {\n\tID                   string\n\tItemName             string\n\tDescription          string\n\tStartingPrice        float64\n\tDuration             time.Duration\n\tSeller               *User\n\tStatus               AuctionStatus\n\tCurrentHighestBid    float64\n\tCurrentHighestBidder *User\n\tBids                 []*Bid\n\tmu                   sync.Mutex\n\tobservers            []chan struct{} // Simple channel-based observer pattern\n}\n\nfunc NewAuctionListing(id, itemName, description string, startingPrice float64, duration time.Duration, seller *User) *AuctionListing {\n\treturn &AuctionListing{\n\t\tID:                id,\n\t\tItemName:          itemName,\n\t\tDescription:       description,\n\t\tStartingPrice:     startingPrice,\n\t\tDuration:          duration,\n\t\tSeller:            seller,\n\t\tStatus:            StatusActive,\n\t\tCurrentHighestBid: startingPrice,\n\t\tBids:              make([]*Bid, 0),\n\t\tobservers:         make([]chan struct{}, 0),\n\t}\n}\n\nfunc (a *AuctionListing) PlaceBid(bid *Bid) bool {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.Status == StatusActive && bid.Amount > a.CurrentHighestBid {\n\t\ta.CurrentHighestBid = bid.Amount\n\t\ta.CurrentHighestBidder = bid.Bidder\n\t\ta.Bids = append(a.Bids, bid)\n\t\ta.notifyObservers()\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (a *AuctionListing) CloseAuction() {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.Status == StatusActive {\n\t\ta.Status = StatusClosed\n\t\ta.notifyObservers()\n\t}\n}\n\nfunc (a *AuctionListing) notifyObservers() {\n\tfor _, observer := range a.observers {\n\t\tselect {\n\t\tcase observer <- struct{}{}: // Non-blocking send\n\t\tdefault:\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/auction_status.go",
    "content": "package onlineauctionsystem\n\ntype AuctionStatus int\n\nconst (\n\tStatusActive AuctionStatus = iota\n\tStatusClosed\n)\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/auction_system.go",
    "content": "package onlineauctionsystem\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype AuctionSystem struct {\n\tusers           map[string]*User\n\tauctionListings map[string]*AuctionListing\n\tmu              sync.RWMutex\n}\n\nvar (\n\tinstance *AuctionSystem\n\tonce     sync.Once\n)\n\nfunc GetInstance() *AuctionSystem {\n\tonce.Do(func() {\n\t\tinstance = &AuctionSystem{\n\t\t\tusers:           make(map[string]*User),\n\t\t\tauctionListings: make(map[string]*AuctionListing),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (as *AuctionSystem) RegisterUser(user *User) {\n\tas.mu.Lock()\n\tdefer as.mu.Unlock()\n\tas.users[user.ID] = user\n}\n\nfunc (as *AuctionSystem) GetUser(userID string) *User {\n\tas.mu.RLock()\n\tdefer as.mu.RUnlock()\n\treturn as.users[userID]\n}\n\nfunc (as *AuctionSystem) CreateAuctionListing(listing *AuctionListing) {\n\tas.mu.Lock()\n\tas.auctionListings[listing.ID] = listing\n\tas.mu.Unlock()\n\n\t// Start auction timer\n\tgo func() {\n\t\ttime.Sleep(listing.Duration)\n\t\tlisting.CloseAuction()\n\t}()\n}\n\nfunc (as *AuctionSystem) SearchAuctionListings(keyword string) []*AuctionListing {\n\tas.mu.RLock()\n\tdefer as.mu.RUnlock()\n\n\tvar matchingListings []*AuctionListing\n\tkeyword = strings.ToLower(keyword)\n\n\tfor _, listing := range as.auctionListings {\n\t\tif strings.Contains(strings.ToLower(listing.ItemName), keyword) ||\n\t\t\tstrings.Contains(strings.ToLower(listing.Description), keyword) {\n\t\t\tmatchingListings = append(matchingListings, listing)\n\t\t}\n\t}\n\treturn matchingListings\n}\n\nfunc (as *AuctionSystem) PlaceBid(auctionListingID string, bid *Bid) bool {\n\tas.mu.RLock()\n\tlisting, exists := as.auctionListings[auctionListingID]\n\tas.mu.RUnlock()\n\n\tif exists {\n\t\treturn listing.PlaceBid(bid)\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/bid.go",
    "content": "package onlineauctionsystem\n\nimport \"time\"\n\ntype Bid struct {\n\tID        string\n\tBidder    *User\n\tAmount    float64\n\tTimestamp time.Time\n}\n\nfunc NewBid(id string, bidder *User, amount float64) *Bid {\n\treturn &Bid{\n\t\tID:        id,\n\t\tBidder:    bidder,\n\t\tAmount:    amount,\n\t\tTimestamp: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/main.go",
    "content": "package onlineauctionsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\tauctionSystem := GetInstance()\n\n\t// Register users\n\tuser1 := NewUser(\"1\", \"John Doe\", \"john@example.com\")\n\tuser2 := NewUser(\"2\", \"Jane Smith\", \"jane@example.com\")\n\tauctionSystem.RegisterUser(user1)\n\tauctionSystem.RegisterUser(user2)\n\n\t// Create auction listings\n\tlisting1 := NewAuctionListing(\"1\", \"Item 1\", \"Description 1\", 100.0, 60*time.Second, user1)\n\tlisting2 := NewAuctionListing(\"2\", \"Item 2\", \"Description 2\", 50.0, 120*time.Second, user2)\n\tauctionSystem.CreateAuctionListing(listing1)\n\tauctionSystem.CreateAuctionListing(listing2)\n\n\t// Search auction listings\n\tsearchResults := auctionSystem.SearchAuctionListings(\"Item\")\n\tfmt.Println(\"Search Results:\")\n\tfor _, listing := range searchResults {\n\t\tfmt.Println(listing.ItemName)\n\t}\n\n\t// Place bids\n\tbid1 := NewBid(\"1\", user2, 150.0)\n\tbid2 := NewBid(\"2\", user1, 200.0)\n\tauctionSystem.PlaceBid(listing1.ID, bid1)\n\tauctionSystem.PlaceBid(listing1.ID, bid2)\n\n\t// Wait for a while to see the auction close\n\ttime.Sleep(65 * time.Second)\n\tfmt.Printf(\"Auction 1 status: %v\\n\", listing1.Status)\n}\n"
  },
  {
    "path": "solutions/golang/onlineauctionsystem/user.go",
    "content": "package onlineauctionsystem\n\ntype User struct {\n\tID       string\n\tUsername string\n\tEmail    string\n}\n\nfunc NewUser(id, username, email string) *User {\n\treturn &User{\n\t\tID:       id,\n\t\tUsername: username,\n\t\tEmail:    email,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/README.md",
    "content": "# Designing an Online Shopping System Like Amazon\n\n## Requirements\n1. The online shopping service should allow users to browse products, add them to the shopping cart, and place orders.\n2. The system should support multiple product categories and provide search functionality.\n3. Users should be able to manage their profiles, view order history, and track order status.\n4. The system should handle inventory management and update product availability accordingly.\n5. The system should support multiple payment methods and ensure secure transactions.\n6. The system should handle concurrent user requests and ensure data consistency.\n7. The system should be scalable to handle a large number of products and users.\n8. The system should provide a user-friendly interface for a seamless shopping experience.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online shopping service, with properties such as ID, name, email, password, and a list of orders.\n2. The **Product** class represents a product available for purchase, with properties like ID, name, description, price, and quantity. It provides methods to update the quantity and check product availability.\n3. The **Order** class represents an order placed by a user, containing properties such as ID, user, order items, total amount, and order status. It calculates the total amount based on the order items.\n4. The **OrderItem** class represents an item within an order, consisting of the product and the quantity ordered.\n5. The **OrderStatus** enum represents the different statuses an order can have, such as pending, processing, shipped, delivered, or cancelled.\n6. The **ShoppingCart** class represents the user's shopping cart, allowing them to add, remove, and update item quantities. It maintains a map of product IDs and order items.\n7. The **Payment** interface defines the contract for processing payments, with a concrete implementation CreditCardPayment.\n8. The **OnlineShoppingService** class is the central component of the online shopping service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register users, add products, search products, place orders, and retrieve order information. It handles concurrent access to shared resources using synchronization.\n9. The **OnlineShoppingServiceDemo** class demonstrates the usage of the online shopping service by registering users, adding products, searching for products, placing orders, and viewing order history."
  },
  {
    "path": "solutions/golang/onlineshoppingservice/credit_card_payment.go",
    "content": "package onlineshopping\n\ntype CreditCardPayment struct{}\n\nfunc (c *CreditCardPayment) ProcessPayment(amount float64) bool {\n\treturn true\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/online_shopping_service.go",
    "content": "package onlineshopping\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype OnlineShoppingService struct {\n\tUsers    map[string]*User\n\tProducts map[string]*Product\n\tOrders   map[string]*Order\n}\n\nvar instance *OnlineShoppingService\n\nfunc GetInstance() *OnlineShoppingService {\n\tif instance == nil {\n\t\tinstance = &OnlineShoppingService{\n\t\t\tUsers:    make(map[string]*User),\n\t\t\tProducts: make(map[string]*Product),\n\t\t\tOrders:   make(map[string]*Order),\n\t\t}\n\t}\n\treturn instance\n}\n\nfunc (s *OnlineShoppingService) RegisterUser(user *User) {\n\ts.Users[user.ID] = user\n}\n\nfunc (s *OnlineShoppingService) AddProduct(product *Product) {\n\ts.Products[product.ID] = product\n}\n\nfunc (s *OnlineShoppingService) SearchProducts(keyword string) []*Product {\n\tvar results []*Product\n\tfor _, product := range s.Products {\n\t\tif strings.Contains(strings.ToLower(product.Name), strings.ToLower(keyword)) {\n\t\t\tresults = append(results, product)\n\t\t}\n\t}\n\treturn results\n}\n\nfunc (s *OnlineShoppingService) PlaceOrder(user *User, cart *ShoppingCart, paymentMethod Payment) (*Order, error) {\n\tvar orderItems []OrderItem\n\tfor _, item := range cart.GetItems() {\n\t\tproduct := item.Product\n\t\tquantity := item.Quantity\n\t\tif product.IsAvailable(quantity) {\n\t\t\tproduct.UpdateQuantity(-quantity)\n\t\t\torderItems = append(orderItems, item)\n\t\t}\n\t}\n\n\tif len(orderItems) == 0 {\n\t\treturn nil, errors.New(\"no available products in the cart\")\n\t}\n\n\torder := NewOrder(fmt.Sprintf(\"ORDER-%s\", user.ID), user, orderItems)\n\ts.Orders[order.ID] = order\n\tuser.AddOrder(*order)\n\tcart.Clear()\n\n\tif paymentMethod.ProcessPayment(order.TotalAmount) {\n\t\torder.SetStatus(Processing)\n\t} else {\n\t\torder.SetStatus(Cancelled)\n\t\tfor _, item := range orderItems {\n\t\t\titem.Product.UpdateQuantity(item.Quantity)\n\t\t}\n\t}\n\n\treturn order, nil\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/online_shopping_service_demo.go",
    "content": "package onlineshopping\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tshoppingService := GetInstance()\n\n\tuser1 := NewUser(\"U001\", \"John Doe\", \"john@example.com\", \"password123\")\n\tuser2 := NewUser(\"U002\", \"Jane Smith\", \"jane@example.com\", \"password456\")\n\tshoppingService.RegisterUser(user1)\n\tshoppingService.RegisterUser(user2)\n\n\tproduct1 := NewProduct(\"P001\", \"Smartphone\", \"High-end smartphone\", 999.99, 10)\n\tproduct2 := NewProduct(\"P002\", \"Laptop\", \"Powerful gaming laptop\", 1999.99, 5)\n\tshoppingService.AddProduct(product1)\n\tshoppingService.AddProduct(product2)\n\n\tcart1 := NewShoppingCart()\n\tcart1.AddItem(product1, 2)\n\tcart1.AddItem(product2, 1)\n\tpayment1 := &CreditCardPayment{}\n\torder1, err := shoppingService.PlaceOrder(user1, cart1, payment1)\n\tif err == nil {\n\t\tfmt.Println(\"Order placed:\", order1.ID)\n\t} else {\n\t\tfmt.Println(\"Failed to place order:\", err)\n\t}\n\n\tsearchResults := shoppingService.SearchProducts(\"laptop\")\n\tfmt.Println(\"Search Results:\")\n\tfor _, product := range searchResults {\n\t\tfmt.Println(product.Name)\n\t}\n\n\tcart2 := NewShoppingCart()\n\tcart2.AddItem(searchResults[0], 1)\n\tpayment2 := &CreditCardPayment{}\n\torder2, err := shoppingService.PlaceOrder(user2, cart2, payment2)\n\tif err == nil {\n\t\tfmt.Println(\"Order placed:\", order2.ID)\n\t} else {\n\t\tfmt.Println(\"Failed to place order:\", err)\n\t}\n\n\tfmt.Println(\"User 1 Order History:\")\n\tfor _, order := range user1.Orders {\n\t\tfmt.Printf(\"Order ID: %s, Total Amount: $%.2f, Status: %v\\n\", order.ID, order.TotalAmount, order.Status)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/order.go",
    "content": "package onlineshopping\n\ntype Order struct {\n\tID          string\n\tUser        *User\n\tItems       []OrderItem\n\tTotalAmount float64\n\tStatus      OrderStatus\n}\n\nfunc NewOrder(id string, user *User, items []OrderItem) *Order {\n\torder := &Order{\n\t\tID:     id,\n\t\tUser:   user,\n\t\tItems:  items,\n\t\tStatus: Pending,\n\t}\n\torder.TotalAmount = order.calculateTotalAmount()\n\treturn order\n}\n\nfunc (o *Order) calculateTotalAmount() float64 {\n\ttotal := 0.0\n\tfor _, item := range o.Items {\n\t\ttotal += item.Product.Price * float64(item.Quantity)\n\t}\n\treturn total\n}\n\nfunc (o *Order) SetStatus(status OrderStatus) {\n\to.Status = status\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/order_item.go",
    "content": "package onlineshopping\n\ntype OrderItem struct {\n\tProduct  *Product\n\tQuantity int\n}\n\nfunc NewOrderItem(product *Product, quantity int) OrderItem {\n\treturn OrderItem{Product: product, Quantity: quantity}\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/order_status.go",
    "content": "package onlineshopping\n\ntype OrderStatus int\n\nconst (\n\tPending OrderStatus = iota\n\tProcessing\n\tShipped\n\tDelivered\n\tCancelled\n)\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/payment.go",
    "content": "package onlineshopping\n\ntype Payment interface {\n\tProcessPayment(amount float64) bool\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/product.go",
    "content": "package onlineshopping\n\ntype Product struct {\n\tID          string\n\tName        string\n\tDescription string\n\tPrice       float64\n\tQuantity    int\n}\n\nfunc NewProduct(id, name, description string, price float64, quantity int) *Product {\n\treturn &Product{\n\t\tID:          id,\n\t\tName:        name,\n\t\tDescription: description,\n\t\tPrice:       price,\n\t\tQuantity:    quantity,\n\t}\n}\n\nfunc (p *Product) UpdateQuantity(quantity int) {\n\tp.Quantity += quantity\n}\n\nfunc (p *Product) IsAvailable(quantity int) bool {\n\treturn p.Quantity >= quantity\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/shopping_cart.go",
    "content": "package onlineshopping\n\ntype ShoppingCart struct {\n\titems map[string]OrderItem\n}\n\nfunc NewShoppingCart() *ShoppingCart {\n\treturn &ShoppingCart{items: make(map[string]OrderItem)}\n}\n\nfunc (c *ShoppingCart) AddItem(product *Product, quantity int) {\n\titem := c.items[product.ID]\n\titem.Quantity += quantity\n\tc.items[product.ID] = OrderItem{Product: product, Quantity: item.Quantity}\n}\n\nfunc (c *ShoppingCart) RemoveItem(productId string) {\n\tdelete(c.items, productId)\n}\n\nfunc (c *ShoppingCart) GetItems() []OrderItem {\n\titems := []OrderItem{}\n\tfor _, item := range c.items {\n\t\titems = append(items, item)\n\t}\n\treturn items\n}\n\nfunc (c *ShoppingCart) Clear() {\n\tc.items = make(map[string]OrderItem)\n}\n"
  },
  {
    "path": "solutions/golang/onlineshoppingservice/user.go",
    "content": "package onlineshopping\n\ntype User struct {\n\tID       string\n\tName     string\n\tEmail    string\n\tPassword string\n\tOrders   []Order\n}\n\nfunc NewUser(id, name, email, password string) *User {\n\treturn &User{\n\t\tID:       id,\n\t\tName:     name,\n\t\tEmail:    email,\n\t\tPassword: password,\n\t\tOrders:   []Order{},\n\t}\n}\n\nfunc (u *User) AddOrder(order Order) {\n\tu.Orders = append(u.Orders, order)\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/README.md",
    "content": "# Designing an Online Stock Brokerage System\n\n## Requirements\n1. The online stock brokerage system should allow users to create and manage their trading accounts.\n2. Users should be able to buy and sell stocks, as well as view their portfolio and transaction history.\n3. The system should provide real-time stock quotes and market data to users.\n4. The system should handle order placement, execution, and settlement processes.\n5. The system should enforce various business rules and validations, such as checking account balances and stock availability.\n6. The system should handle concurrent user requests and ensure data consistency and integrity.\n7. The system should be scalable and able to handle a large number of users and transactions.\n8. The system should be secure and protect sensitive user information.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the stock brokerage system, with properties such as user ID, name, and email.\n2. The **Account** class represents a user's trading account, with properties like account ID, associated user, and balance. It provides methods for depositing and withdrawing funds.\n3. The **Stock** class represents a stock that can be traded, with properties such as symbol, name, and price. It provides a method for updating the stock price.\n4. The **Order** class is an abstract base class representing an order placed by a user. It contains common properties such as order ID, associated account, stock, quantity, price, and order status. The execute() method is declared as abstract, to be implemented by concrete order classes.\n5. The **BuyOrder** and **SellOrder** classes are concrete implementations of the Order class, representing buy and sell orders respectively. They provide the implementation for the execute() method specific to each order type.\n6. The **OrderStatus** enum represents the possible statuses of an order, such as PENDING, EXECUTED, or REJECTED.\n7. The **Portfolio** class represents a user's portfolio, which holds the stocks owned by the user. It provides methods for adding and removing stocks from the portfolio.\n8. The **StockBroker** class is the central component of the stock brokerage system. It follows the Singleton pattern to ensure a single instance of the stock broker. It manages user accounts, stocks, and order processing. It provides methods for creating accounts, adding stocks, placing orders, and processing orders.\n9. The **InsufficientFundsException** and **InsufficientStockException** classes are custom exceptions used to handle insufficient funds and insufficient stock scenarios respectively.\n10. The **StockBrokerageSystem** class serves as the entry point of the application and demonstrates the usage of the stock brokerage system."
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/account.go",
    "content": "package onlinestockbrokeragesystem\n\nimport \"sync\"\n\ntype Account struct {\n\tAccountID string\n\tUser      *User\n\tbalance   float64\n\tPortfolio *Portfolio\n\tmu        sync.RWMutex\n}\n\nfunc NewAccount(accountID string, user *User, initialBalance float64) *Account {\n\taccount := &Account{\n\t\tAccountID: accountID,\n\t\tUser:      user,\n\t\tbalance:   initialBalance,\n\t}\n\taccount.Portfolio = NewPortfolio(account)\n\treturn account\n}\n\nfunc (a *Account) Deposit(amount float64) {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\ta.balance += amount\n}\n\nfunc (a *Account) Withdraw(amount float64) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.balance < amount {\n\t\treturn NewInsufficientFundsError(\"insufficient funds in account\")\n\t}\n\n\ta.balance -= amount\n\treturn nil\n}\n\nfunc (a *Account) GetBalance() float64 {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\treturn a.balance\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/buy_order.go",
    "content": "package onlinestockbrokeragesystem\n\ntype BuyOrder struct {\n\tBaseOrder\n}\n\nfunc NewBuyOrder(orderID string, account *Account, stock *Stock, quantity int, price float64) *BuyOrder {\n\treturn &BuyOrder{\n\t\tBaseOrder: BaseOrder{\n\t\t\tOrderID:  orderID,\n\t\t\tAccount:  account,\n\t\t\tStock:    stock,\n\t\t\tQuantity: quantity,\n\t\t\tPrice:    price,\n\t\t\tStatus:   OrderStatusPending,\n\t\t},\n\t}\n}\n\nfunc (o *BuyOrder) Execute() error {\n\ttotalCost := float64(o.Quantity) * o.Price\n\n\tif err := o.Account.Withdraw(totalCost); err != nil {\n\t\to.Status = OrderStatusRejected\n\t\treturn err\n\t}\n\n\to.Account.Portfolio.AddStock(o.Stock, o.Quantity)\n\to.Status = OrderStatusExecuted\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/exceptions.go",
    "content": "package onlinestockbrokeragesystem\n\ntype InsufficientFundsError struct {\n\tmessage string\n}\n\nfunc NewInsufficientFundsError(message string) *InsufficientFundsError {\n\treturn &InsufficientFundsError{message: message}\n}\n\nfunc (e *InsufficientFundsError) Error() string {\n\treturn e.message\n}\n\ntype InsufficientStockError struct {\n\tmessage string\n}\n\nfunc NewInsufficientStockError(message string) *InsufficientStockError {\n\treturn &InsufficientStockError{message: message}\n}\n\nfunc (e *InsufficientStockError) Error() string {\n\treturn e.message\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/order.go",
    "content": "package onlinestockbrokeragesystem\n\ntype Order interface {\n\tExecute() error\n\tGetStatus() OrderStatus\n\tSetStatus(status OrderStatus)\n}\n\ntype BaseOrder struct {\n\tOrderID  string\n\tAccount  *Account\n\tStock    *Stock\n\tQuantity int\n\tPrice    float64\n\tStatus   OrderStatus\n}\n\nfunc (o *BaseOrder) GetStatus() OrderStatus {\n\treturn o.Status\n}\n\nfunc (o *BaseOrder) SetStatus(status OrderStatus) {\n\to.Status = status\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/portfolio.go",
    "content": "package onlinestockbrokeragesystem\n\nimport \"sync\"\n\ntype Portfolio struct {\n\taccount  *Account\n\tholdings map[string]int\n\tmu       sync.RWMutex\n}\n\nfunc NewPortfolio(account *Account) *Portfolio {\n\treturn &Portfolio{\n\t\taccount:  account,\n\t\tholdings: make(map[string]int),\n\t}\n}\n\nfunc (p *Portfolio) AddStock(stock *Stock, quantity int) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.holdings[stock.Symbol] += quantity\n}\n\nfunc (p *Portfolio) RemoveStock(stock *Stock, quantity int) error {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\n\tcurrentQuantity, exists := p.holdings[stock.Symbol]\n\tif !exists {\n\t\treturn NewInsufficientStockError(\"stock not found in portfolio\")\n\t}\n\n\tif currentQuantity < quantity {\n\t\treturn NewInsufficientStockError(\"insufficient stock quantity in portfolio\")\n\t}\n\n\tp.holdings[stock.Symbol] -= quantity\n\tif p.holdings[stock.Symbol] == 0 {\n\t\tdelete(p.holdings, stock.Symbol)\n\t}\n\treturn nil\n}\n\nfunc (p *Portfolio) GetHoldings() map[string]int {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\n\tholdings := make(map[string]int)\n\tfor symbol, quantity := range p.holdings {\n\t\tholdings[symbol] = quantity\n\t}\n\treturn holdings\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/sell_order.go",
    "content": "package onlinestockbrokeragesystem\n\ntype SellOrder struct {\n\tBaseOrder\n}\n\nfunc NewSellOrder(orderID string, account *Account, stock *Stock, quantity int, price float64) *SellOrder {\n\treturn &SellOrder{\n\t\tBaseOrder: BaseOrder{\n\t\t\tOrderID:  orderID,\n\t\t\tAccount:  account,\n\t\t\tStock:    stock,\n\t\t\tQuantity: quantity,\n\t\t\tPrice:    price,\n\t\t\tStatus:   OrderStatusPending,\n\t\t},\n\t}\n}\n\nfunc (o *SellOrder) Execute() error {\n\tif err := o.Account.Portfolio.RemoveStock(o.Stock, o.Quantity); err != nil {\n\t\to.Status = OrderStatusRejected\n\t\treturn err\n\t}\n\n\ttotalProceeds := float64(o.Quantity) * o.Price\n\to.Account.Deposit(totalProceeds)\n\to.Status = OrderStatusExecuted\n\treturn nil\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/stock.go",
    "content": "package onlinestockbrokeragesystem\n\nimport \"sync\"\n\ntype Stock struct {\n\tSymbol string\n\tName   string\n\tprice  float64\n\tmu     sync.RWMutex\n}\n\nfunc NewStock(symbol, name string, price float64) *Stock {\n\treturn &Stock{\n\t\tSymbol: symbol,\n\t\tName:   name,\n\t\tprice:  price,\n\t}\n}\n\nfunc (s *Stock) UpdatePrice(newPrice float64) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\ts.price = newPrice\n}\n\nfunc (s *Stock) GetPrice() float64 {\n\ts.mu.RLock()\n\tdefer s.mu.RUnlock()\n\treturn s.price\n}\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/stock_broker.go",
    "content": "package onlinestockbrokeragesystem\n\nimport (\n    \"fmt\"\n    \"sync\"\n    \"sync/atomic\"\n)\n\ntype StockBroker struct {\n    accounts        map[string]*Account\n    stocks          map[string]*Stock\n    orderQueue      chan Order\n    accountIDCount  int64\n    mu             sync.RWMutex\n}\n\nvar (\n    instance *StockBroker\n    once     sync.Once\n)\n\nfunc GetStockBroker() *StockBroker {\n    once.Do(func() {\n        instance = &StockBroker{\n            accounts:   make(map[string]*Account),\n            stocks:    make(map[string]*Stock),\n            orderQueue: make(chan Order, 100), // Buffered channel for orders\n        }\n        go instance.processOrders() // Start order processing goroutine\n    })\n    return instance\n}\n\nfunc (sb *StockBroker) CreateAccount(user *User, initialBalance float64) {\n    sb.mu.Lock()\n    defer sb.mu.Unlock()\n\n    accountID := sb.generateAccountID()\n    account := NewAccount(accountID, user, initialBalance)\n    sb.accounts[accountID] = account\n}\n\nfunc (sb *StockBroker) GetAccount(accountID string) *Account {\n    sb.mu.RLock()\n    defer sb.mu.RUnlock()\n    return sb.accounts[accountID]\n}\n\nfunc (sb *StockBroker) AddStock(stock *Stock) {\n    sb.mu.Lock()\n    defer sb.mu.Unlock()\n    sb.stocks[stock.Symbol] = stock\n}\n\nfunc (sb *StockBroker) GetStock(symbol string) *Stock {\n    sb.mu.RLock()\n    defer sb.mu.RUnlock()\n    return sb.stocks[symbol]\n}\n\nfunc (sb *StockBroker) PlaceOrder(order Order) {\n    sb.orderQueue <- order\n}\n\nfunc (sb *StockBroker) processOrders() {\n    for order := range sb.orderQueue {\n        if err := order.Execute(); err != nil {\n            fmt.Printf(\"Order failed: %v\\n\", err)\n        }\n    }\n}\n\nfunc (sb *StockBroker) generateAccountID() string {\n    id := atomic.AddInt64(&sb.accountIDCount, 1)\n    return fmt.Sprintf(\"A%03d\", id)\n}"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/stock_broker_demo.go",
    "content": "package onlinestockbrokeragesystem\n\nimport \"fmt\"\n\nfunc Run() {\n    broker := GetStockBroker()\n\n    // Create user and account\n    user := NewUser(\"U001\", \"John Doe\", \"john@example.com\")\n    broker.CreateAccount(user, 10000.0)\n    account := broker.GetAccount(\"A001\")\n\n    // Add stocks\n    apple := NewStock(\"AAPL\", \"Apple Inc.\", 150.0)\n    google := NewStock(\"GOOGL\", \"Alphabet Inc.\", 2000.0)\n    broker.AddStock(apple)\n    broker.AddStock(google)\n\n    // Place buy orders\n    buyOrder1 := NewBuyOrder(\"O001\", account, apple, 10, 150.0)\n    buyOrder2 := NewBuyOrder(\"O002\", account, google, 5, 2000.0)\n    \n    broker.PlaceOrder(buyOrder1)\n    broker.PlaceOrder(buyOrder2)\n\n    // Give some time for orders to process\n    // In a real system, you'd use proper synchronization\n    fmt.Println(\"Processing buy orders...\")\n    \n    // Place sell order\n    sellOrder := NewSellOrder(\"O003\", account, apple, 5, 160.0)\n    broker.PlaceOrder(sellOrder)\n    \n    fmt.Println(\"Processing sell order...\")\n\n    // Print account details\n    fmt.Printf(\"Account Balance: $%.2f\\n\", account.GetBalance())\n    fmt.Println(\"Portfolio Holdings:\")\n    for symbol, quantity := range account.Portfolio.GetHoldings() {\n        fmt.Printf(\"%s: %d shares\\n\", symbol, quantity)\n    }\n}"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/types.go",
    "content": "package onlinestockbrokeragesystem\n\ntype OrderStatus int\n\nconst (\n\tOrderStatusPending OrderStatus = iota\n\tOrderStatusExecuted\n\tOrderStatusRejected\n)\n"
  },
  {
    "path": "solutions/golang/onlinestockbrokeragesystem/user.go",
    "content": "package onlinestockbrokeragesystem\n\ntype User struct {\n\tUserID string\n\tName   string\n\tEmail  string\n}\n\nfunc NewUser(userID, name, email string) *User {\n\treturn &User{\n\t\tUserID: userID,\n\t\tName:   name,\n\t\tEmail:  email,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/README.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot should have multiple levels, each level with a certain number of parking spots.\n2. The parking lot should support different types of vehicles, such as cars, motorcycles, and trucks.\n3. Each parking spot should be able to accommodate a specific type of vehicle.\n4. The system should assign a parking spot to a vehicle upon entry and release it when the vehicle exits.\n5. The system should track the availability of parking spots and provide real-time information to customers.\n6. The system should handle multiple entry and exit points and support concurrent access.\n\n## Classes, Interfaces and Enumerations\n1. The **ParkingLot** class follows the Singleton pattern to ensure only one instance of the parking lot exists. It maintains a list of levels and provides methods to park and unpark vehicles.\n2. The **Level** class represents a level in the parking lot and contains a list of parking spots. It handles parking and unparking of vehicles within the level.\n3. The **ParkingSpot** class represents an individual parking spot and tracks the availability and the parked vehicle.\n4. The **Vehicle** class is an abstract base class for different types of vehicles. It is extended by Car, Motorcycle, and Truck classes.\n5. The **VehicleType** enum defines the different types of vehicles supported by the parking lot.\n6. Multi-threading is achieved through the use of synchronized keyword on critical sections to ensure thread safety.\n7. The **Main** class demonstrates the usage of the parking lot system.\n\n## Design Patterns Used:\n1. Singleton Pattern: Ensures only one instance of the ParkingLot class.\n2. Factory Pattern (optional extension): Could be used for creating vehicles based on input.\n3. Observer Pattern (optional extension): Could notify customers about available spots."
  },
  {
    "path": "solutions/golang/parkinglot/car.go",
    "content": "package parkinglot\n\nfunc NewCar(licensePlate string) Vehicle {\n\treturn &BaseVehicle{licensePlate: licensePlate, vehicleType: CAR}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/level.go",
    "content": "package parkinglot\n\ntype Level struct {\n\tfloor        int\n\tparkingSpots []*ParkingSpot\n}\n\nfunc NewLevel(floor int, numSpots int) *Level {\n\tlevel := &Level{floor: floor}\n\tbikeSpots := int(float64(numSpots) * 0.50)\n\tcarSpots := int(float64(numSpots) * 0.40)\n\n\tfor i := 1; i <= bikeSpots; i++ {\n\t\tlevel.parkingSpots = append(level.parkingSpots, NewParkingSpot(i, MOTORCYCLE))\n\t}\n\tfor i := bikeSpots + 1; i <= bikeSpots+carSpots; i++ {\n\t\tlevel.parkingSpots = append(level.parkingSpots, NewParkingSpot(i, CAR))\n\t}\n\tfor i := bikeSpots + carSpots + 1; i <= numSpots; i++ {\n\t\tlevel.parkingSpots = append(level.parkingSpots, NewParkingSpot(i, TRUCK))\n\t}\n\treturn level\n}\n\nfunc (l *Level) ParkVehicle(vehicle Vehicle) bool {\n\tfor _, spot := range l.parkingSpots {\n\t\tif spot.IsAvailable() && spot.GetVehicleType() == vehicle.GetType() {\n\t\t\tspot.ParkVehicle(vehicle)\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (l *Level) UnparkVehicle(vehicle Vehicle) bool {\n\tfor _, spot := range l.parkingSpots {\n\t\tif !spot.IsAvailable() && spot.GetParkedVehicle() == vehicle {\n\t\t\tspot.UnparkVehicle()\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (l *Level) DisplayAvailability() {\n\tfor _, spot := range l.parkingSpots {\n\t\tstatus := \"Available\"\n\t\tif !spot.IsAvailable() {\n\t\t\tstatus = \"Occupied\"\n\t\t}\n\t\tprintln(\"Level:\", l.floor, \"Spot:\", spot.GetSpotNumber(), \"Status:\", status, \"Type:\", spot.GetVehicleType())\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/motorcycle.go",
    "content": "package parkinglot\n\nfunc NewMotorcycle(licensePlate string) Vehicle {\n\treturn &BaseVehicle{licensePlate: licensePlate, vehicleType: MOTORCYCLE}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/parking_lot.go",
    "content": "package parkinglot\n\ntype ParkingLot struct {\n\tlevels []*Level\n}\n\nvar instance *ParkingLot\n\nfunc GetParkingLotInstance() *ParkingLot {\n\tif instance == nil {\n\t\tinstance = &ParkingLot{levels: []*Level{}}\n\t}\n\treturn instance\n}\n\nfunc (p *ParkingLot) AddLevel(level *Level) {\n\tp.levels = append(p.levels, level)\n}\n\nfunc (p *ParkingLot) ParkVehicle(vehicle Vehicle) bool {\n\tfor _, level := range p.levels {\n\t\tif level.ParkVehicle(vehicle) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *ParkingLot) UnparkVehicle(vehicle Vehicle) bool {\n\tfor _, level := range p.levels {\n\t\tif level.UnparkVehicle(vehicle) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (p *ParkingLot) DisplayAvailability() {\n\tfor _, level := range p.levels {\n\t\tlevel.DisplayAvailability()\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/parking_lot_demo.go",
    "content": "package parkinglot\n\nfunc Run() {\n\tparkingLot := GetParkingLotInstance()\n\tparkingLot.AddLevel(NewLevel(1, 100))\n\tparkingLot.AddLevel(NewLevel(2, 80))\n\n\tcar := NewCar(\"ABC123\")\n\ttruck := NewTruck(\"XYZ789\")\n\tmotorcycle := NewMotorcycle(\"M1234\")\n\n\tparkingLot.ParkVehicle(car)\n\tparkingLot.ParkVehicle(truck)\n\tparkingLot.ParkVehicle(motorcycle)\n\n\tparkingLot.DisplayAvailability()\n\n\tparkingLot.UnparkVehicle(motorcycle)\n\n\tparkingLot.DisplayAvailability()\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/parking_spot.go",
    "content": "package parkinglot\n\ntype ParkingSpot struct {\n\tspotNumber    int\n\tvehicleType   VehicleType\n\tparkedVehicle Vehicle\n}\n\nfunc NewParkingSpot(spotNumber int, vehicleType VehicleType) *ParkingSpot {\n\treturn &ParkingSpot{spotNumber: spotNumber, vehicleType: vehicleType}\n}\n\nfunc (ps *ParkingSpot) IsAvailable() bool {\n\treturn ps.parkedVehicle == nil\n}\n\nfunc (ps *ParkingSpot) ParkVehicle(vehicle Vehicle) {\n\tif ps.IsAvailable() && vehicle.GetType() == ps.vehicleType {\n\t\tps.parkedVehicle = vehicle\n\t}\n}\n\nfunc (ps *ParkingSpot) UnparkVehicle() {\n\tps.parkedVehicle = nil\n}\n\nfunc (ps *ParkingSpot) GetSpotNumber() int {\n\treturn ps.spotNumber\n}\n\nfunc (ps *ParkingSpot) GetVehicleType() VehicleType {\n\treturn ps.vehicleType\n}\n\nfunc (ps *ParkingSpot) GetParkedVehicle() Vehicle {\n\treturn ps.parkedVehicle\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/truck.go",
    "content": "package parkinglot\n\nfunc NewTruck(licensePlate string) Vehicle {\n\treturn &BaseVehicle{licensePlate: licensePlate, vehicleType: TRUCK}\n}\n"
  },
  {
    "path": "solutions/golang/parkinglot/vehicle.go",
    "content": "package parkinglot\n\ntype VehicleType int\n\nconst (\n\tCAR VehicleType = iota\n\tMOTORCYCLE\n\tTRUCK\n)\n\ntype Vehicle interface {\n\tGetLicensePlate() string\n\tGetType() VehicleType\n}\n\ntype BaseVehicle struct {\n\tlicensePlate string\n\tvehicleType  VehicleType\n}\n\nfunc (v *BaseVehicle) GetLicensePlate() string {\n\treturn v.licensePlate\n}\n\nfunc (v *BaseVehicle) GetType() VehicleType {\n\treturn v.vehicleType\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/README.md",
    "content": "# Designing a Pub-Sub System in Java\n\n## Requirements\n1. The Pub-Sub system should allow publishers to publish messages to specific topics.\n2. Subscribers should be able to subscribe to topics of interest and receive messages published to those topics.\n3. The system should support multiple publishers and subscribers.\n4. Messages should be delivered to all subscribers of a topic in real-time.\n5. The system should handle concurrent access and ensure thread safety.\n6. The Pub-Sub system should be scalable and efficient in terms of message delivery.\n\n## Classes, Interfaces and Enumerations\n1. The **Message** class represents a message that can be published and received by subscribers. It contains the message content.\n2. The **Topic** class represents a topic to which messages can be published. It maintains a set of subscribers and provides methods to add and remove subscribers, as well as publish messages to all subscribers.\n3. The **Subscriber** interface defines the contract for subscribers. It declares the onMessage method that is invoked when a subscriber receives a message.\n4. The **PrintSubscriber** class is a concrete implementation of the Subscriber interface. It receives messages and prints them to the console.\n5. The **Publisher** class represents a publisher that publishes messages to a specific topic.\n6. The **PubSubSystem** class is the main class that manages topics, subscribers, and message publishing. It uses a ConcurrentHashMap to store topics and an ExecutorService to handle concurrent message publishing.\n7. The **PubSubDemo** class demonstrates the usage of the Pub-Sub system by creating topics, subscribers, and publishers, and publishing messages."
  },
  {
    "path": "solutions/golang/pubsubsystem/message.go",
    "content": "package pubsubsystem\n\ntype Message struct {\n\tContent string\n}\n\nfunc NewMessage(content string) *Message {\n\treturn &Message{Content: content}\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/print_subscriber.go",
    "content": "package pubsubsystem\n\nimport \"fmt\"\n\ntype PrintSubscriber struct {\n\tName string\n}\n\nfunc NewPrintSubscriber(name string) *PrintSubscriber {\n\treturn &PrintSubscriber{Name: name}\n}\n\nfunc (ps *PrintSubscriber) OnMessage(message *Message) {\n\tfmt.Printf(\"Subscriber %s received message: %s\\n\", ps.Name, message.Content)\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/publisher.go",
    "content": "package pubsubsystem\n\nimport \"fmt\"\n\ntype Publisher struct {\n\tTopics map[*Topic]struct{}\n}\n\nfunc NewPublisher() *Publisher {\n\treturn &Publisher{Topics: make(map[*Topic]struct{})}\n}\n\nfunc (p *Publisher) RegisterTopic(topic *Topic) {\n\tp.Topics[topic] = struct{}{}\n}\n\nfunc (p *Publisher) Publish(topic *Topic, message *Message) {\n\tif _, exists := p.Topics[topic]; !exists {\n\t\tfmt.Printf(\"This publisher can't publish to topic: %s\\n\", topic.Name)\n\t\treturn\n\t}\n\ttopic.Publish(message)\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/pubsub_system_demo.go",
    "content": "package pubsubsystem\n\nfunc Run() {\n\t// Create topics\n\ttopic1 := NewTopic(\"Topic1\")\n\ttopic2 := NewTopic(\"Topic2\")\n\n\t// Create publishers\n\tpublisher1 := NewPublisher()\n\tpublisher2 := NewPublisher()\n\n\t// Create subscribers\n\tsubscriber1 := NewPrintSubscriber(\"Subscriber1\")\n\tsubscriber2 := NewPrintSubscriber(\"Subscriber2\")\n\tsubscriber3 := NewPrintSubscriber(\"Subscriber3\")\n\n\tpublisher1.RegisterTopic(topic1)\n\tpublisher2.RegisterTopic(topic2)\n\n\t// Subscribe to topics\n\ttopic1.AddSubscriber(subscriber1)\n\ttopic1.AddSubscriber(subscriber2)\n\ttopic2.AddSubscriber(subscriber2)\n\ttopic2.AddSubscriber(subscriber3)\n\n\t// Publish messages\n\tpublisher1.Publish(topic1, NewMessage(\"Message1 for Topic1\"))\n\tpublisher1.Publish(topic1, NewMessage(\"Message2 for Topic1\"))\n\tpublisher2.Publish(topic2, NewMessage(\"Message1 for Topic2\"))\n\n\t// Unsubscribe from a topic\n\ttopic1.RemoveSubscriber(subscriber2)\n\n\t// Publish more messages\n\tpublisher1.Publish(topic1, NewMessage(\"Message3 for Topic1\"))\n\tpublisher2.Publish(topic2, NewMessage(\"Message2 for Topic2\"))\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/subscriber.go",
    "content": "package pubsubsystem\n\ntype Subscriber interface {\n\tOnMessage(message *Message)\n}\n"
  },
  {
    "path": "solutions/golang/pubsubsystem/topic.go",
    "content": "package pubsubsystem\n\nimport (\n\t\"sync\"\n)\n\ntype Topic struct {\n\tName        string\n\tSubscribers map[Subscriber]struct{}\n\tmu          sync.RWMutex\n}\n\nfunc NewTopic(name string) *Topic {\n\treturn &Topic{\n\t\tName:        name,\n\t\tSubscribers: make(map[Subscriber]struct{}),\n\t}\n}\n\nfunc (t *Topic) AddSubscriber(subscriber Subscriber) {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tt.Subscribers[subscriber] = struct{}{}\n}\n\nfunc (t *Topic) RemoveSubscriber(subscriber Subscriber) {\n\tt.mu.Lock()\n\tdefer t.mu.Unlock()\n\tdelete(t.Subscribers, subscriber)\n}\n\nfunc (t *Topic) Publish(message *Message) {\n\tt.mu.RLock()\n\tdefer t.mu.RUnlock()\n\tfor subscriber := range t.Subscribers {\n\t\tsubscriber.OnMessage(message)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/README.md",
    "content": "# Designing Restaurant Management System\n\n## Requirements\n1. The restaurant management system should allow customers to place orders, view the menu, and make reservations.\n2. The system should manage the restaurant's inventory, including ingredients and menu items.\n3. The system should handle order processing, including order preparation, billing, and payment.\n4. The system should support multiple payment methods, such as cash, credit card, and mobile payments.\n5. The system should manage staff information, including roles, schedules, and performance tracking.\n6. The system should generate reports and analytics for management, such as sales reports and inventory analysis.\n7. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **MenuItem** class represents a menu item in the restaurant, with properties such as ID, name, description, price, and availability.\n2. The **Order** class represents an order placed by a customer, with properties such as ID, list of menu items, total amount, order status, and timestamp.\n3. The **OrderStatus** enum represents the different statuses an order can have, such as pending, preparing, ready, completed, or cancelled.\n4. The **Reservation** class represents a reservation made by a customer, with properties such as ID, customer name, contact number, party size, and reservation time.\n5. The **Payment** class represents a payment made for an order, with properties such as ID, amount, payment method, and payment status.\n6. The **PaymentMethod** enum represents the different payment methods supported by the restaurant, such as cash, credit card, or mobile payment.\n7. The **PaymentStatus** enum represents the status of a payment, which can be pending, completed, or failed.\n8. The Staff class represents a staff member of the restaurant, with properties such as ID, name, role, and contact number.\n9. The **Restaurant** class is the main class that manages the restaurant operations. It follows the Singleton pattern to ensure only one instance of the restaurant exists.\n10. The Restaurant class provides methods for managing menu items, placing orders, updating order status, making reservations, processing payments, and managing staff.\n11. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as orders and reservations.\n12. The notifyKitchen and notifyStaff methods are placeholders for notifying relevant staff about order updates and status changes.\n13. The **RestaurantManagementDemo** class demonstrates the usage of the restaurant management system by adding menu items, placing an order, making a reservation, processing a payment, updating order status, adding staff, and retrieving the menu."
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/menu_item.go",
    "content": "package restaurantmanagementsystem\n\ntype MenuItem struct {\n\tID          int\n\tName        string\n\tDescription string\n\tPrice       float64\n\tAvailable   bool\n}\n\nfunc NewMenuItem(id int, name, description string, price float64, available bool) *MenuItem {\n\treturn &MenuItem{\n\t\tID:          id,\n\t\tName:        name,\n\t\tDescription: description,\n\t\tPrice:       price,\n\t\tAvailable:   available,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/order.go",
    "content": "package restaurantmanagementsystem\n\nimport (\n\t\"time\"\n)\n\ntype Order struct {\n\tID          int\n\tItems       []MenuItem\n\tTotalAmount float64\n\tStatus      OrderStatus\n\tTimestamp   time.Time\n}\n\nfunc NewOrder(id int, items []MenuItem, totalAmount float64, status OrderStatus) *Order {\n\treturn &Order{\n\t\tID:          id,\n\t\tItems:       items,\n\t\tTotalAmount: totalAmount,\n\t\tStatus:      status,\n\t\tTimestamp:   time.Now(),\n\t}\n}\n\nfunc (o *Order) SetStatus(status OrderStatus) {\n\to.Status = status\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/order_status.go",
    "content": "package restaurantmanagementsystem\n\ntype OrderStatus int\n\nconst (\n\tOrderPending OrderStatus = iota\n\tOrderPreparing\n\tOrderReady\n\tOrderCompleted\n\tOrderCancelled\n)\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/payment.go",
    "content": "package restaurantmanagementsystem\n\ntype Payment struct {\n\tID     int\n\tAmount float64\n\tMethod PaymentMethod\n\tStatus PaymentStatus\n}\n\nfunc NewPayment(id int, amount float64, method PaymentMethod, status PaymentStatus) *Payment {\n\treturn &Payment{\n\t\tID:     id,\n\t\tAmount: amount,\n\t\tMethod: method,\n\t\tStatus: status,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/payment_method.go",
    "content": "package restaurantmanagementsystem\n\ntype PaymentMethod int\n\nconst (\n\tCash PaymentMethod = iota\n\tCreditCard\n\tMobilePayment\n)\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/payment_status.go",
    "content": "package restaurantmanagementsystem\n\ntype PaymentStatus int\n\nconst (\n\tPaymentPending PaymentStatus = iota\n\tPaymentCompleted\n\tPaymentFailed\n)\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/reservation.go",
    "content": "package restaurantmanagementsystem\n\nimport (\n\t\"time\"\n)\n\ntype Reservation struct {\n\tID              int\n\tCustomerName    string\n\tContactNumber   string\n\tPartySize       int\n\tReservationTime time.Time\n}\n\nfunc NewReservation(id int, customerName, contactNumber string, partySize int, reservationTime time.Time) *Reservation {\n\treturn &Reservation{\n\t\tID:              id,\n\t\tCustomerName:    customerName,\n\t\tContactNumber:   contactNumber,\n\t\tPartySize:       partySize,\n\t\tReservationTime: reservationTime,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/restaurant.go",
    "content": "package restaurantmanagementsystem\n\nimport \"sync\"\n\ntype Restaurant struct {\n\tmenu         []MenuItem\n\torders       map[int]*Order\n\treservations []Reservation\n\tpayments     map[int]*Payment\n\tstaff        []Staff\n\tmu           sync.Mutex\n}\n\nvar restaurantInstance *Restaurant\nvar once sync.Once\n\nfunc GetRestaurantInstance() *Restaurant {\n\tonce.Do(func() {\n\t\trestaurantInstance = &Restaurant{\n\t\t\tmenu:         []MenuItem{},\n\t\t\torders:       make(map[int]*Order),\n\t\t\treservations: []Reservation{},\n\t\t\tpayments:     make(map[int]*Payment),\n\t\t\tstaff:        []Staff{},\n\t\t}\n\t})\n\treturn restaurantInstance\n}\n\nfunc (r *Restaurant) AddMenuItem(item *MenuItem) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.menu = append(r.menu, *item)\n}\n\nfunc (r *Restaurant) RemoveMenuItem(item *MenuItem) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tfor i, menuItem := range r.menu {\n\t\tif menuItem.ID == item.ID {\n\t\t\tr.menu = append(r.menu[:i], r.menu[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc (r *Restaurant) GetMenu() []MenuItem {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\treturn r.menu\n}\n\nfunc (r *Restaurant) PlaceOrder(order *Order) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.orders[order.ID] = order\n\tr.notifyKitchen(order)\n}\n\nfunc (r *Restaurant) UpdateOrderStatus(orderID int, status OrderStatus) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tif order, exists := r.orders[orderID]; exists {\n\t\torder.SetStatus(status)\n\t\tr.notifyStaff(order)\n\t}\n}\n\nfunc (r *Restaurant) MakeReservation(reservation *Reservation) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.reservations = append(r.reservations, *reservation)\n}\n\nfunc (r *Restaurant) ProcessPayment(payment *Payment) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.payments[payment.ID] = payment\n}\n\nfunc (r *Restaurant) AddStaff(staff *Staff) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tr.staff = append(r.staff, *staff)\n}\n\nfunc (r *Restaurant) notifyKitchen(order *Order) {\n\t// Notify kitchen staff to prepare the order\n}\n\nfunc (r *Restaurant) notifyStaff(order *Order) {\n\t// Notify relevant staff about the order status update\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/restaurant_management_demo.go",
    "content": "package restaurantmanagementsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\trestaurant := GetRestaurantInstance()\n\n\t// Add menu items\n\trestaurant.AddMenuItem(NewMenuItem(1, \"Burger\", \"Delicious burger\", 9.99, true))\n\trestaurant.AddMenuItem(NewMenuItem(2, \"Pizza\", \"Cheesy pizza\", 12.99, true))\n\trestaurant.AddMenuItem(NewMenuItem(3, \"Salad\", \"Fresh salad\", 7.99, true))\n\n\t// Place an order\n\torder := NewOrder(1, []MenuItem{\n\t\t*NewMenuItem(1, \"Burger\", \"Delicious burger\", 9.99, true),\n\t\t*NewMenuItem(3, \"Salad\", \"Fresh salad\", 7.99, true),\n\t}, 17.98, OrderPending)\n\trestaurant.PlaceOrder(order)\n\n\t// Make a reservation\n\treservation := NewReservation(1, \"John Doe\", \"1234567890\", 4, time.Now())\n\trestaurant.MakeReservation(reservation)\n\n\t// Process a payment\n\tpayment := NewPayment(1, 17.98, CreditCard, PaymentPending)\n\trestaurant.ProcessPayment(payment)\n\n\t// Update order status\n\trestaurant.UpdateOrderStatus(1, OrderPreparing)\n\trestaurant.UpdateOrderStatus(1, OrderReady)\n\trestaurant.UpdateOrderStatus(1, OrderCompleted)\n\n\t// Add staff\n\trestaurant.AddStaff(NewStaff(1, \"Alice\", \"Manager\", \"9876543210\"))\n\trestaurant.AddStaff(NewStaff(2, \"Bob\", \"Chef\", \"5432109876\"))\n\n\t// Get menu\n\tfmt.Println(\"Menu:\")\n\tfor _, item := range restaurant.GetMenu() {\n\t\tfmt.Printf(\"%s - $%.2f\\n\", item.Name, item.Price)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/restaurantmanagementsystem/staff.go",
    "content": "package restaurantmanagementsystem\n\ntype Staff struct {\n\tID            int\n\tName          string\n\tRole          string\n\tContactNumber string\n}\n\nfunc NewStaff(id int, name, role, contactNumber string) *Staff {\n\treturn &Staff{\n\t\tID:            id,\n\t\tName:          name,\n\t\tRole:          role,\n\t\tContactNumber: contactNumber,\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/README.md",
    "content": "# Designing a Ride-Sharing Service Like Uber\n\n## Requirements\n1. The ride sharing service should allow passengers to request rides and drivers to accept and fulfill those ride requests.\n2. Passengers should be able to specify their pickup location, destination, and desired ride type (e.g., regular, premium).\n3. Drivers should be able to see available ride requests and choose to accept or decline them.\n4. The system should match ride requests with available drivers based on proximity and other factors.\n5. The system should calculate the fare for each ride based on distance, time, and ride type.\n6. The system should handle payments and process transactions between passengers and drivers.\n7. The system should provide real-time tracking of ongoing rides and notify passengers and drivers about ride status updates.\n8. The system should handle concurrent requests and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Passenger** class represents a passenger in the ride sharing service, with properties such as ID, name, contact information, and location.\n2. The **Driver** class represents a driver in the ride sharing service, with properties such as ID, name, contact information, license plate, location, and status (available or busy).\n3. The **Ride** class represents a ride requested by a passenger and accepted by a driver, with properties such as ID, passenger, driver, source location, destination location, status, and fare.\n4. The **Location** class represents a geographical location with latitude and longitude coordinates.\n5. The **Payment** class represents a payment made for a ride, with properties such as ID, ride, amount, and payment status.\n6. The **RideService** class is the main class that manages the ride sharing service. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The RideService class provides methods for adding passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides.\n8. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and ConcurrentLinkedQueue) to handle concurrent access to shared data, such as ride requests and driver availability.\n9. The notifyDrivers, notifyPassenger, and notifyDriver methods are placeholders for notifying relevant parties about ride status updates.\n10. The calculateFare and processPayment methods are placeholders for calculating ride fares and processing payments, respectively.\n11. The **RideSharingDemo** class demonstrates the usage of the ride sharing service by creating passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides."
  },
  {
    "path": "solutions/golang/ridesharingservice/driver.go",
    "content": "package ridesharingservice\n\ntype Driver struct {\n\tID           int\n\tName         string\n\tContact      string\n\tLicensePlate string\n\tLocation     *Location\n\tStatus       DriverStatus\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/driver_status.go",
    "content": "package ridesharingservice\n\ntype DriverStatus int\n\nconst (\n\tAvailable DriverStatus = iota\n\tBusy\n)\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/location.go",
    "content": "package ridesharingservice\n\ntype Location struct {\n\tLatitude  float64\n\tLongitude float64\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/passenger.go",
    "content": "package ridesharingservice\n\ntype Passenger struct {\n\tID       int\n\tName     string\n\tContact  string\n\tLocation *Location\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/ride.go",
    "content": "package ridesharingservice\n\ntype Ride struct {\n\tID          int\n\tPassenger   *Passenger\n\tDriver      *Driver\n\tSource      *Location\n\tDestination *Location\n\tStatus      RideStatus\n\tFare        float64\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/ride_service.go",
    "content": "package ridesharingservice\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype RideService struct {\n\tpassengers     map[int]*Passenger\n\tdrivers        map[int]*Driver\n\trides          map[int]*Ride\n\trequestedRides chan *Ride\n\tmu             sync.Mutex\n}\n\nvar instance *RideService\nvar once sync.Once\n\nfunc GetRideService() *RideService {\n\tonce.Do(func() {\n\t\tinstance = &RideService{\n\t\t\tpassengers:     make(map[int]*Passenger),\n\t\t\tdrivers:        make(map[int]*Driver),\n\t\t\trides:          make(map[int]*Ride),\n\t\t\trequestedRides: make(chan *Ride, 10),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (rs *RideService) AddPassenger(passenger *Passenger) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\trs.passengers[passenger.ID] = passenger\n}\n\nfunc (rs *RideService) AddDriver(driver *Driver) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\trs.drivers[driver.ID] = driver\n}\n\nfunc (rs *RideService) RequestRide(passenger *Passenger, source, destination *Location) {\n\tride := &Ride{\n\t\tID:          rs.generateRideID(),\n\t\tPassenger:   passenger,\n\t\tSource:      source,\n\t\tDestination: destination,\n\t\tStatus:      Requested,\n\t}\n\trs.requestedRides <- ride\n\trs.notifyDrivers(ride)\n}\n\nfunc (rs *RideService) AcceptRide(driver *Driver, ride *Ride) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\tif ride.Status == Requested {\n\t\tride.Driver = driver\n\t\tride.Status = Accepted\n\t\tdriver.Status = Busy\n\t\trs.notifyPassenger(ride)\n\t}\n}\n\nfunc (rs *RideService) StartRide(ride *Ride) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\tif ride.Status == Accepted {\n\t\tride.Status = InProgress\n\t\trs.notifyPassenger(ride)\n\t}\n}\n\nfunc (rs *RideService) CompleteRide(ride *Ride) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\tif ride.Status == InProgress {\n\t\tride.Status = Completed\n\t\tride.Driver.Status = Available\n\t\tride.Fare = rs.calculateFare(ride)\n\t\trs.notifyPassenger(ride)\n\t\trs.notifyDriver(ride)\n\t}\n}\n\nfunc (rs *RideService) CancelRide(ride *Ride) {\n\trs.mu.Lock()\n\tdefer rs.mu.Unlock()\n\tif ride.Status == Requested || ride.Status == Accepted {\n\t\tride.Status = Cancelled\n\t\tif ride.Driver != nil {\n\t\t\tride.Driver.Status = Available\n\t\t}\n\t\trs.notifyPassenger(ride)\n\t\trs.notifyDriver(ride)\n\t}\n}\n\nfunc (rs *RideService) notifyDrivers(ride *Ride) {\n\tfor _, driver := range rs.drivers {\n\t\tif driver.Status == Available && rs.calculateDistance(driver.Location, ride.Source) <= 5.0 {\n\t\t\tfmt.Printf(\"Notifying driver %s about ride request: %d\\n\", driver.Name, ride.ID)\n\t\t}\n\t}\n}\n\nfunc (rs *RideService) notifyPassenger(ride *Ride) {\n\tmessage := \"\"\n\tswitch ride.Status {\n\tcase Accepted:\n\t\tmessage = fmt.Sprintf(\"Your ride has been accepted by driver: %s\", ride.Driver.Name)\n\tcase InProgress:\n\t\tmessage = \"Your ride is in progress\"\n\tcase Completed:\n\t\tmessage = fmt.Sprintf(\"Your ride has been completed. Fare: $%.2f\", ride.Fare)\n\tcase Cancelled:\n\t\tmessage = \"Your ride has been cancelled\"\n\t}\n\tfmt.Printf(\"Notifying passenger %s: %s\\n\", ride.Passenger.Name, message)\n}\n\nfunc (rs *RideService) notifyDriver(ride *Ride) {\n\tif ride.Driver != nil {\n\t\tmessage := \"\"\n\t\tswitch ride.Status {\n\t\tcase Completed:\n\t\t\tmessage = fmt.Sprintf(\"Ride completed. Fare: $%.2f\", ride.Fare)\n\t\tcase Cancelled:\n\t\t\tmessage = \"Ride cancelled by passenger\"\n\t\t}\n\t\tfmt.Printf(\"Notifying driver %s: %s\\n\", ride.Driver.Name, message)\n\t}\n}\n\nfunc (rs *RideService) calculateFare(ride *Ride) float64 {\n\tbaseFare := 2.0\n\tperKmFare := 1.5\n\tperMinuteFare := 0.25\n\n\tdistance := rs.calculateDistance(ride.Source, ride.Destination)\n\tduration := rs.calculateDuration(ride.Source, ride.Destination)\n\n\treturn baseFare + (distance * perKmFare) + (duration * perMinuteFare)\n}\n\nfunc (rs *RideService) calculateDistance(source, destination *Location) float64 {\n\treturn rand.Float64()*20 + 1\n}\n\nfunc (rs *RideService) calculateDuration(source, destination *Location) float64 {\n\tdistance := rs.calculateDistance(source, destination)\n\treturn (distance / 30) * 60\n}\n\nfunc (rs *RideService) generateRideID() int {\n\treturn int(time.Now().Unix())\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/ride_sharing_service_demo.go",
    "content": "package ridesharingservice\n\nimport \"fmt\"\n\nfunc Run() {\n\trideService := GetRideService()\n\n\t// Create passengers\n\tpassenger1 := &Passenger{ID: 1, Name: \"John Doe\", Contact: \"1234567890\", Location: &Location{Latitude: 37.7749, Longitude: -122.4194}}\n\tpassenger2 := &Passenger{ID: 2, Name: \"Jane Smith\", Contact: \"9876543210\", Location: &Location{Latitude: 37.7860, Longitude: -122.4070}}\n\trideService.AddPassenger(passenger1)\n\trideService.AddPassenger(passenger2)\n\n\t// Create drivers\n\tdriver1 := &Driver{ID: 1, Name: \"Alice Johnson\", Contact: \"4567890123\", LicensePlate: \"ABC123\", Location: &Location{Latitude: 37.7749, Longitude: -122.4194}, Status: Available}\n\tdriver2 := &Driver{ID: 2, Name: \"Bob Williams\", Contact: \"7890123456\", LicensePlate: \"XYZ789\", Location: &Location{Latitude: 37.7860, Longitude: -122.4070}, Status: Available}\n\trideService.AddDriver(driver1)\n\trideService.AddDriver(driver2)\n\n\t// Passenger 1 requests a ride\n\trideService.RequestRide(passenger1, passenger1.Location, &Location{Latitude: 37.7887, Longitude: -122.4098})\n\n\t// Driver 1 accepts the ride\n\tride := <-rideService.requestedRides\n\trideService.AcceptRide(driver1, ride)\n\n\t// Start and complete the ride\n\trideService.StartRide(ride)\n\trideService.CompleteRide(ride)\n\n\t// Passenger 2 requests a ride and cancels it\n\trideService.RequestRide(passenger2, passenger2.Location, &Location{Latitude: 37.7749, Longitude: -122.4194})\n\tride2 := <-rideService.requestedRides\n\trideService.AcceptRide(driver2, ride2)\n\trideService.CancelRide(ride2)\n\n\tfmt.Println(\"Demo completed\")\n}\n"
  },
  {
    "path": "solutions/golang/ridesharingservice/ride_status.go",
    "content": "package ridesharingservice\n\ntype RideStatus int\n\nconst (\n\tRequested RideStatus = iota\n\tAccepted\n\tInProgress\n\tCompleted\n\tCancelled\n)\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/README.md",
    "content": "# Designing Snake and Ladder Game\n\n## Requirements\n1. The game should be played on a board with numbered cells, typically with 100 cells.\n2. The board should have a predefined set of snakes and ladders, connecting certain cells.\n3. The game should support multiple players, each represented by a unique game piece.\n4. Players should take turns rolling a dice to determine the number of cells to move forward.\n5. If a player lands on a cell with the head of a snake, they should slide down to the cell with the tail of the snake.\n6. If a player lands on a cell with the base of a ladder, they should climb up to the cell at the top of the ladder.\n7. The game should continue until one of the players reaches the final cell on the board.\n8. The game should handle multiple game sessions concurrently, allowing different groups of players to play independently.\n\n## Classes, Interfaces and Enumerations\n1. The **Board** class represents the game board with a fixed size (e.g., 100 cells). It contains the positions of snakes and ladders and provides methods to initialize them and retrieve the new position after encountering a snake or ladder.\n2. The **Player** class represents a player in the game, with properties such as name and current position on the board.\n3. The **Snake** class represents a snake on the board, with properties for the start and end positions.\n4. The **Ladder** class represents a ladder on the board, with properties for the start and end positions.\n5. The **Dice** class represents a dice used in the game, with a method to roll the dice and return a random value between 1 and 6.\n6. The **SnakeAndLadderGame** class represents a single game session. It initializes the game with a board, a list of players, and a dice. The play method handles the game loop, where players take turns rolling the dice and moving their positions on the board. It checks for snakes and ladders and updates the player's position accordingly. The game continues until a player reaches the final position on the board.\n7. The **GameManager** class is a singleton that manages multiple game sessions. It maintains a list of active games and provides a method to start a new game with a list of player names. Each game is started in a separate thread to allow concurrent game sessions.\n8. The **SnakeAndLadderDemo** class demonstrates the usage of the game by creating an instance of the GameManager and starting two separate game sessions with different sets of players."
  },
  {
    "path": "solutions/golang/snakeandladdergame/board.go",
    "content": "package snakeandladdergame\n\ntype Board struct {\n\tSize    int\n\tSnakes  []*Snake\n\tLadders []*Ladder\n}\n\nfunc NewBoard() *Board {\n\tboard := &Board{\n\t\tSize:    100,\n\t\tSnakes:  []*Snake{},\n\t\tLadders: []*Ladder{},\n\t}\n\tboard.initializeSnakesAndLadders()\n\treturn board\n}\n\nfunc (b *Board) initializeSnakesAndLadders() {\n\tb.Snakes = append(b.Snakes, NewSnake(16, 6), NewSnake(48, 26), NewSnake(64, 60), NewSnake(93, 73))\n\tb.Ladders = append(b.Ladders, NewLadder(1, 38), NewLadder(4, 14), NewLadder(9, 31), NewLadder(21, 42),\n\t\tNewLadder(28, 84), NewLadder(51, 67), NewLadder(80, 99))\n}\n\nfunc (b *Board) GetNewPosition(position int) int {\n\tfor _, snake := range b.Snakes {\n\t\tif snake.Start == position {\n\t\t\treturn snake.End\n\t\t}\n\t}\n\tfor _, ladder := range b.Ladders {\n\t\tif ladder.Start == position {\n\t\t\treturn ladder.End\n\t\t}\n\t}\n\treturn position\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/dice.go",
    "content": "package snakeandladdergame\n\nimport \"math/rand\"\n\ntype Dice struct{}\n\nfunc NewDice() *Dice {\n\treturn &Dice{}\n}\n\nfunc (d *Dice) Roll() int {\n\treturn rand.Intn(6) + 1\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/game_manager.go",
    "content": "package snakeandladdergame\n\nimport \"sync\"\n\ntype GameManager struct {\n\tGames []*SnakeAndLadderGame\n}\n\nvar instance *GameManager\n\nfunc GetGameManager() *GameManager {\n\tif instance == nil {\n\t\tinstance = &GameManager{\n\t\t\tGames: []*SnakeAndLadderGame{},\n\t\t}\n\t}\n\treturn instance\n}\n\nfunc (gm *GameManager) StartNewGame(wg *sync.WaitGroup, playerNames []string) {\n\tgame := NewSnakeAndLadderGame(playerNames)\n\tgm.Games = append(gm.Games, game)\n\twg.Add(1)\n\tgo game.Play(wg)\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/ladder.go",
    "content": "package snakeandladdergame\n\ntype Ladder struct {\n\tStart int\n\tEnd   int\n}\n\nfunc NewLadder(start, end int) *Ladder {\n\treturn &Ladder{Start: start, End: end}\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/player.go",
    "content": "package snakeandladdergame\n\ntype Player struct {\n\tName     string\n\tPosition int\n}\n\nfunc NewPlayer(name string) *Player {\n\treturn &Player{Name: name, Position: 0}\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/snake.go",
    "content": "package snakeandladdergame\n\ntype Snake struct {\n\tStart int\n\tEnd   int\n}\n\nfunc NewSnake(start, end int) *Snake {\n\treturn &Snake{Start: start, End: end}\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/snake_and_ladder_demo.go",
    "content": "package snakeandladdergame\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\nfunc Run() {\n\tgameManager := GetGameManager()\n\twg := new(sync.WaitGroup)\n\t// Start game 1\n\tplayers1 := []string{\"Player 1\", \"Player 2\", \"Player 3\"}\n\tgameManager.StartNewGame(wg, players1)\n\n\t// Start game 2\n\tplayers2 := []string{\"Player 4\", \"Player 5\"}\n\tgameManager.StartNewGame(wg, players2)\n\n\tfmt.Println(\"Games started. Check game output above.\")\n\t//Wait for all games to finish\n\twg.Wait()\n}\n"
  },
  {
    "path": "solutions/golang/snakeandladdergame/snake_and_ladder_game.go",
    "content": "package snakeandladdergame\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\ntype SnakeAndLadderGame struct {\n\tID               int64\n\tBoard            *Board\n\tPlayers          []*Player\n\tDice             *Dice\n\tCurrentPlayerIdx int\n}\n\nfunc NewSnakeAndLadderGame(playerNames []string) *SnakeAndLadderGame {\n\tgame := &SnakeAndLadderGame{\n\t\tID:               generateID(),\n\t\tBoard:            NewBoard(),\n\t\tDice:             NewDice(),\n\t\tPlayers:          []*Player{},\n\t\tCurrentPlayerIdx: 0,\n\t}\n\n\tfor _, name := range playerNames {\n\t\tgame.Players = append(game.Players, NewPlayer(name))\n\t}\n\treturn game\n}\n\nfunc (g *SnakeAndLadderGame) Play(wg *sync.WaitGroup) {\n\tfor !g.isGameOver() {\n\t\tplayer := g.Players[g.CurrentPlayerIdx]\n\t\troll := g.Dice.Roll()\n\t\tnewPosition := player.Position + roll\n\n\t\tif newPosition <= g.Board.Size {\n\t\t\tplayer.Position = g.Board.GetNewPosition(newPosition)\n\t\t\tfmt.Printf(\"Game: %d :- %s rolled a %d and moved to position %d\\n\", g.ID, player.Name, roll, player.Position)\n\t\t}\n\n\t\tif player.Position == g.Board.Size {\n\t\t\tfmt.Printf(\"For Game %d :- %s wins!\\n\", g.ID, player.Name)\n\t\t\tbreak\n\t\t}\n\n\t\tg.CurrentPlayerIdx = (g.CurrentPlayerIdx + 1) % len(g.Players)\n\t\ttime.Sleep(10 * time.Millisecond) //To simulate the demo\n\t}\n\twg.Done()\n}\n\nfunc (g *SnakeAndLadderGame) isGameOver() bool {\n\tfor _, player := range g.Players {\n\t\tif player.Position == g.Board.Size {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar idCounter int64\n\nfunc generateID() int64 {\n\treturn atomic.AddInt64(&idCounter, 1)\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/README.md",
    "content": "# Designing a Social Network Like Facebook\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their personal information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their information, such as profile picture, bio, and interests.\n- Users should be able to update their profile information.\n#### Friend Connections:\n- Users should be able to send friend requests to other users.\n- Users should be able to accept or decline friend requests.\n- Users should be able to view their list of friends.\n#### Posts and Newsfeed:\n- Users should be able to create posts with text, images, or videos.\n- Users should be able to view a newsfeed consisting of posts from their friends and their own posts.\n- The newsfeed should be sorted in reverse chronological order.\n#### Likes and Comments:\n- Users should be able to like and comment on posts.\n- Users should be able to view the list of likes and comments on a post.\n#### Privacy and Security:\n- Users should be able to control the visibility of their posts and profile information.\n- The system should enforce secure access control to ensure data privacy.\n#### Notifications:\n- Users should receive notifications for events such as friend requests, likes, comments, and mentions.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the social networking system, containing properties such as ID, name, email, password, profile picture, bio, list of friends, and list of posts.\n2. The **Post** class represents a post created by a user, containing properties such as ID, user ID, content, image URLs, video URLs, timestamp, likes, and comments.\n3. The **Comment** class represents a comment made by a user on a post, containing properties such as ID, user ID, post ID, content, and timestamp.\n4. The **Notification** class represents a notification generated for a user, containing properties such as ID, user ID, notification type, content, and timestamp.\n5. The **NotificationType** enum defines the different types of notifications, such as friend request, friend request accepted, like, comment, and mention.\n6. The **SocialNetworkingService** class is the main class that manages the social networking system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SocialNetworkingService class provides methods for user registration, login, profile updates, friend requests, post creation, newsfeed generation, likes, comments, and notifications.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SocialNetworkingDemo** class demonstrates the usage of the social networking system by registering users, logging in, sending friend requests, creating posts, liking posts, commenting on posts, and retrieving newsfeed and notifications."
  },
  {
    "path": "solutions/golang/socialnetworkingservice/comment.go",
    "content": "package socialnetworkingservice\n\nimport \"time\"\n\ntype Comment struct {\n\tID        string\n\tUserID    string\n\tPostID    string\n\tContent   string\n\tTimestamp time.Time\n}\n\nfunc NewComment(id, userID, postID, content string) *Comment {\n\treturn &Comment{\n\t\tID:        id,\n\t\tUserID:    userID,\n\t\tPostID:    postID,\n\t\tContent:   content,\n\t\tTimestamp: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/notification.go",
    "content": "package socialnetworkingservice\n\nimport \"time\"\n\ntype Notification struct {\n\tID        string\n\tUserID    string\n\tType      NotificationType\n\tContent   string\n\tTimestamp time.Time\n}\n\nfunc NewNotification(id, userID string, notifType NotificationType, content string) *Notification {\n\treturn &Notification{\n\t\tID:        id,\n\t\tUserID:    userID,\n\t\tType:      notifType,\n\t\tContent:   content,\n\t\tTimestamp: time.Now(),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/post.go",
    "content": "package socialnetworkingservice\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype Post struct {\n\tID        string\n\tUserID    string\n\tContent   string\n\tImageURLs []string\n\tVideoURLs []string\n\tTimestamp time.Time\n\tlikes     map[string]bool\n\tcomments  []*Comment\n\tmu        sync.RWMutex\n}\n\nfunc NewPost(id, userID, content string, imageURLs, videoURLs []string) *Post {\n\treturn &Post{\n\t\tID:        id,\n\t\tUserID:    userID,\n\t\tContent:   content,\n\t\tImageURLs: imageURLs,\n\t\tVideoURLs: videoURLs,\n\t\tTimestamp: time.Now(),\n\t\tlikes:     make(map[string]bool),\n\t\tcomments:  make([]*Comment, 0),\n\t}\n}\n\nfunc (p *Post) AddLike(userID string) bool {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif !p.likes[userID] {\n\t\tp.likes[userID] = true\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (p *Post) AddComment(comment *Comment) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tp.comments = append(p.comments, comment)\n}\n\nfunc (p *Post) GetLikes() []string {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\tlikes := make([]string, 0, len(p.likes))\n\tfor userID := range p.likes {\n\t\tlikes = append(likes, userID)\n\t}\n\treturn likes\n}\n\nfunc (p *Post) GetComments() []*Comment {\n\tp.mu.RLock()\n\tdefer p.mu.RUnlock()\n\tcomments := make([]*Comment, len(p.comments))\n\tcopy(comments, p.comments)\n\treturn comments\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/social_networking_service.go",
    "content": "package socialnetworkingservice\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype SocialNetwork struct {\n\tusers         map[string]*User\n\tposts         map[string]*Post\n\tnotifications map[string][]*Notification\n\tmu            sync.RWMutex\n}\n\nvar (\n\tinstance *SocialNetwork\n\tonce     sync.Once\n)\n\nfunc GetSocialNetwork() *SocialNetwork {\n\tonce.Do(func() {\n\t\tinstance = &SocialNetwork{\n\t\t\tusers:         make(map[string]*User),\n\t\t\tposts:         make(map[string]*Post),\n\t\t\tnotifications: make(map[string][]*Notification),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (sn *SocialNetwork) RegisterUser(user *User) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\tif _, exists := sn.users[user.ID]; exists {\n\t\treturn fmt.Errorf(\"user with ID %s already exists\", user.ID)\n\t}\n\tsn.users[user.ID] = user\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) LoginUser(email, password string) (*User, error) {\n\tsn.mu.RLock()\n\tdefer sn.mu.RUnlock()\n\n\tfor _, user := range sn.users {\n\t\tif user.Email == email && user.Password == password {\n\t\t\treturn user, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"invalid email or password\")\n}\n\nfunc (sn *SocialNetwork) UpdateUserProfile(user *User) {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\tsn.users[user.ID] = user\n}\n\nfunc (sn *SocialNetwork) SendFriendRequest(senderID, receiverID string) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\treceiver, exists := sn.users[receiverID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"receiver not found\")\n\t} else {\n\t\tfmt.Printf(receiver.ID)\n\t}\n\n\tnotification := NewNotification(\n\t\tfmt.Sprintf(\"notif-%d\", time.Now().UnixNano()),\n\t\treceiverID,\n\t\tNotificationTypeFriendRequest,\n\t\tfmt.Sprintf(\"Friend request from %s\", senderID),\n\t)\n\n\tsn.addNotification(receiverID, notification)\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) AcceptFriendRequest(userID, friendID string) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\tuser, exists1 := sn.users[userID]\n\tfriend, exists2 := sn.users[friendID]\n\n\tif !exists1 || !exists2 {\n\t\treturn fmt.Errorf(\"user or friend not found\")\n\t}\n\n\tuser.AddFriend(friendID)\n\tfriend.AddFriend(userID)\n\n\tnotification := NewNotification(\n\t\tfmt.Sprintf(\"notif-%d\", time.Now().UnixNano()),\n\t\tfriendID,\n\t\tNotificationTypeFriendRequestAccepted,\n\t\tfmt.Sprintf(\"Friend request accepted by %s\", userID),\n\t)\n\n\tsn.addNotification(friendID, notification)\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) CreatePost(post *Post) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\tuser, exists := sn.users[post.UserID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"user not found\")\n\t}\n\n\tsn.posts[post.ID] = post\n\tuser.AddPost(post)\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) GetNewsfeed(userID string) ([]*Post, error) {\n\tsn.mu.RLock()\n\tdefer sn.mu.RUnlock()\n\n\tuser, exists := sn.users[userID]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"user not found\")\n\t}\n\n\tvar newsfeed []*Post\n\n\t// Add user's own posts\n\tnewsfeed = append(newsfeed, user.GetPosts()...)\n\n\t// Add friends' posts\n\tfor friendID := range user.friends {\n\t\tif friend, ok := sn.users[friendID]; ok {\n\t\t\tnewsfeed = append(newsfeed, friend.GetPosts()...)\n\t\t}\n\t}\n\n\t// Sort by timestamp (newest first)\n\tsort.Slice(newsfeed, func(i, j int) bool {\n\t\treturn newsfeed[i].Timestamp.After(newsfeed[j].Timestamp)\n\t})\n\n\treturn newsfeed, nil\n}\n\nfunc (sn *SocialNetwork) LikePost(userID, postID string) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\tpost, exists := sn.posts[postID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"post not found\")\n\t}\n\n\tif added := post.AddLike(userID); added {\n\t\tnotification := NewNotification(\n\t\t\tfmt.Sprintf(\"notif-%d\", time.Now().UnixNano()),\n\t\t\tpost.UserID,\n\t\t\tNotificationTypeLike,\n\t\t\tfmt.Sprintf(\"Your post was liked by %s\", userID),\n\t\t)\n\t\tsn.addNotification(post.UserID, notification)\n\t}\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) CommentOnPost(comment *Comment) error {\n\tsn.mu.Lock()\n\tdefer sn.mu.Unlock()\n\n\tpost, exists := sn.posts[comment.PostID]\n\tif !exists {\n\t\treturn fmt.Errorf(\"post not found\")\n\t}\n\n\tpost.AddComment(comment)\n\n\tnotification := NewNotification(\n\t\tfmt.Sprintf(\"notif-%d\", time.Now().UnixNano()),\n\t\tpost.UserID,\n\t\tNotificationTypeComment,\n\t\tfmt.Sprintf(\"Your post received a comment from %s\", comment.UserID),\n\t)\n\tsn.addNotification(post.UserID, notification)\n\treturn nil\n}\n\nfunc (sn *SocialNetwork) GetNotifications(userID string) ([]*Notification, error) {\n\tsn.mu.RLock()\n\tdefer sn.mu.RUnlock()\n\n\tif _, exists := sn.users[userID]; !exists {\n\t\treturn nil, fmt.Errorf(\"user not found\")\n\t}\n\n\treturn sn.notifications[userID], nil\n}\n\nfunc (sn *SocialNetwork) addNotification(userID string, notification *Notification) {\n\tsn.notifications[userID] = append(sn.notifications[userID], notification)\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/social_networking_service_demo.go",
    "content": "package socialnetworkingservice\n\nimport (\n\t\"fmt\"\n\t\"log\"\n)\n\nfunc Run() {\n\tsocialNetwork := GetSocialNetwork()\n\n\t// Create users\n\tuser1 := NewUser(\"1\", \"John Doe\", \"john@example.com\", \"password\", \"profile1.jpg\", \"I love coding!\")\n\tuser2 := NewUser(\"2\", \"Jane Smith\", \"jane@example.com\", \"password\", \"profile2.jpg\", \"Exploring the world!\")\n\n\t// Register users\n\tif err := socialNetwork.RegisterUser(user1); err != nil {\n\t\tlog.Printf(\"Failed to register user1: %v\", err)\n\t\treturn\n\t}\n\tif err := socialNetwork.RegisterUser(user2); err != nil {\n\t\tlog.Printf(\"Failed to register user2: %v\", err)\n\t\treturn\n\t}\n\n\t// Login\n\tloggedInUser, err := socialNetwork.LoginUser(\"john@example.com\", \"password\")\n\tif err != nil {\n\t\tlog.Printf(\"Login failed: %v\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"User logged in: %s\\n\", loggedInUser.Name)\n\n\t// Send friend request\n\tif err := socialNetwork.SendFriendRequest(user1.ID, user2.ID); err != nil {\n\t\tlog.Printf(\"Failed to send friend request: %v\", err)\n\t\treturn\n\t}\n\n\t// Accept friend request\n\tif err := socialNetwork.AcceptFriendRequest(user2.ID, user1.ID); err != nil {\n\t\tlog.Printf(\"Failed to accept friend request: %v\", err)\n\t\treturn\n\t}\n\n\t// Create posts\n\tpost1 := NewPost(\"post1\", user1.ID, \"My first post!\", []string{}, []string{})\n\tpost2 := NewPost(\"post2\", user2.ID, \"Having a great day!\", []string{}, []string{})\n\n\tif err := socialNetwork.CreatePost(post1); err != nil {\n\t\tlog.Printf(\"Failed to create post1: %v\", err)\n\t\treturn\n\t}\n\tif err := socialNetwork.CreatePost(post2); err != nil {\n\t\tlog.Printf(\"Failed to create post2: %v\", err)\n\t\treturn\n\t}\n\n\t// Like and comment\n\tif err := socialNetwork.LikePost(user2.ID, post1.ID); err != nil {\n\t\tlog.Printf(\"Failed to like post: %v\", err)\n\t\treturn\n\t}\n\n\tcomment := NewComment(\"comment1\", user2.ID, post1.ID, \"Great post!\")\n\tif err := socialNetwork.CommentOnPost(comment); err != nil {\n\t\tlog.Printf(\"Failed to comment on post: %v\", err)\n\t\treturn\n\t}\n\n\t// Get newsfeed\n\tnewsfeed, err := socialNetwork.GetNewsfeed(user1.ID)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to get newsfeed: %v\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"\\nNewsfeed:\")\n\tfor _, post := range newsfeed {\n\t\tfmt.Printf(\"Post: %s\\n\", post.Content)\n\t\tfmt.Printf(\"Likes: %d\\n\", len(post.GetLikes()))\n\t\tfmt.Printf(\"Comments: %d\\n\\n\", len(post.GetComments()))\n\t}\n\n\t// Get notifications\n\tnotifications, err := socialNetwork.GetNotifications(user1.ID)\n\tif err != nil {\n\t\tlog.Printf(\"Failed to get notifications: %v\", err)\n\t\treturn\n\t}\n\n\tfmt.Println(\"Notifications:\")\n\tfor _, notification := range notifications {\n\t\tfmt.Printf(\"Type: %s\\n\", notification.Type)\n\t\tfmt.Printf(\"Content: %s\\n\\n\", notification.Content)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/types.go",
    "content": "package socialnetworkingservice\n\ntype NotificationType int\n\nconst (\n    NotificationTypeFriendRequest NotificationType = iota\n    NotificationTypeFriendRequestAccepted\n    NotificationTypeLike\n    NotificationTypeComment\n    NotificationTypeMention\n)\n\nfunc (nt NotificationType) String() string {\n    return [...]string{\n        \"FRIEND_REQUEST\",\n        \"FRIEND_REQUEST_ACCEPTED\",\n        \"LIKE\",\n        \"COMMENT\",\n        \"MENTION\",\n    }[nt]\n}"
  },
  {
    "path": "solutions/golang/socialnetworkingservice/user.go",
    "content": "package socialnetworkingservice\n\nimport \"sync\"\n\ntype User struct {\n\tID             string\n\tName           string\n\tEmail          string\n\tPassword       string\n\tProfilePicture string\n\tBio            string\n\tfriends        map[string]bool\n\tposts          []*Post\n\tmu             sync.RWMutex\n}\n\nfunc NewUser(id, name, email, password, profilePicture, bio string) *User {\n\treturn &User{\n\t\tID:             id,\n\t\tName:           name,\n\t\tEmail:          email,\n\t\tPassword:       password,\n\t\tProfilePicture: profilePicture,\n\t\tBio:            bio,\n\t\tfriends:        make(map[string]bool),\n\t\tposts:          make([]*Post, 0),\n\t}\n}\n\nfunc (u *User) AddFriend(friendID string) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.friends[friendID] = true\n}\n\nfunc (u *User) AddPost(post *Post) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.posts = append(u.posts, post)\n}\n\nfunc (u *User) GetFriends() []string {\n\tu.mu.RLock()\n\tdefer u.mu.RUnlock()\n\tfriends := make([]string, 0, len(u.friends))\n\tfor friendID := range u.friends {\n\t\tfriends = append(friends, friendID)\n\t}\n\treturn friends\n}\n\nfunc (u *User) GetPosts() []*Post {\n\tu.mu.RLock()\n\tdefer u.mu.RUnlock()\n\tposts := make([]*Post, len(u.posts))\n\tcopy(posts, u.posts)\n\treturn posts\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/README.md",
    "content": "# Designing Splitwise\n\n## Requirements\n1. The system should allow users to create accounts and manage their profile information.\n2. Users should be able to create groups and add other users to the groups.\n3. Users should be able to add expenses within a group, specifying the amount, description, and participants.\n4. The system should automatically split the expenses among the participants based on their share.\n5. Users should be able to view their individual balances with other users and settle up the balances.\n6. The system should support different split methods, such as equal split, percentage split, and exact amounts.\n7. Users should be able to view their transaction history and group expenses.\n8. The system should handle concurrent transactions and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the Splitwise system, with properties such as ID, name, email, and a map to store balances with other users.\n2. The **Group** class represents a group in Splitwise, containing a list of member users and a list of expenses.\n3. The **Expense** class represents an expense within a group, with properties such as ID, amount, description, the user who paid, and a list of splits.\n4. The **Split** class is an abstract class representing the split of an expense. It is extended by EqualSplit, PercentSplit, and ExactSplit classes to handle different split methods.\n5. The **Transaction** class represents a transaction between two users, with properties such as ID, sender, receiver, and amount.\n6. The **SplitwiseService** class is the main class that manages the Splitwise system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SplitwiseService class provides methods for adding users, groups, and expenses, splitting expenses, updating balances, settling balances, and creating transactions.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SplitwiseDemo** class demonstrates the usage of the Splitwise system by creating users, a group, adding an expense, settling balances, and printing user balances."
  },
  {
    "path": "solutions/golang/splitwise/equal_split.go",
    "content": "package splitwise\n\ntype EqualSplit struct {\n\tUser   *User\n\tAmount float64\n}\n\nfunc NewEqualSplit(user *User) *EqualSplit {\n\treturn &EqualSplit{User: user}\n}\n\nfunc (e *EqualSplit) GetAmount() float64 {\n\treturn e.Amount\n}\n\nfunc (e *EqualSplit) SetAmount(amount float64) {\n\te.Amount = amount\n}\n\nfunc (e *EqualSplit) GetUser() *User {\n\treturn e.User\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/expense.go",
    "content": "package splitwise\n\ntype Expense struct {\n\tID          string\n\tAmount      float64\n\tDescription string\n\tPaidBy      *User\n\tSplits      []Split\n}\n\nfunc NewExpense(id string, amount float64, description string, paidBy *User) *Expense {\n\treturn &Expense{\n\t\tID:          id,\n\t\tAmount:      amount,\n\t\tDescription: description,\n\t\tPaidBy:      paidBy,\n\t\tSplits:      []Split{},\n\t}\n}\n\nfunc (e *Expense) AddSplit(split Split) {\n\te.Splits = append(e.Splits, split)\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/group.go",
    "content": "package splitwise\n\ntype Group struct {\n\tID       string\n\tName     string\n\tMembers  []*User\n\tExpenses []*Expense\n}\n\nfunc NewGroup(id, name string) *Group {\n\treturn &Group{\n\t\tID:       id,\n\t\tName:     name,\n\t\tMembers:  []*User{},\n\t\tExpenses: []*Expense{},\n\t}\n}\n\nfunc (g *Group) AddMember(user *User) {\n\tg.Members = append(g.Members, user)\n}\n\nfunc (g *Group) AddExpense(expense *Expense) {\n\tg.Expenses = append(g.Expenses, expense)\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/percent_split.go",
    "content": "package splitwise\n\ntype PercentSplit struct {\n\tUser    *User\n\tAmount  float64\n\tPercent float64\n}\n\nfunc NewPercentSplit(user *User, percent float64) *PercentSplit {\n\treturn &PercentSplit{User: user, Percent: percent}\n}\n\nfunc (p *PercentSplit) GetAmount() float64 {\n\treturn p.Amount\n}\n\nfunc (p *PercentSplit) SetAmount(amount float64) {\n\tp.Amount = amount\n}\n\nfunc (p *PercentSplit) GetUser() *User {\n\treturn p.User\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/split.go",
    "content": "package splitwise\n\ntype Split interface {\n\tGetAmount() float64\n\tSetAmount(amount float64)\n\tGetUser() *User\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/splitwise_demo.go",
    "content": "package splitwise\n\nimport (\n\t\"fmt\"\n)\n\nfunc Run() {\n\tservice := GetSplitwiseService()\n\n\t// Create users\n\tuser1 := NewUser(\"1\", \"Alice\", \"alice@example.com\")\n\tuser2 := NewUser(\"2\", \"Bob\", \"bob@example.com\")\n\tuser3 := NewUser(\"3\", \"Charlie\", \"charlie@example.com\")\n\tservice.AddUser(user1)\n\tservice.AddUser(user2)\n\tservice.AddUser(user3)\n\n\t// Create group and add users\n\tgroup := NewGroup(\"1\", \"Apartment\")\n\tgroup.AddMember(user1)\n\tgroup.AddMember(user2)\n\tgroup.AddMember(user3)\n\tservice.AddGroup(group)\n\n\t// Add expense\n\texpense := NewExpense(\"1\", 300, \"Rent\", user1)\n\texpense.AddSplit(NewEqualSplit(user1))\n\texpense.AddSplit(NewEqualSplit(user2))\n\texpense.AddSplit(NewPercentSplit(user3, 20))\n\tservice.AddExpense(group.ID, expense)\n\n\t// Settle balances\n\tservice.SettleBalance(user1.ID, user2.ID)\n\tservice.SettleBalance(user1.ID, user3.ID)\n\n\t// Print balances\n\tfor _, user := range []*User{user1, user2, user3} {\n\t\tfmt.Printf(\"User: %s\\n\", user.Name)\n\t\tfor key, balance := range user.Balances {\n\t\t\tfmt.Printf(\"  Balance with %s: %.2f\\n\", key, balance)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/splitwise_service.go",
    "content": "package splitwise\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n)\n\ntype SplitwiseService struct {\n\tusers   map[string]*User\n\tgroups  map[string]*Group\n\tcounter int\n\tmu      sync.Mutex\n}\n\nvar instance *SplitwiseService\nvar once sync.Once\n\nfunc GetSplitwiseService() *SplitwiseService {\n\tonce.Do(func() {\n\t\tinstance = &SplitwiseService{\n\t\t\tusers:  make(map[string]*User),\n\t\t\tgroups: make(map[string]*Group),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (s *SplitwiseService) AddUser(user *User) {\n\ts.users[user.ID] = user\n}\n\nfunc (s *SplitwiseService) AddGroup(group *Group) {\n\ts.groups[group.ID] = group\n}\n\nfunc (s *SplitwiseService) AddExpense(groupID string, expense *Expense) {\n\tgroup, exists := s.groups[groupID]\n\tif !exists {\n\t\treturn\n\t}\n\tgroup.AddExpense(expense)\n\ts.splitExpense(expense)\n\ts.updateBalances(expense)\n}\n\nfunc (s *SplitwiseService) splitExpense(expense *Expense) {\n\ttotalAmount := expense.Amount\n\ttotalSplits := len(expense.Splits)\n\n\tfor _, split := range expense.Splits {\n\t\tswitch v := split.(type) {\n\t\tcase *EqualSplit:\n\t\t\tv.SetAmount(totalAmount / float64(totalSplits))\n\t\tcase *PercentSplit:\n\t\t\tv.SetAmount(totalAmount * v.Percent / 100.0)\n\t\t}\n\t}\n}\n\nfunc (s *SplitwiseService) updateBalances(expense *Expense) {\n\tfor _, split := range expense.Splits {\n\t\tpaidBy := expense.PaidBy\n\t\tuser := split.GetUser()\n\t\tamount := split.GetAmount()\n\t\tif paidBy != user {\n\t\t\ts.updateBalance(paidBy, user, amount)\n\t\t\ts.updateBalance(user, paidBy, -amount)\n\t\t}\n\t}\n}\n\nfunc (s *SplitwiseService) updateBalance(user1, user2 *User, amount float64) {\n\tkey := user1.ID + \":\" + user2.ID\n\tuser1.Balances[key] += amount\n}\n\nfunc (s *SplitwiseService) SettleBalance(userID1, userID2 string) {\n\tuser1, exists1 := s.users[userID1]\n\tuser2, exists2 := s.users[userID2]\n\tif !exists1 || !exists2 {\n\t\treturn\n\t}\n\n\tkey := user1.ID + \":\" + user2.ID\n\tbalance := user1.Balances[key]\n\n\tif balance > 0 {\n\t\ts.createTransaction(user1, user2, balance)\n\t\tuser1.Balances[key] = 0\n\t\tuser2.Balances[user2.ID+\":\"+user1.ID] = 0\n\t} else if balance < 0 {\n\t\ts.createTransaction(user2, user1, -balance)\n\t\tuser1.Balances[key] = 0\n\t\tuser2.Balances[user2.ID+\":\"+user1.ID] = 0\n\t}\n}\n\nfunc (s *SplitwiseService) createTransaction(sender, receiver *User, amount float64) {\n\tfmt.Printf(\"Transaction: %s pays %s an amount of %.2f\\n\", sender.Name, receiver.Name, amount)\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/transaction.go",
    "content": "package splitwise\n\ntype Transaction struct {\n\tID       string\n\tSender   *User\n\tReceiver *User\n\tAmount   float64\n}\n\nfunc NewTransaction(id string, sender, receiver *User, amount float64) *Transaction {\n\treturn &Transaction{ID: id, Sender: sender, Receiver: receiver, Amount: amount}\n}\n"
  },
  {
    "path": "solutions/golang/splitwise/user.go",
    "content": "package splitwise\n\ntype User struct {\n\tID       string\n\tName     string\n\tEmail    string\n\tBalances map[string]float64\n}\n\nfunc NewUser(id, name, email string) *User {\n\treturn &User{\n\t\tID:       id,\n\t\tName:     name,\n\t\tEmail:    email,\n\t\tBalances: make(map[string]float64),\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/stackOverFlow/README.md",
    "content": "# Designing Stack Overflow\n\n## Requirements\n1. Users can post questions, answer questions, and comment on questions and answers.\n2. Users can vote on questions and answers.\n3. Questions should have tags associated with them.\n4. Users can search for questions based on keywords, tags, or user profiles.\n5. The system should assign reputation score to users based on their activity and the quality of their contributions.\n6. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the Stack Overflow system, with properties such as id, username, email, and reputation.\n2. The **Question** class represents a question posted by a user, with properties such as id, title, content, author, answers, comments, tags, votes and creation date.\n3. The **Answer** class represents an answer to a question, with properties such as id, content, author, associated question, comments, votes and creation date.\n4. The **Comment** class represents a comment on a question or an answer, with properties such as id, content, author, and creation date.\n5. The **Tag** class represents a tag associated with a question, with properties such as id and name.\n6. The **Vote** class represents vote associated with a question/answer.\n7. The **StackOverflow** class is the main class that manages the Stack Overflow system. It provides methods for creating user, posting questions, answers, and comments, voting on questions and answers, searching for questions, and retrieving questions by tags and users.\n8.  The **StackOverflowDemo** class demonstrates the usage of the Stack Overflow system by creating users, posting questions and answers, voting, searching for questions, and retrieving questions by tags and users."
  },
  {
    "path": "solutions/golang/stackOverFlow/answer.go",
    "content": "package stackoverflow\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\ntype Answer struct {\n\tID           string\n\tContent      string\n\tAuthor       *User\n\tQuestion     *Question\n\tCreationDate time.Time\n\tisAccepted   bool\n\tcomments     []*Comment\n\tvotes        []*Vote\n\tmu           sync.RWMutex\n}\n\nfunc NewAnswer(author *User, question *Question, content string) *Answer {\n\treturn &Answer{\n\t\tID:           generateID(),\n\t\tAuthor:       author,\n\t\tQuestion:     question,\n\t\tContent:      content,\n\t\tCreationDate: time.Now(),\n\t\tcomments:     make([]*Comment, 0),\n\t\tvotes:        make([]*Vote, 0),\n\t}\n}\n\nfunc (a *Answer) Vote(user *User, value int) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif value != 1 && value != -1 {\n\t\treturn fmt.Errorf(\"vote value must be either 1 or -1\")\n\t}\n\n\t// Remove existing vote from this user\n\tfor i, v := range a.votes {\n\t\tif v.User.ID == user.ID {\n\t\t\ta.votes = append(a.votes[:i], a.votes[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n\n\ta.votes = append(a.votes, &Vote{User: user, Value: value})\n\ta.Author.UpdateReputation(value * 10) // +10 for upvote, -10 for downvote\n\treturn nil\n}\n\nfunc (a *Answer) GetVoteCount() int {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\n\tcount := 0\n\tfor _, vote := range a.votes {\n\t\tcount += vote.Value\n\t}\n\treturn count\n}\n\nfunc (a *Answer) AddComment(comment *Comment) error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\ta.comments = append(a.comments, comment)\n\treturn nil\n}\n\nfunc (a *Answer) GetComments() []*Comment {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\tcomments := make([]*Comment, len(a.comments))\n\tcopy(comments, a.comments)\n\treturn comments\n}\n\nfunc (a *Answer) MarkAsAccepted() error {\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\n\tif a.isAccepted {\n\t\treturn fmt.Errorf(\"answer is already accepted\")\n\t}\n\n\ta.isAccepted = true\n\ta.Author.UpdateReputation(15) // +15 reputation for accepted answer\n\treturn nil\n}\n\nfunc (a *Answer) IsAccepted() bool {\n\ta.mu.RLock()\n\tdefer a.mu.RUnlock()\n\treturn a.isAccepted\n}\n"
  },
  {
    "path": "solutions/golang/stackOverFlow/stackoverflow.go",
    "content": "package stackoverflow\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype StackOverflow struct {\n\tusers     map[string]*User\n\tquestions map[string]*Question\n\tanswers   map[string]*Answer\n\ttags      map[string]*Tag\n\tmu        sync.RWMutex\n}\n\nfunc NewStackOverflow() *StackOverflow {\n\treturn &StackOverflow{\n\t\tusers:     make(map[string]*User),\n\t\tquestions: make(map[string]*Question),\n\t\tanswers:   make(map[string]*Answer),\n\t\ttags:      make(map[string]*Tag),\n\t}\n}\n\nfunc (so *StackOverflow) CreateUser(username, email string) *User {\n\tso.mu.Lock()\n\tdefer so.mu.Unlock()\n\n\tid := generateID()\n\tuser := NewUser(id, username, email)\n\tso.users[id] = user\n\treturn user\n}\n\nfunc (so *StackOverflow) AskQuestion(user *User, title, content string, tags []string) (*Question, error) {\n\tif user == nil {\n\t\treturn nil, fmt.Errorf(\"user cannot be nil\")\n\t}\n\n\tquestion := NewQuestion(user, title, content, tags)\n\n\tso.mu.Lock()\n\tdefer so.mu.Unlock()\n\n\tso.questions[question.ID] = question\n\tuser.AddQuestion(question)\n\n\t// Register tags\n\tfor _, tag := range question.GetTags() {\n\t\tso.tags[tag.Name] = tag\n\t}\n\n\treturn question, nil\n}\n\nfunc (so *StackOverflow) AnswerQuestion(user *User, question *Question, content string) (*Answer, error) {\n\tif user == nil || question == nil {\n\t\treturn nil, fmt.Errorf(\"user and question cannot be nil\")\n\t}\n\n\tanswer := NewAnswer(user, question, content)\n\n\tso.mu.Lock()\n\tdefer so.mu.Unlock()\n\n\tso.answers[answer.ID] = answer\n\tquestion.AddAnswer(answer)\n\tuser.AddAnswer(answer)\n\n\treturn answer, nil\n}\n\nfunc (so *StackOverflow) AddComment(user *User, target Commentable, content string) (*Comment, error) {\n\tif user == nil || target == nil {\n\t\treturn nil, fmt.Errorf(\"user and target cannot be nil\")\n\t}\n\n\tcomment := NewComment(user, content)\n\tif err := target.AddComment(comment); err != nil {\n\t\treturn nil, err\n\t}\n\n\tuser.AddComment(comment)\n\treturn comment, nil\n}\n\nfunc (so *StackOverflow) VoteQuestion(user *User, question *Question, value int) error {\n\tif user == nil || question == nil {\n\t\treturn fmt.Errorf(\"user and question cannot be nil\")\n\t}\n\treturn question.Vote(user, value)\n}\n\nfunc (so *StackOverflow) VoteAnswer(user *User, answer *Answer, value int) error {\n\tif user == nil || answer == nil {\n\t\treturn fmt.Errorf(\"user and answer cannot be nil\")\n\t}\n\treturn answer.Vote(user, value)\n}\n\nfunc (so *StackOverflow) AcceptAnswer(answer *Answer) error {\n\tif answer == nil {\n\t\treturn fmt.Errorf(\"answer cannot be nil\")\n\t}\n\treturn answer.MarkAsAccepted()\n}\n\nfunc (so *StackOverflow) SearchQuestions(query string) []*Question {\n\tso.mu.RLock()\n\tdefer so.mu.RUnlock()\n\n\tquery = strings.ToLower(query)\n\tvar results []*Question\n\n\tfor _, q := range so.questions {\n\t\tif strings.Contains(strings.ToLower(q.Title), query) ||\n\t\t\tstrings.Contains(strings.ToLower(q.Content), query) {\n\t\t\tresults = append(results, q)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Search in tags\n\t\tfor _, tag := range q.GetTags() {\n\t\t\tif strings.EqualFold(tag.Name, query) {\n\t\t\t\tresults = append(results, q)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn results\n}\n\nfunc (so *StackOverflow) GetQuestionsByUser(user *User) []*Question {\n\tif user == nil {\n\t\treturn nil\n\t}\n\treturn user.GetQuestions()\n}\n"
  },
  {
    "path": "solutions/golang/stackOverFlow/stackoverflow_demo.go",
    "content": "package stackoverflow\n\nimport \"fmt\"\n\nfunc Run() {\n\tsystem := NewStackOverflow()\n\n\t// Create users\n\talice := system.CreateUser(\"Alice\", \"alice@example.com\")\n\tbob := system.CreateUser(\"Bob\", \"bob@example.com\")\n\tcharlie := system.CreateUser(\"Charlie\", \"charlie@example.com\")\n\n\tfmt.Println(\"Users created:\", alice.Username, bob.Username, charlie.Username)\n\n\t// Alice asks a question about Java\n\tjavaQuestion, err := system.AskQuestion(alice,\n\t\t\"What is polymorphism in Java?\",\n\t\t\"Can someone explain polymorphism in Java with an example?\",\n\t\t[]string{\"java\", \"oop\"})\n\tif err != nil {\n\t\tfmt.Printf(\"Error asking Java question: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Bob answers Alice's question\n\tbobAnswer, err := system.AnswerQuestion(bob, javaQuestion,\n\t\t\"Polymorphism in Java is the ability of an object to take on many forms...\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error answering question: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Charlie comments on the question\n\t_, err = system.AddComment(charlie, javaQuestion,\n\t\t\"Great question! I'm also interested in learning about this.\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error adding comment to question: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Alice comments on Bob's answer\n\t_, err = system.AddComment(alice, bobAnswer,\n\t\t\"Thanks for the explanation! Could you provide a code example?\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error adding comment to answer: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Charlie votes on the question and answer\n\tif err := system.VoteQuestion(charlie, javaQuestion, 1); err != nil {\n\t\tfmt.Printf(\"Error voting on question: %v\\n\", err)\n\t\treturn\n\t}\n\tif err := system.VoteAnswer(charlie, bobAnswer, 1); err != nil {\n\t\tfmt.Printf(\"Error voting on answer: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Alice accepts Bob's answer\n\tif err := system.AcceptAnswer(bobAnswer); err != nil {\n\t\tfmt.Printf(\"Error accepting answer: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Bob asks a Python question\n\tpythonQuestion, err := system.AskQuestion(bob,\n\t\t\"How to use list comprehensions in Python?\",\n\t\t\"I'm new to Python and I've heard about list comprehensions. Can someone explain how to use them?\",\n\t\t[]string{\"python\", \"list-comprehension\"})\n\tif err != nil {\n\t\tfmt.Printf(\"Error asking Python question: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Alice answers Bob's question\n\taliceAnswer, err := system.AnswerQuestion(alice, pythonQuestion,\n\t\t\"List comprehensions in Python provide a concise way to create lists...\")\n\tif err != nil {\n\t\tfmt.Printf(\"Error answering Python question: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Charlie votes on Bob's question and Alice's answer\n\tif err := system.VoteQuestion(charlie, pythonQuestion, 1); err != nil {\n\t\tfmt.Printf(\"Error voting on Python question: %v\\n\", err)\n\t\treturn\n\t}\n\tif err := system.VoteAnswer(charlie, aliceAnswer, 1); err != nil {\n\t\tfmt.Printf(\"Error voting on Alice's answer: %v\\n\", err)\n\t\treturn\n\t}\n\n\t// Print out the current state\n\tfmt.Println(\"\\n=== Java Question ===\")\n\tfmt.Printf(\"Title: %s\\n\", javaQuestion.Title)\n\tfmt.Printf(\"Asked by: %s\\n\", javaQuestion.Author.Username)\n\tfmt.Printf(\"Tags: \")\n\tfor _, tag := range javaQuestion.GetTags() {\n\t\tfmt.Printf(\"%s \", tag.Name)\n\t}\n\tfmt.Printf(\"\\nVotes: %d\\n\", javaQuestion.GetVoteCount())\n\tfmt.Printf(\"Comments: %d\\n\", len(javaQuestion.GetComments()))\n\n\tfmt.Printf(\"\\nAnswer by %s:\\n\", bobAnswer.Author.Username)\n\tfmt.Printf(\"Content: %s\\n\", bobAnswer.Content)\n\tfmt.Printf(\"Votes: %d\\n\", bobAnswer.GetVoteCount())\n\tfmt.Printf(\"Accepted: %v\\n\", bobAnswer.IsAccepted())\n\tfmt.Printf(\"Comments: %d\\n\", len(bobAnswer.GetComments()))\n\n\tfmt.Println(\"\\n=== User Reputations ===\")\n\tfmt.Printf(\"Alice: %d\\n\", alice.GetReputation())\n\tfmt.Printf(\"Bob: %d\\n\", bob.GetReputation())\n\tfmt.Printf(\"Charlie: %d\\n\", charlie.GetReputation())\n\n\tfmt.Println(\"\\n=== Search Results ===\")\n\tfmt.Println(\"Search Results for 'java':\")\n\tjavaResults := system.SearchQuestions(\"java\")\n\tfor _, q := range javaResults {\n\t\tfmt.Printf(\"- %s\\n\", q.Title)\n\t}\n\n\tfmt.Println(\"\\nSearch Results for 'python':\")\n\tpythonResults := system.SearchQuestions(\"python\")\n\tfor _, q := range pythonResults {\n\t\tfmt.Printf(\"- %s\\n\", q.Title)\n\t}\n\n\tfmt.Println(\"\\n=== Bob's Questions ===\")\n\tbobQuestions := system.GetQuestionsByUser(bob)\n\tfor _, q := range bobQuestions {\n\t\tfmt.Printf(\"- %s\\n\", q.Title)\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/stackOverFlow/types.go",
    "content": "package stackoverflow\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n)\n\n// Interfaces\ntype Votable interface {\n\tVote(user *User, value int) error\n\tGetVoteCount() int\n}\n\ntype Commentable interface {\n\tAddComment(comment *Comment) error\n\tGetComments() []*Comment\n}\n\n// Reputation constants\nconst (\n\tQuestionReputation = 5\n\tAnswerReputation   = 10\n\tCommentReputation  = 2\n)\n\n// Vote type\ntype Vote struct {\n\tUser  *User\n\tValue int\n}\n\n// Comment type\ntype Comment struct {\n\tID           string\n\tContent      string\n\tAuthor       *User\n\tCreationDate time.Time\n\tmu           sync.RWMutex\n}\n\nfunc NewComment(author *User, content string) *Comment {\n\treturn &Comment{\n\t\tID:           generateID(),\n\t\tContent:      content,\n\t\tAuthor:       author,\n\t\tCreationDate: time.Now(),\n\t}\n}\n\n// Tag type\ntype Tag struct {\n\tID   string\n\tName string\n}\n\nfunc NewTag(name string) *Tag {\n\treturn &Tag{\n\t\tID:   generateID(),\n\t\tName: name,\n\t}\n}\n\n// User type\ntype User struct {\n\tID         string\n\tUsername   string\n\tEmail      string\n\treputation int\n\tquestions  []*Question\n\tanswers    []*Answer\n\tcomments   []*Comment\n\tmu         sync.RWMutex\n}\n\nfunc NewUser(id, username, email string) *User {\n\treturn &User{\n\t\tID:        id,\n\t\tUsername:  username,\n\t\tEmail:     email,\n\t\tquestions: make([]*Question, 0),\n\t\tanswers:   make([]*Answer, 0),\n\t\tcomments:  make([]*Comment, 0),\n\t}\n}\n\nfunc (u *User) UpdateReputation(value int) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.reputation += value\n\tif u.reputation < 0 {\n\t\tu.reputation = 0\n\t}\n}\n\nfunc (u *User) GetReputation() int {\n\tu.mu.RLock()\n\tdefer u.mu.RUnlock()\n\treturn u.reputation\n}\n\nfunc (u *User) AddQuestion(q *Question) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.questions = append(u.questions, q)\n\tu.UpdateReputation(QuestionReputation)\n}\n\nfunc (u *User) AddAnswer(a *Answer) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.answers = append(u.answers, a)\n\tu.UpdateReputation(AnswerReputation)\n}\n\nfunc (u *User) AddComment(c *Comment) {\n\tu.mu.Lock()\n\tdefer u.mu.Unlock()\n\tu.comments = append(u.comments, c)\n\tu.UpdateReputation(CommentReputation)\n}\n\nfunc (u *User) GetQuestions() []*Question {\n\tu.mu.RLock()\n\tdefer u.mu.RUnlock()\n\tquestions := make([]*Question, len(u.questions))\n\tcopy(questions, u.questions)\n\treturn questions\n}\n\n// Question type\ntype Question struct {\n\tID           string\n\tTitle        string\n\tContent      string\n\tAuthor       *User\n\tCreationDate time.Time\n\tanswers      []*Answer\n\tcomments     []*Comment\n\ttags         []*Tag\n\tvotes        []*Vote\n\tmu           sync.RWMutex\n}\n\nfunc NewQuestion(author *User, title, content string, tagNames []string) *Question {\n\tq := &Question{\n\t\tID:           generateID(),\n\t\tTitle:        title,\n\t\tContent:      content,\n\t\tAuthor:       author,\n\t\tCreationDate: time.Now(),\n\t\tanswers:      make([]*Answer, 0),\n\t\tcomments:     make([]*Comment, 0),\n\t\ttags:         make([]*Tag, 0),\n\t\tvotes:        make([]*Vote, 0),\n\t}\n\n\tfor _, tagName := range tagNames {\n\t\tq.tags = append(q.tags, NewTag(tagName))\n\t}\n\n\treturn q\n}\n\nfunc (q *Question) AddAnswer(answer *Answer) error {\n\tq.mu.Lock()\n\tdefer q.mu.Unlock()\n\n\t// Check for duplicate answer\n\tfor _, a := range q.answers {\n\t\tif a.ID == answer.ID {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tq.answers = append(q.answers, answer)\n\treturn nil\n}\n\nfunc (q *Question) Vote(user *User, value int) error {\n\tq.mu.Lock()\n\tdefer q.mu.Unlock()\n\n\tif value != 1 && value != -1 {\n\t\treturn fmt.Errorf(\"vote value must be either 1 or -1\")\n\t}\n\n\t// Remove existing vote from this user\n\tfor i, v := range q.votes {\n\t\tif v.User.ID == user.ID {\n\t\t\tq.votes = append(q.votes[:i], q.votes[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tq.votes = append(q.votes, &Vote{User: user, Value: value})\n\tq.Author.UpdateReputation(value * 5) // +5 for upvote, -5 for downvote\n\treturn nil\n}\n\nfunc (q *Question) GetVoteCount() int {\n\tq.mu.RLock()\n\tdefer q.mu.RUnlock()\n\n\tcount := 0\n\tfor _, vote := range q.votes {\n\t\tcount += vote.Value\n\t}\n\treturn count\n}\n\nfunc (q *Question) AddComment(comment *Comment) error {\n\tq.mu.Lock()\n\tdefer q.mu.Unlock()\n\tq.comments = append(q.comments, comment)\n\treturn nil\n}\n\nfunc (q *Question) GetComments() []*Comment {\n\tq.mu.RLock()\n\tdefer q.mu.RUnlock()\n\tcomments := make([]*Comment, len(q.comments))\n\tcopy(comments, q.comments)\n\treturn comments\n}\n\nfunc (q *Question) GetAnswers() []*Answer {\n\tq.mu.RLock()\n\tdefer q.mu.RUnlock()\n\tanswers := make([]*Answer, len(q.answers))\n\tcopy(answers, q.answers)\n\treturn answers\n}\n\nfunc (q *Question) GetTags() []*Tag {\n\tq.mu.RLock()\n\tdefer q.mu.RUnlock()\n\ttags := make([]*Tag, len(q.tags))\n\tcopy(tags, q.tags)\n\treturn tags\n}\n\n// Utility functions\nfunc generateID() string {\n\treturn fmt.Sprintf(\"%d\", time.Now().UnixNano())\n}\n"
  },
  {
    "path": "solutions/golang/taskmanagementsystem/README.md",
    "content": "# Designing a Task Management System\n\n## Requirements\n1. The task management system should allow users to create, update, and delete tasks.\n2. Each task should have a title, description, due date, priority, and status (e.g., pending, in progress, completed).\n3. Users should be able to assign tasks to other users and set reminders for tasks.\n4. The system should support searching and filtering tasks based on various criteria (e.g., priority, due date, assigned user).\n5. Users should be able to mark tasks as completed and view their task history.\n6. The system should handle concurrent access to tasks and ensure data consistency.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the task management system, with properties such as id, name, and email.\n2. The **TaskStatus** enum defines the possible states of a task, such as pending, in progress, and completed.\n3. The **Task** class represents a task in the system, with properties like id, title, description, due date, priority, status, and assigned user.\n4. The **TaskManager** class is the core of the task management system and follows the Singleton pattern to ensure a single instance of the task manager.\n5. The TaskManager class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to tasks and ensure thread safety.\n6. The TaskManager class provides methods for creating, updating, deleting, searching, and filtering tasks, as well as marking tasks as completed and retrieving task history for a user.\n7. The **TaskManagementSystem** class serves as the entry point of the application and demonstrates the usage of the task management system."
  },
  {
    "path": "solutions/golang/taskmanagementsystem/task.go",
    "content": "package taskmanagementsystem\n\nimport \"time\"\n\ntype Task struct {\n\tId           string\n\tTitle        string\n\tDescription  string\n\tDueDate      time.Time\n\tPriority     int\n\tStatus       TaskStatus\n\tAssignedUser *User\n}\n\nfunc NewTask(id, title, description string, dueDate time.Time, priority int, assignedUser *User) *Task {\n\treturn &Task{\n\t\tId:           id,\n\t\tTitle:        title,\n\t\tDescription:  description,\n\t\tDueDate:      dueDate,\n\t\tPriority:     priority,\n\t\tStatus:       Pending,\n\t\tAssignedUser: assignedUser,\n\t}\n}\n\nfunc (t *Task) GetId() string {\n\treturn t.Id\n}\n\nfunc (t *Task) GetTitle() string {\n\treturn t.Title\n}\n\nfunc (t *Task) GetDescription() string {\n\treturn t.Description\n}\n\nfunc (t *Task) GetDueDate() time.Time {\n\treturn t.DueDate\n}\n\nfunc (t *Task) GetPriority() int {\n\treturn t.Priority\n}\n\nfunc (t *Task) GetStatus() TaskStatus {\n\treturn t.Status\n}\n\nfunc (t *Task) GetAssignedUser() *User {\n\treturn t.AssignedUser\n}\n\nfunc (t *Task) SetTitle(title string) {\n\tt.Title = title\n}\n\nfunc (t *Task) SetDescription(description string) {\n\tt.Description = description\n}\n\nfunc (t *Task) SetDueDate(dueDate time.Time) {\n\tt.DueDate = dueDate\n}\n\nfunc (t *Task) SetPriority(priority int) {\n\tt.Priority = priority\n}\n\nfunc (t *Task) SetStatus(status TaskStatus) {\n\tt.Status = status\n}\n"
  },
  {
    "path": "solutions/golang/taskmanagementsystem/task_management_system_demo.go",
    "content": "package taskmanagementsystem\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\nfunc Run() {\n\ttaskManager := GetTaskManager()\n\n\t// Create users\n\tuser1 := NewUser(\"1\", \"John Doe\", \"john@example.com\")\n\tuser2 := NewUser(\"2\", \"Jane Smith\", \"jane@example.com\")\n\n\t// Create tasks\n\ttask1 := NewTask(\"1\", \"Task 1\", \"Description 1\", time.Now(), 1, user1)\n\ttask2 := NewTask(\"2\", \"Task 2\", \"Description 2\", time.Now(), 2, user2)\n\ttask3 := NewTask(\"3\", \"Task 3\", \"Description 3\", time.Now(), 1, user1)\n\n\t// Add tasks to the task manager\n\ttaskManager.CreateTask(task1)\n\ttaskManager.CreateTask(task2)\n\ttaskManager.CreateTask(task3)\n\n\t// Update a task\n\ttask2.SetDescription(\"Updated description\")\n\ttaskManager.UpdateTask(task2)\n\n\t// Search tasks\n\tsearchResults := taskManager.SearchTasks(\"Task\")\n\tfmt.Println(\"Search Results:\")\n\tfor _, task := range searchResults {\n\t\tfmt.Println(task.GetTitle())\n\t}\n\n\t// Filter tasks\n\tfilteredTasks := taskManager.FilterTasks(Pending, time.Unix(0, 0), time.Now(), 1)\n\tfmt.Println(\"Filtered Tasks:\")\n\tfor _, task := range filteredTasks {\n\t\tfmt.Println(task.GetTitle())\n\t}\n\n\t// Mark a task as completed\n\ttaskManager.MarkTaskAsCompleted(\"1\")\n\n\t// Get task history for a user\n\ttaskHistory := taskManager.GetTaskHistory(user1)\n\tfmt.Printf(\"Task History for %s:\\n\", user1.GetName())\n\tfor _, task := range taskHistory {\n\t\tfmt.Println(task.GetTitle())\n\t}\n\n\t// Delete a task\n\ttaskManager.DeleteTask(\"3\")\n}\n"
  },
  {
    "path": "solutions/golang/taskmanagementsystem/task_manager.go",
    "content": "package taskmanagementsystem\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype TaskManager struct {\n\ttasks     map[string]*Task\n\tuserTasks map[string][]*Task\n\tmu        sync.Mutex\n}\n\nvar instance *TaskManager\nvar once sync.Once\n\nfunc GetTaskManager() *TaskManager {\n\tonce.Do(func() {\n\t\tinstance = &TaskManager{\n\t\t\ttasks:     make(map[string]*Task),\n\t\t\tuserTasks: make(map[string][]*Task),\n\t\t}\n\t})\n\treturn instance\n}\n\nfunc (tm *TaskManager) CreateTask(task *Task) {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\ttm.tasks[task.GetId()] = task\n\ttm.assignTaskToUser(task.GetAssignedUser(), task)\n}\n\nfunc (tm *TaskManager) UpdateTask(updatedTask *Task) {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\tif existingTask, exists := tm.tasks[updatedTask.GetId()]; exists {\n\t\texistingTask.SetTitle(updatedTask.GetTitle())\n\t\texistingTask.SetDescription(updatedTask.GetDescription())\n\t\texistingTask.SetDueDate(updatedTask.GetDueDate())\n\t\texistingTask.SetPriority(updatedTask.GetPriority())\n\t\texistingTask.SetStatus(updatedTask.GetStatus())\n\n\t\tif existingTask.GetAssignedUser() != updatedTask.GetAssignedUser() {\n\t\t\ttm.unassignTaskFromUser(existingTask.GetAssignedUser(), existingTask)\n\t\t\ttm.assignTaskToUser(updatedTask.GetAssignedUser(), existingTask)\n\t\t}\n\t}\n}\n\nfunc (tm *TaskManager) DeleteTask(taskId string) {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\tif task, exists := tm.tasks[taskId]; exists {\n\t\tdelete(tm.tasks, taskId)\n\t\ttm.unassignTaskFromUser(task.GetAssignedUser(), task)\n\t}\n}\n\nfunc (tm *TaskManager) SearchTasks(keyword string) []*Task {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\tvar matchingTasks []*Task\n\tfor _, task := range tm.tasks {\n\t\tif contains(task.GetTitle(), keyword) || contains(task.GetDescription(), keyword) {\n\t\t\tmatchingTasks = append(matchingTasks, task)\n\t\t}\n\t}\n\treturn matchingTasks\n}\n\nfunc (tm *TaskManager) FilterTasks(status TaskStatus, startDate, endDate time.Time, priority int) []*Task {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\tvar filteredTasks []*Task\n\tfor _, task := range tm.tasks {\n\t\tif task.GetStatus() == status &&\n\t\t\ttask.GetDueDate().After(startDate) &&\n\t\t\ttask.GetDueDate().Before(endDate) &&\n\t\t\ttask.GetPriority() == priority {\n\t\t\tfilteredTasks = append(filteredTasks, task)\n\t\t}\n\t}\n\treturn filteredTasks\n}\n\nfunc (tm *TaskManager) MarkTaskAsCompleted(taskId string) {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\tif task, exists := tm.tasks[taskId]; exists {\n\t\ttask.SetStatus(Completed)\n\t}\n}\n\nfunc (tm *TaskManager) GetTaskHistory(user *User) []*Task {\n\ttm.mu.Lock()\n\tdefer tm.mu.Unlock()\n\n\treturn tm.userTasks[user.GetId()]\n}\n\nfunc (tm *TaskManager) assignTaskToUser(user *User, task *Task) {\n\ttm.userTasks[user.GetId()] = append(tm.userTasks[user.GetId()], task)\n}\n\nfunc (tm *TaskManager) unassignTaskFromUser(user *User, task *Task) {\n\ttasks := tm.userTasks[user.GetId()]\n\tfor i, t := range tasks {\n\t\tif t == task {\n\t\t\ttm.userTasks[user.GetId()] = append(tasks[:i], tasks[i+1:]...)\n\t\t\tbreak\n\t\t}\n\t}\n}\n\nfunc contains(text, substr string) bool {\n\treturn len(text) >= len(substr) && text[:len(substr)] == substr\n}\n"
  },
  {
    "path": "solutions/golang/taskmanagementsystem/task_status.go",
    "content": "package taskmanagementsystem\n\ntype TaskStatus string\n\nconst (\n\tPending    TaskStatus = \"PENDING\"\n\tInProgress TaskStatus = \"IN_PROGRESS\"\n\tCompleted  TaskStatus = \"COMPLETED\"\n)\n"
  },
  {
    "path": "solutions/golang/taskmanagementsystem/user.go",
    "content": "package taskmanagementsystem\n\ntype User struct {\n\tId    string\n\tName  string\n\tEmail string\n}\n\nfunc NewUser(id, name, email string) *User {\n\treturn &User{Id: id, Name: name, Email: email}\n}\n\nfunc (u *User) GetId() string {\n\treturn u.Id\n}\n\nfunc (u *User) GetName() string {\n\treturn u.Name\n}\n"
  },
  {
    "path": "solutions/golang/tictactoe/README.md",
    "content": "# Designing a Tic Tac Toe Game\n\n## Requirements\n1. The Tic-Tac-Toe game should be played on a 3x3 grid.\n2. Two players take turns marking their symbols (X or O) on the grid.\n3. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game.\n4. If all the cells on the grid are filled and no player has won, the game ends in a draw.\n5. The game should have a user interface to display the grid and allow players to make their moves.\n6. The game should handle player turns and validate moves to ensure they are legal.\n7. The game should detect and announce the winner or a draw at the end of the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Player** class represents a player in the game, with a name and a symbol (X or O).\n2. The **Board** class represents the game board, which is a 3x3 grid. It provides methods to make moves, check for a winner, and check if the board is full.\n3. The **Game** class manages the game flow and player interactions. It handles player turns, validates moves, and determines the winner or a draw.\n4. The **TicTacToe** class is the entry point of the application and creates instances of the players and the game."
  },
  {
    "path": "solutions/golang/tictactoe/board.go",
    "content": "package tictactoe\n\nimport \"fmt\"\n\ntype Board struct {\n\tGrid       [3][3]rune\n\tMovesCount int\n}\n\nfunc NewBoard() *Board {\n\tboard := &Board{}\n\tboard.InitializeBoard()\n\treturn board\n}\n\nfunc (b *Board) InitializeBoard() {\n\tfor row := 0; row < 3; row++ {\n\t\tfor col := 0; col < 3; col++ {\n\t\t\tb.Grid[row][col] = '-'\n\t\t}\n\t}\n\tb.MovesCount = 0\n}\n\nfunc (b *Board) MakeMove(row, col int, symbol rune) error {\n\tif row < 0 || row >= 3 || col < 0 || col >= 3 || b.Grid[row][col] != '-' {\n\t\treturn fmt.Errorf(\"invalid move!\")\n\t}\n\tb.Grid[row][col] = symbol\n\tb.MovesCount++\n\treturn nil\n}\n\nfunc (b *Board) IsFull() bool {\n\treturn b.MovesCount == 9\n}\n\nfunc (b *Board) HasWinner() bool {\n\t// Check rows\n\tfor row := 0; row < 3; row++ {\n\t\tif b.Grid[row][0] != '-' && b.Grid[row][0] == b.Grid[row][1] && b.Grid[row][1] == b.Grid[row][2] {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Check columns\n\tfor col := 0; col < 3; col++ {\n\t\tif b.Grid[0][col] != '-' && b.Grid[0][col] == b.Grid[1][col] && b.Grid[1][col] == b.Grid[2][col] {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// Check diagonals\n\tif b.Grid[0][0] != '-' && b.Grid[0][0] == b.Grid[1][1] && b.Grid[1][1] == b.Grid[2][2] {\n\t\treturn true\n\t}\n\treturn b.Grid[0][2] != '-' && b.Grid[0][2] == b.Grid[1][1] && b.Grid[1][1] == b.Grid[2][0]\n}\n\nfunc (b *Board) PrintBoard() {\n\tfor row := 0; row < 3; row++ {\n\t\tfor col := 0; col < 3; col++ {\n\t\t\tfmt.Print(string(b.Grid[row][col]) + \" \")\n\t\t}\n\t\tfmt.Println()\n\t}\n\tfmt.Println()\n}\n"
  },
  {
    "path": "solutions/golang/tictactoe/game.go",
    "content": "package tictactoe\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n)\n\ntype Game struct {\n\tPlayer1       *Player\n\tPlayer2       *Player\n\tBoard         *Board\n\tCurrentPlayer *Player\n}\n\nfunc NewGame(player1, player2 *Player) *Game {\n\treturn &Game{\n\t\tPlayer1:       player1,\n\t\tPlayer2:       player2,\n\t\tBoard:         NewBoard(),\n\t\tCurrentPlayer: player1,\n\t}\n}\n\nfunc (g *Game) Play() {\n\tg.Board.PrintBoard()\n\n\tfor !g.Board.IsFull() && !g.Board.HasWinner() {\n\t\tfmt.Printf(\"%s's turn.\\n\", g.CurrentPlayer.Name)\n\t\trow := g.getValidInput(\"Enter row (0-2): \")\n\t\tcol := g.getValidInput(\"Enter column (0-2): \")\n\n\t\terr := g.Board.MakeMove(row, col, g.CurrentPlayer.Symbol)\n\t\tif err != nil {\n\t\t\tfmt.Println(err.Error())\n\t\t\tcontinue\n\t\t}\n\n\t\tg.Board.PrintBoard()\n\t\tg.switchPlayer()\n\t}\n\n\tif g.Board.HasWinner() {\n\t\tg.switchPlayer() // Switch back to the winner\n\t\tfmt.Printf(\"%s wins!\\n\", g.CurrentPlayer.Name)\n\t} else {\n\t\tfmt.Println(\"It's a draw!\")\n\t}\n}\n\nfunc (g *Game) switchPlayer() {\n\tif g.CurrentPlayer == g.Player1 {\n\t\tg.CurrentPlayer = g.Player2\n\t} else {\n\t\tg.CurrentPlayer = g.Player1\n\t}\n}\n\nfunc (g *Game) getValidInput(prompt string) int {\n\tscanner := bufio.NewScanner(os.Stdin)\n\tfor {\n\t\tfmt.Print(prompt)\n\t\tscanner.Scan()\n\t\tinput, err := strconv.Atoi(scanner.Text())\n\t\tif err == nil && input >= 0 && input <= 2 {\n\t\t\treturn input\n\t\t}\n\t\tfmt.Println(\"Invalid input! Please enter a number between 0 and 2.\")\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/tictactoe/player.go",
    "content": "package tictactoe\n\ntype Player struct {\n\tName   string\n\tSymbol rune\n}\n\nfunc NewPlayer(name string, symbol rune) *Player {\n\treturn &Player{Name: name, Symbol: symbol}\n}\n"
  },
  {
    "path": "solutions/golang/tictactoe/tictactoe_demo.go",
    "content": "package tictactoe\n\nfunc Run() {\n\tplayer1 := NewPlayer(\"Player 1\", 'X')\n\tplayer2 := NewPlayer(\"Player 2\", 'O')\n\n\tgame := NewGame(player1, player2)\n\tgame.Play()\n}\n"
  },
  {
    "path": "solutions/golang/trafficsignalsystem/README.md",
    "content": "# Designing a Traffic Signal Control System\n\n## Requirements\n1. The traffic signal system should control the flow of traffic at an intersection with multiple roads.\n2. The system should support different types of signals, such as red, yellow, and green.\n3. The duration of each signal should be configurable and adjustable based on traffic conditions.\n4. The system should handle the transition between signals smoothly, ensuring safe and efficient traffic flow.\n5. The system should be able to detect and handle emergency situations, such as an ambulance or fire truck approaching the intersection.\n6. The system should be scalable and extensible to support additional features and functionality.\n\n## Classes, Interfaces and Enumerations\n1. The **Signal** enum represents the different states of a traffic light: red, yellow, and green.\n2. The **Road** class represents a road in the traffic signal system, with properties such as ID, name, and an associated traffic light.\n3. The **TrafficLight** class represents a traffic light, with properties such as ID, current signal, and durations for each signal state. It provides methods to change the signal and notify observers (e.g., roads) about signal changes.\n4. The **TrafficController** class serves as the central controller for the traffic signal system. It follows the Singleton pattern to ensure a single instance of the controller. It manages the roads and their associated traffic lights, starts the traffic control process, and handles emergency situations.\n5. The **TrafficSignalSystemDemo** class is the main entry point of the application. It demonstrates the usage of the traffic signal system by creating roads, traffic lights, assigning traffic lights to roads, and starting the traffic control process."
  },
  {
    "path": "solutions/golang/trafficsignalsystem/road.go",
    "content": "package trafficsignalsystem\n\ntype Road struct {\n\tID           string\n\tName         string\n\tTrafficLight *TrafficLight\n}\n\nfunc NewRoad(id, name string) *Road {\n\treturn &Road{ID: id, Name: name}\n}\n\nfunc (r *Road) SetTrafficLight(trafficLight *TrafficLight) {\n\tr.TrafficLight = trafficLight\n}\n"
  },
  {
    "path": "solutions/golang/trafficsignalsystem/signal.go",
    "content": "package trafficsignalsystem\n\ntype Signal string\n\nconst (\n\tRed    Signal = \"RED\"\n\tYellow Signal = \"YELLOW\"\n\tGreen  Signal = \"GREEN\"\n)\n"
  },
  {
    "path": "solutions/golang/trafficsignalsystem/traffic_controller.go",
    "content": "package trafficsignalsystem\n\nimport (\n\t\"sync\"\n\t\"time\"\n)\n\ntype TrafficController struct {\n\troads map[string]*Road\n\tmu    sync.Mutex\n}\n\nvar instance *TrafficController\nvar once sync.Once\n\n// GetTrafficController returns the singleton instance of TrafficController\nfunc GetTrafficController() *TrafficController {\n\tonce.Do(func() {\n\t\tinstance = &TrafficController{roads: make(map[string]*Road)}\n\t})\n\treturn instance\n}\n\nfunc (tc *TrafficController) AddRoad(road *Road) {\n\ttc.mu.Lock()\n\tdefer tc.mu.Unlock()\n\ttc.roads[road.ID] = road\n}\n\nfunc (tc *TrafficController) StartTrafficControl() {\n\ttc.mu.Lock()\n\tdefer tc.mu.Unlock()\n\n\tfor _, road := range tc.roads {\n\t\ttrafficLight := road.TrafficLight\n\t\tgo func(tl *TrafficLight) {\n\t\t\tfor {\n\t\t\t\ttime.Sleep(time.Duration(tl.RedDuration) * time.Millisecond)\n\t\t\t\ttl.ChangeSignal(Green)\n\t\t\t\ttime.Sleep(time.Duration(tl.GreenDuration) * time.Millisecond)\n\t\t\t\ttl.ChangeSignal(Yellow)\n\t\t\t\ttime.Sleep(time.Duration(tl.YellowDuration) * time.Millisecond)\n\t\t\t\ttl.ChangeSignal(Red)\n\t\t\t}\n\t\t}(trafficLight)\n\t}\n}\n\nfunc (tc *TrafficController) HandleEmergency(roadID string) {\n\ttc.mu.Lock()\n\tdefer tc.mu.Unlock()\n\n\tif road, exists := tc.roads[roadID]; exists {\n\t\ttrafficLight := road.TrafficLight\n\t\ttrafficLight.ChangeSignal(Green)\n\t\t// Emergency handling logic here\n\t}\n}\n"
  },
  {
    "path": "solutions/golang/trafficsignalsystem/traffic_light.go",
    "content": "package trafficsignalsystem\n\nimport \"fmt\"\n\ntype TrafficLight struct {\n\tID             string\n\tCurrentSignal  Signal\n\tRedDuration    int\n\tYellowDuration int\n\tGreenDuration  int\n}\n\nfunc NewTrafficLight(id string, redDuration, yellowDuration, greenDuration int) *TrafficLight {\n\treturn &TrafficLight{\n\t\tID:             id,\n\t\tRedDuration:    redDuration,\n\t\tYellowDuration: yellowDuration,\n\t\tGreenDuration:  greenDuration,\n\t\tCurrentSignal:  Red,\n\t}\n}\n\nfunc (tl *TrafficLight) ChangeSignal(newSignal Signal) {\n\ttl.CurrentSignal = newSignal\n\ttl.notifyObservers()\n}\n\nfunc (tl *TrafficLight) notifyObservers() {\n\tfmt.Printf(\"Traffic Light %s changed to %s\\n\", tl.ID, tl.CurrentSignal)\n}\n"
  },
  {
    "path": "solutions/golang/trafficsignalsystem/traffic_signal_system_demo.go",
    "content": "package trafficsignalsystem\n\nimport \"time\"\n\n// Run demonstrates the Traffic Signal System functionality\nfunc Run() {\n\t// Initialize the traffic controller\n\ttrafficController := GetTrafficController()\n\n\t// Create roads\n\troad1 := NewRoad(\"R1\", \"Main Street\")\n\troad2 := NewRoad(\"R2\", \"Broadway\")\n\troad3 := NewRoad(\"R3\", \"Park Avenue\")\n\troad4 := NewRoad(\"R4\", \"Elm Street\")\n\n\t// Create traffic lights\n\ttrafficLight1 := NewTrafficLight(\"TL1\", 6000, 3000, 9000)\n\ttrafficLight2 := NewTrafficLight(\"TL2\", 6000, 3000, 9000)\n\ttrafficLight3 := NewTrafficLight(\"TL3\", 6000, 3000, 9000)\n\ttrafficLight4 := NewTrafficLight(\"TL4\", 6000, 3000, 9000)\n\n\t// Assign traffic lights to roads\n\troad1.SetTrafficLight(trafficLight1)\n\troad2.SetTrafficLight(trafficLight2)\n\troad3.SetTrafficLight(trafficLight3)\n\troad4.SetTrafficLight(trafficLight4)\n\n\t// Add roads to the traffic controller\n\ttrafficController.AddRoad(road1)\n\ttrafficController.AddRoad(road2)\n\ttrafficController.AddRoad(road3)\n\ttrafficController.AddRoad(road4)\n\n\t// Start traffic control\n\tgo trafficController.StartTrafficControl()\n\n\t// Simulate an emergency after some time\n\ttime.Sleep(10 * time.Second)\n\ttrafficController.HandleEmergency(\"R2\")\n}\n"
  },
  {
    "path": "solutions/golang/vendingmachine/README.md",
    "content": "# Designing a Vending Machine\n\n## Requirements\n1. The vending machine should support multiple products with different prices and quantities.\n1. The machine should accept coins and notes of different denominations.\n1. The machine should dispense the selected product and return change if necessary.\n1. The machine should keep track of the available products and their quantities.\n1. The machine should handle multiple transactions concurrently and ensure data consistency.\n1. The machine should provide an interface for restocking products and collecting money.\n1. The machine should handle exceptional scenarios, such as insufficient funds or out-of-stock products.\n\n## Classes, Interfaces and Enumerations\n1. The **Product** class represents a product in the vending machine, with properties such as name and price.\n2. The **Coin** and **Note** enums represent the different denominations of coins and notes accepted by the vending machine.\n3. The **Inventory** class manages the available products and their quantities in the vending machine. It uses a concurrent hash map to ensure thread safety.\n4. The **VendingMachineState** interface defines the behavior of the vending machine in different states, such as idle, ready, and dispense.\n5. The **IdleState**, **ReadyState**, and **DispenseState** classes implement the VendingMachineState interface and define the specific behaviors for each state.\n6. The **VendingMachine** class is the main class that represents the vending machine. It follows the Singleton pattern to ensure only one instance of the vending machine exists.\n7. The VendingMachine class maintains the current state, selected product, total payment, and provides methods for state transitions and payment handling.\n8. The **VendingMachineDemo** class demonstrates the usage of the vending machine by adding products to the inventory, selecting products, inserting coins and notes, dispensing products, and returning change."
  },
  {
    "path": "solutions/golang/vendingmachine/coin.go",
    "content": "package vending_machine\n\ntype Coin float64\n\nconst (\n\tPENNY   Coin = 0.01\n\tNICKEL  Coin = 0.05\n\tDIME    Coin = 0.10\n\tQUARTER Coin = 0.25\n)\n"
  },
  {
    "path": "solutions/golang/vendingmachine/inventory.go",
    "content": "package vending_machine\n\ntype Inventory struct {\n\tproducts map[*Product]int\n}\n\nfunc NewInventory() *Inventory {\n\treturn &Inventory{products: make(map[*Product]int)}\n}\n\nfunc (inv *Inventory) AddProduct(product *Product, quantity int) {\n\tinv.products[product] = quantity\n}\n\nfunc (inv *Inventory) IsAvailable(product *Product) bool {\n\tqty, exists := inv.products[product]\n\treturn exists && qty > 0\n}\n"
  },
  {
    "path": "solutions/golang/vendingmachine/note.go",
    "content": "package vending_machine\n\ntype Note int\n\nconst (\n\tONE    Note = 1\n\tFIVE   Note = 5\n\tTEN    Note = 10\n\tTWENTY Note = 20\n)\n"
  },
  {
    "path": "solutions/golang/vendingmachine/product.go",
    "content": "package vending_machine\n\ntype Product struct {\n\tname  string\n\tprice float64\n}\n\nfunc NewProduct(name string, price float64) *Product {\n\treturn &Product{name: name, price: price}\n}\n"
  },
  {
    "path": "solutions/golang/vendingmachine/state.go",
    "content": "package vending_machine\n\nimport \"fmt\"\n\ntype VendingMachineState interface {\n\tSelectProduct(product *Product)\n\tInsertCoin(coin Coin)\n\tInsertNote(note Note)\n\tDispenseProduct()\n\tReturnChange()\n}\n\n// IdleState struct\ntype IdleState struct {\n\tvendingMachine *VendingMachine\n}\n\nfunc (s *IdleState) SelectProduct(product *Product) {\n\tif s.vendingMachine.inventory.IsAvailable(product) {\n\t\ts.vendingMachine.selectedProduct = product\n\t\ts.vendingMachine.SetState(s.vendingMachine.readyState)\n\t\tfmt.Println(\"Product selected:\", product.name)\n\t} else {\n\t\tfmt.Println(\"Product not available:\", product.name)\n\t}\n}\n\nfunc (s *IdleState) InsertCoin(coin Coin) { fmt.Println(\"Please select a product first.\") }\nfunc (s *IdleState) InsertNote(note Note) { fmt.Println(\"Please select a product first.\") }\nfunc (s *IdleState) DispenseProduct()     { fmt.Println(\"Please select a product and make payment.\") }\nfunc (s *IdleState) ReturnChange()        { fmt.Println(\"No change to return.\") }\n\n// ReadyState struct\ntype ReadyState struct {\n\tvendingMachine *VendingMachine\n}\n\nfunc (s *ReadyState) SelectProduct(product *Product) {\n\tfmt.Println(\"Product already selected. Please make payment.\")\n}\n\nfunc (s *ReadyState) InsertCoin(coin Coin) {\n\ts.vendingMachine.totalPayment += float64(coin)\n\tfmt.Println(\"Coin inserted:\", coin)\n\ts.checkPaymentStatus()\n}\n\nfunc (s *ReadyState) InsertNote(note Note) {\n\ts.vendingMachine.totalPayment += float64(note)\n\tfmt.Println(\"Note inserted:\", note)\n\ts.checkPaymentStatus()\n}\n\nfunc (s *ReadyState) DispenseProduct() { fmt.Println(\"Please make payment first.\") }\nfunc (s *ReadyState) ReturnChange() {\n\tchange := s.vendingMachine.totalPayment - s.vendingMachine.selectedProduct.price\n\tif change > 0 {\n\t\tfmt.Printf(\"Change returned: $%.2f\\n\", change)\n\t\ts.vendingMachine.ResetPayment()\n\t} else {\n\t\tfmt.Println(\"No change to return.\")\n\t}\n\ts.vendingMachine.SetState(s.vendingMachine.idleState)\n}\n\nfunc (s *ReadyState) checkPaymentStatus() {\n\tif s.vendingMachine.totalPayment >= s.vendingMachine.selectedProduct.price {\n\t\ts.vendingMachine.SetState(s.vendingMachine.dispenseState)\n\t}\n}\n\n// DispenseState struct\ntype DispenseState struct {\n\tvendingMachine *VendingMachine\n}\n\nfunc (s *DispenseState) SelectProduct(product *Product) { fmt.Println(\"Product already selected.\") }\nfunc (s *DispenseState) InsertCoin(coin Coin)           { fmt.Println(\"Please collect the product.\") }\nfunc (s *DispenseState) InsertNote(note Note)           { fmt.Println(\"Please collect the product.\") }\nfunc (s *DispenseState) DispenseProduct() {\n\tfmt.Println(\"Product dispensed:\", s.vendingMachine.selectedProduct.name)\n\ts.vendingMachine.SetState(s.vendingMachine.returnChangeState)\n}\n\nfunc (s *DispenseState) ReturnChange() { fmt.Println(\"Please collect the product first.\") }\n\n// ReturnChangeState struct\ntype ReturnChangeState struct {\n\tvendingMachine *VendingMachine\n}\n\nfunc (s *ReturnChangeState) SelectProduct(product *Product) {\n\tfmt.Println(\"Please collect the change first.\")\n}\nfunc (s *ReturnChangeState) InsertCoin(coin Coin) { fmt.Println(\"Please collect the change first.\") }\nfunc (s *ReturnChangeState) InsertNote(note Note) { fmt.Println(\"Please collect the change first.\") }\nfunc (s *ReturnChangeState) DispenseProduct() {\n\tfmt.Println(\"Product already dispensed. Please collect the change.\")\n}\nfunc (s *ReturnChangeState) ReturnChange() {\n\tchange := s.vendingMachine.totalPayment - s.vendingMachine.selectedProduct.price\n\tif change > 0 {\n\t\tfmt.Printf(\"Change returned: $%.2f\\n\", change)\n\t\ts.vendingMachine.ResetPayment()\n\t} else {\n\t\tfmt.Println(\"No change to return.\")\n\t}\n\ts.vendingMachine.ResetSelectedProduct()\n\ts.vendingMachine.SetState(s.vendingMachine.idleState)\n}\n"
  },
  {
    "path": "solutions/golang/vendingmachine/vending_machine.go",
    "content": "package vending_machine\n\ntype VendingMachine struct {\n\tinventory         *Inventory\n\tidleState         VendingMachineState\n\treadyState        VendingMachineState\n\tdispenseState     VendingMachineState\n\treturnChangeState VendingMachineState\n\tcurrentState      VendingMachineState\n\tselectedProduct   *Product\n\ttotalPayment      float64\n}\n\nfunc NewVendingMachine() *VendingMachine {\n\tvm := &VendingMachine{\n\t\tinventory: NewInventory(),\n\t}\n\tvm.idleState = &IdleState{vm}\n\tvm.readyState = &ReadyState{vm}\n\tvm.dispenseState = &DispenseState{vm}\n\tvm.returnChangeState = &ReturnChangeState{vm}\n\tvm.currentState = vm.idleState\n\treturn vm\n}\n\nfunc (vm *VendingMachine) SelectProduct(product *Product) {\n\tvm.currentState.SelectProduct(product)\n}\n\nfunc (vm *VendingMachine) InsertCoin(coin Coin) {\n\tvm.currentState.InsertCoin(coin)\n}\n\nfunc (vm *VendingMachine) InsertNote(note Note) {\n\tvm.currentState.InsertNote(note)\n}\n\nfunc (vm *VendingMachine) DispenseProduct() {\n\tvm.currentState.DispenseProduct()\n}\n\nfunc (vm *VendingMachine) ReturnChange() {\n\tvm.currentState.ReturnChange()\n}\n\nfunc (vm *VendingMachine) SetState(state VendingMachineState) {\n\tvm.currentState = state\n}\n\nfunc (vm *VendingMachine) ResetPayment() {\n\tvm.totalPayment = 0\n}\n\nfunc (vm *VendingMachine) ResetSelectedProduct() {\n\tvm.selectedProduct = nil\n}\n"
  },
  {
    "path": "solutions/golang/vendingmachine/vending_machine_demo.go",
    "content": "package vending_machine\n\nimport \"fmt\"\n\n// Run demonstrates the Vending Machine functionality.\nfunc Run() {\n\t// Initialize the vending machine\n\tvm := NewVendingMachine()\n\n\t// Create some products\n\tcoke := NewProduct(\"Coke\", 1.5)\n\tpepsi := NewProduct(\"Pepsi\", 1.5)\n\twater := NewProduct(\"Water\", 1.0)\n\n\t// Add products to the inventory\n\tvm.inventory.AddProduct(coke, 5)\n\tvm.inventory.AddProduct(pepsi, 3)\n\tvm.inventory.AddProduct(water, 2)\n\n\t// Demonstrate a transaction\n\tfmt.Println(\"Starting Vending Machine Demo\")\n\n\tfmt.Println(\"\\nSelecting Coke\")\n\tvm.SelectProduct(coke)\n\n\tfmt.Println(\"Inserting coins\")\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\n\tfmt.Println(\"Dispensing product\")\n\tvm.DispenseProduct()\n\n\tfmt.Println(\"Returning change\")\n\tvm.ReturnChange()\n\n\t// Another example with insufficient funds\n\tfmt.Println(\"\\nSelecting Pepsi with insufficient funds\")\n\tvm.SelectProduct(pepsi)\n\tvm.InsertCoin(QUARTER)\n\n\tfmt.Println(\"Trying to dispense Pepsi\")\n\tvm.DispenseProduct()\n\n\tfmt.Println(\"Adding more coins for Pepsi\")\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\tvm.InsertCoin(QUARTER)\n\n\tfmt.Println(\"Dispensing product\")\n\tvm.DispenseProduct()\n\n\tfmt.Println(\"Returning change\")\n\tvm.ReturnChange()\n}\n"
  },
  {
    "path": "solutions/golang/votingsystem/README.md",
    "content": "### Airline Management System\n\nThis is a simple airline management system that allows you to manage flights, passengers, and bookings."
  },
  {
    "path": "solutions/java/.gitignore",
    "content": "### IntelliJ IDEA ###\nout/\n!**/src/main/**/out/\n!**/src/test/**/out/\n\n### Eclipse ###\n.apt_generated\n.classpath\n.factorypath\n.taskList\n.settings\n.springBeans\n.sts4-cache\nbin/\n!**/src/main/**/bin/\n!**/src/test/**/bin/\n\n### NetBeans ###\n/nbproject/private/\n/nbbuild/\n/dist/\n/nbdist/\n/.nb-gradle/\n\n### VS Code ###\n.vscode/\n\n### Mac OS ###\n.DS_Store\n\n*.png\n**/diagrams/"
  },
  {
    "path": "solutions/java/pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>coffeevendingmachine</groupId>\n    <artifactId>coffeevendingmachine</artifactId>\n    <version>1.0-SNAPSHOT</version>\n    <packaging>jar</packaging>\n    <name>Coffee Vending Machine</name>\n    <properties>\n        <maven.compiler.source>1.8</maven.compiler.source>\n        <maven.compiler.target>1.8</maven.compiler.target>\n        <junit.jupiter.version>5.10.2</junit.jupiter.version>\n    </properties>\n    <dependencies>\n        <dependency>\n            <groupId>org.junit.jupiter</groupId>\n            <artifactId>junit-jupiter</artifactId>\n            <version>${junit.jupiter.version}</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>3.2.5</version>\n                <configuration>\n                    <useModulePath>false</useModulePath>\n                </configuration>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "solutions/java/src/LLDRunner.java",
    "content": "import airlinemanagementsystem.AirlineManagementSystemDemo;\nimport atm.ATMDemo;\nimport chessgame.ChessGameDemo;\nimport courseregistrationsystem.CourseRegistrationSystemDemo;\nimport fooddeliveryservice.FoodDeliveryServiceDemo;\nimport librarymanagementsystem.LibraryManagementSystemDemo;\nimport loggingframework.LoggingFrameworkDemo;\nimport lrucache.LRUCacheDemo;\nimport musicstreamingservice.MusicStreamingServiceDemo;\nimport onlineauctionsystem.AuctionSystemDemo;\nimport onlineshoppingservice.OnlineShoppingServiceDemo;\nimport parkinglot.ParkingLotDemo;\nimport ridesharingservice.RideSharingServiceDemo;\nimport snakeandladdergame.SnakeAndLadderDemo;\nimport socialnetworkingservice.SocialNetworkingServiceDemo;\nimport stackoverflow.StackOverflowDemo;\nimport taskmanagementsystem.TaskManagementSystemDemo;\nimport vendingmachine.VendingMachineDemo;\n\npublic class LLDRunner {\n    public static void main(String[] args) {\n        // Uncomment the LLD problem you want to run with sample input defined in the corresponding Demo class.\n\n//        AirlineManagementSystemDemo.run();\n//        ATMDemo.run();\n//        CarRentalSystemDemo.run();\n//        ChessGameDemo.run();\n//        CoffeeVendingMachineDemo.run();\n//        ConcertTicketBookingSystemDemo.run();\n//        CourseRegistrationSystemDemo.run();\n//        CricinfoDemo.run();\n//        DigitalWalletDemo.run();\n//        ElevatorSystemDemo.run();\n//        FoodDeliveryServiceDemo.run();\n//        HotelManagementSystemDemo.run();\n//        LibraryManagementSystemDemo.run();\n//        LinkedInDemo.run();\n//        LoggingFrameworkDemo.run();\n//        LRUCacheDemo.run();\n//        MovieTicketBookingDemo.run();\n//        MusicStreamingServiceDemo.run();\n//        AuctionSystemDemo.run();\n//        OnlineShoppingServiceDemo.run();\n//        StockBrokerageSystemDemo.run();\n//        ParkingLotDemo.run();\n//        PubSubSystemDemo.run();\n//        RestaurantManagementDemo.run();\n//        RideSharingServiceDemo.run();\n//        SnakeAndLadderDemo.run();\n//        SocialNetworkingServiceDemo.run();\n//        SplitwiseDemo.run();\n//        StackOverflowDemo.run();\n//        TaskManagementSystemDemo.run();\n//        TicTacToeDemo.run();\n//        TrafficSignalSystemDemo.run();\n//        VendingMachineDemo.run();\n//        VotingSystemDemo.run();\n    }\n}"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/Aircraft.java",
    "content": "package airlinemanagementsystem;\n\npublic class Aircraft {\n    private final String tailNumber;\n    private final String model;\n    private final int totalSeats;\n\n    public Aircraft(String tailNumber, String model, int totalSeats) {\n        this.tailNumber = tailNumber;\n        this.model = model;\n        this.totalSeats = totalSeats;\n    }\n\n    public String getTailNumber() {\n        return tailNumber;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/AirlineManagementSystem.java",
    "content": "package airlinemanagementsystem;\n\nimport airlinemanagementsystem.booking.Booking;\nimport airlinemanagementsystem.booking.BookingManager;\nimport airlinemanagementsystem.flight.Flight;\nimport airlinemanagementsystem.flight.FlightSearch;\nimport airlinemanagementsystem.payment.Payment;\nimport airlinemanagementsystem.payment.PaymentProcessor;\nimport airlinemanagementsystem.seat.Seat;\n\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class AirlineManagementSystem {\n    private final Map<String, Flight> flights;\n    private final Map<String, Aircraft> aircrafts;\n    private final Map<String, Passenger> passengers;\n    private final FlightSearch flightSearch;\n    private final BookingManager bookingManager;\n    private final PaymentProcessor paymentProcessor;\n\n    public AirlineManagementSystem() {\n        flights = new HashMap<>();\n        aircrafts = new HashMap<>();\n        passengers = new HashMap<>();\n        flightSearch = new FlightSearch();\n        bookingManager = BookingManager.getInstance();\n        paymentProcessor = PaymentProcessor.getInstance();\n    }\n\n    public Passenger addPassenger(String name, String email) {\n        Passenger passenger = new Passenger(name, email);\n        passengers.put(passenger.getId(), passenger);\n        return passenger;\n    }\n\n    public Aircraft addAircraft(String tailNumber, String model, int totalSeats) {\n        Aircraft aircraft = new Aircraft(tailNumber, model, totalSeats);\n        aircrafts.put(tailNumber, aircraft);\n        return aircraft;\n    }\n\n    public Flight addFlight(String source, String destination, LocalDateTime departure,\n                            LocalDateTime arrival, String aircraftNumber) {\n        Aircraft aircraft = aircrafts.get(aircraftNumber);\n        Flight flight = new Flight(source, destination, departure, arrival, aircraft);\n        flights.put(flight.getFlightNumber(), flight);\n        flightSearch.addFlight(flight);\n        return flight;\n    }\n\n    public List<Flight> searchFlights(String source, String destination, LocalDate date) {\n        return flightSearch.searchFlights(source, destination, date);\n    }\n\n    public Booking bookFlight(String flightNumber, String passengerId, Seat seat, double price) {\n        Flight flight = flights.get(flightNumber);\n        Passenger passenger = passengers.get(passengerId);\n        return bookingManager.createBooking(flight, passenger, seat, price);\n    }\n\n    public void cancelBooking(String bookingNumber) {\n        bookingManager.cancelBooking(bookingNumber);\n    }\n\n    public void processPayment(Payment payment) {\n        paymentProcessor.processPayment(payment);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/AirlineManagementSystemDemo.java",
    "content": "package airlinemanagementsystem;\n\nimport airlinemanagementsystem.booking.Booking;\nimport airlinemanagementsystem.flight.Flight;\nimport airlinemanagementsystem.seat.Seat;\nimport airlinemanagementsystem.seat.SeatType;\n\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\nimport java.util.List;\n\npublic class AirlineManagementSystemDemo {\n    public static void run() {\n        AirlineManagementSystem airlineManagementSystem = new AirlineManagementSystem();\n\n        // Create passengers\n        Passenger passenger1 = airlineManagementSystem.addPassenger(\"John Doe\", \"john@example.com\");\n        Passenger passenger2 = airlineManagementSystem.addPassenger(\"John Smith\", \"smith@example.com\");\n\n        // Create aircrafts\n        Aircraft aircraft1 = airlineManagementSystem.addAircraft(\"A001\", \"Boeing 747\", 300);\n        Aircraft aircraft2 = airlineManagementSystem.addAircraft(\"A002\", \"Airbus A380\", 500);\n\n        // Create flights\n        LocalDateTime departureTime1 = LocalDateTime.now().plusDays(1);\n        LocalDateTime arrivalTime1 = departureTime1.plusHours(2);\n        Flight flight1 = airlineManagementSystem.addFlight(\"New York\", \"London\", departureTime1, arrivalTime1, aircraft1.getTailNumber());\n\n        LocalDateTime departureTime2 = LocalDateTime.now().plusDays(3);\n        LocalDateTime arrivalTime2 = departureTime2.plusHours(5);\n        Flight flight2 = airlineManagementSystem.addFlight(\"Paris\", \"Tokyo\", departureTime2, arrivalTime2, aircraft2.getTailNumber());\n\n        // Search flights\n        List<Flight> searchResults = airlineManagementSystem.searchFlights(\"New York\", \"London\", LocalDate.now().plusDays(1));\n        System.out.println(\"Search Results:\");\n        for (Flight flight : searchResults) {\n            System.out.println(\"Flight: \" + flight.getFlightNumber() + \" - \" + flight.getSource() + \" to \" + flight.getDestination());\n        }\n\n        // Book a flight\n        Booking booking = airlineManagementSystem.bookFlight(flight1.getFlightNumber(), passenger1.getId(), new Seat(\"25A\", SeatType.ECONOMY), 100);\n        if (booking != null) {\n            System.out.println(\"Booking successful. Booking ID: \" + booking.getId());\n        } else {\n            System.out.println(\"Booking failed.\");\n        }\n\n        // Cancel a booking\n        airlineManagementSystem.cancelBooking(booking.getId());\n        System.out.println(\"Booking cancelled.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/Passenger.java",
    "content": "package airlinemanagementsystem;\n\nimport java.util.UUID;\n\npublic class Passenger {\n    private final String id;\n    private final String name;\n    private final String email;\n\n    public Passenger(String name, String email) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public String getId() {\n        return id;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/README.md",
    "content": "# Airline Management System (LLD)\n\n## Problem Statement\n\nDesign and implement an Airline Management System that allows users to book flights, manage passengers, handle seat assignments, process payments, and track bookings and flights.\n\n---\n\n## Requirements\n\n- **Flight Management:** The system manages flights, each with a unique flight number, aircraft, source, destination, and schedule.\n- **Aircraft Management:** Each flight is associated with an aircraft, which has a model and a set of seats.\n- **Seat Management:** The system manages seat assignments and availability for each flight.\n- **Passenger Management:** Passengers can be added, updated, and associated with bookings.\n- **Booking Management:** Users can book flights, and the system tracks bookings, assigned seats, and passengers.\n- **Payment Processing:** The system processes payments for bookings.\n- **Extensibility:** Easy to add new features such as loyalty programs, meal selection, or multi-leg journeys.\n\n---\n\n## Core Entities\n\n- **AirlineManagementSystem:** Main class that manages flights, bookings, passengers, and payments.\n- **Flight:** Represents a flight with flight number, aircraft, source, destination, schedule, and seats.\n- **Aircraft:** Represents an aircraft with a model and a set of seats.\n- **Seat:** Represents a seat on an aircraft, with seat number, class, and availability.\n- **Passenger:** Represents a user with ID, name, and contact details.\n- **Booking:** Represents a booking, including user(s), flight, seat(s), and payment.\n- **Payment (in payment/):** Represents a payment transaction for a booking.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/airlinemanagementsystem-class-diagram.png)\n\n### 1. AirlineManagementSystem\n\n- **Fields:** List<Flight> flights, List<Booking> bookings, List<Passenger> passengers, PaymentProcessor paymentProcessor\n- **Methods:** addFlight(Flight), addPassenger(Passenger), bookFlight(Passenger, Flight, Seat, Payment), getAvailableSeats(Flight), getBookings(Passenger), etc.\n\n### 2. Flight (in flight/)\n\n- **Fields:** String flightNumber, Aircraft aircraft, String source, String destination, Date schedule, List<Seat> seats\n\n### 3. Aircraft\n\n- **Fields:** String model, List<Seat> seats\n\n### 4. Seat (in seat/)\n\n- **Fields:** String seatNumber, String seatClass, boolean isAvailable\n\n### 5. Passenger\n\n- **Fields:** int id, String name, String contactInfo\n\n### 6. Booking (in booking/)\n\n- **Fields:** int id, Passenger user, Flight flight, List<Seat> seats, Payment payment\n\n### 7. Payment (in payment/)\n\n- **Fields:** int id, double amount, String method, PaymentStatus status\n\n### 8. PaymentProcessor (in payment/)\n\n- **Methods:** process(Payment), validate(Payment)\n\n---\n\n## Example Usage\n\n```java\nAirlineManagementSystem system = new AirlineManagementSystem();\nAircraft aircraft = new Aircraft(\"Boeing 737\", seatList);\nFlight flight = new Flight(\"AI101\", aircraft, \"DEL\", \"BOM\", new Date(), seatList);\nsystem.addFlight(flight);\n\nPassenger alice = new Passenger(1, \"Alice\", \"alice@email.com\");\nsystem.addPassenger(alice);\n\nSeat seat = flight.getAvailableSeats().get(0);\nPayment payment = new Payment(1, 5000.0, \"CREDIT_CARD\");\nsystem.bookFlight(alice, flight, seat, payment);\n```\n\n---\n\n## Demo\n\nSee `AirlineManagementSystemDemo.java` for a sample usage and simulation of the airline management system.\n\n---\n\n## Extending the Framework\n\n- **Add loyalty programs:** Track frequent flyer points and rewards.\n- **Add meal selection:** Allow passengers to select meals during booking.\n- **Add multi-leg journeys:** Support bookings with multiple connecting flights.\n\n---\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/booking/Booking.java",
    "content": "package airlinemanagementsystem.booking;\n\nimport airlinemanagementsystem.flight.Flight;\nimport airlinemanagementsystem.Passenger;\nimport airlinemanagementsystem.seat.Seat;\n\nimport java.util.UUID;\n\npublic class Booking {\n    private final String id;\n    private final Flight flight;\n    private final Passenger passenger;\n    private final Seat seat;\n    private final double price;\n    private BookingStatus status;\n\n    public Booking(Flight flight, Passenger passenger, Seat seat, double price) {\n        this.id = UUID.randomUUID().toString();\n        this.flight = flight;\n        this.passenger = passenger;\n        this.seat = seat;\n        this.price = price;\n        this.status = BookingStatus.CONFIRMED;\n    }\n\n    public void cancel() {\n        status = BookingStatus.CANCELLED;\n        seat.release();\n    }\n\n    public String getId() {\n        return id;\n    }\n}"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/booking/BookingManager.java",
    "content": "package airlinemanagementsystem.booking;\n\nimport airlinemanagementsystem.flight.Flight;\nimport airlinemanagementsystem.Passenger;\nimport airlinemanagementsystem.seat.Seat;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.UUID;\n\npublic class BookingManager {\n    private static BookingManager instance;\n    private final Map<String, Booking> bookings;\n    private final Object lock = new Object();\n\n    private BookingManager() {\n        bookings = new HashMap<>();\n    }\n\n    public static synchronized BookingManager getInstance() {\n        if (instance == null) {\n            instance = new BookingManager();\n        }\n        return instance;\n    }\n\n    public Booking createBooking(Flight flight, Passenger passenger, Seat seat, double price) {\n        String bookingNumber = UUID.randomUUID().toString();\n        Booking booking = new Booking(flight, passenger, seat, price);\n        synchronized (lock) {\n            bookings.put(bookingNumber, booking);\n        }\n        return booking;\n    }\n\n    public void cancelBooking(String bookingNumber) {\n        synchronized (lock) {\n            Booking booking = bookings.get(bookingNumber);\n            if (booking != null) {\n                booking.cancel();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/booking/BookingStatus.java",
    "content": "package airlinemanagementsystem.booking;\n\npublic enum BookingStatus {\n    CONFIRMED,\n    CANCELLED,\n    PENDING,\n    EXPIRED\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/flight/Flight.java",
    "content": "package airlinemanagementsystem.flight;\n\nimport airlinemanagementsystem.Aircraft;\nimport airlinemanagementsystem.seat.Seat;\n\nimport java.time.LocalDateTime;\nimport java.util.*;\n\npublic class Flight {\n    private final String flightNumber;\n    private final String source;\n    private final String destination;\n    private final LocalDateTime departureTime;\n    private final LocalDateTime arrivalTime;\n    private final FlightStatus status;\n    private final Aircraft aircraft;\n    private final Map<String, Seat> seats;\n    private final List<Seat> availableSeats;\n\n    public Flight(String source, String destination, LocalDateTime departureTime, LocalDateTime arrivalTime, Aircraft aircraft) {\n        this.flightNumber = UUID.randomUUID().toString();\n        this.source = source;\n        this.destination = destination;\n        this.departureTime = departureTime;\n        this.arrivalTime = arrivalTime;\n        this.status = FlightStatus.ON_TIME;\n        this.aircraft = aircraft;\n        this.seats = new HashMap<>();\n        this.availableSeats = new ArrayList<>();\n    }\n\n    public synchronized boolean isSeatAvailable(String seatNo) {\n        Seat seat = seats.get(seatNo);\n        return seat != null && !seat.isBooked();\n    }\n\n    public synchronized void reserveSeat(String seatNo) {\n        Seat seat = seats.get(seatNo);\n        if (seat == null) throw new IllegalArgumentException(\"Invalid seat number\");\n        seat.reserve();\n    }\n\n    public synchronized void releaseSeat(String seatNo) {\n        Seat seat = seats.get(seatNo);\n        if (seat != null) seat.release();\n    }\n\n    public String getSource() {\n        return source;\n    }\n\n    public String getDestination() {\n        return destination;\n    }\n\n    public LocalDateTime getDepartureTime() {\n        return departureTime;\n    }\n\n    public String getFlightNumber() {\n        return flightNumber;\n    }\n\n    public LocalDateTime getArrivalTime() {\n        return arrivalTime;\n    }\n\n    public List<Seat> getAvailableSeats() {\n        return availableSeats;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/flight/FlightSearch.java",
    "content": "package airlinemanagementsystem.flight;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class FlightSearch {\n    private final List<Flight> flights;\n\n    public FlightSearch() {\n        this.flights = new ArrayList<>();\n    }\n\n    public void addFlight(Flight flight) {\n        flights.add(flight);\n    }\n\n    public List<Flight> searchFlights(String source, String destination, LocalDate date) {\n        return flights.stream()\n                .filter(flight -> flight.getSource().equalsIgnoreCase(source)\n                        && flight.getDestination().equalsIgnoreCase(destination)\n                        && flight.getDepartureTime().toLocalDate().equals(date))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/flight/FlightStatus.java",
    "content": "package airlinemanagementsystem.flight;\n\npublic enum FlightStatus {\n    ON_TIME, DELAYED, CANCELLED\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/payment/Payment.java",
    "content": "package airlinemanagementsystem.payment;\n\npublic class Payment {\n    private final String paymentId;\n    private final String paymentMethod;\n    private final double amount;\n    private PaymentStatus status;\n\n    public Payment(String paymentId, String paymentMethod, double amount) {\n        this.paymentId = paymentId;\n        this.paymentMethod = paymentMethod;\n        this.amount = amount;\n        this.status = PaymentStatus.PENDING;\n    }\n\n    public void processPayment() {\n        // Process payment logic\n        status = PaymentStatus.COMPLETED;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/payment/PaymentProcessor.java",
    "content": "package airlinemanagementsystem.payment;\n\npublic class PaymentProcessor {\n    private static PaymentProcessor instance;\n\n    private PaymentProcessor() {\n    }\n\n    public static synchronized PaymentProcessor getInstance() {\n        if (instance == null) {\n            instance = new PaymentProcessor();\n        }\n        return instance;\n    }\n\n    public void processPayment(Payment payment) {\n        // Process payment using the selected payment method\n        payment.processPayment();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/payment/PaymentStatus.java",
    "content": "package airlinemanagementsystem.payment;\n\npublic enum PaymentStatus {\n    PENDING,\n    COMPLETED,\n    FAILED,\n    REFUNDED\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/seat/Seat.java",
    "content": "package airlinemanagementsystem.seat;\n\npublic class Seat {\n    private final String seatNumber;\n    private final SeatType type;\n    private SeatStatus status;\n\n    public Seat(String seatNumber, SeatType type) {\n        this.seatNumber = seatNumber;\n        this.type = type;\n        this.status = SeatStatus.AVAILABLE;\n    }\n\n    public String getSeatNumber() {\n        return seatNumber;\n    }\n\n    public void reserve() {\n        status = SeatStatus.RESERVED;\n    }\n\n    public void release() {\n        status = SeatStatus.AVAILABLE;\n    }\n\n    public synchronized boolean isBooked() {\n        return status == SeatStatus.OCCUPIED;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/seat/SeatStatus.java",
    "content": "package airlinemanagementsystem.seat;\n\npublic enum SeatStatus {\n    AVAILABLE,\n    RESERVED,\n    OCCUPIED\n}\n"
  },
  {
    "path": "solutions/java/src/airlinemanagementsystem/seat/SeatType.java",
    "content": "package airlinemanagementsystem.seat;\n\npublic enum SeatType {\n    ECONOMY,\n    PREMIUM_ECONOMY,\n    BUSINESS,\n    FIRST_CLASS\n}\n"
  },
  {
    "path": "solutions/java/src/atm/ATMDemo.java",
    "content": "package atm;\n\nimport atm.enums.OperationType;\n\npublic class ATMDemo {\n    public static void main(String[] args) {\n        ATMSystem atmSystem = ATMSystem.getInstance();\n\n        // Perform Check Balance operation\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"1234\");\n        atmSystem.selectOperation(OperationType.CHECK_BALANCE); // $1000\n\n        // Perform Withdraw Cash operation\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"1234\");\n        atmSystem.selectOperation(OperationType.WITHDRAW_CASH, 570);\n\n        // Perform Deposit Cash operation\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"1234\");\n        atmSystem.selectOperation(OperationType.DEPOSIT_CASH, 200);\n\n        // Perform Check Balance operation\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"1234\");\n        atmSystem.selectOperation(OperationType.CHECK_BALANCE); // $630\n\n        // Perform Withdraw Cash more than balance\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"1234\");\n        atmSystem.selectOperation(OperationType.WITHDRAW_CASH, 700); // Insufficient balance\n\n        // Insert Incorrect PIN\n        atmSystem.insertCard(\"1234-5678-9012-3456\");\n        atmSystem.enterPin(\"3425\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/ATMSystem.java",
    "content": "package atm;\n\nimport atm.chainofresponsibility.DispenseChain;\nimport atm.chainofresponsibility.NoteDispenser100;\nimport atm.chainofresponsibility.NoteDispenser20;\nimport atm.chainofresponsibility.NoteDispenser50;\nimport atm.entities.BankService;\nimport atm.entities.Card;\nimport atm.entities.CashDispenser;\nimport atm.enums.OperationType;\nimport atm.state.ATMState;\nimport atm.state.IdleState;\n\nimport java.util.concurrent.atomic.AtomicLong;\n\npublic class ATMSystem {\n    private static ATMSystem INSTANCE;\n    private final BankService bankService;\n    private final CashDispenser cashDispenser;\n    private static final AtomicLong transactionCounter = new AtomicLong(0);\n    private ATMState currentState;\n    private Card currentCard;\n\n    private ATMSystem() {\n        this.currentState = new IdleState();\n        this.bankService = new BankService();\n\n        // Setup the dispenser chain\n        DispenseChain c1 = new NoteDispenser100(10); // 10 x $100 notes\n        DispenseChain c2 = new NoteDispenser50(20); // 20 x $50 notes\n        DispenseChain c3 = new NoteDispenser20(30); // 30 x $20 notes\n        c1.setNextChain(c2);\n        c2.setNextChain(c3);\n        this.cashDispenser = new CashDispenser(c1);\n    }\n\n    public static ATMSystem getInstance() {\n        if (INSTANCE == null) {\n            INSTANCE = new ATMSystem();\n        }\n        return INSTANCE;\n    }\n\n    public void changeState(ATMState newState) { this.currentState = newState; }\n    public void setCurrentCard(Card card) { this.currentCard = card; }\n\n    public void insertCard(String cardNumber) {\n        currentState.insertCard(this, cardNumber);\n    }\n\n    public void enterPin(String pin) {\n        currentState.enterPin(this, pin);\n    }\n\n    public void selectOperation(OperationType op, int... args) { currentState.selectOperation(this, op, args); }\n\n    public Card getCard(String cardNumber) {\n        return bankService.getCard(cardNumber);\n    }\n\n    public boolean authenticate(String pin) {\n        return bankService.authenticate(currentCard, pin);\n    }\n\n    public void checkBalance() {\n        double balance = bankService.getBalance(currentCard);\n        System.out.printf(\"Your current account balance is: $%.2f%n\", balance);\n    }\n\n    public void withdrawCash(int amount) {\n        if (!cashDispenser.canDispenseCash(amount)) {\n            throw new IllegalStateException(\"Insufficient cash available in the ATM.\");\n        }\n\n        bankService.withdrawMoney(currentCard, amount);\n\n        try {\n            cashDispenser.dispenseCash(amount);\n        } catch (Exception e) {\n            bankService.depositMoney(currentCard, amount); // Deposit back if dispensing fails\n        }\n    }\n\n    public void depositCash(int amount) {\n        bankService.depositMoney(currentCard, amount);\n    }\n\n    public Card getCurrentCard() {\n        return currentCard;\n    }\n\n    public BankService getBankService() {\n        return bankService;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/README.md",
    "content": "# ATM System (LLD)\n\n## Problem Statement\n\nDesign and implement an ATM (Automated Teller Machine) system that allows users to perform basic banking operations such as balance inquiry, cash withdrawal, and cash deposit, with secure authentication and proper cash management.\n\n---\n\n## Requirements\n\n- **User Authentication:** Users must authenticate using a card and PIN.\n- **Balance Inquiry:** Users can check their account balance.\n- **Cash Withdrawal:** Users can withdraw cash if sufficient balance and cash are available.\n- **Cash Deposit:** Users can deposit cash into their account.\n- **Transaction Management:** The system records and processes transactions (withdrawal, deposit).\n- **Banking Service Integration:** The ATM interacts with a backend banking service to validate accounts and perform transactions.\n- **Cash Dispenser:** The ATM manages its own cash inventory and dispenses cash securely.\n- **Concurrency & Consistency:** The system handles concurrent access and ensures data consistency.\n- **User Interface:** The ATM provides a user-friendly interface for operations.\n- **Extensibility:** Easy to add new features such as mini-statements, fund transfers, or multi-currency support.\n\n---\n\n## Core Entities\n\n- **ATM:** Main class for ATM operations; interacts with `BankingService` and `CashDispenser`.\n- **Card:** Represents an ATM card with card number and PIN.\n- **Account:** Represents a bank account with account number and balance; supports debit and credit operations.\n- **Transaction (abstract):** Base class for transactions; extended by `WithdrawalTransaction` and `DepositTransaction`.\n- **WithdrawalTransaction / DepositTransaction:** Concrete transaction types for withdrawal and deposit.\n- **BankingService:** Manages bank accounts and processes transactions; uses thread-safe data structures.\n- **CashDispenser:** Manages the ATM's cash inventory and handles dispensing; ensures thread safety.\n- **ATMDemo:** Demonstrates the usage of the ATM system with sample accounts and operations.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/atmSystem-class-diagram.png)\n\n### 1. ATM\n- **Fields:** BankingService bankService, CashDispenser cashDispenser\n- **Methods:** authenticateUser(Card), checkBalance(String accountNumber), withdrawCash(String accountNumber, double amount), depositCash(String accountNumber, double amount)\n\n### 2. Card\n- **Fields:** String cardNumber, String pin\n\n### 3. Account\n- **Fields:** String accountNumber, double balance\n- **Methods:** debit(double), credit(double), getBalance()\n\n### 4. Transaction (abstract)\n- **Fields:** String accountNumber, double amount, Date date\n- **Methods:** process()\n\n### 5. WithdrawalTransaction / DepositTransaction\n- **Inherits:** Transaction\n- **Methods:** process()\n\n### 6. BankingService\n- **Fields:** Map<String, Account> accounts\n- **Methods:** createAccount(String, double), getAccount(String), processTransaction(Transaction)\n\n### 7. CashDispenser\n- **Fields:** double cashAvailable\n- **Methods:** dispenseCash(double), addCash(double), getCashAvailable()\n\n### 8. ATMDemo\n- **Methods:** run() — demonstrates sample ATM operations\n\n---\n\n## Example Usage\n\n```java\nBankingService bankService = new BankingService();\nCashDispenser cashDispenser = new CashDispenser(10000);\nATM atmSystem = new ATM(bankService, cashDispenser);\n\nbankService.createAccount(\"1234567890\", 1000.0);\nCard card = new Card(\"1234567890\", \"1234\");\natmSystem.authenticateUser(card);\n\ndouble balance = atmSystem.checkBalance(\"1234567890\");\natmSystem.withdrawCash(\"1234567890\", 500.0);\natmSystem.depositCash(\"1234567890\", 200.0);\n```\n\n---\n\n## Demo\n\nSee `ATMDemo.java` for a sample usage and simulation of the ATM system.\n\n---\n\n## Extending the Framework\n\n- **Add mini-statements:** Show recent transactions.\n- **Add fund transfers:** Allow transfers between accounts.\n- **Add multi-currency support:** Handle different currencies and conversions.\n\n---"
  },
  {
    "path": "solutions/java/src/atm/chainofresponsibility/DispenseChain.java",
    "content": "package atm.chainofresponsibility;\n\n// The chain interface\npublic interface DispenseChain {\n    void setNextChain(DispenseChain nextChain);\n    void dispense(int amount);\n    boolean canDispense(int amount);\n}\n"
  },
  {
    "path": "solutions/java/src/atm/chainofresponsibility/NoteDispenser.java",
    "content": "package atm.chainofresponsibility;\n\nabstract class NoteDispenser implements DispenseChain {\n    private DispenseChain nextChain;\n    private final int noteValue;\n    private int numNotes;\n\n    public NoteDispenser(int noteValue, int numNotes) {\n        this.noteValue = noteValue;\n        this.numNotes = numNotes;\n    }\n\n    @Override\n    public void setNextChain(DispenseChain nextChain) {\n        this.nextChain = nextChain;\n    }\n\n    @Override\n    public synchronized void dispense(int amount) {\n        if (amount >= noteValue) {\n            int numToDispense = Math.min(amount / noteValue, this.numNotes);\n            int remainingAmount = amount - (numToDispense * noteValue);\n\n            if (numToDispense > 0) {\n                System.out.println(\"Dispensing \" + numToDispense + \" x $\" + noteValue + \" note(s)\");\n                this.numNotes -= numToDispense;\n            }\n\n            if (remainingAmount > 0 && this.nextChain != null) {\n                this.nextChain.dispense(remainingAmount);\n            }\n        } else if (this.nextChain != null) {\n            this.nextChain.dispense(amount);\n        }\n    }\n\n    @Override\n    public synchronized boolean canDispense(int amount) {\n        if (amount < 0) return false;\n        if (amount == 0) return true;\n\n        int numToUse = Math.min(amount / noteValue, this.numNotes);\n        int remainingAmount = amount - (numToUse * noteValue);\n\n        if (remainingAmount == 0) return true;\n        if (this.nextChain != null) {\n            return this.nextChain.canDispense(remainingAmount);\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/chainofresponsibility/NoteDispenser100.java",
    "content": "package atm.chainofresponsibility;\n\npublic class NoteDispenser100 extends NoteDispenser{\n    public NoteDispenser100(int numNotes) {\n        super(100, numNotes);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/chainofresponsibility/NoteDispenser20.java",
    "content": "package atm.chainofresponsibility;\n\npublic class NoteDispenser20 extends NoteDispenser{\n    public NoteDispenser20(int numNotes) { super(20, numNotes); }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/chainofresponsibility/NoteDispenser50.java",
    "content": "package atm.chainofresponsibility;\n\npublic class NoteDispenser50 extends NoteDispenser{\n    public NoteDispenser50(int numNotes) { super(50, numNotes); }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/entities/Account.java",
    "content": "package atm.entities;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Account {\n    private final String accountNumber;\n    private double balance;\n    private Map<String, Card> cards;\n\n    public Account(String accountNumber, double balance) {\n        this.accountNumber = accountNumber;\n        this.balance = balance;\n        this.cards = new HashMap<>();\n    }\n\n    public String getAccountNumber() {\n        return accountNumber;\n    }\n\n    public double getBalance() {\n        return balance;\n    }\n\n    public Map<String, Card> getCards() {\n        return cards;\n    }\n\n    public synchronized void deposit(double amount) {\n        balance += amount;\n    }\n\n    public synchronized boolean withdraw(double amount) {\n        if (balance >= amount) {\n            balance -= amount;\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/entities/BankService.java",
    "content": "package atm.entities;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class BankService {\n    private final Map<String, Account> accounts = new ConcurrentHashMap<>();\n    private final Map<String, Card> cards = new ConcurrentHashMap<>();\n    private final Map<Card, Account> cardAccountMap = new ConcurrentHashMap<>();\n\n    public BankService() {\n        // Create sample accounts and cards\n        Account account1 = createAccount(\"1234567890\", 1000.0);\n        Card card1 = createCard(\"1234-5678-9012-3456\", \"1234\");\n        linkCardToAccount(card1, account1);\n\n        Account account2 = createAccount(\"9876543210\", 500.0);\n        Card card2 = createCard(\"9876-5432-1098-7654\", \"4321\");\n        linkCardToAccount(card2, account2);\n    }\n\n    public Account createAccount(String accountNumber, double initialBalance) {\n        Account account = new Account(accountNumber, initialBalance);\n        accounts.put(accountNumber, account);\n        return account;\n    }\n\n    public Card createCard(String cardNumber, String pin) {\n        Card card = new Card(cardNumber, pin);\n        cards.put(cardNumber, card);\n        return card;\n    }\n\n    public boolean authenticate(Card card, String pin) {\n        return card.getPin().equals(pin);\n    }\n\n    public Card getCard(String cardNumber) {\n        return cards.getOrDefault(cardNumber, null);\n    }\n\n    public double getBalance(Card card) {\n        return cardAccountMap.get(card).getBalance();\n    }\n\n    public void withdrawMoney(Card card, double amount) {\n        cardAccountMap.get(card).withdraw(amount);\n    }\n\n    public void depositMoney(Card card, double amount) {\n        cardAccountMap.get(card).deposit(amount);\n    }\n\n    public void linkCardToAccount(Card card, Account account) {\n        account.getCards().put(card.getCardNumber(), card);\n        cardAccountMap.put(card, account);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/entities/Card.java",
    "content": "package atm.entities;\n\npublic class Card {\n    private final String cardNumber;\n    private final String pin;\n\n    public Card(String cardNumber, String pin) {\n        this.cardNumber = cardNumber;\n        this.pin = pin;\n    }\n\n    public String getCardNumber() {\n        return cardNumber;\n    }\n\n    public String getPin() {\n        return pin;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/entities/CashDispenser.java",
    "content": "package atm.entities;\n\nimport atm.chainofresponsibility.DispenseChain;\n\npublic class CashDispenser {\n    private final DispenseChain chain;\n\n    public CashDispenser(DispenseChain chain) {\n        this.chain = chain;\n    }\n\n    public synchronized void dispenseCash(int amount) {\n        chain.dispense(amount);\n    }\n\n    public synchronized boolean canDispenseCash(int amount) {\n        if (amount % 10 != 0) {\n            return false;\n        }\n        return chain.canDispense(amount);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/enums/OperationType.java",
    "content": "package atm.enums;\n\npublic enum OperationType {\n    CHECK_BALANCE,\n    WITHDRAW_CASH,\n    DEPOSIT_CASH\n}\n"
  },
  {
    "path": "solutions/java/src/atm/state/ATMState.java",
    "content": "package atm.state;\n\nimport atm.ATMSystem;\nimport atm.enums.OperationType;\n\npublic interface ATMState {\n    void insertCard(ATMSystem atmSystem, String cardNumber);\n    void enterPin(ATMSystem atmSystem, String pin);\n    void selectOperation(ATMSystem atmSystem, OperationType op, int... args);\n    void ejectCard(ATMSystem atmSystem);\n}\n"
  },
  {
    "path": "solutions/java/src/atm/state/AuthenticatedState.java",
    "content": "package atm.state;\n\nimport atm.ATMSystem;\nimport atm.enums.OperationType;\n\npublic class AuthenticatedState implements ATMState {\n    @Override\n    public void insertCard(ATMSystem atmSystem, String cardNumber) {\n        System.out.println(\"Error: A card is already inserted and a session is active.\");\n    }\n\n    @Override\n    public void enterPin(ATMSystem atmSystem, String pin) {\n        System.out.println(\"Error: PIN has already been entered and authenticated.\");\n    }\n\n    @Override\n    public void selectOperation(ATMSystem atmSystem, OperationType op, int... args) {\n        // In a real UI, this would be a menu. Here we use a switch.\n        switch (op) {\n            case CHECK_BALANCE:\n                atmSystem.checkBalance();\n                break;\n\n            case WITHDRAW_CASH:\n                if (args.length == 0 || args[0] <= 0) {\n                    System.out.println(\"Error: Invalid withdrawal amount specified.\");\n                    break;\n                }\n                int amountToWithdraw = args[0];\n\n                double accountBalance = atmSystem.getBankService().getBalance(atmSystem.getCurrentCard());\n\n                if (amountToWithdraw > accountBalance) {\n                    System.out.println(\"Error: Insufficient balance.\");\n                    break;\n                }\n\n                System.out.println(\"Processing withdrawal for $\" + amountToWithdraw);\n                // Delegate the complex withdrawal logic to the ATM's dedicated method\n                atmSystem.withdrawCash(amountToWithdraw);\n                break;\n\n            case DEPOSIT_CASH:\n                if (args.length == 0 || args[0] <= 0) {\n                    System.out.println(\"Error: Invalid withdrawal amount specified.\");\n                    break;\n                }\n                int amountToDeposit = args[0];\n                System.out.println(\"Processing deposit for $\" + amountToDeposit);\n                atmSystem.depositCash(amountToDeposit);\n                break;\n\n            default:\n                System.out.println(\"Error: Invalid operation selected.\");\n                break;\n        }\n\n        // End the session after one transaction\n        System.out.println(\"Transaction complete.\");\n        ejectCard(atmSystem);\n    }\n\n    @Override\n    public void ejectCard(ATMSystem atmSystem) {\n        System.out.println(\"Ending session. Card has been ejected. Thank you for using our ATM.\");\n        atmSystem.setCurrentCard(null);\n        atmSystem.changeState(new IdleState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/state/HasCardState.java",
    "content": "package atm.state;\n\nimport atm.ATMSystem;\nimport atm.enums.OperationType;\n\npublic class HasCardState implements ATMState {\n    @Override\n    public void insertCard(ATMSystem atmSystem, String cardNumber) {\n        System.out.println(\"Error: A card is already inserted. Cannot insert another card.\");\n    }\n\n    @Override\n    public void enterPin(ATMSystem atmSystem, String pin) {\n        System.out.println(\"Authenticating PIN...\");\n        boolean isAuthenticated = atmSystem.authenticate(pin);;\n\n        if (isAuthenticated) {\n            System.out.println(\"Authentication successful.\");\n            atmSystem.changeState(new AuthenticatedState());\n        } else {\n            System.out.println(\"Authentication failed: Incorrect PIN.\");\n            ejectCard(atmSystem);\n        }\n    }\n\n    @Override\n    public void selectOperation(ATMSystem atmSystem, OperationType op, int... args) {\n        System.out.println(\"Error: Please enter your PIN first to select an operation.\");\n    }\n\n    @Override\n    public void ejectCard(ATMSystem atmSystem) {\n        System.out.println(\"Card has been ejected. Thank you for using our ATM.\");\n        atmSystem.setCurrentCard(null);\n        atmSystem.changeState(new IdleState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/atm/state/IdleState.java",
    "content": "package atm.state;\n\nimport atm.ATMSystem;\nimport atm.entities.Card;\nimport atm.enums.OperationType;\n\npublic class IdleState implements ATMState {\n    @Override\n    public void insertCard(ATMSystem atmSystem, String cardNumber) {\n        System.out.println(\"\\nCard has been inserted.\");\n        Card card = atmSystem.getCard(cardNumber);\n\n        if (card == null) {\n            ejectCard(atmSystem);\n        } else {\n            atmSystem.setCurrentCard(card);\n            atmSystem.changeState(new HasCardState());\n        }\n    }\n\n    @Override\n    public void enterPin(ATMSystem atmSystem, String pin) {\n        System.out.println(\"Error: Please insert a card first.\");\n    }\n\n    @Override\n    public void selectOperation(ATMSystem atmSystem, OperationType op, int... args) {\n        System.out.println(\"Error: Please insert a card first.\");\n    }\n\n    @Override\n    public void ejectCard(ATMSystem atmSystem) {\n        System.out.println(\"Error: Card not found.\");\n        atmSystem.setCurrentCard(null);\n    }\n}"
  },
  {
    "path": "solutions/java/src/carrentalsystem/Car.java",
    "content": "package carrentalsystem;\n\npublic class Car {\n    private final String make;\n    private final String model;\n    private final int year;\n    private final String licensePlate;\n    private final double rentalPricePerDay;\n    private boolean available;\n\n    public Car(String make, String model, int year, String licensePlate, double rentalPricePerDay) {\n        this.make = make;\n        this.model = model;\n        this.year = year;\n        this.licensePlate = licensePlate;\n        this.rentalPricePerDay = rentalPricePerDay;\n        this.available = true;\n    }\n\n    public double getRentalPricePerDay() {\n        return rentalPricePerDay;\n    }\n\n    public String getLicensePlate() {\n        return licensePlate;\n    }\n\n    public String getMake() {\n        return make;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    public boolean isAvailable() {\n        return available;\n    }\n\n    public void setAvailable(boolean available) {\n        this.available = available;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/CarRentalSystem.java",
    "content": "package carrentalsystem;\n\nimport carrentalsystem.payment.CreditCardPaymentProcessor;\nimport carrentalsystem.payment.PaymentProcessor;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class CarRentalSystem {\n    private static CarRentalSystem instance = new CarRentalSystem();\n    private final Map<String, Car> cars;\n    private final Map<String, Reservation> reservations;\n    private final PaymentProcessor paymentProcessor;\n\n    private CarRentalSystem() {\n        cars = new ConcurrentHashMap<>();\n        reservations = new ConcurrentHashMap<>();\n        paymentProcessor = new CreditCardPaymentProcessor();\n    }\n\n    public static CarRentalSystem getInstance() {\n        return instance;\n    }\n\n    public void addCar(Car car) {\n        cars.put(car.getLicensePlate(), car);\n    }\n\n    public void removeCar(String licensePlate) {\n        cars.remove(licensePlate);\n    }\n\n    public List<Car> searchCars(String make, String model, LocalDate startDate, LocalDate endDate) {\n        List<Car> availableCars = new ArrayList<>();\n        for (Car car : cars.values()) {\n            if (car.getMake().equalsIgnoreCase(make) && car.getModel().equalsIgnoreCase(model) && car.isAvailable()) {\n                if (isCarAvailable(car, startDate, endDate)) {\n                    availableCars.add(car);\n                }\n            }\n        }\n        return availableCars;\n    }\n\n    private boolean isCarAvailable(Car car, LocalDate startDate, LocalDate endDate) {\n        for (Reservation reservation : reservations.values()) {\n            if (reservation.getCar().equals(car)) {\n                if (startDate.isBefore(reservation.getEndDate()) && endDate.isAfter(reservation.getStartDate())) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    public synchronized Reservation makeReservation(Customer customer, Car car, LocalDate startDate, LocalDate endDate) {\n        if (isCarAvailable(car, startDate, endDate)) {\n            String reservationId = generateReservationId();\n            Reservation reservation = new Reservation(reservationId, customer, car, startDate, endDate);\n            reservations.put(reservationId, reservation);\n            car.setAvailable(false);\n            return reservation;\n        }\n        return null;\n    }\n\n    public synchronized void cancelReservation(String reservationId) {\n        Reservation reservation = reservations.remove(reservationId);\n        if (reservation != null) {\n            reservation.getCar().setAvailable(true);\n        }\n    }\n\n    public boolean processPayment(Reservation reservation) {\n        return paymentProcessor.processPayment(reservation.getTotalPrice());\n    }\n\n    private String generateReservationId() {\n        return \"RES\" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/CarRentalSystemDemo.java",
    "content": "package carrentalsystem;\n\nimport java.time.LocalDate;\nimport java.util.List;\n\npublic class CarRentalSystemDemo {\n    public static void run() {\n        CarRentalSystem carRentalSystem = CarRentalSystem.getInstance();\n\n        // Add cars to the rental system\n        carRentalSystem.addCar(new Car(\"Toyota\", \"Camry\", 2022, \"ABC123\", 50.0));\n        carRentalSystem.addCar(new Car(\"Honda\", \"Civic\", 2021, \"XYZ789\", 45.0));\n        carRentalSystem.addCar(new Car(\"Ford\", \"Mustang\", 2023, \"DEF456\", 80.0));\n\n        // Create customers\n        Customer customer1 = new Customer(\"John Doe\", \"john@example.com\", \"DL1234\");\n\n        // Make reservations\n        LocalDate startDate = LocalDate.now();\n        LocalDate endDate = startDate.plusDays(3);\n        List<Car> availableCars = carRentalSystem.searchCars(\"Toyota\", \"Camry\", startDate, endDate);\n        if (!availableCars.isEmpty()) {\n            Car selectedCar = availableCars.getFirst();\n            Reservation reservation = carRentalSystem.makeReservation(customer1, selectedCar, startDate, endDate);\n            if (reservation != null) {\n                boolean paymentSuccess = carRentalSystem.processPayment(reservation);\n                if (paymentSuccess) {\n                    System.out.println(\"Reservation successful. Reservation ID: \" + reservation.getReservationId());\n                } else {\n                    System.out.println(\"Payment failed. Reservation canceled.\");\n                    carRentalSystem.cancelReservation(reservation.getReservationId());\n                }\n            } else {\n                System.out.println(\"Selected car is not available for the given dates.\");\n            }\n        } else {\n            System.out.println(\"No available cars found for the given criteria.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/CarStatus.java",
    "content": "package carrentalsystem;\n\npublic enum CarStatus {\n    AVAILABLE, BOOKED, MAINTENANCE\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/CarType.java",
    "content": "package carrentalsystem;\n\npublic enum CarType {\n    SUV, SEDAN, HATCHBACK\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/Customer.java",
    "content": "package carrentalsystem;\n\npublic class Customer {\n    private final String name;\n    private final String contactInfo;\n    private final String driversLicenseNumber;\n\n    public Customer(String name, String contactInfo, String driversLicenseNumber) {\n        this.name = name;\n        this.contactInfo = contactInfo;\n        this.driversLicenseNumber = driversLicenseNumber;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/README.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/carrentalsystem-class-diagram.png)\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "solutions/java/src/carrentalsystem/Reservation.java",
    "content": "package carrentalsystem;\n\nimport java.time.LocalDate;\nimport java.time.temporal.ChronoUnit;\n\npublic class Reservation {\n    private final String reservationId;\n    private final Customer customer;\n    private final Car car;\n    private final LocalDate startDate;\n    private final LocalDate endDate;\n    private final double totalPrice;\n\n    public Reservation(String reservationId, Customer customer, Car car, LocalDate startDate, LocalDate endDate) {\n        this.reservationId = reservationId;\n        this.customer = customer;\n        this.car = car;\n        this.startDate = startDate;\n        this.endDate = endDate;\n        this.totalPrice = calculateTotalPrice();\n    }\n\n    private double calculateTotalPrice() {\n        long daysRented = ChronoUnit.DAYS.between(startDate, endDate) + 1;\n        return car.getRentalPricePerDay() * daysRented;\n    }\n\n    public LocalDate getStartDate() {\n        return startDate;\n    }\n\n    public LocalDate getEndDate() {\n        return endDate;\n    }\n\n    public Car getCar() {\n        return car;\n    }\n\n    public double getTotalPrice() {\n        return totalPrice;\n    }\n\n    public String getReservationId() {\n        return reservationId;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/payment/CreditCardPaymentProcessor.java",
    "content": "package carrentalsystem.payment;\n\npublic class CreditCardPaymentProcessor implements PaymentProcessor {\n    @Override\n    public boolean processPayment(double amount) {\n        // Process credit card payment\n        // ...\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/payment/PayPalPaymentProcessor.java",
    "content": "package carrentalsystem.payment;\n\npublic class PayPalPaymentProcessor implements PaymentProcessor {\n    @Override\n    public boolean processPayment(double amount) {\n        // Process PayPal payment\n        // ...\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/carrentalsystem/payment/PaymentProcessor.java",
    "content": "package carrentalsystem.payment;\n\npublic interface PaymentProcessor {\n    boolean processPayment(double amount);\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/Board.java",
    "content": "package chessgame;\n\nimport chessgame.pieces.*;\n\npublic class Board {\n    private final Cell[][] board;\n\n    public Board() {\n        board = new Cell[8][8];\n\n        for (int row = 0; row < 8; row++)\n            for (int col = 0; col < 8; col++)\n                board[row][col] = new Cell(row, col);\n\n        setupPieces();\n    }\n\n    private void setupPieces() {\n        // Add pawns and main pieces for both sides\n        for (int j = 0; j < 8; j++) {\n            board[1][j].setPiece(new Pawn(Color.WHITE));\n            board[6][j].setPiece(new Pawn(Color.BLACK));\n        }\n\n        // Initialize white pieces\n        board[0][0].setPiece(new Rook(Color.WHITE));\n        board[0][1].setPiece(new Knight(Color.WHITE));\n        board[0][2].setPiece(new Bishop(Color.WHITE));\n        board[0][3].setPiece(new Queen(Color.WHITE));\n        board[0][4].setPiece(new King(Color.WHITE));\n        board[0][5].setPiece(new Bishop(Color.WHITE));\n        board[0][6].setPiece(new Knight(Color.WHITE));\n        board[0][7].setPiece(new Rook(Color.WHITE));\n\n        // Initialize black pieces\n        board[7][0].setPiece(new Rook(Color.BLACK));\n        board[7][1].setPiece(new Knight(Color.BLACK));\n        board[7][2].setPiece(new Bishop(Color.BLACK));\n        board[7][3].setPiece(new Queen(Color.BLACK));\n        board[7][4].setPiece(new King(Color.BLACK));\n        board[7][5].setPiece(new Bishop(Color.BLACK));\n        board[7][6].setPiece(new Knight(Color.BLACK));\n        board[7][7].setPiece(new Rook(Color.BLACK));\n    }\n\n    public Cell getCell(int row, int col) {\n        return board[row][col];\n    }\n\n    public synchronized boolean movePiece(Move move) {\n        Cell from = move.getStart(), to = move.getEnd();\n        Piece piece = from.getPiece();\n        if (piece == null || !piece.canMove(this, from, to)) return false;\n\n        to.setPiece(piece);\n        from.setPiece(null);\n        return true;\n    }\n\n    public Piece getPiece(int row, int col) {\n        return board[row][col].getPiece();\n    }\n\n    public void setPiece(int row, int col, Piece piece) {\n        board[row][col].setPiece(piece);\n    }\n\n    public boolean isCheckmate(Color color) {\n        // TODO: Implement checkmate logic\n        return false;\n    }\n\n    public boolean isStalemate(Color color) {\n        // TODO: Implement stalemate logic\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/Cell.java",
    "content": "package chessgame;\n\nimport chessgame.pieces.Piece;\n\npublic class Cell {\n    private final int row, col;\n    private Piece piece;\n\n    public Cell(int row, int col) {\n        this.row = row;\n        this.col = col;\n    }\n\n    public boolean isOccupied() {\n        return piece != null;\n    }\n\n    public Piece getPiece() { return piece; }\n    public void setPiece(Piece piece) { this.piece = piece; }\n\n    public int getRow() { return row; }\n    public int getCol() { return col; }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/ChessGame.java",
    "content": "package chessgame;\n\nimport chessgame.pieces.Piece;\n\nimport java.util.Scanner;\n\npublic class ChessGame {\n    private final Board board;\n    private Player whitePlayer, blackPlayer;\n    private Player currentPlayer;\n\n    public ChessGame() {\n        board = new Board();\n    }\n\n    public void setPlayers(String playerWhiteName, String playerBlackName) {\n        this.whitePlayer = new Player(playerWhiteName, Color.WHITE);\n        this.blackPlayer = new Player(playerBlackName, Color.BLACK);\n        this.currentPlayer = whitePlayer;\n    }\n\n    public void start() {\n        // Game loop\n        while (!isGameOver()) {\n            Player player = currentPlayer;\n            System.out.println(player.getName() + \"'s turn.\");\n            // Get move from the player\n            Move move = getPlayerMove(player);\n            // Make the move on the board\n            try {\n                board.movePiece(move);\n            } catch (InvalidMoveException e) {\n                System.out.println(e.getMessage());\n                System.out.println(\"Try again!\");\n                continue;\n            }\n            // Switch to the next player\n            switchTurn();\n        }\n        // Display game result\n        displayResult();\n    }\n\n    private void switchTurn() {\n        currentPlayer = currentPlayer == whitePlayer ? blackPlayer : whitePlayer;\n    }\n\n    private boolean isGameOver() {\n        return board.isCheckmate(whitePlayer.getColor()) || board.isCheckmate(blackPlayer.getColor()) ||\n                board.isStalemate(whitePlayer.getColor()) || board.isStalemate(blackPlayer.getColor());\n    }\n\n    private Move getPlayerMove(Player player) {\n        // For simplicity, let's assume the player enters the move via console input\n        Scanner scanner = new Scanner(System.in);\n        System.out.print(\"Enter source row: \");\n        int sourceRow = scanner.nextInt();\n        System.out.print(\"Enter source column: \");\n        int sourceCol = scanner.nextInt();\n        System.out.print(\"Enter destination row: \");\n        int destRow = scanner.nextInt();\n        System.out.print(\"Enter destination column: \");\n        int destCol = scanner.nextInt();\n\n        Piece piece = board.getPiece(sourceRow, sourceCol);\n        if (piece == null || piece.getColor() != player.getColor()) {\n            throw new IllegalArgumentException(\"Invalid piece selection!\");\n        }\n\n        return new Move(board.getCell(sourceRow, sourceCol), board.getCell(destRow, destCol));\n    }\n\n    private void displayResult() {\n        if (board.isCheckmate(Color.WHITE)) {\n            System.out.println(\"Black wins by checkmate!\");\n        } else if (board.isCheckmate(Color.BLACK)) {\n            System.out.println(\"White wins by checkmate!\");\n        } else if (board.isStalemate(Color.WHITE) || board.isStalemate(Color.BLACK)) {\n            System.out.println(\"The game ends in a stalemate!\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/ChessGameDemo.java",
    "content": "package chessgame;\n\npublic class ChessGameDemo {\n    public static void run() {\n        ChessGame chessGame = new ChessGame();\n        chessGame.setPlayers(\"Alice\", \"Bob\");\n        chessGame.start();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/Color.java",
    "content": "package chessgame;\n\npublic enum Color {\n    WHITE, BLACK\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/InvalidMoveException.java",
    "content": "package chessgame;\n\npublic class InvalidMoveException extends RuntimeException {\n    public InvalidMoveException(final String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/Move.java",
    "content": "package chessgame;\n\npublic class Move {\n    private final Cell start;\n    private final Cell end;\n\n    public Move(Cell start, Cell end) {\n        this.start = start;\n        this.end = end;\n    }\n\n    public Cell getStart() { return start; }\n\n    public Cell getEnd() { return end; }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/Player.java",
    "content": "package chessgame;\n\npublic class Player {\n    private final String name;\n    private final Color color;\n\n    public Player(String name, Color color) {\n        this.name = name;\n        this.color = color;\n    }\n\n    public Color getColor() {\n        return color;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/README.md",
    "content": "# Chess Game (LLD)\n\n## Problem Statement\n\nDesign and implement a Chess Game that allows two players to play chess on a standard 8x8 board, enforces chess rules, validates moves, and determines game status (check, checkmate, stalemate).\n\n---\n\n## Requirements\n\n- **Two Players:** The game is played between two players (White and Black).\n- **Board:** The game uses a standard 8x8 chess board.\n- **Pieces:** All standard chess pieces (King, Queen, Rook, Bishop, Knight, Pawn) with their movement rules.\n- **Move Validation:** The game validates moves according to chess rules and prevents illegal moves.\n- **Turn Management:** Players alternate turns.\n- **Game Status:** The game detects check, checkmate, and stalemate.\n- **Exception Handling:** The system throws exceptions for invalid moves.\n- **Extensibility:** Easy to add features such as move history, undo, or AI opponent.\n\n---\n\n## Core Entities\n\n- **ChessGame:** Main class that manages the game flow, player turns, and game status.\n- **Board:** Represents the 8x8 chess board and manages piece positions.\n- **Cell:** Represents a cell on the board, with row, column, and piece.\n- **Player:** Represents a player with a name and color.\n- **Color (enum):** WHITE, BLACK.\n- **Move:** Represents a move from one cell to another.\n- **Piece (abstract, in pieces/):** Base class for all chess pieces.\n- **King, Queen, Rook, Bishop, Knight, Pawn (in pieces/):** Concrete piece classes with movement logic.\n- **InvalidMoveException:** Exception thrown for invalid moves.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/chessgame-class-diagram.png)\n\n### 1. ChessGame\n- **Fields:** Board board, Player[] players, int currentPlayerIndex, boolean isGameOver\n- **Methods:** start(), makeMove(Move), switchPlayer(), isCheck(), isCheckmate(), isStalemate(), getCurrentPlayer()\n\n### 2. Board\n- **Fields:** Cell[][] grid, List<Piece> pieces\n- **Methods:** getCell(int row, int col), movePiece(Move), isCellOccupied(int row, int col), isCheck(Color), isCheckmate(Color), isStalemate(Color), printBoard()\n\n### 3. Cell\n- **Fields:** int row, int col, Piece piece\n- **Methods:** getPiece(), setPiece(Piece), isEmpty()\n\n### 4. Player\n- **Fields:** String name, Color color\n\n### 5. Color (enum)\n- Values: WHITE, BLACK\n\n### 6. Move\n- **Fields:** Cell from, Cell to\n\n### 7. Piece (abstract, in pieces/)\n- **Fields:** Color color, Cell position\n- **Methods:** isValidMove(Board, Move), getPossibleMoves(Board)\n\n### 8. InvalidMoveException\n- **Thrown:** When a move is not valid according to chess rules\n\n---\n\n## Example Usage\n\n```java\nPlayer white = new Player(\"Alice\", Color.WHITE);\nPlayer black = new Player(\"Bob\", Color.BLACK);\nChessGame game = new ChessGame(white, black);\ngame.start();\n\nMove move = new Move(game.getBoard().getCell(6, 4), game.getBoard().getCell(4, 4)); // e2 to e4\ngame.makeMove(move);\n```\n\n---\n\n## Demo\n\nSee `ChessGameDemo.java` for a sample usage and simulation of the chess game.\n\n---\n\n## Extending the Framework\n\n- **Add move history:** Track all moves for undo/redo or replay.\n- **Add AI opponent:** Implement a computer player.\n- **Add GUI:** Build a graphical interface for the game.\n\n---"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Bishop.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class Bishop extends Piece {\n    public Bishop(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        int rowDiff = Math.abs(to.getRow() - from.getRow());\n        int colDiff = Math.abs(to.getCol() - from.getCol());\n        return (rowDiff == colDiff);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/King.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class King extends Piece {\n    public King(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        int rowDiff = Math.abs(to.getRow() - from.getRow());\n        int colDiff = Math.abs(to.getCol()- from.getCol());\n        return (rowDiff <= 1 && colDiff <= 1);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Knight.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class Knight extends Piece {\n    public Knight(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        int rowDiff = Math.abs(to.getRow() - from.getRow());\n        int colDiff = Math.abs(to.getCol() - from.getCol());\n        return (rowDiff == 2 && colDiff == 1) || (rowDiff == 1 && colDiff == 2);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Pawn.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class Pawn extends Piece {\n    public Pawn(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        int rowDiff = to.getRow() - from.getRow();\n        int colDiff = Math.abs(to.getCol() - from.getCol());\n\n        if (color == Color.WHITE) {\n            return (rowDiff == 1 && colDiff == 0) ||\n                    (from.getRow() == 1 && rowDiff == 2 && colDiff == 0) ||\n                    (rowDiff == 1 && colDiff == 1 && board.getPiece(to.getRow(), to.getCol()) != null);\n        } else {\n            return (rowDiff == -1 && colDiff == 0) ||\n                    (from.getRow() == 6 && rowDiff == -2 && colDiff == 0) ||\n                    (rowDiff == -1 && colDiff == 1 && board.getPiece(to.getRow(), to.getCol()) != null);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Piece.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic abstract class Piece {\n    protected final Color color;\n\n    public Piece(Color color) {\n        this.color = color;\n    }\n\n    public abstract boolean canMove(Board board, Cell from, Cell to);\n\n    public Color getColor() {\n        return color;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Queen.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class Queen extends Piece {\n    public Queen(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        int rowDiff = Math.abs(to.getRow() - from.getRow());\n        int colDiff = Math.abs(to.getCol() - from.getCol());\n        return (rowDiff == colDiff) || (from.getRow() == to.getRow() || from.getCol() == to.getCol());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/chessgame/pieces/Rook.java",
    "content": "package chessgame.pieces;\n\nimport chessgame.Board;\nimport chessgame.Cell;\nimport chessgame.Color;\n\npublic class Rook extends Piece {\n    public Rook(Color color) {\n        super(color);\n    }\n\n    @Override\n    public boolean canMove(Board board, Cell from, Cell to) {\n        return (from.getRow() == to.getRow() || from.getCol() == to.getCol());\n    }\n}"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/CoffeeVendingMachine.java",
    "content": "package coffeevendingmachine;\n\n\nimport coffeevendingmachine.decorator.CaramelSyrupDecorator;\nimport coffeevendingmachine.decorator.ExtraSugarDecorator;\nimport coffeevendingmachine.enums.CoffeeType;\nimport coffeevendingmachine.enums.ToppingType;\nimport coffeevendingmachine.factory.CoffeeFactory;\nimport coffeevendingmachine.state.ReadyState;\nimport coffeevendingmachine.state.VendingMachineState;\nimport coffeevendingmachine.decorator.Coffee;\n\nimport java.util.List;\n\npublic class CoffeeVendingMachine {\n    private static final CoffeeVendingMachine INSTANCE = new CoffeeVendingMachine();\n    private VendingMachineState state;\n    private Coffee selectedCoffee;\n    private int moneyInserted;\n\n    private CoffeeVendingMachine() {\n        this.state = new ReadyState();\n        this.moneyInserted = 0;\n    }\n\n    public static CoffeeVendingMachine getInstance() {\n        return INSTANCE;\n    }\n\n    // --- Actions delegated to the current state ---\n    public void selectCoffee(CoffeeType type, List<ToppingType> toppings) {\n        // 1. Create the base coffee using the factory\n        Coffee coffee = CoffeeFactory.createCoffee(type);\n\n        // 2. Wrap it with decorators\n        for (ToppingType topping : toppings) {\n            switch (topping) {\n                case EXTRA_SUGAR:\n                    coffee = new ExtraSugarDecorator(coffee);\n                    break;\n                case CARAMEL_SYRUP:\n                    coffee = new CaramelSyrupDecorator(coffee);\n                    break;\n            }\n        }\n        // Let the state handle the rest\n        this.state.selectCoffee(this, coffee);\n    }\n\n    public void insertMoney(int amount) { state.insertMoney(this, amount); }\n    public void dispenseCoffee() { state.dispenseCoffee(this); }\n    public void cancel() { state.cancel(this); }\n\n    // --- Getters and Setters used by State objects ---\n    public void setState(VendingMachineState state) { this.state = state; }\n    public VendingMachineState getState() { return state; }\n    public void setSelectedCoffee(Coffee selectedCoffee) { this.selectedCoffee = selectedCoffee; }\n    public Coffee getSelectedCoffee() { return selectedCoffee; }\n    public void setMoneyInserted(int moneyInserted) { this.moneyInserted = moneyInserted; }\n    public int getMoneyInserted() { return moneyInserted; }\n\n    public void reset() {\n        this.selectedCoffee = null;\n        this.moneyInserted = 0;\n    }\n\n    public Map<String, Integer> showIngredientsMap() {\n        return ingredientStore.getAllIngredients();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/CoffeeVendingMachineDemo.java",
    "content": "package coffeevendingmachine;\n\nimport coffeevendingmachine.enums.CoffeeType;\nimport coffeevendingmachine.enums.Ingredient;\nimport coffeevendingmachine.enums.ToppingType;\n\nimport java.util.List;\n\npublic class CoffeeVendingMachineDemo {\n    public static void main(String[] args) {\n        CoffeeVendingMachine machine = CoffeeVendingMachine.getInstance();\n        Inventory inventory = Inventory.getInstance();\n\n        // --- Initial setup: Refill inventory ---\n        System.out.println(\"=== Initializing Vending Machine ===\");\n        inventory.addStock(Ingredient.COFFEE_BEANS, 50);\n        inventory.addStock(Ingredient.WATER, 500);\n        inventory.addStock(Ingredient.MILK, 200);\n        inventory.addStock(Ingredient.SUGAR, 100);\n        inventory.addStock(Ingredient.CARAMEL_SYRUP, 50);\n        inventory.printInventory();\n\n        // --- Scenario 1: Successful Purchase of a Latte ---\n        System.out.println(\"\\n--- SCENARIO 1: Buy a Latte (Success) ---\");\n        machine.selectCoffee(CoffeeType.LATTE, List.of());\n        machine.insertMoney(200);\n        machine.insertMoney(50); // Total 250, price is 220\n        machine.dispenseCoffee();\n        inventory.printInventory();\n\n        // --- Scenario 2: Purchase with Insufficient Funds & Cancellation ---\n        System.out.println(\"\\n--- SCENARIO 2: Buy Espresso (Insufficient Funds & Cancel) ---\");\n        machine.selectCoffee(CoffeeType.ESPRESSO, List.of());\n        machine.insertMoney(100); // Price is 150\n        machine.dispenseCoffee(); // Should fail\n        machine.cancel(); // Should refund 100\n        inventory.printInventory(); // Should be unchanged\n\n        // --- Scenario 3: Attempt to Buy with Insufficient Ingredients ---\n        System.out.println(\"\\n--- SCENARIO 3: Buy Cappuccino (Out of Milk) ---\");\n        inventory.printInventory();\n        machine.selectCoffee(CoffeeType.CAPPUCCINO, List.of(ToppingType.CARAMEL_SYRUP, ToppingType.EXTRA_SUGAR));\n        machine.insertMoney(300);\n        machine.dispenseCoffee(); // Should fail and refund\n        inventory.printInventory();\n\n        // --- Refill and final test ---\n        System.out.println(\"\\n--- REFILLING AND FINAL TEST ---\");\n        inventory.addStock(Ingredient.MILK, 200);\n        inventory.printInventory();\n        machine.selectCoffee(CoffeeType.LATTE, List.of(ToppingType.CARAMEL_SYRUP));\n        machine.insertMoney(250);\n        machine.dispenseCoffee();\n        inventory.printInventory();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/Inventory.java",
    "content": "package coffeevendingmachine;\n\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Inventory {\n    private static final Inventory INSTANCE = new Inventory();\n    private final Map<Ingredient, Integer> stock = new ConcurrentHashMap<>();\n\n    private Inventory() {\n        // Private constructor to prevent instantiation\n    }\n\n    public static Inventory getInstance() {\n        return INSTANCE;\n    }\n\n    public void addStock(Ingredient ingredient, int quantity) {\n        stock.put(ingredient, stock.getOrDefault(ingredient, 0) + quantity);\n    }\n\n    public boolean hasIngredients(Map<Ingredient, Integer> recipe) {\n        return recipe.entrySet().stream()\n                .allMatch(entry -> stock.getOrDefault(entry.getKey(), 0) >= entry.getValue());\n    }\n\n    public synchronized void deductIngredients(Map<Ingredient, Integer> recipe) {\n        if (!hasIngredients(recipe)) {\n            System.err.println(\"Not enough ingredients to make coffee.\");\n            return;\n        }\n        recipe.forEach((ingredient, quantity) ->\n                stock.put(ingredient, stock.get(ingredient) - quantity));\n    }\n\n    public void printInventory() {\n        System.out.println(\"--- Current Inventory ---\");\n        stock.forEach((key, value) -> System.out.println(key + \": \" + value));\n        System.out.println(\"-------------------------\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/README.md",
    "content": "# Coffee Vending Machine (LLD)\n\n## Problem Statement\n\nDesign and implement a Coffee Vending Machine system that can serve different types of coffee, manage ingredient inventory, process payments, and handle user interactions such as selecting coffee and refilling ingredients.\n\n---\n\n## Requirements\n\n- **Multiple Coffee Types:** The machine should support multiple coffee recipes (e.g., Espresso, Latte, Cappuccino).\n- **Ingredient Management:** The machine should track and manage ingredient levels, and prevent dispensing if ingredients are insufficient.\n- **Payment Processing:** The machine should process payments before dispensing coffee.\n- **Refill Ingredients:** The machine should allow refilling of ingredients.\n- **Extensibility:** Easy to add new coffee types or payment methods.\n\n---\n\n## Core Entities\n\n- **CoffeeVendingMachine:** Main class that manages the overall operation, user interaction, and coordinates other components.\n- **CoffeeRecipe:** Represents a coffee recipe, including required ingredients and their quantities.\n- **IngredientStore:** Manages the inventory of ingredients, supports checking and refilling.\n- **Dispenser:** Handles the dispensing of coffee after successful payment and ingredient check.\n- **PaymentProcessor:** Handles payment logic and validation.\n- **Payment:** Represents a payment transaction.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/coffeevendingmachine-class-diagram.png)\n\n### 1. CoffeeVendingMachine\n- **Fields:** ingredientStore, paymentProcessor, Map<String, CoffeeRecipe> recipes, Dispenser\n- **Methods:** selectCoffee(String), makeCoffee(String, Payment), refillIngredient(String, int), addRecipe(CoffeeRecipe), etc.\n\n### 2. CoffeeRecipe\n- **Fields:** name, Map<String, Integer> ingredients\n- **Methods:** getName(), getIngredients()\n\n### 3. IngredientStore\n- **Fields:** Map<String, Integer> ingredientLevels\n- **Methods:** hasIngredients(Map<String, Integer>), useIngredients(Map<String, Integer>), refill(String, int), getLevel(String)\n\n### 4. Dispenser\n- **Methods:** dispense(String)\n\n### 5. PaymentProcessor\n- **Methods:** processPayment(Payment)\n\n### 6. Payment\n- **Fields:** amount, paymentType, etc.\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** (Conceptually) for supporting different payment methods or coffee recipes.\n- **Separation of Concerns:** Each class has a single responsibility (inventory, payment, dispensing, etc.).\n\n---\n\n## Example Usage\n\n```java\nCoffeeVendingMachine machine = new CoffeeVendingMachine();\nmachine.addRecipe(new CoffeeRecipe(\"Espresso\", Map.of(\"CoffeeBeans\", 10, \"Water\", 30)));\nmachine.refillIngredient(\"CoffeeBeans\", 100);\nmachine.refillIngredient(\"Water\", 200);\n\nPayment payment = new Payment(50, \"CASH\");\nmachine.makeCoffee(\"Espresso\", payment);\n```\n\n---\n\n## Demo\n\nSee `CoffeeVendingMachineDemo.java` for a sample usage and simulation of the coffee vending machine.\n\n---\n\n## Extending the Framework\n\n- **Add new coffee types:** Create new `CoffeeRecipe` instances and add them to the machine.\n- **Add new payment methods:** Extend `PaymentProcessor` to support new payment types.\n- **Add new ingredients:** Update `IngredientStore` and recipes as needed.\n\n---"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/decorator/CaramelSyrupDecorator.java",
    "content": "package coffeevendingmachine.decorator;\n\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class CaramelSyrupDecorator extends CoffeeDecorator {\n    private static final int COST = 30;\n    private static final Map<Ingredient, Integer> RECIPE_ADDITION = Map.of(Ingredient.CARAMEL_SYRUP, 10);\n\n    public CaramelSyrupDecorator(Coffee coffee) {\n        super(coffee);\n    }\n\n    @Override\n    public String getCoffeeType() {\n        return decoratedCoffee.getCoffeeType() + \", Caramel Syrup\";\n    }\n\n    @Override\n    public int getPrice() {\n        return decoratedCoffee.getPrice() + COST;\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        Map<Ingredient, Integer> newRecipe = new HashMap<>(decoratedCoffee.getRecipe());\n        RECIPE_ADDITION.forEach((ingredient, qty) ->\n                newRecipe.merge(ingredient, qty, Integer::sum));\n        return newRecipe;\n    }\n\n    @Override\n    public void prepare() {\n        // First, prepare the underlying coffee (e.g., the Latte with Sugar)\n        super.prepare();\n        // Then, add the specific step for this decorator\n        System.out.println(\"- Drizzling Caramel Syrup on top.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/decorator/Coffee.java",
    "content": "package coffeevendingmachine.decorator;\n\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\n\npublic abstract class Coffee {\n    protected String coffeeType = \"Unknown Coffee\";\n\n    public String getCoffeeType() {\n        return coffeeType;\n    }\n\n    // The Template Method\n    public void prepare() {\n        System.out.println(\"\\nPreparing your \" + this.getCoffeeType() + \"...\");\n        grindBeans();\n        brew();\n        addCondiments(); // The \"hook\" for base coffee types\n        pourIntoCup();\n        System.out.println(this.getCoffeeType() + \" is ready!\");\n    }\n\n    // Common steps\n    private void grindBeans() { System.out.println(\"- Grinding fresh coffee beans.\"); }\n    private void brew() { System.out.println(\"- Brewing coffee with hot water.\"); }\n    private void pourIntoCup() { System.out.println(\"- Pouring into a cup.\"); }\n\n    // Abstract step to be implemented by subclasses\n    protected abstract void addCondiments();\n\n    public abstract int getPrice();\n    public abstract Map<Ingredient, Integer> getRecipe();\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/decorator/CoffeeDecorator.java",
    "content": "package coffeevendingmachine.decorator;\n\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\n\npublic abstract class CoffeeDecorator extends Coffee {\n    protected Coffee decoratedCoffee;\n\n    public CoffeeDecorator(Coffee coffee) {\n        this.decoratedCoffee = coffee;\n    }\n\n    // Delegate calls to the wrapped object.\n    // Concrete decorators will override these to add their own logic.\n    @Override\n    public int getPrice() {\n        return decoratedCoffee.getPrice();\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        return decoratedCoffee.getRecipe();\n    }\n\n    @Override\n    protected void addCondiments() {\n        decoratedCoffee.addCondiments();\n    }\n\n    @Override\n    public void prepare() {\n        decoratedCoffee.prepare();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/decorator/ExtraSugarDecorator.java",
    "content": "package coffeevendingmachine.decorator;\n\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ExtraSugarDecorator extends CoffeeDecorator {\n    private static final int COST = 10;\n    private static final Map<Ingredient, Integer> RECIPE_ADDITION = Map.of(Ingredient.SUGAR, 1);\n\n    public ExtraSugarDecorator(Coffee coffee) {\n        super(coffee);\n    }\n\n    @Override\n    public String getCoffeeType() {\n        return decoratedCoffee.getCoffeeType() + \", Extra Sugar\";\n    }\n\n    @Override\n    public int getPrice() {\n        return decoratedCoffee.getPrice() + COST;\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        // Merge the recipes\n        Map<Ingredient, Integer> newRecipe = new HashMap<>(decoratedCoffee.getRecipe());\n        RECIPE_ADDITION.forEach((ingredient, qty) ->\n                newRecipe.merge(ingredient, qty, Integer::sum));\n        return newRecipe;\n    }\n\n    @Override\n    public void prepare() {\n        super.prepare();\n        System.out.println(\"- Stirring in Extra Sugar.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/enums/CoffeeType.java",
    "content": "package coffeevendingmachine.enums;\n\npublic enum CoffeeType {\n    ESPRESSO,\n    LATTE,\n    CAPPUCCINO;\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/enums/Ingredient.java",
    "content": "package coffeevendingmachine.enums;\n\npublic enum Ingredient {\n    COFFEE_BEANS,\n    MILK,\n    SUGAR,\n    WATER,\n    CARAMEL_SYRUP\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/enums/ToppingType.java",
    "content": "package coffeevendingmachine.enums;\n\npublic enum ToppingType {\n    EXTRA_SUGAR,\n    CARAMEL_SYRUP\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/factory/CoffeeFactory.java",
    "content": "package coffeevendingmachine.factory;\n\nimport coffeevendingmachine.enums.CoffeeType;\nimport coffeevendingmachine.templatemethod.Cappuccino;\nimport coffeevendingmachine.decorator.Coffee;\nimport coffeevendingmachine.templatemethod.Espresso;\nimport coffeevendingmachine.templatemethod.Latte;\n\npublic class CoffeeFactory {\n    public static Coffee createCoffee(CoffeeType type) {\n        switch (type) {\n            case ESPRESSO:\n                return new Espresso();\n            case LATTE:\n                return new Latte();\n            case CAPPUCCINO:\n                return new Cappuccino();\n            default:\n                throw new IllegalArgumentException(\"Unsupported coffee type: \" + type);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/state/OutOfIngredientState.java",
    "content": "package coffeevendingmachine.state;\n\nimport coffeevendingmachine.CoffeeVendingMachine;\nimport coffeevendingmachine.decorator.Coffee;\n\npublic class OutOfIngredientState implements VendingMachineState {\n    @Override\n    public void selectCoffee(CoffeeVendingMachine m, Coffee c) {\n        System.out.println(\"Sorry, the machine is out of ingredients.\");\n    }\n\n    @Override\n    public void insertMoney(CoffeeVendingMachine m, int a) {\n        System.out.println(\"Sorry, the machine is out of ingredients. Money refunded.\");\n    }\n\n    @Override\n    public void dispenseCoffee(CoffeeVendingMachine m) {\n        System.out.println(\"Sorry, the machine is out of ingredients.\");\n    }\n\n    @Override\n    public void cancel(CoffeeVendingMachine machine) {\n        System.out.println(\"Refunding \" + machine.getMoneyInserted());\n        machine.reset();\n        machine.setState(new ReadyState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/state/PaidState.java",
    "content": "package coffeevendingmachine.state;\n\nimport coffeevendingmachine.CoffeeVendingMachine;\nimport coffeevendingmachine.Inventory;\nimport coffeevendingmachine.decorator.Coffee;\n\npublic class PaidState implements VendingMachineState {\n    @Override\n    public void selectCoffee(CoffeeVendingMachine m, Coffee c) {\n        System.out.println(\"Cannot select another coffee now.\");\n    }\n\n    @Override\n    public void insertMoney(CoffeeVendingMachine m, int a) {\n        System.out.println(\"Already paid. Please wait for your coffee.\");\n    }\n\n    @Override\n    public void dispenseCoffee(CoffeeVendingMachine machine) {\n        Inventory inventory = Inventory.getInstance();\n        Coffee coffeeToDispense = machine.getSelectedCoffee();\n\n        if (!inventory.hasIngredients(machine.getSelectedCoffee().getRecipe())) {\n            System.out.println(\"Sorry, out of ingredients for \" + machine.getSelectedCoffee().getCoffeeType());\n            machine.setState(new OutOfIngredientState());\n            machine.getState().cancel(machine);\n            return;\n        }\n        inventory.deductIngredients(machine.getSelectedCoffee().getRecipe());\n\n        coffeeToDispense.prepare();\n\n        int change = machine.getMoneyInserted() - machine.getSelectedCoffee().getPrice();\n        if (change > 0)\n            System.out.println(\"Returning change: \" + change);\n\n        machine.reset();\n        machine.setState(new ReadyState());\n    }\n\n    @Override\n    public void cancel(CoffeeVendingMachine m) {\n        new SelectingState().cancel(m); // Same as in SelectingState\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/state/ReadyState.java",
    "content": "package coffeevendingmachine.state;\n\nimport coffeevendingmachine.CoffeeVendingMachine;\nimport coffeevendingmachine.decorator.Coffee;\n\npublic class ReadyState implements VendingMachineState {\n    @Override\n    public void selectCoffee(CoffeeVendingMachine machine, Coffee coffee) {\n        machine.setSelectedCoffee(coffee);\n        machine.setState(new SelectingState());\n        System.out.println(coffee.getCoffeeType() + \" selected. Price: \" + coffee.getPrice());\n    }\n\n    @Override\n    public void insertMoney(CoffeeVendingMachine m, int a) {\n        System.out.println(\"Please select a coffee first.\");\n    }\n\n    @Override\n    public void dispenseCoffee(CoffeeVendingMachine m) {\n        System.out.println(\"Please select and pay first.\");\n    }\n\n    @Override\n    public void cancel(CoffeeVendingMachine m) {\n        System.out.println(\"Nothing to cancel.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/state/SelectingState.java",
    "content": "package coffeevendingmachine.state;\n\nimport coffeevendingmachine.CoffeeVendingMachine;\nimport coffeevendingmachine.decorator.Coffee;\n\npublic class SelectingState implements VendingMachineState {\n    @Override\n    public void selectCoffee(CoffeeVendingMachine m, Coffee c) {\n        System.out.println(\"Already selected. Please pay or cancel.\");\n    }\n\n    @Override\n    public void insertMoney(CoffeeVendingMachine machine, int amount) {\n        machine.setMoneyInserted(machine.getMoneyInserted() + amount);\n        System.out.println(\"Inserted \" + amount + \". Total: \" + machine.getMoneyInserted());\n        if (machine.getMoneyInserted() >= machine.getSelectedCoffee().getPrice()) {\n            machine.setState(new PaidState());\n        }\n    }\n\n    @Override\n    public void dispenseCoffee(CoffeeVendingMachine m) {\n        System.out.println(\"Please insert enough money first.\");\n    }\n\n    @Override public void cancel(CoffeeVendingMachine machine) {\n        System.out.println(\"Transaction cancelled. Refunding \" + machine.getMoneyInserted());\n        machine.reset();\n        machine.setState(new ReadyState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/state/VendingMachineState.java",
    "content": "package coffeevendingmachine.state;\n\nimport coffeevendingmachine.CoffeeVendingMachine;\nimport coffeevendingmachine.decorator.Coffee;\n\npublic interface VendingMachineState {\n    void selectCoffee(CoffeeVendingMachine machine, Coffee coffee);\n    void insertMoney(CoffeeVendingMachine machine, int amount);\n    void dispenseCoffee(CoffeeVendingMachine machine);\n    void cancel(CoffeeVendingMachine machine);\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/templatemethod/Cappuccino.java",
    "content": "package coffeevendingmachine.templatemethod;\n\nimport coffeevendingmachine.decorator.Coffee;\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\n\npublic class Cappuccino extends Coffee {\n    public Cappuccino() {\n        this.coffeeType = \"Cappuccino\";\n    }\n\n    @Override\n    protected void addCondiments() {\n        System.out.println(\"- Adding steamed milk and foam.\");\n    }\n\n    @Override\n    public int getPrice() {\n        return 250;\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        return Map.of(Ingredient.COFFEE_BEANS, 7, Ingredient.WATER, 30, Ingredient.MILK, 100);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/templatemethod/Espresso.java",
    "content": "package coffeevendingmachine.templatemethod;\n\nimport coffeevendingmachine.decorator.Coffee;\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\n\npublic class Espresso extends Coffee {\n    public Espresso() {\n        this.coffeeType = \"Espresso\";\n    }\n\n    @Override\n    protected void addCondiments() { /* No extra condiments for espresso */ }\n\n    @Override\n    public int getPrice() {\n        return 150;\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        return Map.of(Ingredient.COFFEE_BEANS, 7, Ingredient.WATER, 30);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/coffeevendingmachine/templatemethod/Latte.java",
    "content": "package coffeevendingmachine.templatemethod;\n\nimport coffeevendingmachine.decorator.Coffee;\nimport coffeevendingmachine.enums.Ingredient;\n\nimport java.util.Map;\n\npublic class Latte extends Coffee {\n    public Latte() {\n        this.coffeeType = \"Latte\";\n    }\n\n    // Latte's implementation of the template hook\n    @Override\n    protected void addCondiments() {\n        System.out.println(\"- Adding steamed milk.\");\n    }\n\n    @Override\n    public int getPrice() {\n        return 220;\n    }\n\n    @Override\n    public Map<Ingredient, Integer> getRecipe() {\n        return Map.of(Ingredient.COFFEE_BEANS, 7, Ingredient.WATER, 30, Ingredient.MILK, 150);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/Booking.java",
    "content": "package concertticketbookingsystem;\n\nimport java.util.List;\n\npublic class Booking {\n    private final String id;\n    private final User user;\n    private final Concert concert;\n    private final List<Seat> seats;\n    private final double totalPrice;\n    private BookingStatus status;\n\n    public Booking(String id, User user, Concert concert, List<Seat> seats) {\n        this.id = id;\n        this.user = user;\n        this.concert = concert;\n        this.seats = seats;\n        this.totalPrice = calculateTotalPrice();\n        this.status = BookingStatus.PENDING;\n    }\n\n    private double calculateTotalPrice() {\n        return seats.stream().mapToDouble(Seat::getPrice).sum();\n    }\n\n    public void confirmBooking() {\n        if (status == BookingStatus.PENDING) {\n            status = BookingStatus.CONFIRMED;\n            // Send booking confirmation to the user\n            // ...\n        }\n    }\n\n    public void cancelBooking() {\n        if (status == BookingStatus.CONFIRMED) {\n            status = BookingStatus.CANCELLED;\n            seats.forEach(Seat::release);\n            System.out.printf(\"Booking %s cancelled\\n\", id);\n            // Send booking cancellation notification to the user\n            // ...\n        }\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public User getUser() {\n        return user;\n    }\n\n    public Concert getConcert() {\n        return concert;\n    }\n\n    public List<Seat> getSeats() {\n        return seats;\n    }\n\n    public double getTotalPrice() {\n        return totalPrice;\n    }\n\n    public BookingStatus getStatus() {\n        return status;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/BookingStatus.java",
    "content": "package concertticketbookingsystem;\n\npublic enum BookingStatus {\n    PENDING,\n    CONFIRMED,\n    CANCELLED\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/Concert.java",
    "content": "package concertticketbookingsystem;\n\nimport java.time.LocalDateTime;\nimport java.util.List;\n\npublic class Concert {\n    private final String id;\n    private final String artist;\n    private final String venue;\n    private final LocalDateTime dateTime;\n    private final List<Seat> seats;\n\n    public Concert(String id, String artist, String venue, LocalDateTime dateTime, List<Seat> seats) {\n        this.id = id;\n        this.artist = artist;\n        this.venue = venue;\n        this.dateTime = dateTime;\n        this.seats = seats;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getArtist() {\n        return artist;\n    }\n\n    public String getVenue() {\n        return venue;\n    }\n\n    public LocalDateTime getDateTime() {\n        return dateTime;\n    }\n\n    public List<Seat> getSeats() {\n        return seats;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/ConcertTicketBookingSystem.java",
    "content": "package concertticketbookingsystem;\n\nimport java.time.LocalDateTime;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\npublic class ConcertTicketBookingSystem {\n    private static ConcertTicketBookingSystem instance;\n    private final Map<String, Concert> concerts;\n    private final Map<String, Booking> bookings;\n    private final Object lock = new Object();\n\n    private ConcertTicketBookingSystem() {\n        concerts = new ConcurrentHashMap<>();\n        bookings = new ConcurrentHashMap<>();\n    }\n\n    public static synchronized ConcertTicketBookingSystem getInstance() {\n        if (instance == null) {\n            instance = new ConcertTicketBookingSystem();\n        }\n        return instance;\n    }\n\n    public void addConcert(Concert concert) {\n        concerts.put(concert.getId(), concert);\n    }\n\n    public Concert getConcert(String concertId) {\n        return concerts.get(concertId);\n    }\n\n    public List<Concert> searchConcerts(String artist, String venue, LocalDateTime dateTime) {\n        return concerts.values().stream()\n                .filter(concert -> concert.getArtist().equalsIgnoreCase(artist) &&\n                        concert.getVenue().equalsIgnoreCase(venue) &&\n                        concert.getDateTime().equals(dateTime))\n                .collect(Collectors.toList());\n    }\n\n    public Booking bookTickets(User user, Concert concert, List<Seat> seats) {\n        synchronized (lock) {\n            // Check seat availability and book seats\n            for (Seat seat : seats) {\n                if (seat.getStatus() != SeatStatus.AVAILABLE) {\n                    throw new SeatNotAvailableException(\"Seat \" + seat.getSeatNumber() + \" is not available.\");\n                }\n            }\n            seats.forEach(Seat::book);\n\n            // Create booking\n            String bookingId = generateBookingId();\n            Booking booking = new Booking(bookingId, user, concert, seats);\n            bookings.put(bookingId, booking);\n\n            // Process payment\n            processPayment(booking);\n\n            // Confirm booking\n            booking.confirmBooking();\n\n            System.out.println(\"Booking \" + booking.getId() + \" - \" + booking.getSeats().size() + \" seats booked\");\n\n            return booking;\n        }\n    }\n\n    public void cancelBooking(String bookingId) {\n        Booking booking = bookings.get(bookingId);\n        if (booking != null) {\n            booking.cancelBooking();\n            bookings.remove(bookingId);\n        }\n    }\n\n    private void processPayment(Booking booking) {\n        // Process payment for the booking\n        // ...\n    }\n\n    private String generateBookingId() {\n        return \"BKG\" + UUID.randomUUID();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/ConcertTicketBookingSystemDemo.java",
    "content": "package concertticketbookingsystem;\n\nimport java.time.LocalDateTime;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class ConcertTicketBookingSystemDemo {\n    public static void run() {\n        // Create concert ticket booking system instance\n        ConcertTicketBookingSystem bookingSystem = ConcertTicketBookingSystem.getInstance();\n\n        // Create concerts\n        List<Seat> concert1Seats = generateSeats(100);\n        Concert concert1 = new Concert(\"C001\", \"Artist 1\", \"Venue 1\", LocalDateTime.now().plusDays(30), concert1Seats);\n        bookingSystem.addConcert(concert1);\n\n        List<Seat> concert2Seats = generateSeats(50);\n        Concert concert2 = new Concert(\"C002\", \"Artist 2\", \"Venue 2\", LocalDateTime.now().plusDays(60), concert2Seats);\n        bookingSystem.addConcert(concert2);\n\n        // Create users\n        User user1 = new User(\"U001\", \"John Doe\", \"john@example.com\");\n        User user2 = new User(\"U002\", \"Jane Smith\", \"jane@example.com\");\n\n        // Search concerts\n        List<Concert> searchResults = bookingSystem.searchConcerts(\"Artist 1\", \"Venue 1\", LocalDateTime.now().plusDays(30));\n        System.out.println(\"Search Results:\");\n        for (Concert concert : searchResults) {\n            System.out.println(\"Concert: \" + concert.getArtist() + \" at \" + concert.getVenue());\n        }\n\n        // Book tickets\n        List<Seat> selectedSeats1 = selectSeats(concert1, 3);\n        Booking booking1 = bookingSystem.bookTickets(user1, concert1, selectedSeats1);\n\n        List<Seat> selectedSeats2 = selectSeats(concert2, 2);\n        Booking booking2 = bookingSystem.bookTickets(user2, concert2, selectedSeats2);\n\n        // Cancel booking\n        bookingSystem.cancelBooking(booking1.getId());\n\n        // Book tickets again\n        List<Seat> selectedSeats3 = selectSeats(concert1, 2);\n        Booking booking3 = bookingSystem.bookTickets(user2, concert1, selectedSeats3);\n    }\n\n    private static List<Seat> generateSeats(int numberOfSeats) {\n        List<Seat> seats = new ArrayList<>();\n        for (int i = 1; i <= numberOfSeats; i++) {\n            String seatNumber = \"S\" + i;\n            SeatType seatType = (i <= 10) ? SeatType.VIP : (i <= 30) ? SeatType.PREMIUM : SeatType.REGULAR;\n            double price = (seatType == SeatType.VIP) ? 100.0 : (seatType == SeatType.PREMIUM) ? 75.0 : 50.0;\n            seats.add(new Seat(seatNumber, seatNumber, seatType, price));\n        }\n        return seats;\n    }\n\n    private static List<Seat> selectSeats(Concert concert, int numberOfSeats) {\n        List<Seat> selectedSeats = new ArrayList<>();\n        List<Seat> availableSeats = concert.getSeats().stream()\n                .filter(seat -> seat.getStatus() == SeatStatus.AVAILABLE)\n                .limit(numberOfSeats)\n                .toList();\n        selectedSeats.addAll(availableSeats);\n        return selectedSeats;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/README.md",
    "content": "# Concert Ticket Booking System (LLD)\n\n## Problem Statement\n\nDesign and implement a Concert Ticket Booking System that allows users to book seats for concerts. The system should manage concert details, seat availability, and handle bookings with proper validation.\n\n---\n\n## Requirements\n\n- **Concert Management:** The system manages concert details including name, date, venue, and available seats.\n- **Seat Management:** The system tracks different types of seats (VIP, STANDARD, ECONOMY) and their availability.\n- **Booking Management:** Users can book seats, and the system handles booking status (CONFIRMED, CANCELLED).\n- **User Management:** The system maintains user information for bookings.\n- **Validation:** The system prevents double bookings and handles seat availability checks.\n\n---\n\n## Core Entities\n\n- **ConcertTicketBookingSystem:** Main class that manages concerts, bookings, and seat allocation.\n- **Concert:** Represents a concert with its details and seat management.\n- **Seat:** Represents a seat with its type, status, and booking information.\n- **User:** Represents a user who can book tickets.\n- **Booking:** Represents a booking with its status and associated details.\n- **SeatType:** Enum for different seat categories (VIP, STANDARD, ECONOMY).\n- **SeatStatus:** Enum for seat states (AVAILABLE, BOOKED).\n- **BookingStatus:** Enum for booking states (CONFIRMED, CANCELLED).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/concertticketbookingsystem-class-diagram.png)\n\n### 1. ConcertTicketBookingSystem\n- **Fields:** List<Concert> concerts, List<Booking> bookings\n- **Methods:** addConcert(), bookSeat(), cancelBooking(), getAvailableSeats(), etc.\n\n### 2. Concert\n- **Fields:** String name, String date, String venue, List<Seat> seats\n- **Methods:** addSeat(), getAvailableSeats(), bookSeat(), etc.\n\n### 3. Seat\n- **Fields:** String seatNumber, SeatType type, SeatStatus status, Booking booking\n- **Methods:** isAvailable(), book(), cancel(), etc.\n\n### 4. User\n- **Fields:** String name, String email\n\n### 5. Booking\n- **Fields:** String bookingId, User user, Concert concert, Seat seat, BookingStatus status\n- **Methods:** confirm(), cancel(), etc.\n\n### 6. Enums\n- **SeatType:** VIP, STANDARD, ECONOMY\n- **SeatStatus:** AVAILABLE, BOOKED\n- **BookingStatus:** CONFIRMED, CANCELLED\n\n---\n\n## Example Usage\n\n```java\nConcertTicketBookingSystem system = new ConcertTicketBookingSystem();\n\n// Add a concert\nConcert concert = system.addConcert(\"Rock Concert\", \"2024-12-31\", \"Stadium\");\n\n// Book a seat\nUser user = new User(\"John Doe\", \"john@example.com\");\nBooking booking = system.bookSeat(concert, \"A1\", user);\n\n// Cancel booking\nsystem.cancelBooking(booking);\n```\n\n---\n\n## Demo\n\nSee `ConcertTicketBookingSystemDemo.java` for a sample usage and simulation of the booking system.\n\n---\n\n## Extending the Framework\n\n- **Add payment processing:** Integrate payment gateway for parkingTicket purchases\n- **Add waitlist functionality:** Handle seat waitlist when fully booked\n- **Add discount management:** Support for different pricing tiers and discounts\n- **Add notification system:** Send booking confirmations and updates\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For managing the booking system instance\n- **Factory Pattern:** For creating different types of seats\n- **Observer Pattern:** For notifying users about booking status changes\n\n---"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/Seat.java",
    "content": "package concertticketbookingsystem;\n\npublic class Seat {\n    private final String id;\n    private final String seatNumber;\n    private final SeatType seatType;\n    private final double price;\n    private SeatStatus status;\n\n    public Seat(String id, String seatNumber, SeatType seatType, double price) {\n        this.id = id;\n        this.seatNumber = seatNumber;\n        this.seatType = seatType;\n        this.price = price;\n        this.status = SeatStatus.AVAILABLE;\n    }\n\n    public synchronized void book() {\n        if (status == SeatStatus.AVAILABLE) {\n            status = SeatStatus.BOOKED;\n        } else {\n            throw new SeatNotAvailableException(\"Seat is already booked or reserved.\");\n        }\n    }\n\n    public synchronized void release() {\n        if (status == SeatStatus.BOOKED) {\n            status = SeatStatus.AVAILABLE;\n        }\n    }\n\n    public double getPrice() {\n        return price;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getSeatNumber() {\n        return seatNumber;\n    }\n\n    public SeatType getSeatType() {\n        return seatType;\n    }\n\n    public SeatStatus getStatus() {\n        return status;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/SeatNotAvailableException.java",
    "content": "package concertticketbookingsystem;\n\npublic class SeatNotAvailableException extends RuntimeException {\n    public SeatNotAvailableException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/SeatStatus.java",
    "content": "package concertticketbookingsystem;\n\npublic enum SeatStatus {\n    AVAILABLE,\n    BOOKED,\n    RESERVED\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/SeatType.java",
    "content": "package concertticketbookingsystem;\n\npublic enum SeatType {\n    REGULAR,\n    PREMIUM,\n    VIP\n}\n"
  },
  {
    "path": "solutions/java/src/concertticketbookingsystem/User.java",
    "content": "package concertticketbookingsystem;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final String email;\n\n    public User(String id, String name, String email) {\n        this.id = id;\n        this.name = name;\n        this.email = email;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/CourseRegistrationDemo.java",
    "content": "package courseregistrationsystem;\n\nimport courseregistrationsystem.model.*;\nimport courseregistrationsystem.observer.WaitlistManager;\nimport courseregistrationsystem.repository.CourseRepository;\nimport courseregistrationsystem.repository.StudentRepository;\n\nimport java.time.DayOfWeek;\nimport java.time.LocalTime;\n\npublic class CourseRegistrationDemo {\n    public static void main(String[] args) {\n        // 1. Setup the system\n        CourseRegistrationSystemFacade system = new CourseRegistrationSystemFacade();\n        StudentRepository studentRepo = StudentRepository.getInstance();\n        CourseRepository courseRepo = CourseRepository.getInstance();\n        WaitlistManager waitlistManager = WaitlistManager.getInstance();\n\n        // 2. Setup courses and professors\n        Course cs101 = new Course(\"CS101\", \"Intro to Programming\");\n        Course cs201 = new Course(\"CS201\", \"Data Structures\");\n        cs201.addPrerequisite(cs101);\n        courseRepo.saveCourse(cs101); courseRepo.saveCourse(cs201);\n\n        Professor profA = new Professor(\"P1\", \"Dr. Smith\");\n\n        // 3. Setup course offerings using the Builder\n        CourseOffering cs101Offering = new CourseOffering.Builder(\"CS101-F23\", cs101)\n                .withProfessor(profA).at(new TimeSlot(DayOfWeek.MONDAY, LocalTime.of(10, 0), LocalTime.of(11, 30)))\n                .withCapacity(1).build();\n\n        CourseOffering cs201Offering = new CourseOffering.Builder(\"CS201-F23\", cs201)\n                .withProfessor(profA).at(new TimeSlot(DayOfWeek.WEDNESDAY, LocalTime.of(14, 0), LocalTime.of(15, 30)))\n                .withCapacity(2).build();\n\n        // Register the WaitlistManager as an observer for the course offering\n        cs101Offering.addObserver(waitlistManager);\n\n        courseRepo.saveOffering(cs101Offering); courseRepo.saveOffering(cs201Offering);\n\n        // 4. Setup students\n        Student alice = new Student(\"S1\", \"Alice\");\n        Student bob = new Student(\"S2\", \"Bob\");\n        Student charlie = new Student(\"S3\", \"Charlie\");\n        alice.addCompletedCourse(cs101); // Alice has the prerequisite for CS201\n        studentRepo.save(alice); studentRepo.save(bob); studentRepo.save(charlie);\n\n        // 5. Run Registration Scenarios\n        System.out.println(\"----------- SCENARIO 1: Successful Registration -----------\");\n        system.registerStudentForCourse(alice.getId(), cs201Offering.getId());\n\n        System.out.println(\"\\n----------- SCENARIO 2: Prerequisite Failure -----------\");\n        system.registerStudentForCourse(bob.getId(), cs201Offering.getId());\n\n        System.out.println(\"\\n----------- SCENARIO 3: Course Capacity and Waitlist -----------\");\n        system.registerStudentForCourse(bob.getId(), cs101Offering.getId()); // Bob gets the last spot\n        system.registerStudentForCourse(charlie.getId(), cs101Offering.getId()); // Charlie gets waitlisted\n\n        System.out.println(\"\\n----------- SCENARIO 4: Dropping a course and Observer pattern triggering waitlist promotion -----------\");\n        system.dropStudentFromCourse(bob.getId(), cs101Offering.getId());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/CourseRegistrationService.java",
    "content": "package courseregistrationsystem;\n\nimport courseregistrationsystem.chain.*;\nimport courseregistrationsystem.exception.RegistrationException;\n\npublic class CourseRegistrationService {\n    private final RegistrationRuleHandler registrationChain;\n    public CourseRegistrationService() {\n        // Build the chain of responsibility\n        RegistrationRuleHandler capacityHandler = new CapacityRuleHandler();\n        RegistrationRuleHandler conflictHandler = new ScheduleConflictRuleHandler();\n        conflictHandler.setNext(capacityHandler);\n        RegistrationRuleHandler prereqHandler = new PrerequisiteRuleHandler();\n        prereqHandler.setNext(conflictHandler);\n        this.registrationChain = prereqHandler;\n    }\n    public void register(RegistrationRequest request) throws RegistrationException {\n        registrationChain.handle(request);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/CourseRegistrationSystemFacade.java",
    "content": "package courseregistrationsystem;\n\nimport courseregistrationsystem.chain.RegistrationRequest;\nimport courseregistrationsystem.exception.RegistrationException;\nimport courseregistrationsystem.repository.CourseRepository;\nimport courseregistrationsystem.repository.StudentRepository;\n\npublic class CourseRegistrationSystemFacade {\n    private final CourseRegistrationService courseRegistrationService = new CourseRegistrationService();\n    private final StudentRepository studentRepo = StudentRepository.getInstance();\n    private final CourseRepository courseRepo = CourseRepository.getInstance();\n\n    public void registerStudentForCourse(String studentId, String offeringId) {\n        studentRepo.findById(studentId).ifPresentOrElse(student ->\n                courseRepo.findOfferingById(offeringId).ifPresentOrElse(offering -> {\n                            try {\n                                courseRegistrationService.register(new RegistrationRequest(student, offering));\n                            } catch (RegistrationException e) {\n                                System.err.println(\"Registration Failed for \" + student.getName() + \": \" + e.getMessage());\n                            }\n                        }, () -> System.err.println(\"Error: Course offering \" + offeringId + \" not found.\")\n                ), () -> System.err.println(\"Error: Student \" + studentId + \" not found.\"));\n    }\n\n    public void dropStudentFromCourse(String studentId, String offeringId) {\n        studentRepo.findById(studentId).ifPresent(student ->\n                courseRepo.findOfferingById(offeringId).ifPresent(offering -> {\n                    offering.dropStudent(student);\n                    System.out.println(student.getName() + \" dropped from \" + offering.getCourse().getCourseCode());\n                })\n        );\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/README.md",
    "content": "# Course Registration System (LLD)\n\n## Problem Statement\n\nDesign and implement a Course Registration System that allows students to register for courses, manages course capacity, and tracks student enrollments.\n\n---\n\n## Requirements\n\n- **Student Registration:** Students can register for courses.\n- **Course Management:** The system manages courses, each with a unique code, name, and capacity.\n- **Capacity Enforcement:** Students cannot register for a course if it is full.\n- **Duplicate Prevention:** A student cannot register for the same course more than once.\n- **Enrollment Tracking:** The system tracks which students are enrolled in which courses.\n- **Extensibility:** Easy to add new features such as course prerequisites, waitlists, or drop functionality.\n\n---\n\n## Core Entities\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/CourseRegistrationSystem-class-diagram.png)\n\n- **CourseRegistrationSystem:** Main class that manages students, courses, and registrations.\n- **Student:** Represents a student with a unique ID and name.\n- **Course:** Represents a course with a unique code, name, and capacity.\n- **Registration:** Represents a registration record of a student in a course.\n\n---\n\n## Class Design\n\n### 1. CourseRegistrationSystem\n- **Fields:** Map<String, Course> courses, Map<Integer, Student> students, List<Registration> registrations\n- **Methods:** registerStudent(Student), addCourse(Course), register(int studentId, String courseCode), getStudentCourses(int studentId), getCourseStudents(String courseCode), etc.\n\n### 2. Student\n- **Fields:** int id, String name\n\n### 3. Course\n- **Fields:** String code, String name, int capacity, List<Student> enrolledStudents\n- **Methods:** enrollStudent(Student), isFull(), getEnrolledStudents()\n\n### 4. Registration\n- **Fields:** Student student, Course course\n\n---\n\n## Example Usage\n\n```java\nCourseRegistrationSystem system = new CourseRegistrationSystem();\nsystem.registerStudent(new Student(1, \"Alice\"));\nsystem.registerStudent(new Student(2, \"Bob\"));\nsystem.addCourse(new Course(\"CS101\", \"Intro to CS\", 2));\nsystem.addCourse(new Course(\"MATH101\", \"Calculus I\", 1));\n\nsystem.register(1, \"CS101\"); // Alice registers for CS101\nsystem.register(2, \"CS101\"); // Bob registers for CS101\nsystem.register(1, \"MATH101\"); // Alice registers for MATH101\n\n// List courses for Alice\nList<Course> aliceCourses = system.getStudentCourses(1);\n// List students in CS101\nList<Student> cs101Students = system.getCourseStudents(\"CS101\");\n```\n\n---\n\n## Demo\n\nSee `CourseRegistrationSystemDemo.java` for a sample usage and simulation of the course registration system.\n\n---\n\n## Extending the Framework\n\n- **Add course prerequisites:** Track and enforce prerequisites for course registration.\n- **Add waitlists:** Allow students to join a waitlist if a course is full.\n- **Add drop functionality:** Allow students to drop courses.\n\n---"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/chain/CapacityRuleHandler.java",
    "content": "package courseregistrationsystem.chain;\n\nimport courseregistrationsystem.exception.RegistrationException;\n\npublic class CapacityRuleHandler extends RegistrationRuleHandler {\n    @Override\n    public void handle(RegistrationRequest request) throws RegistrationException {\n        if (request.offering().isFull()) {\n            request.offering().addToWaitlist(request.student());\n            System.out.println(\"Course \" + request.offering().getCourse().getCourseCode() + \" is full. \" + request.student().getName() + \" added to waitlist.\");\n        } else {\n            request.offering().addStudent(request.student());\n            System.out.println(request.student().getName() + \" successfully registered for \" + request.offering().getCourse().getCourseCode());\n        }\n        handleNext(request);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/chain/PrerequisiteRuleHandler.java",
    "content": "package courseregistrationsystem.chain;\n\nimport courseregistrationsystem.exception.RegistrationException;\nimport courseregistrationsystem.model.Course;\n\nimport java.util.Set;\n\npublic class PrerequisiteRuleHandler extends RegistrationRuleHandler {\n    @Override\n    public void handle(RegistrationRequest request) throws RegistrationException {\n        Set<Course> completed = request.student().getCompletedCourses();\n        Set<Course> prereqs = request.offering().getCourse().getPrerequisites();\n        if (!completed.containsAll(prereqs)) {\n            throw new RegistrationException(\"Prerequisite not met for course \" + request.offering().getCourse().getCourseCode());\n        }\n        handleNext(request);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/chain/RegistrationRequest.java",
    "content": "package courseregistrationsystem.chain;\n\nimport courseregistrationsystem.model.CourseOffering;\nimport courseregistrationsystem.model.Student;\n\npublic record RegistrationRequest(Student student, CourseOffering offering) {}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/chain/RegistrationRuleHandler.java",
    "content": "package courseregistrationsystem.chain;\n\nimport courseregistrationsystem.exception.RegistrationException;\n\npublic abstract class RegistrationRuleHandler {\n    private RegistrationRuleHandler next;\n\n    public void setNext(RegistrationRuleHandler next) { this.next = next; }\n\n    public abstract void handle(RegistrationRequest request) throws RegistrationException;\n\n    protected void handleNext(RegistrationRequest request) throws RegistrationException {\n        if (next != null) {\n            next.handle(request);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/chain/ScheduleConflictRuleHandler.java",
    "content": "package courseregistrationsystem.chain;\n\nimport courseregistrationsystem.exception.RegistrationException;\n\npublic class ScheduleConflictRuleHandler extends RegistrationRuleHandler {\n    @Override\n    public void handle(RegistrationRequest request) throws RegistrationException {\n        boolean conflict = request.student().getRegisteredOfferings().stream()\n                .anyMatch(offering -> offering.getTimeSlot().overlaps(request.offering().getTimeSlot()));\n        if (conflict) {\n            throw new RegistrationException(\"Schedule conflict detected for course \" + request.offering().getCourse().getCourseCode());\n        }\n        handleNext(request);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/exception/RegistrationException.java",
    "content": "package courseregistrationsystem.exception;\n\npublic class RegistrationException extends Exception {\n    public RegistrationException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/model/Course.java",
    "content": "package courseregistrationsystem.model;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class Course {\n    private final String courseCode;\n    private final String title;\n    private final Set<Course> prerequisites = new HashSet<>();\n\n    public Course(String courseCode, String title) { this.courseCode = courseCode; this.title = title; }\n\n    public void addPrerequisite(Course course) { prerequisites.add(course); }\n    public String getCourseCode() { return courseCode; }\n    public Set<Course> getPrerequisites() { return prerequisites; }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/model/CourseOffering.java",
    "content": "package courseregistrationsystem.model;\n\nimport courseregistrationsystem.observer.CourseOfferingObserver;\n\nimport java.util.*;\n\npublic class CourseOffering {\n    private final String id;\n    private final Course course;\n    private final Professor professor;\n    private final TimeSlot timeSlot;\n    private final int capacity;\n    private final List<Student> registeredStudents = new ArrayList<>();\n    private final Queue<Student> waitlistedStudents = new LinkedList<>();\n    private final List<CourseOfferingObserver> observers = new ArrayList<>();\n\n    private CourseOffering(Builder builder) {\n        this.id = builder.id;\n        this.course = builder.course;\n        this.professor = builder.professor;\n        this.timeSlot = builder.timeSlot;\n        this.capacity = builder.capacity;\n    }\n\n    public void addObserver(CourseOfferingObserver observer) { observers.add(observer); }\n    private void notifyObservers() { observers.forEach(o -> o.onSpotAvailable(this)); }\n\n    public boolean isFull() { return registeredStudents.size() >= capacity; }\n    public void addStudent(Student student) { registeredStudents.add(student); student.enroll(this); }\n    public void addToWaitlist(Student student) { waitlistedStudents.add(student); }\n\n    public void dropStudent(Student student) {\n        boolean wasFull = isFull();\n        registeredStudents.remove(student);\n        student.drop(this);\n        if (wasFull && !isFull()) {\n            notifyObservers();\n        }\n    }\n\n    public Optional<Student> getNextFromWaitlist() { return Optional.ofNullable(waitlistedStudents.poll()); }\n    public String getId() { return id; }\n    public Course getCourse() { return course; }\n    public TimeSlot getTimeSlot() { return timeSlot; }\n\n    // Builder Pattern\n    public static class Builder {\n        private String id; private Course course; private Professor professor; private TimeSlot timeSlot; private int capacity;\n        public Builder(String id, Course course) { this.id = id; this.course = course; }\n        public Builder withProfessor(Professor professor) { this.professor = professor; return this; }\n        public Builder at(TimeSlot timeSlot) { this.timeSlot = timeSlot; return this; }\n        public Builder withCapacity(int capacity) { this.capacity = capacity; return this; }\n        public CourseOffering build() { return new CourseOffering(this); }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/model/Professor.java",
    "content": "package courseregistrationsystem.model;\n\npublic record Professor(String id, String name) {}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/model/Student.java",
    "content": "package courseregistrationsystem.model;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\npublic class Student {\n    private final String id;\n    private final String name;\n    private final Set<Course> completedCourses = new HashSet<>();\n    private final Set<CourseOffering> registeredOfferings = new HashSet<>();\n\n    public Student(String id, String name) { this.id = id; this.name = name; }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public Set<Course> getCompletedCourses() { return completedCourses; }\n    public Set<CourseOffering> getRegisteredOfferings() { return registeredOfferings; }\n    public void addCompletedCourse(Course course) { completedCourses.add(course); }\n    public void enroll(CourseOffering offering) { registeredOfferings.add(offering); }\n    public void drop(CourseOffering offering) { registeredOfferings.remove(offering); }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/model/TimeSlot.java",
    "content": "package courseregistrationsystem.model;\n\nimport java.time.DayOfWeek;\nimport java.time.LocalTime;\n\npublic record TimeSlot(DayOfWeek day, LocalTime startTime, LocalTime endTime) {\n    public boolean overlaps(TimeSlot other) {\n        return this.day == other.day &&\n                this.startTime.isBefore(other.endTime) &&\n                this.endTime.isAfter(other.startTime);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/observer/CourseOfferingObserver.java",
    "content": "package courseregistrationsystem.observer;\n\nimport courseregistrationsystem.model.CourseOffering;\n\npublic interface CourseOfferingObserver {\n    void onSpotAvailable(CourseOffering offering);\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/observer/WaitlistManager.java",
    "content": "package courseregistrationsystem.observer;\n\nimport courseregistrationsystem.CourseRegistrationService;\nimport courseregistrationsystem.chain.RegistrationRequest;\nimport courseregistrationsystem.exception.RegistrationException;\nimport courseregistrationsystem.model.CourseOffering;\n\npublic class WaitlistManager implements CourseOfferingObserver {\n    private static final WaitlistManager INSTANCE = new WaitlistManager();\n    private final CourseRegistrationService courseRegistrationService = new CourseRegistrationService(); // To re-register a waitlisted student\n    public static WaitlistManager getInstance() { return INSTANCE; }\n    private WaitlistManager() {}\n\n    @Override\n    public void onSpotAvailable(CourseOffering offering) {\n        System.out.println(\"OBSERVER (WaitlistManager): Spot available in \" + offering.getCourse().getCourseCode() + \". Processing waitlist.\");\n        offering.getNextFromWaitlist().ifPresent(student -> {\n            System.out.println(\"Promoting \" + student.getName() + \" from waitlist for \" + offering.getCourse().getCourseCode());\n            try {\n                // We can re-use the registration service, but a real system might have a simplified \"promote\" logic\n                courseRegistrationService.register(new RegistrationRequest(student, offering));\n            } catch (RegistrationException e) {\n                System.err.println(\"Failed to promote \" + student.getName() + \": \" + e.getMessage());\n                // Handle failure: try next student or notify admin\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/repository/CourseRepository.java",
    "content": "package courseregistrationsystem.repository;\n\nimport courseregistrationsystem.model.Course;\nimport courseregistrationsystem.model.CourseOffering;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class CourseRepository {\n    private static final CourseRepository INSTANCE = new CourseRepository();\n    private final Map<String, Course> courses = new ConcurrentHashMap<>();\n    private final Map<String, CourseOffering> offerings = new ConcurrentHashMap<>();\n\n    public static CourseRepository getInstance() { return INSTANCE; }\n    public void saveCourse(Course c) { courses.put(c.getCourseCode(), c); }\n    public void saveOffering(CourseOffering o) { offerings.put(o.getId(), o); }\n    public Optional<CourseOffering> findOfferingById(String id) { return Optional.ofNullable(offerings.get(id)); }\n}\n"
  },
  {
    "path": "solutions/java/src/courseregistrationsystem/repository/StudentRepository.java",
    "content": "package courseregistrationsystem.repository;\n\nimport courseregistrationsystem.model.Student;\n\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class StudentRepository {\n    private static final StudentRepository INSTANCE = new StudentRepository();\n    private final Map<String, Student> students = new ConcurrentHashMap<>();\n\n    public static StudentRepository getInstance() { return INSTANCE; }\n    public void save(Student s) { students.put(s.getId(), s); }\n    public Optional<Student> findById(String id) { return Optional.ofNullable(students.get(id)); }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/CommentaryManager.java",
    "content": "package cricinfo;\n\nimport cricinfo.enums.ExtraType;\nimport cricinfo.enums.WicketType;\nimport cricinfo.entity.Ball;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Random;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class CommentaryManager {\n    private static volatile CommentaryManager instance;\n    private final Random random = new Random();\n\n    private final Map<String, List<String>> commentaryTemplates = new ConcurrentHashMap<>();\n\n    private CommentaryManager() {\n        initializeTemplates();\n    }\n\n    public static CommentaryManager getInstance() {\n        if (instance == null) {\n            synchronized (CommentaryManager.class) {\n                if (instance == null) {\n                    instance = new CommentaryManager();\n                }\n            }\n        }\n        return instance;\n    }\n\n    private void initializeTemplates() {\n        // Templates for runs\n        commentaryTemplates.put(\"RUNS_0\", List.of(\n                \"%s defends solidly.\",\n                \"No run, good fielding by the cover fielder.\",\n                \"A dot ball to end the over.\",\n                \"Pushed to mid-on, but no run.\"\n        ));\n        commentaryTemplates.put(\"RUNS_1\", List.of(\n                \"Tucked away to the leg side for a single.\",\n                \"Quick single taken by %s.\",\n                \"Pushed to long-on for one.\"\n        ));\n        commentaryTemplates.put(\"RUNS_2\", List.of(\n                \"Two runs taken!\",\n                \"Quick double taken by %s.\",\n                \"Pushed to mid-on for two.\"\n        ));\n        commentaryTemplates.put(\"RUNS_4\", List.of(\n                \"FOUR! %s smashes it through the covers!\",\n                \"Beautiful shot! That's a boundary.\",\n                \"Finds the gap perfectly. Four runs.\"\n        ));\n        commentaryTemplates.put(\"RUNS_6\", List.of(\n                \"SIX! That's out of the park!\",\n                \"%s sends it sailing over the ropes!\",\n                \"Massive hit! It's a maximum.\"\n        ));\n\n        // Templates for wickets\n        commentaryTemplates.put(\"WICKET_\" + WicketType.BOWLED, List.of(\n                \"BOWLED HIM! %s misses completely and the stumps are shattered!\",\n                \"Cleaned up! A perfect yorker from %s.\"\n        ));\n        commentaryTemplates.put(\"WICKET_\" + WicketType.CAUGHT, List.of(\n                \"CAUGHT! %s skies it and the fielder takes a comfortable catch.\",\n                \"Out! A brilliant catch in the deep by %s.\"\n        ));\n        commentaryTemplates.put(\"WICKET_\" + WicketType.LBW, List.of(\n                \"LBW! That one kept low and struck %s right in front.\",\n                \"%s completely misjudged the line and pays the price.\"\n        ));\n\n        commentaryTemplates.put(\"WICKET_\" + WicketType.STUMPED, List.of(\n                \"STUMPED! %s misses it, and the keeper does the rest!\",\n                \"Gone! Lightning-fast work by the keeper to stump %s.\"\n        ));\n\n        // Templates for extras\n        commentaryTemplates.put(\"EXTRA_\" + ExtraType.WIDE, List.of(\n                \"That's a wide. The umpire signals an extra run.\",\n                \"Too far down the leg side, that'll be a wide.\"\n        ));\n        commentaryTemplates.put(\"EXTRA_\" + ExtraType.NO_BALL, List.of(\n                \"No ball! %s has overstepped. It's a free hit.\",\n                \"It's a no-ball for overstepping.\"\n        ));\n    }\n\n    public String generateCommentary(Ball ball) {\n        String key = getEventKey(ball);\n        List<String> templates = commentaryTemplates.getOrDefault(key, List.of(\"Just a standard delivery.\"));\n\n        String template = templates.get(random.nextInt(templates.size()));\n\n        // Format the commentary with player names\n        String batsmanName = ball.getFacedBy() != null ? ball.getFacedBy().getName() : \"\";\n        String bowlerName = ball.getBowledBy() != null ? ball.getBowledBy().getName() : \"\";\n\n        // This handles cases where a template might have more or fewer placeholders\n        // and avoids exceptions.\n        return String.format(template.replace(\"%s\", \"%1$s\"), batsmanName, bowlerName);\n    }\n\n    private String getEventKey(Ball ball) {\n        if (ball.isWicket()) {\n            return \"WICKET_\" + ball.getWicket().getWicketType().toString();\n        }\n        if (ball.getExtraType() != null) {\n            return \"EXTRA_\" + ball.getExtraType().toString();\n        }\n        if (ball.getRunsScored() >= 0 && ball.getRunsScored() <= 6) {\n            switch(ball.getRunsScored()) {\n                case 0: return \"RUNS_0\";\n                case 1: return \"RUNS_1\";\n                case 2: return \"RUNS_2\";\n                case 3: return \"RUNS_3\";\n                case 4: return \"RUNS_4\";\n                case 6: return \"RUNS_6\";\n            }\n        }\n        return \"DEFAULT\"; // Fallback key\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/CricInfoService.java",
    "content": "package cricinfo;\n\nimport cricinfo.enums.PlayerRole;\nimport cricinfo.entity.Ball;\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Player;\nimport cricinfo.entity.Team;\nimport cricinfo.observer.MatchObserver;\nimport cricinfo.repository.MatchRepository;\nimport cricinfo.repository.PlayerRepository;\nimport cricinfo.state.FinishedState;\nimport cricinfo.state.LiveState;\nimport cricinfo.strategy.MatchFormatStrategy;\n\nimport java.util.UUID;\n\npublic class CricInfoService {\n    private static volatile CricInfoService instance;\n    private final MatchRepository matchRepository;\n    private final PlayerRepository playerRepository;\n\n    private CricInfoService() {\n        this.matchRepository = new MatchRepository();\n        this.playerRepository = new PlayerRepository();\n    }\n\n    public static CricInfoService getInstance() {\n        if (instance == null) {\n            synchronized (CricInfoService.class) {\n                if (instance == null) {\n                    instance = new CricInfoService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public Match createMatch(Team team1, Team team2, MatchFormatStrategy format) {\n        String matchId = UUID.randomUUID().toString();\n        Match match = new Match(matchId, team1, team2, format);\n        matchRepository.save(match);\n        System.out.printf(\"Match %s created between %s and %s.%n\", format.getFormatName(), team1.getName(), team2.getName());\n        return match;\n    }\n\n    public void startMatch(String matchId) {\n        matchRepository.findById(matchId).ifPresent(match -> {\n            match.setState(new LiveState());\n            System.out.printf(\"Match %s is now LIVE.%n\", matchId);\n        });\n    }\n\n    public void processBallUpdate(String matchId, Ball ball) {\n        matchRepository.findById(matchId).ifPresent(match -> match.processBall(ball));\n    }\n\n    public void startNextInnings(String matchId) {\n        matchRepository.findById(matchId).ifPresent(Match::startNextInnings);\n    }\n\n    public void subscribeToMatch(String matchId, MatchObserver observer) {\n        matchRepository.findById(matchId).ifPresent(match -> match.addObserver(observer));\n    }\n\n    public void endMatch(String matchId) {\n        matchRepository.findById(matchId).ifPresent(match -> {\n            match.setState(new FinishedState());\n            System.out.printf(\"Match %s has FINISHED.%n\", matchId);\n        });\n    }\n\n    public Player addPlayer(String playerId, String playerName, PlayerRole playerRole) {\n        Player player = new Player(playerId, playerName, playerRole);\n        playerRepository.save(player);\n        return player;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/CricinfoDemo.java",
    "content": "package cricinfo;\n\nimport cricinfo.enums.PlayerRole;\nimport cricinfo.enums.WicketType;\nimport cricinfo.entity.*;\nimport cricinfo.observer.CommentaryDisplay;\nimport cricinfo.observer.ScorecardDisplay;\nimport cricinfo.observer.UserNotifier;\nimport cricinfo.strategy.T20FormatStrategy;\n\nimport java.util.List;\n\npublic class CricinfoDemo {\n    public static void main(String[] args) {\n        // Get the Singleton service instance\n        CricInfoService service = CricInfoService.getInstance();\n\n        // 1. Setup Players and Teams\n        Player p1 = service.addPlayer(\"P1\", \"Virat\", PlayerRole.BATSMAN);\n        Player p2 = service.addPlayer(\"P2\", \"Rohit\", PlayerRole.BATSMAN);\n        Player p3 = service.addPlayer(\"P3\", \"Bumrah\", PlayerRole.BOWLER);\n        Player p4 = service.addPlayer(\"P4\", \"Jadeja\", PlayerRole.ALL_ROUNDER);\n\n        Player p5 = service.addPlayer(\"P5\", \"Warner\", PlayerRole.BATSMAN);\n        Player p6 = service.addPlayer(\"P6\", \"Smith\", PlayerRole.BATSMAN);\n        Player p7 = service.addPlayer(\"P7\", \"Starc\", PlayerRole.BOWLER);\n        Player p8 = service.addPlayer(\"P8\", \"Maxwell\", PlayerRole.ALL_ROUNDER);\n\n        Team india = new Team(\"T1\", \"India\", List.of(p1, p2, p3, p4));\n        Team australia = new Team(\"T2\", \"Australia\", List.of(p5, p6, p7, p8));\n\n        // 2. Create a T20 Match using the service\n        Match t20Match = service.createMatch(india, australia, new T20FormatStrategy());\n        String matchId = t20Match.getId();\n\n        // 3. Create and subscribe observers\n        ScorecardDisplay scorecard = new ScorecardDisplay();\n        CommentaryDisplay commentary = new CommentaryDisplay();\n        UserNotifier notifier = new UserNotifier();\n\n        service.subscribeToMatch(matchId, scorecard);\n        service.subscribeToMatch(matchId, commentary);\n        service.subscribeToMatch(matchId, notifier);\n\n        // 4. Start the match\n        service.startMatch(matchId);\n\n        System.out.println(\"\\n--- SIMULATING FIRST INNINGS ---\");\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p1).withRuns(2).build());\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p1).withRuns(1).build());\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p2).withRuns(6).build());\n\n        Wicket p2Wicket = new Wicket.Builder(WicketType.BOWLED, p2).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p2).withRuns(0).withWicket(p2Wicket).build());\n\n        Wicket p3Wicket = new Wicket.Builder(WicketType.LBW, p3).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p3).withRuns(0).withWicket(p3Wicket).build());\n\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p4).withRuns(4).build());\n\n        Wicket p4Wicket = new Wicket.Builder(WicketType.CAUGHT, p4).caughtBy(p6).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p7).facedBy(p4).withRuns(0).withWicket(p4Wicket).build());\n\n        // The system is now in an IN_BREAK state\n        System.out.println(\"\\n\\n--- INNINGS BREAK ---\");\n        System.out.println(\"Players are off the field. Preparing for the second innings.\");\n\n        // 2. Start the second innings\n        service.startNextInnings(matchId);\n\n        System.out.println(\"\\n--- SIMULATING SECOND INNINGS ---\");\n        // Simulate a few balls of the second innings to show it works\n        // Now Australia is batting (p5, p6) and India is bowling (p3)\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p3).facedBy(p5).withRuns(4).build());\n\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p3).facedBy(p5).withRuns(1).build());\n\n        Wicket p5Wicket = new Wicket.Builder(WicketType.BOWLED, p5).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p3).facedBy(p5).withRuns(0).withWicket(p5Wicket).build());\n\n        Wicket p7Wicket = new Wicket.Builder(WicketType.LBW, p7).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p3).facedBy(p7).withRuns(0).withWicket(p7Wicket).build());\n\n        Wicket p8Wicket = new Wicket.Builder(WicketType.STUMPED, p8).build();\n        service.processBallUpdate(matchId, new Ball.BallBuilder()\n                .bowledBy(p3).facedBy(p8).withRuns(0).withWicket(p8Wicket).build());\n\n        service.endMatch(matchId);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/README.md",
    "content": "# Cricket Information System (LLD)\n\n## Problem Statement\n\nDesign and implement a Cricket Information System similar to CricInfo that provides comprehensive information about cricket matches, teams, players, and live scores. The system should handle real-time updates, match statistics, and user interactions.\n\n---\n\n## Requirements\n\n1. **Match Information Management:**\n   - Store and manage cricket match details\n   - Track match schedules and results\n   - Support real-time score updates\n   - Handle match status transitions\n\n2. **Team and Player Management:**\n   - Maintain team rosters and player information\n   - Track player roles and statistics\n   - Support team composition changes\n\n3. **Scorecard Management:**\n   - Record detailed match statistics\n   - Track innings, overs, and ball-by-ball information\n   - Maintain batting and bowling statistics\n\n4. **Search and Retrieval:**\n   - Search for matches, teams, and players\n   - View detailed match information\n   - Access historical data and statistics\n\n5. **System Requirements:**\n   - Handle concurrent access\n   - Ensure data consistency\n   - Support scalability\n   - Allow for future extensions\n\n---\n\n## Core Entities\n\n### 1. Match\n- **Fields:** String id, String title, String venue, Date startTime, Team team1, Team team2, MatchStatus status, Scorecard scorecard\n- **Methods:** updateStatus(), getScorecard(), getMatchDetails()\n\n### 2. Team\n- **Fields:** String id, String name, List<Player> players\n- **Methods:** addPlayer(), removePlayer(), getTeamStats()\n\n### 3. Player\n- **Fields:** String id, String name, String role\n- **Methods:** getPlayerStats(), updateRole()\n\n### 4. Scorecard\n- **Fields:** Match match, List<Innings> innings\n- **Methods:** addInnings(), updateScore(), getMatchSummary()\n\n### 5. Innings\n- **Fields:** String id, Team battingTeam, Team bowlingTeam, List<Over> overs\n- **Methods:** addOver(), getInningsSummary()\n\n### 6. Over\n- **Fields:** int overNumber, List<Ball> balls\n- **Methods:** addBall(), getOverSummary()\n\n### 7. Ball\n- **Fields:** int ballNumber, Player bowler, Player batsman, String result\n- **Methods:** recordResult(), getBallDetails()\n\n### 8. MatchStatus (Enum)\n- **Values:** SCHEDULED, IN_PROGRESS, COMPLETED, ABANDONED\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/cricinfo-class-diagram.png)\n\n---\n\n## Services\n\n### 1. MatchService (Singleton)\n- **Methods:** \n  - addMatch(Match match)\n  - getMatch(String id)\n  - updateMatchStatus(String id, MatchStatus status)\n  - searchMatches(String query)\n\n### 2. ScorecardService (Singleton)\n- **Methods:**\n  - createScorecard(Match match)\n  - updateScorecard(String matchId, Scorecard scorecard)\n  - getScorecard(String matchId)\n  - addInnings(String matchId, Innings innings)\n\n### 3. CricinfoSystem\n- **Methods:**\n  - getMatchDetails(String matchId)\n  - getTeamDetails(String teamId)\n  - getPlayerDetails(String playerId)\n  - search(String query)\n\n---\n\n## Example Usage\n\n```java\nCricinfoSystem system = CricinfoSystem.getInstance();\n\n// Create a new match\nMatch match = system.createMatch(\"IND vs AUS\", \"Melbourne Cricket Ground\", new Date());\n\n// Update match status\nsystem.updateMatchStatus(match.getId(), MatchStatus.IN_PROGRESS);\n\n// Record a ball\nsystem.recordBall(match.getId(), 1, 1, \"FOUR\");\n\n// Get match details\nMatchDetails details = system.getMatchDetails(match.getId());\n```\n\n---\n\n## Demo\n\nSee the demo class for a sample usage and simulation of the cricket information system.\n\n---\n\n## Extending the Framework\n\n- **Add user authentication:** Support for user accounts and preferences\n- **Add commentary system:** Real-time match commentary\n- **Add statistics engine:** Advanced player and team statistics\n- **Add notification system:** Match updates and alerts\n- **Add social features:** User comments and discussions\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For service classes (MatchService, ScorecardService)\n- **Factory Pattern:** For creating matches and scorecards\n- **Observer Pattern:** For real-time updates and notifications\n- **Strategy Pattern:** For different types of match formats\n\n---"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Ball.java",
    "content": "package cricinfo.entity;\n\nimport cricinfo.CommentaryManager;\nimport cricinfo.enums.ExtraType;\n\npublic class Ball {\n    private final int ballNumber;\n    private final Player bowledBy;\n    private final Player facedBy;\n    private final int runsScored;\n    private final Wicket wicket; // Null if no wicket\n    private final ExtraType extraType; // Null if no extra\n    private final String commentary;\n\n    private Ball(BallBuilder builder) {\n        this.ballNumber = builder.ballNumber;\n        this.bowledBy = builder.bowledBy;\n        this.facedBy = builder.facedBy;\n        this.runsScored = builder.runsScored;\n        this.wicket = builder.wicket;\n        this.extraType = builder.extraType;\n        this.commentary = builder.commentary;\n    }\n\n    public boolean isWicket() { return wicket != null; }\n    public boolean isBoundary() { return runsScored == 4 || runsScored == 6; }\n    public String getCommentary() { return commentary; }\n    public int getRunsScored() { return runsScored; }\n    public Player getFacedBy() { return facedBy; }\n    public Player getBowledBy() { return bowledBy; }\n    public Wicket getWicket() { return wicket; }\n\n    public ExtraType getExtraType() {\n        return extraType;\n    }\n    // Other getters\n\n    public static class BallBuilder {\n        private int ballNumber;\n        private Player bowledBy;\n        private Player facedBy;\n        private int runsScored;\n        private Wicket wicket;\n        private ExtraType extraType;\n        private String commentary;\n\n        public BallBuilder withBallNumber(int ballNumber) { this.ballNumber = ballNumber; return this; }\n        public BallBuilder bowledBy(Player bowler) { this.bowledBy = bowler; return this; }\n        public BallBuilder facedBy(Player batsman) { this.facedBy = batsman; return this; }\n        public BallBuilder withRuns(int runs) { this.runsScored = runs; return this; }\n        public BallBuilder withWicket(Wicket wicket) { this.wicket = wicket; return this; }\n        public BallBuilder withExtraType(ExtraType extra) { this.extraType = extra; return this; }\n        public BallBuilder withCommentary(String commentary) { this.commentary = commentary; return this; }\n\n        public Ball build() {\n            // This is needed because the manager needs the ball's final state to generate commentary\n            Ball tempBall = new Ball(this);\n\n            if (this.commentary == null) {\n                this.commentary = CommentaryManager.getInstance().generateCommentary(tempBall);\n            }\n\n            return new Ball(this);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Innings.java",
    "content": "package cricinfo.entity;\n\nimport cricinfo.enums.ExtraType;\n\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Innings {\n    private final Team battingTeam;\n    private final Team bowlingTeam;\n    private int score;\n    private int wickets;\n    private final List<Ball> balls;\n    private final Map<Player, PlayerStats> playerStats;\n\n    public Innings(Team battingTeam, Team bowlingTeam) {\n        this.battingTeam = battingTeam;\n        this.bowlingTeam = bowlingTeam;\n        this.score = 0;\n        this.wickets = 0;\n        this.balls = new ArrayList<>();\n        this.playerStats = new ConcurrentHashMap<>();\n        for(Player player: battingTeam.getPlayers()) {\n            playerStats.put(player, new PlayerStats());\n        }\n        for(Player player: bowlingTeam.getPlayers()) {\n            playerStats.put(player, new PlayerStats());\n        }\n    }\n\n    public void addBall(Ball ball) {\n        balls.add(ball);\n        int runsScored = ball.getRunsScored();\n        this.score += runsScored;\n        if (ball.getExtraType() == ExtraType.WIDE || ball.getExtraType() == ExtraType.NO_BALL) {\n            this.score += 1;\n        } else {\n            ball.getFacedBy().getStats().updateRuns(runsScored);\n            ball.getFacedBy().getStats().incrementBallsPlayed();\n            playerStats.get(ball.getFacedBy()).updateRuns(runsScored);\n            playerStats.get(ball.getFacedBy()).incrementBallsPlayed();\n        }\n        if (ball.isWicket()) {\n            this.wickets++;\n            ball.getBowledBy().getStats().incrementWickets();\n            playerStats.get(ball.getBowledBy()).incrementWickets();\n        }\n    }\n\n    public void printPlayerStats() {\n        for (Map.Entry<Player, PlayerStats> entry : playerStats.entrySet()) {\n            Player player = entry.getKey();\n            PlayerStats stats = entry.getValue();\n\n            if (stats.getBallsPlayed() > 0 || stats.getWickets() > 0) {\n                System.out.println(\"Player: \" + player.getName() + \" - Stats: \" + stats);\n            }\n        }\n    }\n\n    public int getScore() { return score; }\n    public int getWickets() { return wickets; }\n    public Team getBattingTeam() { return battingTeam; }\n\n    public double getOvers() {\n        int validBalls = (int) balls.stream()\n                .filter(b -> b.getExtraType() != ExtraType.WIDE && b.getExtraType() != ExtraType.NO_BALL)\n                .count();\n\n        int completedOvers = validBalls / 6;\n        int ballsInCurrentOver = validBalls % 6;\n\n        return completedOvers + (ballsInCurrentOver / 10.0);\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Match.java",
    "content": "package cricinfo.entity;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.observer.MatchObserver;\nimport cricinfo.state.MatchState;\nimport cricinfo.state.ScheduledState;\nimport cricinfo.strategy.MatchFormatStrategy;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Match {\n    private final String id;\n    private final Team team1;\n    private final Team team2;\n    private final MatchFormatStrategy formatStrategy;\n    private final List<Innings> innings;\n    private MatchState currentState;\n    private MatchStatus currentStatus;\n    private final List<MatchObserver> observers = new ArrayList<>();\n    private Team winner;\n    private String resultMessage;\n\n    public Match(String id, Team team1, Team team2, MatchFormatStrategy formatStrategy) {\n        this.id = id;\n        this.team1 = team1;\n        this.team2 = team2;\n        this.formatStrategy = formatStrategy;\n        this.innings = new ArrayList<>();\n        this.innings.add(new Innings(team1, team2)); // Start first innings\n        this.currentState = new ScheduledState(); // Initial state\n        this.resultMessage = \"\";\n    }\n\n    // State Pattern Methods\n    public void processBall(Ball ball) {\n        currentState.processBall(this, ball);\n    }\n\n    public void startNextInnings() {\n        currentState.startNextInnings(this);\n    }\n\n    public void setState(MatchState state) { this.currentState = state; }\n\n    public void setCurrentStatus(MatchStatus status) { this.currentStatus = status; }\n\n    public void setWinner(Team winner) {\n        this.winner = winner;\n    }\n\n    public void setResultMessage(String resultMessage) {\n        this.resultMessage = resultMessage;\n    }\n\n    public void createNewInnings() {\n        if (innings.size() >= formatStrategy.getTotalInnings()) {\n            System.out.println(\"Cannot create a new innings, match has already reached its limit.\");\n            return;\n        }\n        // Swap the teams for the next innings\n        Innings nextInnings = new Innings(this.team2, this.team1);\n        this.innings.add(nextInnings);\n    }\n\n    // Observer Pattern Methods\n    public void addObserver(MatchObserver observer) { observers.add(observer); }\n    public void removeObserver(MatchObserver observer) { observers.remove(observer); }\n    public void notifyObservers(Ball ball) {\n        for (MatchObserver observer : observers) {\n            observer.update(this, ball);\n        }\n    }\n\n    public Innings getCurrentInnings() { return innings.get(innings.size() - 1); }\n    public Team getTeam1() { return team1; }\n    public Team getTeam2() { return team2; }\n    public Team getWinner() { return winner; }\n    public String getResultMessage() { return resultMessage; }\n    public List<Innings> getInnings() { return innings; }\n    public String getId() { return id; }\n    public MatchStatus getCurrentStatus() { return currentStatus; }\n\n    public MatchFormatStrategy getFormatStrategy() {\n        return formatStrategy;\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Player.java",
    "content": "package cricinfo.entity;\n\nimport cricinfo.enums.PlayerRole;\n\npublic class Player {\n    private final String id;\n    private final String name;\n    private final PlayerRole role;\n    private PlayerStats stats;\n\n    public Player(String id, String name, PlayerRole role) {\n        this.id = id;\n        this.name = name;\n        this.role = role;\n        this.stats = new PlayerStats();\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() { return name; }\n\n    public PlayerStats getStats() {\n        return stats;\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/PlayerStats.java",
    "content": "package cricinfo.entity;\n\npublic class PlayerStats {\n    private int runs;\n    private int ballsPlayed;\n    private int wickets;\n\n    public PlayerStats() {\n        runs = 0;\n        wickets = 0;\n    }\n\n    public void updateRuns(int runScored) {\n        runs += runScored;\n    }\n\n    public void incrementBallsPlayed() {\n        ballsPlayed += 1;\n    }\n\n    public void incrementWickets() {\n        wickets += 1;\n    }\n\n    public int getRuns() { return runs; }\n    public int getWickets() { return wickets; }\n    public int getBallsPlayed() { return ballsPlayed; }\n\n    @Override\n    public String toString() {\n        return \"Runs: \" + runs + \", Balls Played: \" + ballsPlayed + \", Wickets: \" + wickets;\n    }\n }\n"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Team.java",
    "content": "package cricinfo.entity;\n\nimport java.util.List;\n\npublic class Team {\n    private final String id;\n    private final String name;\n    private final List<Player> players;\n\n    public Team(String id, String name, List<Player> players) {\n        this.id = id;\n        this.name = name;\n        this.players = players;\n    }\n    public String getName() { return name; }\n\n    public List<Player> getPlayers() { return players; }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/entity/Wicket.java",
    "content": "package cricinfo.entity;\n\nimport cricinfo.enums.WicketType;\n\npublic class Wicket {\n    private final WicketType wicketType;\n    private final Player playerOut;\n    private final Player caughtBy;\n    private final Player runoutBy;\n\n    private Wicket(Builder builder) {\n        this.wicketType = builder.wicketType;\n        this.playerOut = builder.playerOut;\n        this.caughtBy = builder.caughtBy;\n        this.runoutBy = builder.runoutBy;\n    }\n\n    public WicketType getWicketType() { return wicketType; }\n    public Player getPlayerOut() { return playerOut; }\n    public Player getCaughtBy() { return caughtBy; }\n    public Player getRunoutBy() { return runoutBy; }\n\n    public static class Builder {\n        // Required parameters\n        private final WicketType wicketType;\n        private final Player playerOut;\n\n        // Optional parameters\n        private Player caughtBy = null;\n        private Player runoutBy = null;\n\n        public Builder(WicketType wicketType, Player playerOut) {\n            this.wicketType = wicketType;\n            this.playerOut = playerOut;\n        }\n\n        public Builder caughtBy(Player player) {\n            this.caughtBy = player;\n            return this;\n        }\n\n        public Builder runoutBy(Player player) {\n            this.runoutBy = player;\n            return this;\n        }\n\n        public Wicket build() {\n            // We could add validation here, e.g., ensure 'caughtBy' is only set for WicketType.CAUGHT\n            return new Wicket(this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/enums/ExtraType.java",
    "content": "package cricinfo.enums;\n\npublic enum ExtraType {\n    WIDE,\n    NO_BALL,\n    BYE,\n    LEG_BYE\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/enums/MatchStatus.java",
    "content": "package cricinfo.enums;\n\npublic enum MatchStatus {\n    SCHEDULED,\n    LIVE,\n    IN_BREAK,\n    FINISHED,\n    ABANDONED\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/enums/PlayerRole.java",
    "content": "package cricinfo.enums;\n\npublic enum PlayerRole {\n    BATSMAN,\n    BOWLER,\n    ALL_ROUNDER,\n    WICKET_KEEPER\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/enums/WicketType.java",
    "content": "package cricinfo.enums;\n\npublic enum WicketType {\n    BOWLED,\n    CAUGHT,\n    LBW,\n    RUN_OUT,\n    STUMPED,\n    HIT_WICKET\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/observer/CommentaryDisplay.java",
    "content": "package cricinfo.observer;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic class CommentaryDisplay implements MatchObserver {\n    @Override\n    public void update(Match match, Ball lastBall) {\n        if (match.getCurrentStatus() == MatchStatus.FINISHED) {\n            System.out.println(\"[COMMENTARY]: Match has finished!\");\n        } else if (match.getCurrentStatus() == MatchStatus.IN_BREAK) {\n            System.out.println(\"[COMMENTARY]: Inning has ended!\");\n        } else {\n            System.out.printf(\"[COMMENTARY]: %s%n\", lastBall.getCommentary());\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/observer/MatchObserver.java",
    "content": "package cricinfo.observer;\n\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic interface MatchObserver {\n    void update(Match match, Ball lastBall);\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/observer/ScorecardDisplay.java",
    "content": "package cricinfo.observer;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.entity.Innings;\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic class ScorecardDisplay implements MatchObserver {\n    @Override\n    public void update(Match match, Ball lastBall) {\n        // This block handles end-of-innings or end-of-match signals\n        if (match.getCurrentStatus() == MatchStatus.FINISHED) {\n            System.out.println(\"\\n--- MATCH RESULT ---\");\n            System.out.println(match.getResultMessage().toUpperCase());\n            System.out.println(\"--------------------\");\n\n            System.out.println(\"Player Stats:\");\n            int counter = 1;\n            for (Innings inning: match.getInnings()) {\n                System.out.println(\"Inning \" + counter++);\n                inning.printPlayerStats();\n            }\n\n        } else if (match.getCurrentStatus() == MatchStatus.IN_BREAK) {\n            System.out.println(\"\\n--- END OF INNINGS ---\");\n            Innings lastInnings = match.getInnings().get(match.getInnings().size() - 1);\n            System.out.printf(\"Final Score: %s: %d/%d (Overs: %.1f)%n\",\n                    lastInnings.getBattingTeam().getName(),\n                    lastInnings.getScore(),\n                    lastInnings.getWickets(),\n                    lastInnings.getOvers());\n            System.out.println(\"------------------------\");\n        } else {\n            // This block runs for every ball during a live match\n            System.out.println(\"\\n--- SCORECARD UPDATE ---\");\n            Innings currentInnings = match.getCurrentInnings();\n            System.out.printf(\"%s: %d/%d (Overs: %.1f)%n\",\n                    currentInnings.getBattingTeam().getName(),\n                    currentInnings.getScore(),\n                    currentInnings.getWickets(),\n                    currentInnings.getOvers());\n            System.out.println(\"------------------------\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/observer/UserNotifier.java",
    "content": "package cricinfo.observer;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic class UserNotifier implements MatchObserver {\n    @Override\n    public void update(Match match, Ball lastBall) {\n        if (match.getCurrentStatus() == MatchStatus.FINISHED) {\n            System.out.println(\"[NOTIFICATION]: Match has finished!\");\n        } else if (match.getCurrentStatus() == MatchStatus.IN_BREAK) {\n            System.out.println(\"[NOTIFICATION]: Inning has ended!\");\n        } else if (lastBall.isWicket()) {\n            System.out.println(\"[NOTIFICATION]: Wicket! A player is out.\");\n        } else if (lastBall.isBoundary()) {\n            System.out.printf(\"[NOTIFICATION]: It's a boundary! %d runs.%n\", lastBall.getRunsScored());\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/repository/MatchRepository.java",
    "content": "package cricinfo.repository;\n\nimport cricinfo.entity.Match;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\n\npublic class MatchRepository {\n    private final Map<String, Match> matches = new HashMap<>();\n\n    public void save(Match match) {\n        matches.put(match.getId(), match);\n    }\n\n    public Optional<Match> findById(String id) {\n        return Optional.ofNullable(matches.get(id));\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/repository/PlayerRepository.java",
    "content": "package cricinfo.repository;\n\nimport cricinfo.entity.Player;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\n\npublic class PlayerRepository {\n    private final Map<String, Player> players = new HashMap<>();\n\n    public void save(Player player) { players.put(player.getId(), player); }\n\n    public Optional<Player> findById(String id) {\n        return Optional.ofNullable(players.get(id));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/state/FinishedState.java",
    "content": "package cricinfo.state;\n\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic class FinishedState implements MatchState {\n    @Override\n    public void processBall(Match match, Ball ball) {\n        System.out.println(\"ERROR: Cannot process a ball for a finished match.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/state/InBreakState.java",
    "content": "package cricinfo.state;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.entity.Ball;\nimport cricinfo.entity.Match;\n\npublic class InBreakState implements MatchState {\n    @Override\n    public void processBall(Match match, Ball ball) {\n        System.out.println(\"ERROR: Cannot process a ball. The match is currently in a break.\");\n    }\n\n    @Override\n    public void startNextInnings(Match match) {\n        System.out.println(\"Starting the next innings...\");\n        match.createNewInnings();\n        match.setState(new LiveState());\n        match.setCurrentStatus(MatchStatus.LIVE);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/state/LiveState.java",
    "content": "package cricinfo.state;\n\nimport cricinfo.enums.MatchStatus;\nimport cricinfo.entity.Innings;\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\nimport cricinfo.entity.Team;\n\npublic class LiveState implements MatchState {\n    @Override\n    public void processBall(Match match, Ball ball) {\n        // 1. Process the ball as usual\n        Innings currentInnings = match.getCurrentInnings();\n        currentInnings.addBall(ball);\n        match.notifyObservers(ball); // Notify observers about this specific ball\n        // 2. Check for win/end conditions\n        checkForMatchEnd(match);\n    }\n\n    private void checkForMatchEnd(Match match) {\n        Innings currentInnings = match.getCurrentInnings();\n        int inningsCount = match.getInnings().size();\n        boolean isFinalInnings = (inningsCount == match.getFormatStrategy().getTotalInnings());\n\n        // --- A. WIN CONDITION: Chasing team surpasses the target ---\n        if (isFinalInnings) {\n            int targetScore = match.getInnings().get(0).getScore() + 1;\n            if (currentInnings.getScore() >= targetScore) {\n                int wicketsRemaining = (currentInnings.getBattingTeam().getPlayers().size() - 1) - currentInnings.getWickets();\n                declareWinner(match, currentInnings.getBattingTeam(), \"won by \" + wicketsRemaining + \" wickets\");\n                return; // Match is over\n            }\n        }\n\n        // --- B. END OF INNINGS CONDITION: All out or overs completed ---\n        if (isInningsOver(match)) {\n            if (isFinalInnings) {\n                // The whole match is over, determine winner by runs or a tie\n                int score1 = match.getInnings().get(0).getScore();\n                int score2 = currentInnings.getScore();\n\n                if (score1 > score2) {\n                    declareWinner(match, match.getTeam1(), \"won by \" + (score1 - score2) + \" runs\");\n                } else if (score2 > score1) {\n                    // This case is technically handled above, but is a good safeguard.\n                    int wicketsRemaining = (currentInnings.getBattingTeam().getPlayers().size() - 1) - currentInnings.getWickets();\n                    declareWinner(match, currentInnings.getBattingTeam(), \"won by \" + wicketsRemaining + \" wickets\");\n                } else {\n                    declareWinner(match, null, \"Match Tied\"); // No winner in a tie\n                }\n            } else {\n                // It's just an innings break, not the end of the match\n                System.out.println(\"End of the innings!\");\n                match.setState(new InBreakState());\n                match.setCurrentStatus(MatchStatus.IN_BREAK);\n                match.notifyObservers(null); // Signal innings break to observers\n            }\n        }\n    }\n\n    private void declareWinner(Match match, Team winningTeam, String message) {\n        System.out.println(\"MATCH FINISHED!\");\n        match.setWinner(winningTeam);\n        String resultMessage = (winningTeam != null) ? winningTeam.getName() + \" \" + message : message;\n        match.setResultMessage(resultMessage);\n\n        match.setState(new FinishedState());\n        match.setCurrentStatus(MatchStatus.FINISHED);\n        match.notifyObservers(null); // Signal match end to observers\n    }\n\n    private boolean isInningsOver(Match match) {\n        Innings currentInnings = match.getCurrentInnings();\n        // Condition 1: A team with 11 players is all out when 10 wickets fall.\n        boolean allOut = currentInnings.getWickets() >= currentInnings.getBattingTeam().getPlayers().size() - 1;\n        // Condition 2: All overs have been bowled\n        boolean oversFinished = (int) currentInnings.getOvers() >= match.getFormatStrategy().getTotalOvers();\n        return allOut || oversFinished;\n    }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/state/MatchState.java",
    "content": "package cricinfo.state;\n\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic interface MatchState {\n    void processBall(Match match, Ball ball);\n\n    default void startNextInnings(Match match) {\n        System.out.println(\"ERROR: Cannot start the next innings from the current state.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/state/ScheduledState.java",
    "content": "package cricinfo.state;\n\nimport cricinfo.entity.Match;\nimport cricinfo.entity.Ball;\n\npublic class ScheduledState implements MatchState {\n    @Override\n    public void processBall(Match match, Ball ball) {\n        System.out.println(\"ERROR: Cannot process a ball for a match that has not started.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/strategy/MatchFormatStrategy.java",
    "content": "package cricinfo.strategy;\n\npublic interface MatchFormatStrategy {\n    int getTotalInnings();\n    int getTotalOvers();\n    String getFormatName();\n}\n"
  },
  {
    "path": "solutions/java/src/cricinfo/strategy/ODIFormatStrategy.java",
    "content": "package cricinfo.strategy;\n\npublic class ODIFormatStrategy implements MatchFormatStrategy {\n    @Override\n    public int getTotalInnings() { return 2; }\n\n    @Override\n    public int getTotalOvers() { return 50; }\n\n    @Override\n    public String getFormatName() { return \"ODI\"; }\n}"
  },
  {
    "path": "solutions/java/src/cricinfo/strategy/T20FormatStrategy.java",
    "content": "package cricinfo.strategy;\n\npublic class T20FormatStrategy implements MatchFormatStrategy {\n    @Override\n    public int getTotalInnings() { return 2; }\n\n    @Override\n    public int getTotalOvers() { return 20; }\n\n    @Override\n    public String getFormatName() { return \"T20\"; }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/Account.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Account {\n    private final String id;\n    private final User user;\n    private final String accountNumber;\n    private final Currency currency;\n    private BigDecimal balance;\n    private final List<Transaction> transactions;\n\n    public Account(String id, User user, String accountNumber, Currency currency) {\n        this.id = id;\n        this.user = user;\n        this.accountNumber = accountNumber;\n        this.currency = currency;\n        this.balance = BigDecimal.ZERO;\n        this.transactions = new ArrayList<>();\n    }\n\n    public synchronized void deposit(BigDecimal amount) {\n        balance = balance.add(amount);\n    }\n\n    public synchronized void withdraw(BigDecimal amount) {\n        if (balance.compareTo(amount) >= 0) {\n            balance = balance.subtract(amount);\n        } else {\n            throw new InsufficientFundsException(\"Insufficient funds in the account.\");\n        }\n    }\n\n    public synchronized void addTransaction(Transaction transaction) {\n        transactions.add(transaction);\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public User getUser() {\n        return user;\n    }\n\n    public String getAccountNumber() {\n        return accountNumber;\n    }\n\n    public Currency getCurrency() {\n        return currency;\n    }\n\n    public BigDecimal getBalance() {\n        return balance;\n    }\n\n    public List<Transaction> getTransactions() {\n        return transactions;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/BankAccount.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\n\npublic class BankAccount extends PaymentMethod {\n    private final String accountNumber;\n    private final String routingNumber;\n\n    public BankAccount(String id, User user, String accountNumber, String routingNumber) {\n        super(id, user);\n        this.accountNumber = accountNumber;\n        this.routingNumber = routingNumber;\n    }\n\n    @Override\n    public boolean processPayment(BigDecimal amount, Currency currency) {\n        // Process bank account payment\n        return true;\n    }\n}"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/CreditCard.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\n\npublic class CreditCard extends PaymentMethod {\n    private final String cardNumber;\n    private final String expirationDate;\n    private final String cvv;\n\n    public CreditCard(String id, User user, String cardNumber, String expirationDate, String cvv) {\n        super(id, user);\n        this.cardNumber = cardNumber;\n        this.expirationDate = expirationDate;\n        this.cvv = cvv;\n    }\n\n    @Override\n    public boolean processPayment(BigDecimal amount, Currency currency) {\n        // Process credit card payment\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/Currency.java",
    "content": "package digitalwalletservice;\n\npublic enum Currency {\n    USD,\n    EUR,\n    GBP,\n    JPY\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/CurrencyConverter.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class CurrencyConverter {\n    private static final Map<Currency, BigDecimal> exchangeRates = new HashMap<>();\n\n    static {\n        // Initialize exchange rates\n        exchangeRates.put(Currency.USD, BigDecimal.ONE);\n        exchangeRates.put(Currency.EUR, new BigDecimal(\"0.85\"));\n        exchangeRates.put(Currency.GBP, new BigDecimal(\"0.72\"));\n        exchangeRates.put(Currency.JPY, new BigDecimal(\"110.00\"));\n        // Add more exchange rates as needed\n    }\n\n    public static BigDecimal convert(BigDecimal amount, Currency sourceCurrency, Currency targetCurrency) {\n        BigDecimal sourceRate = exchangeRates.get(sourceCurrency);\n        BigDecimal targetRate = exchangeRates.get(targetCurrency);\n        return amount.multiply(sourceRate).divide(targetRate, RoundingMode.HALF_UP);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/DigitalWallet.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class DigitalWallet {\n    private static DigitalWallet instance;\n    private final Map<String, User> users;\n    private final Map<String, Account> accounts;\n    private final Map<String, PaymentMethod> paymentMethods;\n\n    private DigitalWallet() {\n        users = new ConcurrentHashMap<>();\n        accounts = new ConcurrentHashMap<>();\n        paymentMethods = new ConcurrentHashMap<>();\n    }\n\n    public static synchronized DigitalWallet getInstance() {\n        if (instance == null) {\n            instance = new DigitalWallet();\n        }\n        return instance;\n    }\n\n    public void createUser(User user) {\n        users.put(user.getId(), user);\n    }\n\n    public User getUser(String userId) {\n        return users.get(userId);\n    }\n\n    public void createAccount(Account account) {\n        accounts.put(account.getId(), account);\n        account.getUser().addAccount(account);\n    }\n\n    public Account getAccount(String accountId) {\n        return accounts.get(accountId);\n    }\n\n    public void addPaymentMethod(PaymentMethod paymentMethod) {\n        paymentMethods.put(paymentMethod.getId(), paymentMethod);\n    }\n\n    public PaymentMethod getPaymentMethod(String paymentMethodId) {\n        return paymentMethods.get(paymentMethodId);\n    }\n\n    public synchronized void transferFunds(Account sourceAccount, Account destinationAccount, BigDecimal amount, Currency currency) {\n        if (sourceAccount.getCurrency() != currency) {\n            amount = CurrencyConverter.convert(amount, currency, sourceAccount.getCurrency());\n        }\n        sourceAccount.withdraw(amount);\n\n        if (destinationAccount.getCurrency() != sourceAccount.getCurrency()) {\n            amount = CurrencyConverter.convert(amount, sourceAccount.getCurrency(), destinationAccount.getCurrency());\n        }\n        destinationAccount.deposit(amount);\n\n        String transactionId = generateTransactionId();\n        Transaction transaction = new Transaction(transactionId, sourceAccount, destinationAccount, amount, destinationAccount.getCurrency());\n        sourceAccount.addTransaction(transaction);\n        destinationAccount.addTransaction(transaction);\n    }\n\n    public List<Transaction> getTransactionHistory(Account account) {\n        return account.getTransactions();\n    }\n\n    private String generateTransactionId() {\n        return \"TXN\" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/DigitalWalletDemo.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\nimport java.util.List;\n\npublic class DigitalWalletDemo {\n    public static void run() {\n        DigitalWallet digitalWallet = DigitalWallet.getInstance();\n\n        // Create users\n        User user1 = new User(\"U001\", \"John Doe\", \"john@example.com\", \"password123\");\n        User user2 = new User(\"U002\", \"Jane Smith\", \"jane@example.com\", \"password456\");\n        digitalWallet.createUser(user1);\n        digitalWallet.createUser(user2);\n\n        // Create accounts\n        Account account1 = new Account(\"A001\", user1, \"1234567890\", Currency.USD);\n        Account account2 = new Account(\"A002\", user2, \"9876543210\", Currency.EUR);\n        digitalWallet.createAccount(account1);\n        digitalWallet.createAccount(account2);\n\n        // Add payment methods\n        PaymentMethod creditCard = new CreditCard(\"PM001\", user1, \"1234567890123456\", \"12/25\", \"123\");\n        PaymentMethod bankAccount = new BankAccount(\"PM002\", user2, \"9876543210\", \"987654321\");\n        digitalWallet.addPaymentMethod(creditCard);\n        digitalWallet.addPaymentMethod(bankAccount);\n\n        // Deposit funds\n        account1.deposit(new BigDecimal(\"1000.00\"));\n        account2.deposit(new BigDecimal(\"500.00\"));\n\n        // Transfer funds\n        digitalWallet.transferFunds(account1, account2, new BigDecimal(\"100.00\"), Currency.USD);\n\n        // Get transaction history\n        List<Transaction> transactionHistory1 = digitalWallet.getTransactionHistory(account1);\n        List<Transaction> transactionHistory2 = digitalWallet.getTransactionHistory(account2);\n\n        // Print transaction history\n        System.out.println(\"Transaction History for Account 1:\");\n        for (Transaction transaction : transactionHistory1) {\n            System.out.println(\"Transaction ID: \" + transaction.getId());\n            System.out.println(\"Amount: \" + transaction.getAmount() + \" \" + transaction.getCurrency());\n            System.out.println(\"Timestamp: \" + transaction.getTimestamp());\n            System.out.println();\n        }\n\n        System.out.println(\"Transaction History for Account 2:\");\n        for (Transaction transaction : transactionHistory2) {\n            System.out.println(\"Transaction ID: \" + transaction.getId());\n            System.out.println(\"Amount: \" + transaction.getAmount() + \" \" + transaction.getCurrency());\n            System.out.println(\"Timestamp: \" + transaction.getTimestamp());\n            System.out.println();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/InsufficientFundsException.java",
    "content": "package digitalwalletservice;\n\npublic class InsufficientFundsException extends RuntimeException {\n    public InsufficientFundsException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/PaymentMethod.java",
    "content": "package digitalwalletservice;\n\nimport java.math.BigDecimal;\n\npublic abstract class PaymentMethod {\n    protected final String id;\n    protected final User user;\n\n    public PaymentMethod(String id, User user) {\n        this.id = id;\n        this.user = user;\n    }\n\n    public abstract boolean processPayment(BigDecimal amount, Currency currency);\n\n    public String getId() {\n        return id;\n    }\n\n    public User getUser() {\n        return user;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/digitalwalletservice/README.md",
    "content": "# Digital Wallet Service (LLD)\n\n## Problem Statement\n\nDesign and implement a Digital Wallet Service that allows users to manage their digital money, make transactions, and link multiple payment methods. The system should handle currency conversions, track transactions, and manage different types of accounts.\n\n---\n\n## Requirements\n\n1. **Account Management:**\n   - Create and manage user accounts\n   - Support multiple payment methods (Bank Account, Credit Card)\n   - Handle account balances and transactions\n\n2. **Transaction Management:**\n   - Process money transfers\n   - Track transaction history\n   - Handle transaction status and types\n\n3. **Payment Methods:**\n   - Support bank account integration\n   - Support credit card integration\n   - Allow adding/removing payment methods\n\n4. **Currency Support:**\n   - Handle multiple currencies\n   - Provide currency conversion\n   - Maintain exchange rates\n\n5. **Security and Validation:**\n   - Validate transactions\n   - Handle insufficient funds\n   - Ensure data consistency\n\n---\n\n## Core Entities\n\n### 1. DigitalWallet\n- **Fields:** String id, User user, double balance, List<PaymentMethod> paymentMethods, List<Transaction> transactions\n- **Methods:** addMoney(), sendMoney(), getBalance(), addPaymentMethod(), removePaymentMethod()\n\n### 2. User\n- **Fields:** String id, String name, String email, String phoneNumber\n- **Methods:** updateProfile(), getWallet()\n\n### 3. Account\n- **Fields:** String id, User user, double balance, Currency currency\n- **Methods:** deposit(), withdraw(), getBalance()\n\n### 4. PaymentMethod\n- **Fields:** String id, User user, PaymentMethodType type\n- **Methods:** validate(), processPayment()\n\n### 5. BankAccount\n- **Fields:** String accountNumber, String bankName, String ifscCode\n- **Methods:** transfer(), validate()\n\n### 6. CreditCard\n- **Fields:** String cardNumber, String expiryDate, String cvv\n- **Methods:** charge(), validate()\n\n### 7. Transaction\n- **Fields:** String id, Account from, Account to, double amount, Currency currency, TransactionStatus status\n- **Methods:** process(), cancel(), getStatus()\n\n### 8. Currency\n- **Fields:** String code, String symbol\n- **Methods:** getExchangeRate()\n\n### 9. CurrencyConverter\n- **Methods:** convert(double amount, Currency from, Currency to)\n\n---\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/digitalwalletservice-class-diagram.png)\n\n## Example Usage\n\n```java\n// Create a new user\nUser user = new User(\"John Doe\", \"john@example.com\", \"1234567890\");\n\n// Create a digital wallet\nDigitalWallet wallet = new DigitalWallet(user);\n\n// Add a bank account\nBankAccount bankAccount = new BankAccount(\"1234567890\", \"HDFC Bank\", \"HDFC0001234\");\nwallet.addPaymentMethod(bankAccount);\n\n// Add money to wallet\nwallet.addMoney(1000.0, Currency.USD);\n\n// Send money to another user\nUser recipient = new User(\"Jane Doe\", \"jane@example.com\", \"9876543210\");\nwallet.sendMoney(recipient.getWallet(), 500.0, Currency.USD);\n```\n\n---\n\n## Demo\n\nSee `DigitalWalletDemo.java` for a sample usage and simulation of the digital wallet system.\n\n---\n\n## Extending the Framework\n\n- **Add authentication:** Implement user authentication and authorization\n- **Add transaction limits:** Set and enforce transaction limits\n- **Add rewards system:** Implement cashback and rewards\n- **Add bill payments:** Support utility bill payments\n- **Add investment options:** Support investment in various instruments\n- **Add notification system:** Send transaction alerts and updates\n\n---\n\n## Design Patterns Used\n\n- **Factory Pattern:** For creating different types of payment methods\n- **Strategy Pattern:** For different payment processing strategies\n- **Observer Pattern:** For transaction notifications\n- **Singleton Pattern:** For currency converter service\n\n---\n\n## Exception Handling\n\n- **InsufficientFundsException:** Thrown when there are insufficient funds for a transaction\n- **InvalidPaymentMethodException:** Thrown when payment method validation fails\n- **TransactionFailedException:** Thrown when transaction processing fails\n\n---"
  },
  {
    "path": "solutions/java/src/elevatorsystem/Elevator.java",
    "content": "package elevatorsystem;\n\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.models.Request;\nimport elevatorsystem.observer.ElevatorObserver;\nimport elevatorsystem.state.ElevatorState;\nimport elevatorsystem.state.IdleState;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.TreeSet;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class Elevator implements Runnable {\n    private final int id;\n    private AtomicInteger currentFloor;\n    private ElevatorState state;\n    private volatile boolean isRunning = true;\n\n    private final TreeSet<Integer> upRequests;\n    private final TreeSet<Integer> downRequests;\n\n    // Observer Pattern: List of observers\n    private final List<ElevatorObserver> observers = new ArrayList<>();\n\n    public Elevator(int id) {\n        this.id = id;\n        this.currentFloor = new AtomicInteger(1);\n        this.upRequests = new TreeSet<>();\n        this.downRequests = new TreeSet<>((a, b) -> b - a);\n        this.state = new IdleState();\n    }\n\n    // --- Observer Pattern Methods ---\n    public void addObserver(ElevatorObserver observer) {\n        observers.add(observer);\n        observer.update(this); // Send initial state\n    }\n\n    public void notifyObservers() {\n        for (ElevatorObserver observer : observers) {\n            observer.update(this);\n        }\n    }\n\n    // --- State Pattern Methods ---\n    public void setState(ElevatorState state) {\n        this.state = state;\n        notifyObservers(); // Notify observers on direction change\n    }\n\n    public void move() {\n        state.move(this);\n    }\n\n    // --- Request Handling ---\n    public synchronized void addRequest(Request request) {\n        System.out.println(\"Elevator \" + id + \" processing: \" + request);\n        state.addRequest(this, request);\n    }\n\n    // --- Getters and Setters ---\n    public int getId() { return id; }\n    public int getCurrentFloor() { return currentFloor.get(); }\n\n    public void setCurrentFloor(int floor) {\n        this.currentFloor.set(floor);\n        notifyObservers(); // Notify observers on floor change\n    }\n\n    public Direction getDirection() { return state.getDirection(); }\n    public TreeSet<Integer> getUpRequests() { return upRequests; }\n    public TreeSet<Integer> getDownRequests() { return downRequests; }\n    public boolean isRunning() { return isRunning; }\n    public void stopElevator() { this.isRunning = false; }\n\n    @Override\n    public void run() {\n        while (isRunning) {\n            move();\n            try {\n                Thread.sleep(1000); // Simulate movement time\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                isRunning = false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/elevatorsystem/ElevatorSystem.java",
    "content": "package elevatorsystem;\n\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.enums.RequestSource;\nimport elevatorsystem.models.Request;\nimport elevatorsystem.observer.ElevatorDisplay;\nimport elevatorsystem.strategy.ElevatorSelectionStrategy;\nimport elevatorsystem.strategy.NearestElevatorStrategy;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.stream.Collectors;\n\npublic class ElevatorSystem {\n    private static ElevatorSystem instance;\n\n    private final Map<Integer, Elevator> elevators;\n    private final ElevatorSelectionStrategy selectionStrategy;\n    private final ExecutorService executorService;\n\n    private ElevatorSystem(int numElevators) {\n        this.selectionStrategy = new NearestElevatorStrategy();\n        this.executorService = Executors.newFixedThreadPool(numElevators);\n\n        List<Elevator> elevatorList = new ArrayList<>();\n        ElevatorDisplay elevatorDisplay = new ElevatorDisplay(); // Create the observer\n\n        for (int i = 1; i <= numElevators; i++) {\n            Elevator elevator = new Elevator(i);\n            elevator.addObserver(elevatorDisplay); // Attach the observer\n            elevatorList.add(elevator);\n        }\n\n        this.elevators = elevatorList.stream().collect(Collectors.toMap(Elevator::getId, e -> e));\n    }\n\n    public static synchronized ElevatorSystem getInstance(int numElevators) {\n        if (instance == null) {\n            instance = new ElevatorSystem(numElevators);\n        }\n        return instance;\n    }\n\n    public void start() {\n        for (Elevator elevator : elevators.values()) {\n            executorService.submit(elevator);\n        }\n    }\n\n    // --- Facade Methods ---\n\n    // EXTERNAL Request (Hall Call)\n    public void requestElevator(int floor, Direction direction) {\n        System.out.println(\"\\n>> EXTERNAL Request: User at floor \" + floor + \" wants to go \" + direction);\n        Request request = new Request(floor, direction, RequestSource.EXTERNAL);\n\n        // Use strategy to find the best elevator\n        Optional<Elevator> selectedElevator = selectionStrategy.selectElevator(new ArrayList<>(elevators.values()), request);\n\n        if(selectedElevator.isPresent()) {\n            selectedElevator.get().addRequest(request);\n        } else {\n            System.out.println(\"System busy, please wait.\");\n        }\n    }\n\n    // INTERNAL Request (Cabin Call)\n    public void selectFloor(int elevatorId, int destinationFloor) {\n        System.out.println(\"\\n>> INTERNAL Request: User in Elevator \" + elevatorId + \" selected floor \" + destinationFloor);\n        Request request = new Request(destinationFloor, Direction.IDLE, RequestSource.INTERNAL);\n\n        Elevator elevator = elevators.get(elevatorId);\n        if (elevator != null) {\n            elevator.addRequest(request);\n        } else {\n            System.err.println(\"Invalid elevator ID.\");\n        }\n    }\n\n    public void shutdown() {\n        System.out.println(\"Shutting down elevator system...\");\n        for (Elevator elevator : elevators.values()) {\n            elevator.stopElevator();\n        }\n        executorService.shutdown();\n    }\n}"
  },
  {
    "path": "solutions/java/src/elevatorsystem/ElevatorSystemDemo.java",
    "content": "package elevatorsystem;\n\nimport elevatorsystem.enums.Direction;\n\npublic class ElevatorSystemDemo {\n    public static void main(String[] args) throws InterruptedException {\n        // Setup: A building with 2 elevators\n        int numElevators = 2;\n        // The getInstance method now initializes the elevators and attaches the Display (Observer).\n        ElevatorSystem elevatorSystem = ElevatorSystem.getInstance(numElevators);\n\n        // Start the elevator system\n        elevatorSystem.start();\n        System.out.println(\"Elevator system started. ConsoleDisplay is observing.\\n\");\n\n        // --- SIMULATION START ---\n\n        // 1. External Request: User at floor 5 wants to go UP.\n        // The system will dispatch this to the nearest elevator (likely E1 or E2, both at floor 1).\n        elevatorSystem.requestElevator(5, Direction.UP);\n        Thread.sleep(100); // Wait for the elevator to start moving\n\n        // 2. Internal Request: Assume E1 took the previous request.\n        // The user gets in at floor 5 and presses 10.\n        // We send this request directly to E1.\n\n        // Note: In a real simulation, we'd wait until E1 reaches floor 5, but for this demo,\n        // we simulate the internal button press shortly after the external one.\n        elevatorSystem.selectFloor(1, 10);\n        Thread.sleep(200);\n\n        // 3. External Request: User at floor 3 wants to go DOWN.\n        // E2 (likely still idle at floor 1) might take this, or E1 if it's convenient.\n        elevatorSystem.requestElevator(3, Direction.DOWN);\n        Thread.sleep(300);\n\n        // 4. Internal Request: User in E2 presses 1.\n        elevatorSystem.selectFloor(2, 1);\n\n        // Let the simulation run for a while to observe the display updates\n        System.out.println(\"\\n--- Letting simulation run for 1 second ---\");\n        Thread.sleep(1000);\n\n        // Shutdown the system\n        elevatorSystem.shutdown();\n        System.out.println(\"\\n--- SIMULATION END ---\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/elevatorsystem/README.md",
    "content": "# Elevator System (LLD)\n\n## Problem Statement\n\nDesign and implement an Elevator System that can handle multiple requests, move between floors, and manage direction and vendingMachineState efficiently.\n\n---\n\n## Requirements\n\n- **Multiple Elevator:** The system manages multiple elevators.\n- **Request Handling:** The system can handle requests to move to specific floors in a given direction (UP/DOWN).\n- **Direction Management:** The elevator maintains and updates its current direction (UP, DOWN, IDLE).\n- **State Management:** The elevator tracks its current floor, direction, and pending requests.\n- **Efficient Movement:** The elevator processes requests in an efficient order (e.g., all UP requests, then all DOWN requests).\n- **Extensibility:** Easy to add more elevators or advanced scheduling algorithms.\n\n---\n\n## Core Entities\n\n- **Elevator:** Represents the elevator, manages its vendingMachineState, direction, and request queue.\n- **ElevatorController:** Handles incoming requests and delegates them to the elevator.\n- **Request:** Represents a request to move to a specific floor in a given direction.\n- **Direction (enum):** UP, DOWN, IDLE.\n\n---\n\n## Class Design\n\n### 1. Elevator\n- **Fields:** currentFloor, direction, List<Request> requests, isMoving, etc.\n- **Methods:** addRequest(Request), move(), openDoor(), closeDoor(), processNextRequest(), getCurrentFloor(), getDirection(), etc.\n\n### 2. ElevatorController\n- **Fields:** Elevator elevator\n- **Methods:** requestElevator(int floor, Direction direction), step(), etc.\n\n### 3. Request\n- **Fields:** int floor, Direction direction\n\n### 4. Direction (enum)\n- Values: UP, DOWN, IDLE\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/elevatorsystem-class-diagram.png)\n\n---\n\n## Example Usage\n\n```java\nElevatorController controller = new ElevatorController();\ncontroller.requestElevator(5, Direction.UP);\ncontroller.requestElevator(2, Direction.DOWN);\n\n// Simulate elevator steps\nfor (int i = 0; i < 10; i++) {\n    controller.step();\n}\n```\n\n---\n\n## Demo\n\nSee `ElevatorSystemDemo.java` for a sample usage and simulation of the elevator system.\n\n---\n\n## Extending the Framework\n\n- **Add multiple elevators:** Create a list of `Elevator` objects and update the controller logic.\n- **Advanced scheduling:** Implement algorithms for optimal elevator assignment.\n- **Add features:** Such as maintenance mode, emergency stop, or floor elevatorDisplay.\n\n---"
  },
  {
    "path": "solutions/java/src/elevatorsystem/enums/Direction.java",
    "content": "package elevatorsystem.enums;\n\npublic enum Direction {\n    UP, DOWN, IDLE\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/enums/RequestSource.java",
    "content": "package elevatorsystem.enums;\n\npublic enum RequestSource {\n    INTERNAL, // From inside the cabin\n    EXTERNAL  // From the hall/floor\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/models/Request.java",
    "content": "package elevatorsystem.models;\n\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.enums.RequestSource;\n\npublic class Request {\n    private final int targetFloor;\n    private final Direction direction; // Primarily for External requests\n    private final RequestSource source;\n\n    public Request(int targetFloor, Direction direction, RequestSource source) {\n        this.targetFloor = targetFloor;\n        this.direction = direction;\n        this.source = source;\n    }\n\n    public int getTargetFloor() {\n        return targetFloor;\n    }\n\n    public Direction getDirection() {\n        return direction;\n    }\n\n    public RequestSource getSource() {\n        return source;\n    }\n\n    @Override\n    public String toString() {\n        return source + \" Request to floor \" + targetFloor +\n                (source == RequestSource.EXTERNAL ? \" going \" + direction : \"\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/elevatorsystem/observer/ElevatorDisplay.java",
    "content": "package elevatorsystem.observer;\n\nimport elevatorsystem.Elevator;\n\npublic class ElevatorDisplay implements ElevatorObserver {\n    @Override\n    public void update(Elevator elevator) {\n        System.out.println(\"[DISPLAY] Elevator \" + elevator.getId() +\n                \" | Current Floor: \" + elevator.getCurrentFloor() +\n                \" | Direction: \" + elevator.getDirection());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/observer/ElevatorObserver.java",
    "content": "package elevatorsystem.observer;\n\nimport elevatorsystem.Elevator;\n\npublic interface ElevatorObserver {\n    void update(Elevator elevator);\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/state/ElevatorState.java",
    "content": "package elevatorsystem.state;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.models.Request;\n\npublic interface ElevatorState {\n    void move(Elevator elevator);\n    void addRequest(Elevator elevator, Request request);\n    Direction getDirection();\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/state/IdleState.java",
    "content": "package elevatorsystem.state;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.models.Request;\n\npublic class IdleState implements ElevatorState {\n    @Override\n    public void move(Elevator elevator) {\n        if (!elevator.getUpRequests().isEmpty()) {\n            elevator.setState(new MovingUpState());\n        } else if (!elevator.getDownRequests().isEmpty()) {\n            elevator.setState(new MovingDownState());\n        }\n        // Else stay idle\n    }\n\n    @Override\n    public void addRequest(Elevator elevator, Request request) {\n        if (request.getTargetFloor() > elevator.getCurrentFloor()) {\n            elevator.getUpRequests().add(request.getTargetFloor());\n        } else if (request.getTargetFloor() < elevator.getCurrentFloor()) {\n            elevator.getDownRequests().add(request.getTargetFloor());\n        }\n        // If request is for current floor, doors would open (handled implicitly by moving to that floor)\n    }\n\n    @Override\n    public Direction getDirection() { return Direction.IDLE; }\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/state/MovingDownState.java",
    "content": "package elevatorsystem.state;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.enums.RequestSource;\nimport elevatorsystem.models.Request;\n\npublic class MovingDownState implements ElevatorState {\n    @Override\n    public void move(Elevator elevator) {\n        if (elevator.getDownRequests().isEmpty()) {\n            elevator.setState(new IdleState());\n            return;\n        }\n\n        Integer nextFloor = elevator.getDownRequests().first();\n        elevator.setCurrentFloor(elevator.getCurrentFloor() - 1);\n\n        if (elevator.getCurrentFloor() == nextFloor) {\n            System.out.println(\"Elevator \" + elevator.getId() + \" stopped at floor \" + nextFloor);\n            elevator.getDownRequests().pollFirst();\n        }\n\n        if (elevator.getDownRequests().isEmpty()) {\n            elevator.setState(new IdleState());\n        }\n    }\n\n    @Override\n    public void addRequest(Elevator elevator, Request request) {\n        // Internal requests always get added to the appropriate queue\n        if (request.getSource() == RequestSource.INTERNAL) {\n            if (request.getTargetFloor() > elevator.getCurrentFloor()) {\n                elevator.getUpRequests().add(request.getTargetFloor());\n            } else {\n                elevator.getDownRequests().add(request.getTargetFloor());\n            }\n            return;\n        }\n\n        // External requests\n        if (request.getDirection() == Direction.DOWN && request.getTargetFloor() <= elevator.getCurrentFloor()) {\n            elevator.getDownRequests().add(request.getTargetFloor());\n        } else if (request.getDirection() == Direction.UP) {\n            elevator.getUpRequests().add(request.getTargetFloor());\n        }\n    }\n\n    @Override\n    public Direction getDirection() { return Direction.DOWN; }\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/state/MovingUpState.java",
    "content": "package elevatorsystem.state;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.enums.RequestSource;\nimport elevatorsystem.models.Request;\n\npublic class MovingUpState implements ElevatorState {\n    @Override\n    public void move(Elevator elevator) {\n        if (elevator.getUpRequests().isEmpty()) {\n            elevator.setState(new IdleState());\n            return;\n        }\n\n        Integer nextFloor = elevator.getUpRequests().first();\n        elevator.setCurrentFloor(elevator.getCurrentFloor() + 1);\n\n        if (elevator.getCurrentFloor() == nextFloor) {\n            System.out.println(\"Elevator \" + elevator.getId() + \" stopped at floor \" + nextFloor);\n            elevator.getUpRequests().pollFirst();\n        }\n\n        if (elevator.getUpRequests().isEmpty()) {\n            elevator.setState(new IdleState());\n        }\n    }\n\n    @Override\n    public void addRequest(Elevator elevator, Request request) {\n        // Internal requests always get added to the appropriate queue\n        if (request.getSource() == RequestSource.INTERNAL) {\n            if (request.getTargetFloor() > elevator.getCurrentFloor()) {\n                elevator.getUpRequests().add(request.getTargetFloor());\n            } else {\n                elevator.getDownRequests().add(request.getTargetFloor());\n            }\n            return;\n        }\n\n        // External requests\n        if (request.getDirection() == Direction.UP && request.getTargetFloor() >= elevator.getCurrentFloor()) {\n            elevator.getUpRequests().add(request.getTargetFloor());\n        } else if (request.getDirection() == Direction.DOWN) {\n            elevator.getDownRequests().add(request.getTargetFloor());\n        }\n    }\n\n    @Override\n    public Direction getDirection() { return Direction.UP; }\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/strategy/ElevatorSelectionStrategy.java",
    "content": "package elevatorsystem.strategy;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.models.Request;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic interface ElevatorSelectionStrategy {\n    Optional<Elevator> selectElevator(List<Elevator> elevators, Request request);\n}\n"
  },
  {
    "path": "solutions/java/src/elevatorsystem/strategy/NearestElevatorStrategy.java",
    "content": "package elevatorsystem.strategy;\n\nimport elevatorsystem.Elevator;\nimport elevatorsystem.enums.Direction;\nimport elevatorsystem.models.Request;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic class NearestElevatorStrategy implements ElevatorSelectionStrategy {\n    @Override\n    public Optional<Elevator> selectElevator(List<Elevator> elevators, Request request) {\n        Elevator bestElevator = null;\n        int minDistance = Integer.MAX_VALUE;\n\n        for (Elevator elevator : elevators) {\n            if (isSuitable(elevator, request)) {\n                int distance = Math.abs(elevator.getCurrentFloor() - request.getTargetFloor());\n                if (distance < minDistance) {\n                    minDistance = distance;\n                    bestElevator = elevator;\n                }\n            }\n        }\n        return Optional.ofNullable(bestElevator);\n    }\n\n    private boolean isSuitable(Elevator elevator, Request request) {\n        if (elevator.getDirection() == Direction.IDLE)\n            return true;\n        if (elevator.getDirection() == request.getDirection()) {\n            if (request.getDirection() == Direction.UP && elevator.getCurrentFloor() <= request.getTargetFloor())\n                return true;\n            if (request.getDirection() == Direction.DOWN && elevator.getCurrentFloor() >= request.getTargetFloor())\n                return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/filedirectory/AbstractNode.java",
    "content": "package filedirectory;\n\nimport java.util.Date;\n\n// Abstract class for files and directories\npublic abstract class AbstractNode {\n    protected String name;\n    protected Date createdAt;\n\n    public AbstractNode(String name) {\n        this.name = name;\n        this.createdAt = new Date();\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public Date getCreatedAt() {\n        return createdAt;\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/DirectoryNode.java",
    "content": "package filedirectory;\n\nimport java.util.*;\n\n// Directory Node containing files and subdirectories\npublic class DirectoryNode extends AbstractNode {\n    private Map<String, AbstractNode> children;\n\n    public DirectoryNode(String name) {\n        super(name);\n        this.children = new HashMap<>();\n    }\n\n    public void addNode(AbstractNode node) {\n        children.put(node.getName(), node);\n    }\n\n    public List<AbstractNode> getChildren() {\n        return new ArrayList<>(children.values());\n    }\n\n    public AbstractNode getNode(String name) {\n        return children.get(name);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/filedirectory/FileNode.java",
    "content": "package filedirectory;\n\n// File Node with metadata\npublic class FileNode extends AbstractNode {\n    private String content;\n    private int size;\n\n    public FileNode(String name) {\n        super(name);\n        this.content = \"\";\n        this.size = 0;\n    }\n\n    public void appendContent(String newContent) {\n        this.content += newContent;\n        this.size += newContent.length();\n    }\n\n    public String readContent() {\n        return content;\n    }\n\n    public int getSize() {\n        return size;\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/FileSystem.java",
    "content": "package filedirectory;\n\nimport filedirectory.strategy.NodeSearchStrategy;\n\nimport java.util.*;\n\npublic class FileSystem {\n    private DirectoryNode root;\n\n    public FileSystem() {\n        this.root = new DirectoryNode(\"/\");\n    }\n\n    private DirectoryNode traverse(String path, boolean createMissingDirs) {\n        String[] parts = path.split(\"/\");\n        DirectoryNode current = root;\n\n        for (int i = 1; i < parts.length; i++) {\n            if (!(current.getNode(parts[i]) instanceof DirectoryNode)) {\n                if (createMissingDirs) {\n                    current.addNode(new DirectoryNode(parts[i]));\n                } else {\n                    return null;\n                }\n            }\n            current = (DirectoryNode) current.getNode(parts[i]);\n        }\n        return current;\n    }\n\n    public void mkdir(String path) {\n        traverse(path, true);\n    }\n\n    public void addFile(String filePath, String content) {\n        DirectoryNode parent = traverse(filePath.substring(0, filePath.lastIndexOf(\"/\")), true);\n        String fileName = filePath.substring(filePath.lastIndexOf(\"/\") + 1);\n\n        FileNode file = (FileNode) parent.getNode(fileName);\n        if (file == null) {\n            file = new FileNode(fileName);\n            parent.addNode(file);\n        }\n        file.appendContent(content);\n    }\n\n    public List<AbstractNode> searchNodes(String directoryPath, NodeSearchStrategy strategy, Map<String, Object> params) {\n        DirectoryNode directory = traverse(directoryPath, false);\n        if (directory == null) {\n            throw new IllegalArgumentException(\"Directory not found: \" + directoryPath);\n        }\n        return strategy.search(directory, params);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/filedirectory/FileSystemDemo.java",
    "content": "package filedirectory;\n\nimport filedirectory.strategy.*;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class FileSystemDemo {\n    public static void main(String[] args) {\n        FileSystem fs = new FileSystem();\n\n        fs.mkdir(\"/a/b/c\");\n        fs.addFile(\"/a/b/c/file1.txt\", \"Hello\");\n        fs.addFile(\"/a/b/c/file2.log\", \"Data\");\n        fs.addFile(\"/a/file3.txt\", \"Some large content to increase file size...\");\n        fs.addFile(\"/a/file4.txt\", \"Short\");\n\n        System.out.println(\"Searching for files and directories matching regex 'file.*\\\\.txt' with size between 5 and 50 bytes:\");\n\n        NodeSearchStrategy strategy = new FilenameAndSizeSearchStrategy();\n        Map<String, Object> searchParams = new HashMap<>();\n        searchParams.put(\"filenameRegex\", \"file.*\\\\.txt\");\n        searchParams.put(\"minSize\", 5);\n        searchParams.put(\"maxSize\", 50);\n\n        List<AbstractNode> foundNodes = fs.searchNodes(\"/a\", strategy, searchParams);\n\n        for (AbstractNode node : foundNodes) {\n            if (node instanceof FileNode) {\n                System.out.println(\"[FILE] \" + node.getName() + \" (Size: \" + ((FileNode) node).getSize() + \" bytes)\");\n            } else {\n                System.out.println(\"[DIR] \" + node.getName());\n            }\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/chainofresponsibility/FileSizeFilter.java",
    "content": "package filedirectory.chainofresponsibility;\n\nimport filedirectory.AbstractNode;\nimport filedirectory.FileNode;\nimport filedirectory.chainofresponsibility.NodeFilter;\n\nimport java.util.Map;\n\npublic class FileSizeFilter implements NodeFilter {\n    @Override\n    public boolean apply(AbstractNode node, Map<String, Object> params) {\n        if (!(node instanceof FileNode)) return true;\n        if (!params.containsKey(\"minSize\") || !params.containsKey(\"maxSize\")) return true;\n\n        int minSize = (int) params.get(\"minSize\");\n        int maxSize = (int) params.get(\"maxSize\");\n        int size = ((FileNode) node).getSize();\n\n        return size >= minSize && size <= maxSize;\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/chainofresponsibility/FilenameFilter.java",
    "content": "package filedirectory.chainofresponsibility;\n\nimport filedirectory.AbstractNode;\n\nimport java.util.Map;\nimport java.util.regex.Pattern;\n\n// Concrete Filter: Filter by filename regex\npublic class FilenameFilter implements NodeFilter {\n    @Override\n    public boolean apply(AbstractNode node, Map<String, Object> params) {\n        if (!params.containsKey(\"filenameRegex\")) return true;\n        String regex = (String) params.get(\"filenameRegex\");\n        return Pattern.matches(regex, node.getName());\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/chainofresponsibility/NodeFilter.java",
    "content": "package filedirectory.chainofresponsibility;\n\nimport filedirectory.AbstractNode;\n\nimport java.util.Map;\n\npublic interface NodeFilter {\n    boolean apply(AbstractNode node, Map<String, Object> params);\n}\n"
  },
  {
    "path": "solutions/java/src/filedirectory/chainofresponsibility/NodeFilterChain.java",
    "content": "package filedirectory.chainofresponsibility;\n\nimport filedirectory.AbstractNode;\n\nimport java.util.*;\n\n// Chain of Responsibility: Combines multiple filters\npublic class NodeFilterChain {\n    private List<NodeFilter> filters;\n\n    public NodeFilterChain() {\n        this.filters = new ArrayList<>();\n    }\n\n    public void addFilter(NodeFilter filter) {\n        filters.add(filter);\n    }\n\n    public boolean applyFilters(AbstractNode node, Map<String, Object> params) {\n        for (NodeFilter filter : filters) {\n            if (!filter.apply(node, params)) {\n                return false; // If any filter fails, reject the node\n            }\n        }\n        return true;\n    }\n}"
  },
  {
    "path": "solutions/java/src/filedirectory/strategy/FilenameAndSizeSearchStrategy.java",
    "content": "package filedirectory.strategy;\n\nimport filedirectory.*;\nimport filedirectory.chainofresponsibility.FileSizeFilter;\nimport filedirectory.chainofresponsibility.FilenameFilter;\nimport filedirectory.chainofresponsibility.NodeFilterChain;\n\nimport java.util.*;\n\npublic class FilenameAndSizeSearchStrategy implements NodeSearchStrategy {\n    private NodeFilterChain filterChain;\n\n    public FilenameAndSizeSearchStrategy() {\n        this.filterChain = new NodeFilterChain();\n        filterChain.addFilter(new FilenameFilter());\n        filterChain.addFilter(new FileSizeFilter());\n    }\n\n    @Override\n    public List<AbstractNode> search(DirectoryNode directory, Map<String, Object> params) {\n        List<AbstractNode> result = new ArrayList<>();\n        searchRecursive(directory, params, result);\n        return result;\n    }\n\n    private void searchRecursive(DirectoryNode dir, Map<String, Object> params, List<AbstractNode> result) {\n        for (AbstractNode node : dir.getChildren()) {\n            if (filterChain.applyFilters(node, params)) {\n                result.add(node);\n            }\n            if (node instanceof DirectoryNode) {\n                searchRecursive((DirectoryNode) node, params, result);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/filedirectory/strategy/NodeSearchStrategy.java",
    "content": "package filedirectory.strategy;\n\n\nimport filedirectory.AbstractNode;\nimport filedirectory.DirectoryNode;\n\nimport java.util.*;\n\npublic // Search strategy interface\ninterface NodeSearchStrategy {\n    List<AbstractNode> search(DirectoryNode directory, Map<String, Object> params);\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/FoodDeliveryService.java",
    "content": "package fooddeliveryservice;\n\nimport fooddeliveryservice.entity.*;\nimport fooddeliveryservice.order.Order;\nimport fooddeliveryservice.order.OrderItem;\nimport fooddeliveryservice.order.OrderStatus;\nimport fooddeliveryservice.search.RestaurantSearchStrategy;\nimport fooddeliveryservice.strategy.DeliveryAssignmentStrategy;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class FoodDeliveryService {\n    private static volatile FoodDeliveryService instance;\n    private final Map<String, Customer> customers = new ConcurrentHashMap<>();\n    private final Map<String, Restaurant> restaurants = new ConcurrentHashMap<>();\n    private final Map<String, DeliveryAgent> deliveryAgents = new ConcurrentHashMap<>();\n    private final Map<String, Order> orders = new ConcurrentHashMap<>();\n    private DeliveryAssignmentStrategy assignmentStrategy;\n\n    private FoodDeliveryService() {}\n\n    public static FoodDeliveryService getInstance() {\n        if (instance == null) {\n            synchronized (FoodDeliveryService.class) {\n                if (instance == null) instance = new FoodDeliveryService();\n            }\n        }\n        return instance;\n    }\n\n    public void setAssignmentStrategy(DeliveryAssignmentStrategy assignmentStrategy) {\n        this.assignmentStrategy = assignmentStrategy;\n    }\n\n    // --- Registration ---\n    public Customer registerCustomer(String name, String phone, Address address) {\n        Customer customer = new Customer(name, phone, address);\n        customers.put(customer.getId(), customer);\n        return customer;\n    }\n\n    public Restaurant registerRestaurant(String name, Address address) {\n        Restaurant restaurant = new Restaurant(name, address);\n        restaurants.put(restaurant.getId(), restaurant);\n        return restaurant;\n    }\n\n    public DeliveryAgent registerDeliveryAgent(String name, String phone, Address initialLocation) {\n        DeliveryAgent deliveryAgent = new DeliveryAgent(name, phone, initialLocation);\n        deliveryAgents.put(deliveryAgent.getId(), deliveryAgent);\n        return deliveryAgent;\n    }\n\n    public Order placeOrder(String customerId, String restaurantId, List<OrderItem> items) {\n        Customer customer = customers.get(customerId);\n        Restaurant restaurant = restaurants.get(restaurantId);\n        if (customer == null || restaurant == null) throw new NoSuchElementException(\"Customer or Restaurant not found.\");\n\n        Order order = new Order(customer, restaurant, items);\n        orders.put(order.getId(), order);\n        customer.addOrderToHistory(order);\n        System.out.printf(\"Order %s placed by %s at %s.\\n\", order.getId(), customer.getName(), restaurant.getName());\n        // Initial PENDING status is set in constructor and observers are notified.\n        order.setStatus(OrderStatus.PENDING);\n        return order;\n    }\n\n    public void updateOrderStatus(String orderId, OrderStatus newStatus) {\n        Order order = orders.get(orderId);\n        if (order == null)\n            throw new NoSuchElementException(\"Order not found.\");\n\n        order.setStatus(newStatus);\n\n        // If order is ready, find a delivery agent.\n        if (newStatus == OrderStatus.READY_FOR_PICKUP) {\n            assignDelivery(order);\n        }\n    }\n\n    public void cancelOrder(String orderId) {\n        Order order = orders.get(orderId);\n        if (order == null) {\n            System.out.println(\"ERROR: Order with ID \" + orderId + \" not found.\");\n            return;\n        }\n\n        // Delegate the cancellation logic to the Order object itself.\n        if (order.cancel()) {\n            System.out.println(\"SUCCESS: Order \" + orderId + \" has been successfully canceled.\");\n        } else {\n            System.out.println(\"FAILED: Order \" + orderId + \" could not be canceled. Its status is: \" + order.getStatus());\n        }\n    }\n\n    private void assignDelivery(Order order) {\n        List<DeliveryAgent> availableAgents = new ArrayList<>(deliveryAgents.values());\n\n        assignmentStrategy.findAgent(order, availableAgents).ifPresentOrElse(\n                agent -> {\n                    order.assignDeliveryAgent(agent);\n                    System.out.printf(\"Agent %s (dist: %.2f) assigned to order %s.\\n\",\n                            agent.getName(),\n                            agent.getCurrentLocation().distanceTo(order.getRestaurant().getAddress()),\n                            order.getId());\n                    order.setStatus(OrderStatus.OUT_FOR_DELIVERY);\n                },\n                () -> System.out.println(\"No available delivery agents found for order \" + order.getId())\n        );\n    }\n\n    public List<Restaurant> searchRestaurants(List<RestaurantSearchStrategy> strategies) {\n        // Start with the full list of restaurants\n        List<Restaurant> results = new ArrayList<>(restaurants.values());\n\n        // Sequentially apply each filter strategy\n        // We can also use chain of responsibility design pattern here\n        for (RestaurantSearchStrategy strategy : strategies) {\n            results = strategy.filter(results);\n        }\n\n        return results;\n    }\n\n    public Menu getRestaurantMenu(String restaurantId) {\n        Restaurant restaurant = restaurants.get(restaurantId);\n        if (restaurant == null) {\n            throw new NoSuchElementException(\"Restaurant with ID \" + restaurantId + \" not found.\");\n        }\n        return restaurant.getMenu();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/FoodDeliveryServiceDemo.java",
    "content": "package fooddeliveryservice;\n\nimport fooddeliveryservice.entity.*;\nimport fooddeliveryservice.order.OrderItem;\nimport fooddeliveryservice.order.OrderStatus;\nimport fooddeliveryservice.search.RestaurantSearchStrategy;\nimport fooddeliveryservice.search.SearchByCityStrategy;\nimport fooddeliveryservice.search.SearchByMenuKeywordStrategy;\nimport fooddeliveryservice.search.SearchByProximityStrategy;\nimport fooddeliveryservice.strategy.NearestAvailableAgentStrategy;\n\nimport java.util.List;\n\npublic class FoodDeliveryServiceDemo {\n    public static void main(String[] args) {\n        // 1. Setup the system\n        FoodDeliveryService service = FoodDeliveryService.getInstance();\n        service.setAssignmentStrategy(new NearestAvailableAgentStrategy());\n\n        // 2. Define Addresses\n        Address aliceAddress = new Address(\"123 Maple St\", \"Springfield\", \"12345\", 40.7128, -74.0060);\n        Address pizzaAddress = new Address(\"456 Oak Ave\", \"Springfield\", \"12345\", 40.7138, -74.0070);\n        Address burgerAddress = new Address(\"789 Pine Ln\", \"Springfield\", \"12345\", 40.7108, -74.0050);\n        Address tacoAddress = new Address(\"101 Elm Ct\", \"Shelbyville\", \"54321\", 41.7528, -75.0160);\n\n        // 3. Register entities\n        Customer alice = service.registerCustomer(\"Alice\", \"123-4567-890\", aliceAddress);\n        Restaurant pizzaPalace = service.registerRestaurant(\"Pizza Palace\", pizzaAddress);\n        Restaurant burgerBarn = service.registerRestaurant(\"Burger Barn\", burgerAddress);\n        Restaurant tacoTown = service.registerRestaurant(\"Taco Town\", tacoAddress);\n        service.registerDeliveryAgent(\"Bob\", \"321-4567-880\", new Address(\"1 B\", \"Springfield\", \"12345\", 40.71, -74.00));\n\n        // 4. Setup menus\n        pizzaPalace.addToMenu(new MenuItem(\"P001\", \"Margherita Pizza\", 12.99));\n        pizzaPalace.addToMenu(new MenuItem(\"P002\", \"Veggie Pizza\", 11.99));\n        burgerBarn.addToMenu(new MenuItem(\"B001\", \"Classic Burger\", 8.99));\n        tacoTown.addToMenu(new MenuItem(\"T001\", \"Crunchy Taco\", 3.50));\n\n        // 5. Demonstrate Search Functionality\n        System.out.println(\"\\n--- 1. Searching for Restaurants ---\");\n\n        // (A) Search by City\n        System.out.println(\"\\n(A) Restaurants in 'Springfield':\");\n        List<RestaurantSearchStrategy> citySearch = List.of(new SearchByCityStrategy(\"Springfield\"));\n        List<Restaurant> springfieldRestaurants = service.searchRestaurants(citySearch);\n        springfieldRestaurants.forEach(r -> System.out.println(\"  - \" + r.getName()));\n\n        // (B) Search for restaurants near Alice\n        System.out.println(\"\\n(B) Restaurants near Alice (within 0.01 distance units):\");\n        List<RestaurantSearchStrategy> proximitySearch = List.of(new SearchByProximityStrategy(aliceAddress, 0.01));\n        List<Restaurant> nearbyRestaurants = service.searchRestaurants(proximitySearch);\n        nearbyRestaurants.forEach(r -> System.out.printf(\"  - %s (Distance: %.4f)\\n\", r.getName(), aliceAddress.distanceTo(r.getAddress())));\n\n        // (C) Search for restaurants that serve 'Pizza'\n        System.out.println(\"\\n(C) Restaurants that serve 'Pizza':\");\n        List<RestaurantSearchStrategy> menuSearch = List.of(new SearchByMenuKeywordStrategy(\"Pizza\"));\n        List<Restaurant> pizzaRestaurants = service.searchRestaurants(menuSearch);\n        pizzaRestaurants.forEach(r -> System.out.println(\"  - \" + r.getName()));\n\n        // (D) Combined Search: Find restaurants near Alice that serve 'Burger'\n        System.out.println(\"\\n(D) Burger joints near Alice:\");\n        List<RestaurantSearchStrategy> combinedSearch = List.of(\n                new SearchByProximityStrategy(aliceAddress, 0.01),\n                new SearchByMenuKeywordStrategy(\"Burger\")\n        );\n        List<Restaurant> burgerJointsNearAlice = service.searchRestaurants(combinedSearch);\n        burgerJointsNearAlice.forEach(r -> System.out.println(\"  - \" + r.getName()));\n\n        // 6. Demonstrate Browsing a Menu\n        System.out.println(\"\\n--- 2. Browsing a Menu ---\");\n        System.out.println(\"\\nMenu for 'Pizza Palace':\");\n        Menu pizzaMenu = service.getRestaurantMenu(pizzaPalace.getId());\n        pizzaMenu.getItems().values().forEach(item ->\n                System.out.printf(\"  - %s: $%.2f\\n\", item.getName(), item.getPrice())\n        );\n\n        // 7. Alice places an order from a searched restaurant\n        System.out.println(\"\\n--- 3. Placing an Order ---\");\n        if (!pizzaRestaurants.isEmpty()) {\n            Restaurant chosenRestaurant = pizzaRestaurants.get(0);\n            MenuItem chosenItem = chosenRestaurant.getMenu().getItem(\"P001\");\n\n            System.out.printf(\"\\nAlice is ordering '%s' from '%s'.\\n\", chosenItem.getName(), chosenRestaurant.getName());\n            var order = service.placeOrder(alice.getId(), chosenRestaurant.getId(), List.of(new OrderItem(chosenItem, 1)));\n\n            System.out.println(\"\\n--- Restaurant starts preparing the order ---\");\n            service.updateOrderStatus(order.getId(), OrderStatus.PREPARING);\n\n            System.out.println(\"\\n--- Order is ready for pickup ---\");\n            System.out.println(\"System will now find the nearest available delivery agent...\");\n            service.updateOrderStatus(order.getId(), OrderStatus.READY_FOR_PICKUP);\n\n            System.out.println(\"\\n--- Agent delivers the order ---\");\n            service.updateOrderStatus(order.getId(), OrderStatus.DELIVERED);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/README.md",
    "content": "# Food Delivery Service (LLD)\n\n## Problem Statement\n\nDesign and implement a Food Delivery Service system that allows customers to place orders from restaurants, manages menu items, assigns delivery agents, and tracks order status from placement to delivery.\n\n---\n\n## Requirements\n\n- **Customer Registration:** Customers can register and place orders.\n- **Restaurant Management:** The system manages multiple restaurants, each with its own menu.\n- **Menu Management:** Restaurants can add and update menu items.\n- **Order Placement:** Customers can place orders for menu items from a restaurantManagementSystem.\n- **Order Tracking:** The system tracks the status of each order (e.g., PLACED, PREPARING, OUT_FOR_DELIVERY, DELIVERED).\n- **Delivery Assignment:** Orders are assigned to available delivery agents.\n- **Delivery Agent Management:** The system manages delivery agents and their availability.\n- **Extensibility:** Easy to add new features such as ratings, reviews, or payment integration.\n\n---\n\n## Core Entities\n\n- **FoodDeliveryService:** Main class that manages customers, restaurants, orders, and delivery agents.\n- **Customer:** Represents a customer who can place orders.\n- **Restaurant:** Represents a restaurantManagementSystem with a menu of items.\n- **MenuItem:** Represents an item on a restaurantManagementSystem's menu.\n- **Order:** Represents a customer's order, including items, status, and assigned delivery agent.\n- **DeliveryAgent:** Represents a delivery agent who delivers orders.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/fooddeliveryservice-class-diagram.png)\n\n### 1. FoodDeliveryService\n- **Fields:** List<Customer> customers, List<Restaurant> restaurants, List<DeliveryAgent> agents, List<Order> orders\n- **Methods:** registerCustomer(Customer), addRestaurant(Restaurant), addMenuItem(Restaurant, MenuItem), placeOrder(Customer, Restaurant, List<MenuItem>), assignDeliveryAgent(Order), updateOrderStatus(Order, Status), etc.\n\n### 2. Customer\n- **Fields:** int id, String name, List<Order> orders\n\n### 3. Restaurant\n- **Fields:** int id, String name, List<MenuItem> menu\n\n### 4. MenuItem\n- **Fields:** int id, String name, double price\n\n### 5. Order\n- **Fields:** int id, Customer customer, Restaurant restaurantManagementSystem, List<MenuItem> items, OrderStatus status, DeliveryAgent agent\n\n### 6. DeliveryAgent\n- **Fields:** int id, String name, boolean available, List<Order> assignedOrders\n\n---\n\n## Example Usage\n\n```java\nFoodDeliveryService service = new FoodDeliveryService();\nCustomer alice = new Customer(1, \"Alice\");\nRestaurant pizzaPlace = new Restaurant(1, \"Pizza Place\");\nMenuItem pizza = new MenuItem(1, \"Margherita Pizza\", 10.0);\n\nservice.registerCustomer(alice);\nservice.addRestaurant(pizzaPlace);\nservice.addMenuItem(pizzaPlace, pizza);\n\nservice.placeOrder(alice, pizzaPlace, List.of(pizza));\n```\n\n---\n\n## Demo\n\nSee `FoodDeliveryServiceDemo.java` for a sample usage and simulation of the food delivery service.\n\n---\n\n## Extending the Framework\n\n- **Add ratings and reviews:** Allow customers to rate restaurants and delivery agents.\n- **Add payment integration:** Support online payments.\n- **Add order cancellation or modification:** Allow customers to cancel or modify orders before delivery.\n\n---"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/Address.java",
    "content": "package fooddeliveryservice.entity;\n\npublic class Address {\n    private String street;\n    private String city;\n    private String zipCode;\n    private double latitude;\n    private double longitude;\n\n    public Address(String street, String city, String zipCode, double latitude, double longitude) {\n        this.street = street;\n        this.city = city;\n        this.zipCode = zipCode;\n        this.latitude = latitude;\n        this.longitude = longitude;\n    }\n\n    public String getCity() {\n        return city;\n    }\n\n    public double distanceTo(Address other) {\n        double latDiff = this.latitude - other.latitude;\n        double lonDiff = this.longitude - other.longitude;\n        return Math.sqrt(latDiff * latDiff + lonDiff * lonDiff);\n    }\n\n    @Override\n    public String toString() {\n        return street + \", \" + city + \", \" + zipCode + \" @(\" + latitude + \", \" + longitude + \")\";\n    }\n}"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/Customer.java",
    "content": "package fooddeliveryservice.entity;\n\nimport fooddeliveryservice.order.Order;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Customer extends User {\n    private Address address;\n    private final List<Order> orderHistory = new ArrayList<>();\n\n    public Customer(String name, String phone, Address address) {\n        super(name, phone);\n        this.address = address;\n    }\n\n    public void addOrderToHistory(Order order) { this.orderHistory.add(order); }\n\n    public Address getAddress() {\n        return address;\n    }\n\n    @Override public void onUpdate(Order order) {\n        System.out.printf(\"--- Notification for Customer %s ---\\n\", getName());\n        System.out.printf(\"  Order %s is now %s.\\n\", order.getId(), order.getStatus());\n        System.out.println(\"-------------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/DeliveryAgent.java",
    "content": "package fooddeliveryservice.entity;\n\nimport fooddeliveryservice.order.Order;\n\nimport java.util.concurrent.atomic.AtomicBoolean;\n\npublic class DeliveryAgent extends User {\n    private final AtomicBoolean isAvailable = new AtomicBoolean(true);\n    private Address currentLocation;\n\n    public DeliveryAgent(String name, String phone, Address currentLocation) {\n        super(name, phone);\n        this.currentLocation = currentLocation;\n    }\n\n    public void setAvailable(boolean available) {\n        this.isAvailable.set(available);\n    }\n\n    public synchronized boolean isAvailable() {\n        return isAvailable.get();\n    }\n\n    public void setCurrentLocation(Address currentLocation) { this.currentLocation = currentLocation; }\n\n    public Address getCurrentLocation() { return currentLocation; }\n\n    @Override public void onUpdate(Order order) {\n        System.out.printf(\"--- Notification for Delivery Agent %s ---\\n\", getName());\n        System.out.printf(\"  Order %s update: Status is %s.\\n\", order.getId(), order.getStatus());\n        System.out.println(\"-------------------------------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/Menu.java",
    "content": "package fooddeliveryservice.entity;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Menu {\n    private final Map<String, MenuItem> items = new HashMap<>();\n\n    public void addItem(MenuItem item) {\n        items.put(item.getId(), item);\n    }\n\n    public MenuItem getItem(String id) { return items.get(id); }\n\n    public Map<String, MenuItem> getItems() { return items; }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/MenuItem.java",
    "content": "package fooddeliveryservice.entity;\n\npublic class MenuItem {\n    private final String id;\n    private final String name;\n    private final double price;\n    private boolean available;\n\n    public MenuItem(String id, String name, double price) {\n        this.id = id;\n        this.name = name;\n        this.price = price;\n        this.available = true;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public void setAvailable(boolean available) {\n        this.available = available;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public double getPrice() {\n        return price;\n    }\n\n    public String getMenuItem() {\n        return \"Name: \" + name + \", Price: \" + price;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/Restaurant.java",
    "content": "package fooddeliveryservice.entity;\n\nimport fooddeliveryservice.observer.OrderObserver;\nimport fooddeliveryservice.order.Order;\n\nimport java.util.UUID;\n\npublic class Restaurant implements OrderObserver {\n    private final String id;\n    private final String name;\n    private final Address address;\n    private final Menu menu;\n\n    public Restaurant(String name, Address address) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.address = address;\n        this.menu = new Menu();\n    }\n    public void addToMenu(MenuItem item) { this.menu.addItem(item); }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public Address getAddress() { return address; }\n    public Menu getMenu() { return menu; }\n\n    @Override public void onUpdate(Order order) {\n        System.out.printf(\"--- Notification for Restaurant %s ---\\n\", getName());\n        System.out.printf(\"  Order %s has been updated to %s.\\n\", order.getId(), order.getStatus());\n        System.out.println(\"---------------------------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/entity/User.java",
    "content": "package fooddeliveryservice.entity;\n\nimport fooddeliveryservice.observer.OrderObserver;\n\nimport java.util.UUID;\n\npublic abstract class User implements OrderObserver {\n    private final String id;\n    private String name;\n    private String phone;\n\n    public User(String name, String phone) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.phone = phone;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n}"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/observer/OrderObserver.java",
    "content": "package fooddeliveryservice.observer;\n\nimport fooddeliveryservice.order.Order;\n\npublic interface OrderObserver {\n    void onUpdate(Order order);\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/order/Order.java",
    "content": "package fooddeliveryservice.order;\n\nimport fooddeliveryservice.entity.Customer;\nimport fooddeliveryservice.entity.DeliveryAgent;\nimport fooddeliveryservice.entity.Restaurant;\nimport fooddeliveryservice.observer.OrderObserver;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class Order {\n    private final String id;\n    private final Customer customer;\n    private final Restaurant restaurant;\n    private final List<OrderItem> items;\n    private OrderStatus status;\n    private DeliveryAgent deliveryAgent;\n    private final List<OrderObserver> observers = new ArrayList<>();\n\n    public Order(Customer customer, Restaurant restaurant, List<OrderItem> items) {\n        this.id = UUID.randomUUID().toString();\n        this.customer = customer;\n        this.restaurant = restaurant;\n        this.items = items;\n        this.status = OrderStatus.PENDING;\n        addObserver(customer);\n        addObserver(restaurant);\n    }\n\n    public void addObserver(OrderObserver observer) { observers.add(observer); }\n    private void notifyObservers() { observers.forEach(o -> o.onUpdate(this)); }\n\n    public void setStatus(OrderStatus newStatus) {\n        if (this.status != newStatus) {\n            this.status = newStatus;\n            notifyObservers();\n        }\n    }\n\n    public boolean cancel() {\n        // Only allow cancellation if the order is still in the PENDING state.\n        if (this.status == OrderStatus.PENDING) {\n            setStatus(OrderStatus.CANCELLED);\n            return true;\n        }\n        return false;\n    }\n\n    public void assignDeliveryAgent(DeliveryAgent agent) {\n        this.deliveryAgent = agent;\n        addObserver(agent);\n        agent.setAvailable(false); // Mark agent as busy\n    }\n\n    // Getters\n    public String getId() { return id; }\n    public OrderStatus getStatus() { return status; }\n    public Customer getCustomer() { return customer; }\n    public Restaurant getRestaurant() { return restaurant; }\n    public DeliveryAgent getDeliveryAgent() { return deliveryAgent; }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/order/OrderItem.java",
    "content": "package fooddeliveryservice.order;\n\nimport fooddeliveryservice.entity.MenuItem;\n\npublic class OrderItem {\n    private final MenuItem item;\n    private final int quantity;\n\n    public OrderItem(MenuItem item, int quantity) {\n        this.item = item;\n        this.quantity = quantity;\n    }\n\n    public MenuItem getItem() { return item; }\n    public int getQuantity() { return quantity; }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/order/OrderStatus.java",
    "content": "package fooddeliveryservice.order;\n\npublic enum OrderStatus {\n    PENDING,\n    CONFIRMED,\n    PREPARING,\n    READY_FOR_PICKUP,\n    OUT_FOR_DELIVERY,\n    DELIVERED,\n    CANCELLED\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/search/RestaurantSearchStrategy.java",
    "content": "package fooddeliveryservice.search;\n\nimport fooddeliveryservice.entity.Restaurant;\n\nimport java.util.List;\n\npublic interface RestaurantSearchStrategy {\n    List<Restaurant> filter(List<Restaurant> allRestaurants);\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/search/SearchByCityStrategy.java",
    "content": "package fooddeliveryservice.search;\n\nimport fooddeliveryservice.entity.Restaurant;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class SearchByCityStrategy implements RestaurantSearchStrategy {\n    private final String city;\n\n    public SearchByCityStrategy(String city) {\n        this.city = city;\n    }\n\n    @Override\n    public List<Restaurant> filter(List<Restaurant> allRestaurants) {\n        return allRestaurants.stream()\n                .filter(r -> r.getAddress().getCity().equalsIgnoreCase(city))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/search/SearchByMenuKeywordStrategy.java",
    "content": "package fooddeliveryservice.search;\n\nimport fooddeliveryservice.entity.Restaurant;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class SearchByMenuKeywordStrategy implements RestaurantSearchStrategy {\n    private final String keyword;\n\n    public SearchByMenuKeywordStrategy(String keyword) {\n        this.keyword = keyword.toLowerCase();\n    }\n\n    @Override\n    public List<Restaurant> filter(List<Restaurant> allRestaurants) {\n        return allRestaurants.stream()\n                .filter(r -> r.getMenu().getItems().values().stream()\n                        .anyMatch(item -> item.getName().toLowerCase().contains(keyword)))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/search/SearchByProximityStrategy.java",
    "content": "package fooddeliveryservice.search;\n\nimport fooddeliveryservice.entity.Address;\nimport fooddeliveryservice.entity.Restaurant;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class SearchByProximityStrategy implements RestaurantSearchStrategy {\n    private final Address userLocation;\n    private final double maxDistance;\n\n    public SearchByProximityStrategy(Address userLocation, double maxDistance) {\n        this.userLocation = userLocation;\n        this.maxDistance = maxDistance;\n    }\n\n    @Override\n    public List<Restaurant> filter(List<Restaurant> allRestaurants) {\n        return allRestaurants.stream()\n                // Filter restaurants within the max distance\n                .filter(r -> userLocation.distanceTo(r.getAddress()) <= maxDistance)\n                // Sort the filtered list by distance (nearest first)\n                .sorted(Comparator.comparingDouble(r -> userLocation.distanceTo(r.getAddress())))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/strategy/DeliveryAssignmentStrategy.java",
    "content": "package fooddeliveryservice.strategy;\n\nimport fooddeliveryservice.entity.DeliveryAgent;\nimport fooddeliveryservice.order.Order;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic interface DeliveryAssignmentStrategy {\n    Optional<DeliveryAgent> findAgent(Order order, List<DeliveryAgent> agents);\n}\n"
  },
  {
    "path": "solutions/java/src/fooddeliveryservice/strategy/NearestAvailableAgentStrategy.java",
    "content": "package fooddeliveryservice.strategy;\n\nimport fooddeliveryservice.entity.Address;\nimport fooddeliveryservice.entity.DeliveryAgent;\nimport fooddeliveryservice.order.Order;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Optional;\n\npublic class NearestAvailableAgentStrategy implements DeliveryAssignmentStrategy {\n    @Override\n    public Optional<DeliveryAgent> findAgent(Order order, List<DeliveryAgent> availableAgents) {\n        Address restaurantAddress = order.getRestaurant().getAddress();\n        Address customerAddress = order.getCustomer().getAddress();\n\n        // Find the agent with the minimum total travel distance (Agent -> Restaurant -> Customer)\n        return availableAgents.stream()\n                .filter(DeliveryAgent::isAvailable)\n                .min(Comparator.comparingDouble(agent -> calculateTotalDistance(agent, restaurantAddress, customerAddress)));\n    }\n\n    private double calculateTotalDistance(DeliveryAgent agent, Address restaurantAddress, Address customerAddress) {\n        double agentToRestaurantDist = agent.getCurrentLocation().distanceTo(restaurantAddress);\n        double restaurantToCustomerDist = restaurantAddress.distanceTo(customerAddress);\n        return agentToRestaurantDist + restaurantToCustomerDist;\n    }\n}"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/BookingService.java",
    "content": "package hotelmanagementsystem;\n\nimport hotelmanagementsystem.model.Booking;\nimport hotelmanagementsystem.model.Guest;\nimport hotelmanagementsystem.model.Room;\nimport hotelmanagementsystem.observer.BookingObserver;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class BookingService {\n    private final List<Booking> bookings = new ArrayList<>();\n    private final List<BookingObserver> observers = new ArrayList<>();\n\n    public void addObserver(BookingObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(BookingObserver observer) {\n        observers.remove(observer);\n    }\n\n    public Booking createBooking(Guest guest, Room room, LocalDate startDate, LocalDate endDate) {\n        String bookingId = UUID.randomUUID().toString();\n        Booking booking = new Booking(bookingId, guest, room, startDate, endDate);\n\n        // Use the State pattern to book the room\n        room.book();\n\n        bookings.add(booking);\n        notifyObservers(booking);\n        return booking;\n    }\n\n    private void notifyObservers(Booking booking) {\n        for (BookingObserver observer : observers) {\n            observer.update(booking);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/HotelManagementDemo.java",
    "content": "package hotelmanagementsystem;\n\nimport hotelmanagementsystem.enums.RoomStyle;\nimport hotelmanagementsystem.enums.RoomType;\nimport hotelmanagementsystem.factory.RoomFactory;\nimport hotelmanagementsystem.model.Guest;\nimport hotelmanagementsystem.observer.EmailNotifier;\nimport hotelmanagementsystem.observer.SmsNotifier;\n\nimport java.time.LocalDate;\nimport java.util.List;\n\npublic class HotelManagementDemo {\n    public static void main(String[] args) {\n        // 1. Setup Services and Facade\n        RoomService roomService = new RoomService();\n        BookingService bookingService = new BookingService();\n        PaymentService paymentService = new PaymentService();\n\n        // Register observers for the booking service\n        bookingService.addObserver(new EmailNotifier());\n        bookingService.addObserver(new SmsNotifier());\n\n        HotelManagerFacade hotelManager = new HotelManagerFacade(roomService, bookingService, paymentService);\n\n        // 2. Populate hotel with rooms using the Factory\n        roomService.addRoom(RoomFactory.createRoom(\"101\", \"SINGLE\", \"STANDARD\", 100));\n        roomService.addRoom(RoomFactory.createRoom(\"102\", \"SINGLE\", \"DELUXE\", 120));\n        roomService.addRoom(RoomFactory.createRoom(\"201\", \"DOUBLE\", \"STANDARD\", 150));\n        roomService.addRoom(RoomFactory.createRoom(\"202\", \"DOUBLE\", \"DELUXE\", 180));\n        roomService.addRoom(RoomFactory.createRoom(\"301\", \"SUITE\", \"OCEAN_VIEW\", 300));\n\n        System.out.println(\"----------- SCENARIO 1: Successful Booking with Amenities -----------\");\n        Guest guest1 = new Guest(\"G123\", \"John Doe\", \"john.doe@example.com\");\n        hotelManager.bookRoom(\n                guest1,\n                RoomType.DOUBLE,\n                RoomStyle.DELUXE,\n                LocalDate.now(),\n                LocalDate.now().plusDays(3),\n                List.of(\"Breakfast\", \"Spa\")\n        );\n\n        System.out.println(\"\\n----------- SCENARIO 2: Attempt to book the same room (State Pattern) -----------\");\n        Guest guest2 = new Guest(\"G456\", \"Jane Smith\", \"jane.smith@example.com\");\n        hotelManager.bookRoom(\n                guest2,\n                RoomType.DOUBLE,\n                RoomStyle.DELUXE,\n                LocalDate.now(),\n                LocalDate.now().plusDays(2),\n                List.of()\n        );\n\n        System.out.println(\"\\n----------- SCENARIO 3: Check-out and make room available again (State Pattern) -----------\");\n        // Room 202 was booked by John Doe\n        System.out.println(\"Initial state of Room 202: \" + roomService.findRoomByNumber(\"202\"));\n        hotelManager.checkOut(\"202\");\n        System.out.println(\"State of Room 202 after checkout: \" + roomService.findRoomByNumber(\"202\"));\n\n        System.out.println(\"\\n----------- SCENARIO 4: Book the now available room -----------\");\n        hotelManager.bookRoom(\n                guest2,\n                RoomType.DOUBLE,\n                RoomStyle.DELUXE,\n                LocalDate.now(),\n                LocalDate.now().plusDays(2),\n                List.of()\n        );\n\n        System.out.println(\"\\n----------- SCENARIO 5: Room under maintenance (State Pattern) -----------\");\n        System.out.println(\"State of Room 101: \" + roomService.findRoomByNumber(\"101\"));\n        roomService.findRoomByNumber(\"101\").markForMaintenance();\n        System.out.println(\"State of Room 101 after marking for maintenance: \" + roomService.findRoomByNumber(\"101\"));\n        Guest guest3 = new Guest(\"G789\", \"Peter Jones\", \"peter.jones@example.com\");\n        hotelManager.bookRoom(guest3, RoomType.SINGLE, RoomStyle.STANDARD, LocalDate.now(), LocalDate.now().plusDays(1), List.of());\n    }\n}\n\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/HotelManagerFacade.java",
    "content": "package hotelmanagementsystem;\n\nimport hotelmanagementsystem.decorator.Bookable;\nimport hotelmanagementsystem.decorator.BreakfastDecorator;\nimport hotelmanagementsystem.decorator.RoomBooking;\nimport hotelmanagementsystem.decorator.SpaDecorator;\nimport hotelmanagementsystem.enums.RoomStyle;\nimport hotelmanagementsystem.enums.RoomType;\nimport hotelmanagementsystem.model.Booking;\nimport hotelmanagementsystem.model.Guest;\nimport hotelmanagementsystem.model.Room;\nimport hotelmanagementsystem.specification.RoomAvailableSpecification;\nimport hotelmanagementsystem.specification.RoomStyleSpecification;\nimport hotelmanagementsystem.specification.RoomTypeSpecification;\nimport hotelmanagementsystem.specification.Specification;\n\nimport java.time.LocalDate;\nimport java.util.List;\nimport java.util.Optional;\n\npublic class HotelManagerFacade {\n    private final RoomService roomService;\n    private final BookingService bookingService;\n    private final PaymentService paymentService;\n\n    public HotelManagerFacade(RoomService roomService, BookingService bookingService, PaymentService paymentService) {\n        this.roomService = roomService;\n        this.bookingService = bookingService;\n        this.paymentService = paymentService;\n    }\n\n    public Booking bookRoom(Guest guest, RoomType type, RoomStyle style, LocalDate start, LocalDate end, List<String> amenities) {\n        // 1. Find an available room using the Specification pattern\n        Specification<Room> searchSpec = new RoomAvailableSpecification()\n                .and(new RoomTypeSpecification(type))\n                .and(new RoomStyleSpecification(style));\n\n        Optional<Room> availableRoom = roomService.findRooms(searchSpec).stream().findFirst();\n\n        if (availableRoom.isPresent()) {\n            Room room = availableRoom.get();\n\n            // 2. Create a booking\n            Booking booking = bookingService.createBooking(guest, room, start, end);\n\n            // 3. Use Decorator pattern to calculate total cost with amenities\n            Bookable bookable = new RoomBooking(room);\n            for (String amenity : amenities) {\n                if (\"breakfast\".equalsIgnoreCase(amenity)) {\n                    bookable = new BreakfastDecorator(bookable);\n                } else if (\"spa\".equalsIgnoreCase(amenity)) {\n                    bookable = new SpaDecorator(bookable);\n                }\n            }\n\n            System.out.println(\"Total Cost: \" + bookable.getDescription() + \" = $\" + String.format(\"%.2f\", bookable.getCost()));\n\n            // 4. Process payment\n            paymentService.processPayment(bookable.getCost());\n\n            return booking;\n        } else {\n            System.out.println(\"Sorry, no rooms available matching your criteria.\");\n            return null;\n        }\n    }\n\n    public void checkIn(String bookingId) {\n        // In a real system, you'd fetch the booking by ID\n        // For this demo, we'll find a room and check it in\n        System.out.println(\"Check-in process for booking ID (not implemented for demo): \" + bookingId);\n    }\n\n    public void checkOut(String roomNumber) {\n        Room room = roomService.findRoomByNumber(roomNumber);\n        if(room != null) {\n            room.checkOut();\n        } else {\n            System.out.println(\"Room \" + roomNumber + \" not found.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/PaymentService.java",
    "content": "package hotelmanagementsystem;\n\npublic class PaymentService {\n    public boolean processPayment(double amount) {\n        System.out.println(\"Processing payment of $\" + String.format(\"%.2f\", amount) + \"...\");\n        // In a real system, this would interact with a payment gateway\n        System.out.println(\"Payment successful.\");\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/README.md",
    "content": "# Hotel Management System (LLD)\n\n## Problem Statement\n\nDesign and implement a Hotel Management System that manages hotel rooms, reservations, and guest information. The system should handle room bookings, check-ins, check-outs, and maintain room status.\n\n---\n\n## Requirements\n\n1. **Room Management:**\n   - Track different types of rooms (STANDARD, DELUXE, SUITE)\n   - Manage room availability and status\n   - Handle room pricing and features\n\n2. **Reservation Management:**\n   - Create and manage reservations\n   - Handle check-in and check-out processes\n   - Track reservation status (CONFIRMED, CANCELLED, CHECKED_IN, CHECKED_OUT)\n\n3. **Guest Management:**\n   - Store guest information\n   - Track guest history\n   - Handle guest preferences\n\n4. **Room Status Tracking:**\n   - Monitor room availability (AVAILABLE, OCCUPIED, MAINTENANCE)\n   - Update room status based on reservations\n   - Handle room maintenance requests\n\n5. **Payment Integration:**\n   - Process room payments\n   - Handle different payment methods\n   - Generate invoices\n\n---\n\n## Core Entities\n\n### 1. HotelManagementSystem\n- **Fields:** List<Room> rooms, List<Reservation> reservations, List<Guest> guests\n- **Methods:** \n  - addRoom()\n  - makeReservation()\n  - checkIn()\n  - checkOut()\n  - getAvailableRooms()\n  - cancelReservation()\n\n### 2. Room\n- **Fields:** String roomNumber, RoomType type, double price, RoomStatus status\n- **Methods:** \n  - isAvailable()\n  - updateStatus()\n  - getPrice()\n\n### 3. Guest\n- **Fields:** String id, String name, String email, String phoneNumber\n- **Methods:** \n  - updateProfile()\n  - getReservations()\n\n### 4. Reservation\n- **Fields:** String id, Guest guest, Room room, Date checkInDate, Date checkOutDate, ReservationStatus status\n- **Methods:** \n  - confirm()\n  - cancel()\n  - checkIn()\n  - checkOut()\n\n### 5. RoomType (Enum)\n- **Values:** STANDARD, DELUXE, SUITE\n\n### 6. RoomStatus (Enum)\n- **Values:** AVAILABLE, OCCUPIED, MAINTENANCE\n\n### 7. ReservationStatus (Enum)\n- **Values:** CONFIRMED, CANCELLED, CHECKED_IN, CHECKED_OUT\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/HotelManagementSystem-class-diagram.png)\n\n---\n\n## Example Usage\n\n```java\nHotelManagementSystem system = new HotelManagementSystem();\n\n// Add a room\nRoom room = system.addRoom(\"101\", RoomType.DELUXE, 150.0);\n\n// Create a guest\nGuest guest = new Guest(\"John Doe\", \"john@example.com\", \"1234567890\");\n\n// Make a reservation\nReservation reservation = system.makeReservation(guest, room, checkInDate, checkOutDate);\n\n// Check in\nsystem.checkIn(reservation);\n\n// Check out\nsystem.checkOut(reservation);\n```\n\n---\n\n## Demo\n\nSee `HotelManagementSystemDemo.java` for a sample usage and simulation of the hotel management system.\n\n---\n\n## Extending the Framework\n\n- **Add room service:** Track room service requests and delivery\n- **Add housekeeping:** Manage housekeeping schedules and tasks\n- **Add loyalty program:** Implement guest loyalty points and rewards\n- **Add inventory management:** Track hotel supplies and amenities\n- **Add reporting system:** Generate occupancy and revenue reports\n- **Add notification system:** Send booking confirmations and reminders\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For the hotel management system instance\n- **Factory Pattern:** For creating different types of rooms\n- **Observer Pattern:** For room status updates and notifications\n- **Strategy Pattern:** For different pricing strategies\n\n---\n\n## Exception Handling\n\n- **RoomNotAvailableException:** Thrown when trying to book an unavailable room\n- **InvalidReservationException:** Thrown when reservation details are invalid\n- **CheckInException:** Thrown when check-in process fails\n- **CheckOutException:** Thrown when check-out process fails\n\n---"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/RoomService.java",
    "content": "package hotelmanagementsystem;\n\nimport hotelmanagementsystem.model.Room;\nimport hotelmanagementsystem.specification.Specification;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class RoomService {\n    private final List<Room> rooms = new ArrayList<>();\n\n    public void addRoom(Room room) {\n        rooms.add(room);\n    }\n\n    public List<Room> findRooms(Specification<Room> spec) {\n        return rooms.stream()\n                .filter(spec::isSatisfiedBy)\n                .collect(Collectors.toList());\n    }\n\n    public Room findRoomByNumber(String roomNumber) {\n        return rooms.stream()\n                .filter(r -> r.getRoomNumber().equals(roomNumber))\n                .findFirst()\n                .orElse(null);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/decorator/AmenityDecorator.java",
    "content": "package hotelmanagementsystem.decorator;\n\npublic abstract class AmenityDecorator implements Bookable {\n    protected Bookable bookable;\n\n    public AmenityDecorator(Bookable bookable) {\n        this.bookable = bookable;\n    }\n\n    @Override\n    public double getCost() {\n        return bookable.getCost();\n    }\n\n    @Override\n    public String getDescription() {\n        return bookable.getDescription();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/decorator/Bookable.java",
    "content": "package hotelmanagementsystem.decorator;\n\npublic interface Bookable {\n    double getCost();\n    String getDescription();\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/decorator/BreakfastDecorator.java",
    "content": "package hotelmanagementsystem.decorator;\n\npublic class BreakfastDecorator extends AmenityDecorator {\n    private static final double BREAKFAST_COST = 25.0;\n\n    public BreakfastDecorator(Bookable bookable) {\n        super(bookable);\n    }\n\n    @Override\n    public double getCost() {\n        return super.getCost() + BREAKFAST_COST;\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \" with Breakfast\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/decorator/RoomBooking.java",
    "content": "package hotelmanagementsystem.decorator;\n\nimport hotelmanagementsystem.model.Room;\n\npublic class RoomBooking implements Bookable {\n    private final Room room;\n\n    public RoomBooking(Room room) {\n        this.room = room;\n    }\n\n    @Override\n    public double getCost() {\n        return room.getPrice();\n    }\n\n    @Override\n    public String getDescription() {\n        return room.getStyle() + \" \" + room.getType() + \" Room\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/decorator/SpaDecorator.java",
    "content": "package hotelmanagementsystem.decorator;\n\npublic class SpaDecorator extends AmenityDecorator {\n    private static final double SPA_COST = 50.0;\n\n    public SpaDecorator(Bookable bookable) {\n        super(bookable);\n    }\n\n    @Override\n    public double getCost() {\n        return super.getCost() + SPA_COST;\n    }\n\n\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \" with Spa Access\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/enums/BookingStatus.java",
    "content": "package hotelmanagementsystem.enums;\n\npublic enum BookingStatus {\n    REQUESTED, CONFIRMED, CHECKED_IN, CHECKED_OUT, CANCELLED\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/enums/RoomStyle.java",
    "content": "package hotelmanagementsystem.enums;\n\npublic enum RoomStyle {\n    STANDARD,\n    DELUXE,\n    OCEAN_VIEW\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/enums/RoomType.java",
    "content": "package hotelmanagementsystem.enums;\n\npublic enum RoomType {\n    SINGLE,\n    DOUBLE,\n    SUITE\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/factory/RoomFactory.java",
    "content": "package hotelmanagementsystem.factory;\n\nimport hotelmanagementsystem.enums.RoomStyle;\nimport hotelmanagementsystem.enums.RoomType;\nimport hotelmanagementsystem.model.Room;\n\npublic class RoomFactory {\n    public static Room createRoom(String roomNumber, String type, String style, double price) {\n        RoomType roomType = RoomType.valueOf(type.toUpperCase());\n        RoomStyle roomStyle = RoomStyle.valueOf(style.toUpperCase());\n        return new Room(roomNumber, roomType, roomStyle, price);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/model/Booking.java",
    "content": "package hotelmanagementsystem.model;\n\nimport hotelmanagementsystem.enums.BookingStatus;\n\nimport java.time.LocalDate;\n\npublic class Booking {\n    private final String bookingId;\n    private final Guest guest;\n    private final Room room;\n    private final LocalDate startDate;\n    private final LocalDate endDate;\n    private BookingStatus status;\n\n    public Booking(String bookingId, Guest guest, Room room, LocalDate startDate, LocalDate endDate) {\n        this.bookingId = bookingId;\n        this.guest = guest;\n        this.room = room;\n        this.startDate = startDate;\n        this.endDate = endDate;\n        this.status = BookingStatus.CONFIRMED;\n    }\n\n    public void checkIn() { this.status = BookingStatus.CHECKED_IN; }\n    public void checkOut() { this.status = BookingStatus.CHECKED_OUT; }\n    public void cancel() { this.status = BookingStatus.CANCELLED; }\n\n    public String getBookingId() { return bookingId; }\n    public Guest getGuest() { return guest; }\n    public Room getRoom() { return room; }\n    public LocalDate getStartDate() { return startDate; }\n    public LocalDate getEndDate() { return endDate; }\n    public BookingStatus getStatus() { return status; }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/model/Guest.java",
    "content": "package hotelmanagementsystem.model;\n\npublic class Guest {\n    private final String id;\n    private final String name;\n    private final String email;\n\n    public Guest(String id, String name, String email) {\n        this.id = id;\n        this.name = name;\n        this.email = email;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public String getEmail() { return email; }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/model/Room.java",
    "content": "package hotelmanagementsystem.model;\n\nimport hotelmanagementsystem.enums.RoomStyle;\nimport hotelmanagementsystem.enums.RoomType;\nimport hotelmanagementsystem.state.AvailableState;\nimport hotelmanagementsystem.state.RoomState;\n\npublic class Room {\n    private final String roomNumber;\n    private final RoomType type;\n    private final RoomStyle style;\n    private final double price;\n    private RoomState state;\n\n    public Room(String roomNumber, RoomType type, RoomStyle style, double price) {\n        this.roomNumber = roomNumber;\n        this.type = type;\n        this.style = style;\n        this.price = price;\n        this.state = new AvailableState(); // Initial state\n    }\n\n    public void setState(RoomState state) {\n        this.state = state;\n    }\n\n    public void book() {\n        state.book(this);\n    }\n\n    public void checkIn() {\n        state.checkIn(this);\n    }\n\n    public void checkOut() {\n        state.checkOut(this);\n    }\n\n    public void markForMaintenance() {\n        state.markForMaintenance(this);\n    }\n\n    public String getRoomNumber() { return roomNumber; }\n    public RoomType getType() { return type; }\n    public RoomStyle getStyle() { return style; }\n    public double getPrice() { return price; }\n    public RoomState getState() { return state; }\n\n    @Override\n    public String toString() {\n        return \"Room [Number=\" + roomNumber + \", Type=\" + type + \", Style=\" + style + \", Price=$\" + price + \", State=\" + state.getClass().getSimpleName() + \"]\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/observer/BookingObserver.java",
    "content": "package hotelmanagementsystem.observer;\n\nimport hotelmanagementsystem.model.Booking;\n\npublic interface BookingObserver {\n    void update(Booking booking);\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/observer/EmailNotifier.java",
    "content": "package hotelmanagementsystem.observer;\n\nimport hotelmanagementsystem.model.Booking;\n\npublic class EmailNotifier implements BookingObserver {\n    @Override\n    public void update(Booking booking) {\n        System.out.println(\"--- Email Notification ---\");\n        System.out.println(\"To: \" + booking.getGuest().getEmail());\n        System.out.println(\"Subject: Booking Confirmation \" + booking.getBookingId());\n        System.out.println(\"Dear \" + booking.getGuest().getName() + \",\");\n        System.out.println(\"Your booking for Room \" + booking.getRoom().getRoomNumber() + \" is confirmed.\");\n        System.out.println(\"--------------------------\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/observer/SmsNotifier.java",
    "content": "package hotelmanagementsystem.observer;\n\nimport hotelmanagementsystem.model.Booking;\n\npublic class SmsNotifier implements BookingObserver {\n    @Override\n    public void update(Booking booking) {\n        System.out.println(\"--- SMS Notification ---\");\n        System.out.println(\"To: [Guest's Phone Number]\"); // Assuming guest has a phone number\n        System.out.println(\"Message: Booking \" + booking.getBookingId() + \" for Room \" + booking.getRoom().getRoomNumber() + \" confirmed!\");\n        System.out.println(\"------------------------\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/payment/CashPayment.java",
    "content": "package hotelmanagementsystem.payment;\n\npublic class CashPayment implements Payment {\n    @Override\n    public boolean processPayment(double amount) {\n        // Process cash payment\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/payment/CreditCardPayment.java",
    "content": "package hotelmanagementsystem.payment;\n\npublic class CreditCardPayment implements Payment {\n    @Override\n    public boolean processPayment(double amount) {\n        // Process credit card payment\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/payment/Payment.java",
    "content": "package hotelmanagementsystem.payment;\n\npublic interface Payment {\n    boolean processPayment(double amount);\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/AbstractSpecification.java",
    "content": "package hotelmanagementsystem.specification;\n\npublic abstract class AbstractSpecification<T> implements Specification<T> {\n    public Specification<T> and(Specification<T> other) {\n        return new AndSpecification<>(this, other);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/AndSpecification.java",
    "content": "package hotelmanagementsystem.specification;\n\npublic class AndSpecification<T> extends AbstractSpecification<T> {\n    private final Specification<T> spec1;\n    private final Specification<T> spec2;\n\n    public AndSpecification(Specification<T> spec1, Specification<T> spec2) {\n        this.spec1 = spec1;\n        this.spec2 = spec2;\n    }\n\n    @Override\n    public boolean isSatisfiedBy(T item) {\n        return spec1.isSatisfiedBy(item) && spec2.isSatisfiedBy(item);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/RoomAvailableSpecification.java",
    "content": "package hotelmanagementsystem.specification;\n\nimport hotelmanagementsystem.model.Room;\nimport hotelmanagementsystem.state.AvailableState;\n\npublic class RoomAvailableSpecification extends AbstractSpecification<Room> {\n    @Override\n    public boolean isSatisfiedBy(Room item) {\n        return item.getState() instanceof AvailableState;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/RoomStyleSpecification.java",
    "content": "package hotelmanagementsystem.specification;\n\nimport hotelmanagementsystem.enums.RoomStyle;\nimport hotelmanagementsystem.model.Room;\n\npublic class RoomStyleSpecification extends AbstractSpecification<Room> {\n    private final RoomStyle style;\n\n    public RoomStyleSpecification(RoomStyle style) {\n        this.style = style;\n    }\n\n    @Override\n    public boolean isSatisfiedBy(Room item) {\n        return item.getStyle() == style;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/RoomTypeSpecification.java",
    "content": "package hotelmanagementsystem.specification;\n\nimport hotelmanagementsystem.enums.RoomType;\nimport hotelmanagementsystem.model.Room;\n\npublic class RoomTypeSpecification extends AbstractSpecification<Room> {\n    private final RoomType type;\n\n    public RoomTypeSpecification(RoomType type) {\n        this.type = type;\n    }\n\n    @Override\n    public boolean isSatisfiedBy(Room item) {\n        return item.getType() == type;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/specification/Specification.java",
    "content": "package hotelmanagementsystem.specification;\n\npublic interface Specification<T> {\n    boolean isSatisfiedBy(T item);\n    Specification<T> and(Specification<T> other);\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/state/AvailableState.java",
    "content": "package hotelmanagementsystem.state;\n\nimport hotelmanagementsystem.model.Room;\n\npublic class AvailableState implements RoomState {\n    @Override\n    public void book(Room room) {\n        System.out.println(\"Booking room \" + room.getRoomNumber() + \".\");\n        room.setState(new OccupiedState());\n    }\n\n    @Override\n    public void checkIn(Room room) {\n        System.out.println(\"Checking into room \" + room.getRoomNumber() + \".\");\n        room.setState(new OccupiedState());\n    }\n\n    @Override\n    public void checkOut(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is not occupied.\");\n    }\n\n    @Override\n    public void markForMaintenance(Room room) {\n        System.out.println(\"Marking room \" + room.getRoomNumber() + \" for maintenance.\");\n        room.setState(new MaintenanceState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/state/MaintenanceState.java",
    "content": "package hotelmanagementsystem.state;\n\nimport hotelmanagementsystem.model.Room;\n\npublic class MaintenanceState implements RoomState {\n    @Override\n    public void book(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is under maintenance.\");\n    }\n\n    @Override\n    public void checkIn(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is under maintenance.\");\n    }\n\n    @Override\n    public void checkOut(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is under maintenance.\");\n    }\n\n    @Override\n    public void markForMaintenance(Room room) {\n        System.out.println(\"Room \" + room.getRoomNumber() + \" is already under maintenance. Marking it as available now.\");\n        room.setState(new AvailableState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/state/OccupiedState.java",
    "content": "package hotelmanagementsystem.state;\n\nimport hotelmanagementsystem.model.Room;\n\npublic class OccupiedState implements RoomState {\n    @Override\n    public void book(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is already occupied.\");\n    }\n\n    @Override\n    public void checkIn(Room room) {\n        System.out.println(\"Error: Room \" + room.getRoomNumber() + \" is already checked in.\");\n    }\n\n    @Override\n    public void checkOut(Room room) {\n        System.out.println(\"Checking out of room \" + room.getRoomNumber() + \".\");\n        room.setState(new AvailableState());\n    }\n\n    @Override\n    public void markForMaintenance(Room room) {\n        System.out.println(\"Error: Cannot mark an occupied room for maintenance. Please check out first.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/hotelmanagementsystem/state/RoomState.java",
    "content": "package hotelmanagementsystem.state;\n\nimport hotelmanagementsystem.model.Room;\n\npublic interface RoomState {\n    void book(Room room);\n    void checkIn(Room room);\n    void checkOut(Room room);\n    void markForMaintenance(Room room);\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/LibraryManagementDemo.java",
    "content": "package librarymanagementsystem;\n\nimport librarymanagementsystem.enums.ItemType;\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Member;\nimport librarymanagementsystem.strategy.SearchByAuthorStrategy;\nimport librarymanagementsystem.strategy.SearchByTitleStrategy;\n\nimport java.util.List;\n\npublic class LibraryManagementDemo {\n    public static void main(String[] args) {\n        LibraryManagementSystem library = LibraryManagementSystem.getInstance();\n\n        // --- Setup: Add items and members using the Facade ---\n        System.out.println(\"=== Setting up the Library ===\");\n\n        List<BookCopy> hobbitCopies = library.addItem(ItemType.BOOK, \"B001\", \"The Hobbit\", \"J.R.R. Tolkien\", 2);\n        List<BookCopy> duneCopies = library.addItem(ItemType.BOOK, \"B002\", \"Dune\", \"Frank Herbert\", 1);\n        List<BookCopy> natGeoCopies = library.addItem(ItemType.MAGAZINE, \"M001\", \"National Geographic\", \"NatGeo Society\", 3);\n\n        Member alice = library.addMember(\"MEM01\", \"Alice\");\n        Member bob = library.addMember(\"MEM02\", \"Bob\");\n        Member charlie = library.addMember(\"MEM03\", \"Charlie\");\n        library.printCatalog();\n\n        // --- Scenario 1: Searching (Strategy Pattern) ---\n        System.out.println(\"\\n=== Scenario 1: Searching for Items ===\");\n        System.out.println(\"Searching for title 'Dune':\");\n        library.search(\"Dune\", new SearchByTitleStrategy())\n                .forEach(item -> System.out.println(\"Found: \" + item.getTitle()));\n        System.out.println(\"\\nSearching for author 'Tolkien':\");\n        library.search(\"Tolkien\", new SearchByAuthorStrategy())\n                .forEach(item -> System.out.println(\"Found: \" + item.getTitle()));\n\n        // --- Scenario 2: Checkout and Return (State Pattern) ---\n        System.out.println(\"\\n\\n=== Scenario 2: Checkout and Return ===\");\n        library.checkout(alice.getId(), hobbitCopies.get(0).getId()); // Alice checks out The Hobbit copy 1\n        library.checkout(bob.getId(), duneCopies.get(0).getId()); // Bob checks out Dune copy 1\n        library.printCatalog();\n\n        System.out.println(\"Attempting to checkout an already checked-out book:\");\n        library.checkout(charlie.getId(), hobbitCopies.get(0).getId()); // Charlie fails to check out The Hobbit copy 1\n\n        System.out.println(\"\\nAlice returns The Hobbit:\");\n        library.returnItem(hobbitCopies.get(0).getId());\n        library.printCatalog();\n\n        // --- Scenario 3: Holds and Notifications (Observer Pattern) ---\n        System.out.println(\"\\n\\n=== Scenario 3: Placing a Hold ===\");\n        System.out.println(\"Dune is checked out by Bob. Charlie places a hold.\");\n        library.placeHold(charlie.getId(), \"B002\"); // Charlie places a hold on Dune\n\n        System.out.println(\"\\nBob returns Dune. Charlie should be notified.\");\n        library.returnItem(duneCopies.get(0).getId()); // Bob returns Dune\n\n        System.out.println(\"\\nCharlie checks out the book that was on hold for him.\");\n        library.checkout(charlie.getId(), duneCopies.get(0).getId());\n\n        System.out.println(\"\\nTrying to check out the same on-hold item by another member (Alice):\");\n        library.checkout(alice.getId(), duneCopies.get(0).getId()); // Alice fails, it's checked out by Charlie now.\n\n        library.printCatalog();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/LibraryManagementSystem.java",
    "content": "package librarymanagementsystem;\n\nimport librarymanagementsystem.enums.ItemType;\nimport librarymanagementsystem.factory.ItemFactory;\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.LibraryItem;\nimport librarymanagementsystem.models.Member;\nimport librarymanagementsystem.strategy.SearchStrategy;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class LibraryManagementSystem {\n    private static final LibraryManagementSystem INSTANCE = new LibraryManagementSystem();\n    private final Map<String, LibraryItem> catalog = new HashMap<>();\n    private final Map<String, Member> members = new HashMap<>();\n    private final Map<String, BookCopy> copies = new HashMap<>();\n\n    private LibraryManagementSystem() {}\n    public static LibraryManagementSystem getInstance() { return INSTANCE; }\n\n    // --- Item Management ---\n    public List<BookCopy> addItem(ItemType type, String id, String title, String author, int numCopies) {\n        List<BookCopy> bookCopies = new ArrayList<>();\n        LibraryItem item = ItemFactory.createItem(type, id, title, author);\n        catalog.put(id, item);\n        for (int i = 0; i < numCopies; i++) {\n            String copyId = id + \"-c\" + (i + 1);\n            BookCopy copy = new BookCopy(copyId, item);\n            copies.put(copyId, new BookCopy(copyId, item));\n            bookCopies.add(copy);\n        }\n        System.out.println(\"Added \" + numCopies + \" copies of '\" + title + \"'\");\n        return bookCopies;\n    }\n\n    // --- User Management ---\n    public Member addMember(String id, String name) {\n        Member member = new Member(id, name);\n        members.put(id, member);\n        return member;\n    }\n\n    // --- Core Actions ---\n    public void checkout(String memberId, String copyId) {\n        Member member = members.get(memberId);\n        BookCopy copy = copies.get(copyId);\n        if (member != null && copy != null) {\n            copy.checkout(member);\n        } else {\n            System.out.println(\"Error: Invalid member or copy ID.\");\n        }\n    }\n\n    public void returnItem(String copyId) {\n        BookCopy copy = copies.get(copyId);\n        if (copy != null) {\n            copy.returnItem();\n        } else {\n            System.out.println(\"Error: Invalid copy ID.\");\n        }\n    }\n\n    public void placeHold(String memberId, String itemId) {\n        Member member = members.get(memberId);\n        LibraryItem item = catalog.get(itemId);\n        if (member != null && item != null) {\n            // Place hold on any copy that is checked out\n            item.getCopies().stream()\n                    .filter(c -> !c.isAvailable())\n                    .findFirst()\n                    .ifPresent(copy -> copy.placeHold(member));\n        }\n    }\n\n    // --- Search (Using Strategy Pattern) ---\n    public List<LibraryItem> search(String query, SearchStrategy strategy) {\n        return strategy.search(query, new ArrayList<>(catalog.values()));\n    }\n\n    public void printCatalog() {\n        System.out.println(\"\\n--- Library Catalog ---\");\n        catalog.values().forEach(item -> System.out.printf(\"ID: %s, Title: %s, Author/Publisher: %s, Available: %d\\n\",\n                item.getId(), item.getTitle(), item.getAuthorOrPublisher(), item.getAvailableCopyCount()));\n        System.out.println(\"-----------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/README.md",
    "content": "# Library Management System (LLD)\n\n## Problem Statement\n\nDesign and implement a Library Management System that allows members to borrow and return books, manages book inventory, tracks loans, and supports catalog search.\n\n---\n\n## Requirements\n\n- **Book Management:** The system manages a catalog of books, each with multiple copies.\n- **Member Management:** The system manages library members who can borrow and return books.\n- **Loan Management:** The system tracks which member has borrowed which book copy and when.\n- **Borrowing and Returning:** Members can borrow available book copies and return them.\n- **Catalog Search:** Members can search for books by title, author, or ISBN.\n- **Extensibility:** Easy to add new features such as reservations, fines, or notifications.\n\n---\n\n## Core Entities\n\n- **LibraryManagementSystem:** Main class that manages books, members, loans, and the catalog.\n- **Book:** Represents a book with title, author, ISBN, and other metadata.\n- **BookCopy:** Represents a physical copy of a book, with a unique copy ID and availability status.\n- **Member:** Represents a library member with a unique ID and name.\n- **Loan:** Represents a loan record for a book copy borrowed by a member.\n- **Catalog:** Manages the collection of books and supports search functionality.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/LibraryManagementSystem-class-diagram.png)\n\n### 1. LibraryManagementSystem\n- **Fields:** List<Book> books, List<Member> members, List<Loan> loans, Catalog catalog\n- **Methods:** addBook(Book), addMember(Member), borrowBook(Member, Book), returnBook(Member, BookCopy), getLoans(Member), searchBooks(String query), etc.\n\n### 2. Book\n- **Fields:** String title, String author, String isbn, List<BookCopy> copies\n\n### 3. BookCopy\n- **Fields:** int copyId, Book book, boolean isAvailable\n\n### 4. Member\n- **Fields:** int id, String name, List<Loan> loans\n\n### 5. Loan\n- **Fields:** int id, Member member, BookCopy bookCopy, Date loanDate, Date returnDate\n\n### 6. Catalog\n- **Fields:** List<Book> books\n- **Methods:** searchByTitle(String), searchByAuthor(String), searchByISBN(String)\n\n---\n\n## Example Usage\n\n```java\nLibraryManagementSystem system = new LibraryManagementSystem();\nBook book = new Book(\"Effective Java\", \"Joshua Bloch\", \"978-0134685991\");\nsystem.addBook(book);\n\nMember alice = new Member(1, \"Alice\");\nsystem.addMember(alice);\n\nsystem.borrowBook(alice, book);\nsystem.returnBook(alice, book.getCopies().get(0));\n```\n\n---\n\n## Demo\n\nSee `LibraryManagementSystemDemo.java` for a sample usage and simulation of the library management system.\n\n---\n\n## Extending the Framework\n\n- **Add reservations:** Allow members to reserve books that are currently checked out.\n- **Add fines:** Track overdue books and calculate fines.\n- **Add notifications:** Notify members about due dates, reservations, or new arrivals.\n\n---"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/TransactionService.java",
    "content": "package librarymanagementsystem;\n\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Loan;\nimport librarymanagementsystem.models.Member;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class TransactionService {\n    private static final TransactionService INSTANCE = new TransactionService();\n    private final Map<String, Loan> activeLoans = new HashMap<>(); // Key: BookCopy ID\n\n    private TransactionService() {}\n    public static TransactionService getInstance() { return INSTANCE; }\n\n    public void createLoan(BookCopy copy, Member member) {\n        if (activeLoans.containsKey(copy.getId())) {\n            throw new IllegalStateException(\"This copy is already on loan.\");\n        }\n        Loan loan = new Loan(copy, member);\n        activeLoans.put(copy.getId(), loan);\n        member.addLoan(loan);\n    }\n\n    public void endLoan(BookCopy copy) {\n        Loan loan = activeLoans.remove(copy.getId());\n        if (loan != null) {\n            loan.getMember().removeLoan(loan);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/enums/ItemType.java",
    "content": "package librarymanagementsystem.enums;\n\npublic enum ItemType {\n    BOOK,\n    MAGAZINE\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/factory/ItemFactory.java",
    "content": "package librarymanagementsystem.factory;\n\nimport librarymanagementsystem.enums.ItemType;\nimport librarymanagementsystem.models.Book;\nimport librarymanagementsystem.models.LibraryItem;\nimport librarymanagementsystem.models.Magazine;\n\npublic class ItemFactory {\n    public static LibraryItem createItem(ItemType type, String id, String title, String author) {\n        switch (type) {\n            case BOOK: return new Book(id, title, author);\n            case MAGAZINE: return new Magazine(id, title, author); // Author might be publisher here\n            default: throw new IllegalArgumentException(\"Unknown item type.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/Book.java",
    "content": "package librarymanagementsystem.models;\n\npublic class Book extends LibraryItem {\n    private final String author;\n\n    public Book(String id, String title, String author) {\n        super(id, title);\n        this.author = author;\n    }\n\n    @Override\n    public String getAuthorOrPublisher() { return author; }\n}"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/BookCopy.java",
    "content": "package librarymanagementsystem.models;\n\n\nimport librarymanagementsystem.state.AvailableState;\nimport librarymanagementsystem.state.ItemState;\n\npublic class BookCopy {\n    private final String id;\n    private final LibraryItem item;\n    private ItemState currentState;\n\n    public BookCopy(String id, LibraryItem item) {\n        this.id = id;\n        this.item = item;\n        this.currentState = new AvailableState();\n        item.addCopy(this);\n    }\n\n    public void checkout(Member member) { currentState.checkout(this, member); }\n    public void returnItem() { currentState.returnItem(this); }\n    public void placeHold(Member member) { currentState.placeHold(this, member); }\n\n    public void setState(ItemState state) { this.currentState = state; }\n    public String getId() { return id; }\n    public LibraryItem getItem() { return item; }\n    public boolean isAvailable() { return currentState instanceof AvailableState; }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/LibraryItem.java",
    "content": "package librarymanagementsystem.models;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class LibraryItem {\n    private final String id;\n    private final String title;\n    protected final List<BookCopy> copies = new ArrayList<>();\n    // Observer Pattern: List of members waiting for this item\n    private final List<Member> observers = new ArrayList<>();\n\n    public LibraryItem(String id, String title) {\n        this.id = id;\n        this.title = title;\n    }\n\n    public void addCopy(BookCopy copy) { this.copies.add(copy); }\n    public void addObserver(Member member) { observers.add(member); }\n    public void removeObserver(Member member) { observers.remove(member); }\n\n    public void notifyObservers() {\n        System.out.println(\"Notifying \" + observers.size() + \" observers for '\" + title + \"'...\");\n        // Use a copy to avoid ConcurrentModificationException if observer unsubscribes\n        new ArrayList<>(observers).forEach(observer -> observer.update(this));\n    }\n\n    public BookCopy getAvailableCopy() {\n        return copies.stream()\n                .filter(BookCopy::isAvailable)\n                .findFirst()\n                .orElse(null);\n    }\n\n    // Getters\n    public String getId() { return id; }\n    public String getTitle() { return title; }\n\n    public List<BookCopy> getCopies() {\n        return copies;\n    }\n\n    public abstract String getAuthorOrPublisher();\n    public long getAvailableCopyCount() {\n        return copies.stream().filter(BookCopy::isAvailable).count();\n    }\n\n    public boolean hasObservers() { return !observers.isEmpty(); }\n    public boolean isObserver(Member member) { return observers.contains(member); }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/Loan.java",
    "content": "package librarymanagementsystem.models;\n\nimport java.time.LocalDate;\n\npublic class Loan {\n    private final BookCopy copy;\n    private final Member member;\n    private final LocalDate checkoutDate;\n\n    public Loan(BookCopy copy, Member member) {\n        this.copy = copy;\n        this.member = member;\n        this.checkoutDate = LocalDate.now();\n    }\n\n    public BookCopy getCopy() { return copy; }\n    public Member getMember() { return member; }\n}"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/Magazine.java",
    "content": "package librarymanagementsystem.models;\n\npublic class Magazine extends LibraryItem {\n    private final String publisher;\n\n    public Magazine(String id, String title, String publisher) {\n        super(id, title);\n        this.publisher = publisher;\n    }\n\n    @Override\n    public String getAuthorOrPublisher() { return publisher; }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/models/Member.java",
    "content": "package librarymanagementsystem.models;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Member {\n    private final String id;\n    private final String name;\n    private final List<Loan> loans = new ArrayList<>();\n\n    public Member(String id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    // Observer update method\n    public void update(LibraryItem item) {\n        System.out.println(\"NOTIFICATION for \" + name + \": The book '\" + item.getTitle() + \"' you placed a hold on is now available!\");\n    }\n\n    public void addLoan(Loan loan) { loans.add(loan); }\n    public void removeLoan(Loan loan) { loans.remove(loan); }\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public List<Loan> getLoans() { return loans; }\n}"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/state/AvailableState.java",
    "content": "package librarymanagementsystem.state;\n\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Member;\nimport librarymanagementsystem.TransactionService;\n\npublic class AvailableState implements ItemState {\n    @Override\n    public void checkout(BookCopy copy, Member member) {\n        TransactionService.getInstance().createLoan(copy, member);\n        copy.setState(new CheckedOutState());\n        System.out.println(copy.getId() + \" checked out by \" + member.getName());\n    }\n\n    @Override\n    public void returnItem(BookCopy c) {\n        System.out.println(\"Cannot return an item that is already available.\");\n    }\n\n    @Override\n    public void placeHold(BookCopy c, Member m) {\n        System.out.println(\"Cannot place hold on an available item. Please check it out.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/state/CheckedOutState.java",
    "content": "package librarymanagementsystem.state;\n\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Member;\nimport librarymanagementsystem.TransactionService;\n\npublic class CheckedOutState implements ItemState {\n    @Override public void checkout(BookCopy c, Member m) { System.out.println(c.getId() + \" is already checked out.\"); }\n\n    @Override\n    public void returnItem(BookCopy copy) {\n        TransactionService.getInstance().endLoan(copy);\n        System.out.println(copy.getId() + \" returned.\");\n        // If there are holds, move to OnHold state. Otherwise, become Available.\n        if (copy.getItem().hasObservers()) {\n            copy.setState(new OnHoldState());\n            copy.getItem().notifyObservers(); // Notify members that item is back but on hold\n        } else {\n            copy.setState(new AvailableState());\n        }\n    }\n\n    @Override\n    public void placeHold(BookCopy copy, Member member) {\n        copy.getItem().addObserver(member);\n        System.out.println(member.getName() + \" placed a hold on '\" + copy.getItem().getTitle() + \"'\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/state/ItemState.java",
    "content": "package librarymanagementsystem.state;\n\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Member;\n\npublic interface ItemState {\n    void checkout(BookCopy copy, Member member);\n    void returnItem(BookCopy copy);\n    void placeHold(BookCopy copy, Member member);\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/state/OnHoldState.java",
    "content": "package librarymanagementsystem.state;\n\nimport librarymanagementsystem.models.BookCopy;\nimport librarymanagementsystem.models.Member;\nimport librarymanagementsystem.TransactionService;\n\npublic class OnHoldState implements ItemState {\n    @Override\n    public void checkout(BookCopy copy, Member member) {\n        // Only a member who placed the hold can check it out.\n        if (copy.getItem().isObserver(member)) {\n            TransactionService.getInstance().createLoan(copy, member);\n            copy.getItem().removeObserver(member); // Remove from waiting list\n            copy.setState(new CheckedOutState());\n            System.out.println(\"Hold fulfilled. \" + copy.getId() + \" checked out by \" + member.getName());\n        } else {\n            System.out.println(\"This item is on hold for another member.\");\n        }\n    }\n\n    @Override\n    public void returnItem(BookCopy c) {\n        System.out.println(\"Invalid action. Item is on hold, not checked out.\");\n    }\n\n    @Override\n    public void placeHold(BookCopy c, Member m) {\n        System.out.println(\"Item is already on hold.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/strategy/SearchByAuthorStrategy.java",
    "content": "package librarymanagementsystem.strategy;\n\nimport librarymanagementsystem.models.LibraryItem;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class SearchByAuthorStrategy implements SearchStrategy {\n    @Override\n    public List<LibraryItem> search(String query, List<LibraryItem> items) {\n        List<LibraryItem> result = new ArrayList<>();\n        items.stream()\n                .filter(item -> item.getAuthorOrPublisher().toLowerCase().contains(query.toLowerCase()))\n                .forEach(result::add);\n        return result;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/strategy/SearchByTitleStrategy.java",
    "content": "package librarymanagementsystem.strategy;\n\nimport librarymanagementsystem.models.LibraryItem;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class SearchByTitleStrategy implements SearchStrategy {\n    @Override\n    public List<LibraryItem> search(String query, List<LibraryItem> items) {\n        List<LibraryItem> result = new ArrayList<>();\n        items.stream()\n                .filter(item -> item.getTitle().toLowerCase().contains(query.toLowerCase()))\n                .forEach(result::add);\n        return result;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/librarymanagementsystem/strategy/SearchStrategy.java",
    "content": "package librarymanagementsystem.strategy;\n\nimport librarymanagementsystem.models.LibraryItem;\n\nimport java.util.List;\n\npublic interface SearchStrategy {\n    List<LibraryItem> search(String query, List<LibraryItem> items);\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/LinkedInDemo.java",
    "content": "package linkedin;\n\nimport linkedin.entities.Education;\nimport linkedin.entities.Experience;\nimport linkedin.entities.Member;\nimport linkedin.entities.Post;\n\nimport java.time.LocalDate;\nimport java.util.List;\n\npublic class LinkedInDemo {\n    public static void main(String[] args) {\n        LinkedInSystem system = LinkedInSystem.getInstance();\n\n        // --- 1. Create Members using the Builder Pattern ---\n        System.out.println(\"--- 1. Member Registration ---\");\n        Member alice = new Member.Builder(\"Alice\", \"alice@example.com\")\n                .withSummary(\"Senior Software Engineer with 10 years of experience.\")\n                .addExperience(new Experience(\"Sr. Software Engineer\", \"Google\", LocalDate.of(2018, 1, 1), null))\n                .addExperience(new Experience(\"Software Engineer\", \"Microsoft\", LocalDate.of(2014, 6, 1), LocalDate.of(2017, 12, 31)))\n                .addEducation(new Education(\"Princeton University\", \"M.S. in Computer Science\", 2012, 2014))\n                .build();\n\n        Member bob = new Member.Builder(\"Bob\", \"bob@example.com\")\n                .withSummary(\"Product Manager at Stripe.\")\n                .addExperience(new Experience(\"Product Manager\", \"Stripe\", LocalDate.of(2020, 2, 1), null))\n                .addEducation(new Education(\"MIT\", \"B.S. in Business Analytics\", 2015, 2019))\n                .build();\n\n        Member charlie = new Member.Builder(\"Charlie\", \"charlie@example.com\").build();\n\n        system.registerMember(alice);\n        system.registerMember(bob);\n        system.registerMember(charlie);\n\n        alice.displayProfile();\n\n        // --- 2. Connection Management ---\n        System.out.println(\"\\n--- 2. Connection Management ---\");\n        // Alice sends requests to Bob and Charlie\n        String requestId1 = system.sendConnectionRequest(alice, bob);\n        String requestId2 = system.sendConnectionRequest(alice, charlie);\n\n        bob.viewNotifications(); // Bob sees Alice's request.\n\n        System.out.println(\"\\nBob accepts Alice's request.\");\n        system.acceptConnectionRequest(requestId1);\n        System.out.println(\"Alice and Bob are now connected.\");\n\n        // --- 3. Posting and News Feed ---\n        System.out.println(\"\\n--- 3. Posting & News Feed ---\");\n        bob.displayProfile(); // Bob has 1 connection\n        system.createPost(bob.getId(), \"Excited to share we've launched our new feature! #productmanagement\");\n\n        // Alice views her news feed. She should see Bob's post.\n        system.viewNewsFeed(alice.getId());\n\n        // Charlie views his feed. It should be empty as he is not connected to anyone.\n        system.viewNewsFeed(charlie.getId());\n\n        // --- 4. Interacting with a Post (Observer Pattern in action) ---\n        System.out.println(\"\\n--- 4. Post Interaction & Notifications ---\");\n        Post bobsPost = system.getLatestPostByMember(bob.getId());\n        if (bobsPost != null) {\n            bobsPost.addLike(alice);\n            bobsPost.addComment(alice, \"This looks amazing! Great work!\");\n        }\n\n        // Bob checks his notifications. He should see a like and a comment from Alice.\n        bob.viewNotifications();\n\n        // --- 5. Searching for Members ---\n        System.out.println(\"\\n--- 5. Member Search ---\");\n        List<Member> searchResults = system.searchMemberByName(\"ali\");\n        System.out.println(\"Search results for 'ali':\");\n        searchResults.forEach(m -> System.out.println(\" - \" + m.getName()));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/LinkedInSystem.java",
    "content": "package linkedin;\n\nimport linkedin.entities.Member;\nimport linkedin.entities.Post;\nimport linkedin.services.ConnectionService;\nimport linkedin.services.NewsFeedService;\nimport linkedin.services.NotificationService;\nimport linkedin.services.SearchService;\nimport linkedin.strategy.ChronologicalSortStrategy;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class LinkedInSystem {\n    private static volatile LinkedInSystem instance;\n\n    // Data stores (simulating databases)\n    private final Map<String, Member> members = new ConcurrentHashMap<>();\n\n    // Services\n    private final ConnectionService connectionService;\n    private final NewsFeedService newsFeedService;\n    private final SearchService searchService;\n\n    private LinkedInSystem() {\n        // Initialize services\n        this.connectionService = new ConnectionService(new NotificationService());\n        this.newsFeedService = new NewsFeedService();\n        this.searchService = new SearchService(members.values());\n    }\n\n    public static LinkedInSystem getInstance() {\n        if (instance == null) {\n            synchronized (LinkedInSystem.class) {\n                if (instance == null) {\n                    instance = new LinkedInSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void registerMember(Member member) {\n        members.put(member.getId(), member);\n        System.out.println(\"New member registered: \" + member.getName());\n    }\n\n    public Member getMember(String name) {\n        return members.values().stream().filter(m -> m.getName().equals(name)).findFirst().orElse(null);\n    }\n\n    public String sendConnectionRequest(Member from, Member to) {\n        return connectionService.sendRequest(from, to);\n    }\n\n    public void acceptConnectionRequest(String requestId) {\n        connectionService.acceptRequest(requestId);\n    }\n\n    public void createPost(String memberId, String content) {\n        Member author = members.get(memberId);\n        Post post = new Post(author, content);\n        newsFeedService.addPost(author, post);\n        System.out.printf(\"%s created a new post.%n\", author.getName());\n    }\n\n    public Post getLatestPostByMember(String memberId) {\n        List<Post> memberPosts = newsFeedService.getMemberPosts(members.get(memberId));\n        if (memberPosts == null || memberPosts.isEmpty()) return null;\n        return memberPosts.get(memberPosts.size() - 1);\n    }\n\n    public void viewNewsFeed(String memberId) {\n        Member member = members.get(memberId);\n        System.out.println(\"\\n--- News Feed for \" + member.getName() + \" ---\");\n        // Using the default chronological strategy\n        newsFeedService.displayFeedForMember(member, new ChronologicalSortStrategy());\n    }\n\n    public List<Member> searchMemberByName(String name) {\n        return searchService.searchByName(name);\n    }\n}"
  },
  {
    "path": "solutions/java/src/linkedin/README.md",
    "content": "# LinkedIn (LLD)\n\n## Problem Statement\n\nDesign and implement a LinkedIn-like professional networking platform that allows users to create profiles, connect with others, post jobs, send messages, and receive notifications.\n\n---\n\n## Requirements\n\n- **User Management:** Users can register, log in, and manage their profiles.\n- **Profile Management:** Users can add education, experience, and skills to their profiles.\n- **Connections:** Users can send and accept connection requests.\n- **Job Posting:** Users (or companies) can post job openings.\n- **Messaging:** Users can send direct messages to their connections.\n- **Notifications:** The system notifies users of connection requests, job matches, messages, and other events.\n- **Extensibility:** Easy to add new features such as endorsements, recommendations, or company pages.\n\n---\n\n## Core Entities\n\n- **LinkedInService:** Main class that manages users, connections, job postings, messages, and notifications.\n- **User:** Represents a user with profile, connections, messages, and notifications.\n- **Profile:** Represents a user's professional profile, including education, experience, and skills.\n- **Connection:** Represents a connection between two users.\n- **JobPosting:** Represents a job posted by a user or company.\n- **Message:** Represents a direct message between users.\n- **Notification:** Represents a notification sent to a user.\n- **NotificationType (enum):** Types of notifications (e.g., CONNECTION_REQUEST, JOB_MATCH, MESSAGE).\n- **Skill:** Represents a skill in a user's profile.\n- **Education:** Represents an education entry in a user's profile.\n- **Experience:** Represents a work experience entry in a user's profile.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/linkedin-class-diagram.png)\n\n### 1. LinkedInService\n- **Fields:** List<User> users, List<JobPosting> jobPostings, List<Connection> connections, List<Notification> notifications\n- **Methods:** registerUser(User), addConnection(User, User), postJob(JobPosting), sendMessage(User, User, String), sendNotification(Notification), searchUsers(String), searchJobs(String), etc.\n\n### 2. User\n- **Fields:** int id, String name, Profile profile, List<Connection> connections, List<Message> messages, List<Notification> notifications\n- **Methods:** sendConnectionRequest(User), acceptConnection(Connection), sendMessage(User, String), addSkill(Skill), addEducation(Education), addExperience(Experience), etc.\n\n### 3. Profile\n- **Fields:** List<Skill> skills, List<Education> education, List<Experience> experience\n\n### 4. Connection\n- **Fields:** int id, User user1, User user2, boolean isAccepted\n\n### 5. JobPosting\n- **Fields:** int id, String title, String description, User postedBy\n\n### 6. Message\n- **Fields:** int id, User sender, User receiver, String content\n\n### 7. Notification\n- **Fields:** int id, User recipient, String message, NotificationType type\n\n### 8. NotificationType (enum)\n- Values: CONNECTION_REQUEST, JOB_MATCH, MESSAGE, etc.\n\n### 9. Skill\n- **Fields:** String name\n\n### 10. Education\n- **Fields:** String institution, String degree, String fieldOfStudy, int startYear, int endYear\n\n### 11. Experience\n- **Fields:** String company, String title, int startYear, int endYear\n\n---\n\n## Example Usage\n\n```java\nLinkedInService service = new LinkedInService();\nUser alice = new User(1, \"Alice\");\nUser bob = new User(2, \"Bob\");\nservice.registerUser(alice);\nservice.registerUser(bob);\n\nalice.sendConnectionRequest(bob);\nservice.addConnection(alice, bob);\n\nProfile profile = alice.getProfile();\nprofile.addSkill(new Skill(\"Java\"));\nprofile.addEducation(new Education(\"MIT\", \"BSc\", \"CS\", 2010, 2014));\nprofile.addExperience(new Experience(\"Google\", \"Software Engineer\", 2014, 2018));\n\nJobPosting job = new JobPosting(1, \"Backend Developer\", \"Work on scalable systems\", alice);\nservice.postJob(job);\n\nservice.sendMessage(alice, bob, \"Hi Bob, let's connect!\");\n```\n\n---\n\n## Demo\n\nSee `LinkedInDemo.java` for a sample usage and simulation of the LinkedIn system.\n\n---\n\n## Extending the Framework\n\n- **Add endorsements:** Allow users to endorse each other's skills.\n- **Add recommendations:** Support written recommendations for users.\n- **Add company pages:** Allow companies to create and manage their own pages.\n\n---"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Comment.java",
    "content": "package linkedin.entities;\n\nimport java.time.LocalDateTime;\n\npublic class Comment {\n    private final Member author;\n    private final String text;\n    private final LocalDateTime createdAt;\n\n    public Comment(Member author, String text) {\n        this.author = author;\n        this.text = text;\n        this.createdAt = LocalDateTime.now();\n    }\n    public Member getAuthor() { return author; }\n    public String getText() { return text; }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Connection.java",
    "content": "package linkedin.entities;\n\nimport linkedin.enums.ConnectionStatus;\n\nimport java.time.LocalDateTime;\n\npublic class Connection {\n    private final Member fromMember;\n    private final Member toMember;\n    private ConnectionStatus status;\n    private final LocalDateTime requestedAt;\n    private LocalDateTime acceptedAt;\n\n    public Connection(Member fromMember, Member toMember) {\n        this.fromMember = fromMember;\n        this.toMember = toMember;\n        this.status = ConnectionStatus.PENDING;\n        this.requestedAt = LocalDateTime.now();\n    }\n\n    public Member getFromMember() { return fromMember; }\n    public Member getToMember() { return toMember; }\n    public ConnectionStatus getStatus() { return status; }\n\n    public void setStatus(ConnectionStatus status) {\n        this.status = status;\n        if (status == ConnectionStatus.ACCEPTED) {\n            this.acceptedAt = LocalDateTime.now();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Education.java",
    "content": "package linkedin.entities;\n\npublic class Education {\n    private final String school;\n    private final String degree;\n    private final int startYear;\n    private final int endYear;\n\n    public Education(String school, String degree, int startYear, int endYear) {\n        this.school = school;\n        this.degree = degree;\n        this.startYear = startYear;\n        this.endYear = endYear;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"%s, %s (%d - %d)\", degree, school, startYear, endYear);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Experience.java",
    "content": "package linkedin.entities;\n\nimport java.time.LocalDate;\n\npublic class Experience {\n    private final String title;\n    private final String company;\n    private final LocalDate startDate;\n    private final LocalDate endDate; // Can be null for current job\n\n    public Experience(String title, String company, LocalDate startDate, LocalDate endDate) {\n        this.title = title;\n        this.company = company;\n        this.startDate = startDate;\n        this.endDate = endDate;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"%s at %s (%s to %s)\", title, company, startDate, endDate == null ? \"Present\" : endDate);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Like.java",
    "content": "package linkedin.entities;\n\nimport java.time.LocalDateTime;\n\npublic class Like {\n    private final Member member;\n    private final LocalDateTime createdAt;\n\n    public Like(Member member) {\n        this.member = member;\n        this.createdAt = LocalDateTime.now();\n    }\n    public Member getMember() { return member; }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Member.java",
    "content": "package linkedin.entities;\n\nimport linkedin.observer.NotificationObserver;\n\nimport java.util.*;\n\npublic class Member implements NotificationObserver {\n    private final String id;\n    private final String name;\n    private final String email;\n    private final Profile profile;\n    private final Set<Member> connections = new HashSet<>();\n    private final List<Notification> notifications = new ArrayList<>();\n\n    private Member(String id, String name, String email, Profile profile) {\n        this.id = id;\n        this.name = name;\n        this.email = email;\n        this.profile = profile;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public String getEmail() { return email; }\n    public Set<Member> getConnections() { return connections; }\n    public Profile getProfile() { return profile; }\n\n    public void addConnection(Member member) {\n        connections.add(member);\n    }\n\n    public void displayProfile() {\n        System.out.println(\"\\n--- Profile for \" + name + \" (\" + email + \") ---\");\n        profile.display();\n        System.out.println(\"  Connections: \" + connections.size());\n    }\n\n    public void viewNotifications() {\n        System.out.println(\"\\n--- Notifications for \" + name + \" ---\");\n        if (notifications.isEmpty()) {\n            System.out.println(\"  No new notifications.\");\n            return;\n        }\n        notifications.stream()\n                .filter(n -> !n.isRead())\n                .forEach(n -> {\n                    System.out.println(\"  - \" + n.getContent());\n                    n.markAsRead(); // Mark as read after viewing\n                });\n    }\n\n    @Override\n    public void update(Notification notification) {\n        this.notifications.add(notification);\n        System.out.printf(\"Notification pushed to %s: %s%n\", this.name, notification.getContent());\n    }\n\n    // Builder Class\n    public static class Builder {\n        private final String id;\n        private final String name;\n        private final String email;\n        private final Profile profile = new Profile();\n\n        public Builder(String name, String email) {\n            this.id = UUID.randomUUID().toString();\n            this.name = name;\n            this.email = email;\n        }\n\n        public Builder withSummary(String summary) {\n            this.profile.setSummary(summary);\n            return this;\n        }\n\n        public Builder addExperience(Experience experience) {\n            this.profile.addExperience(experience);\n            return this;\n        }\n\n        public Builder addEducation(Education education) {\n            this.profile.addEducation(education);\n            return this;\n        }\n\n        public Member build() {\n            return new Member(id, name, email, profile);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/NewsFeed.java",
    "content": "package linkedin.entities;\n\nimport linkedin.strategy.FeedSortingStrategy;\n\nimport java.util.List;\n\npublic class NewsFeed {\n    private final List<Post> posts;\n\n    public NewsFeed(List<Post> posts) {\n        this.posts = posts;\n    }\n\n    public void display(FeedSortingStrategy strategy) {\n        List<Post> sortedPosts = strategy.sort(posts);\n        if (sortedPosts.isEmpty()) {\n            System.out.println(\"  Your news feed is empty.\");\n            return;\n        }\n        sortedPosts.forEach(post -> {\n            System.out.println(\"----------------------------------------\");\n            System.out.printf(\"Post by: %s (at %s)%n\", post.getAuthor().getName(), post.getCreatedAt().toLocalDate());\n            System.out.println(\"Content: \" + post.getContent());\n            System.out.printf(\"Likes: %d, Comments: %d%n\", post.getLikes().size(), post.getComments().size());\n            System.out.println(\"----------------------------------------\");\n        });\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Notification.java",
    "content": "package linkedin.entities;\n\nimport linkedin.enums.NotificationType;\n\nimport java.time.LocalDateTime;\nimport java.util.UUID;\n\npublic class Notification {\n    private final String id;\n    private final String memberId; // The ID of the member to notify\n    private final NotificationType type;\n    private final String content;\n    private final LocalDateTime createdAt;\n    private boolean isRead = false;\n\n    public Notification(String memberId, NotificationType type, String content) {\n        this.id = UUID.randomUUID().toString();\n        this.memberId = memberId;\n        this.type = type;\n        this.content = content;\n        this.createdAt = LocalDateTime.now();\n    }\n\n    public String getContent() { return content; }\n    public void markAsRead() { this.isRead = true; }\n    public boolean isRead() { return isRead; }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Post.java",
    "content": "package linkedin.entities;\n\nimport linkedin.enums.NotificationType;\nimport linkedin.observer.Subject;\n\nimport java.time.LocalDateTime;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class Post extends Subject {\n    private final String id;\n    private final Member author;\n    private final String content;\n    private final LocalDateTime createdAt;\n    private final List<Like> likes = new ArrayList<>();\n    private final List<Comment> comments = new ArrayList<>();\n\n    public Post(Member author, String content) {\n        this.id = UUID.randomUUID().toString();\n        this.author = author;\n        this.content = content;\n        this.createdAt = LocalDateTime.now();\n        // The author should be notified of interactions with their own post\n        this.addObserver(author);\n    }\n\n    public void addLike(Member member) {\n        likes.add(new Like(member));\n        String notificationContent = member.getName() + \" liked your post.\";\n        Notification notification = new Notification(author.getId(), NotificationType.POST_LIKE, notificationContent);\n        notifyObservers(notification);\n    }\n\n    public void addComment(Member member, String text) {\n        comments.add(new Comment(member, text));\n        String notificationContent = member.getName() + \" commented on your post: \\\"\" + text + \"\\\"\";\n        Notification notification = new Notification(author.getId(), NotificationType.POST_COMMENT, notificationContent);\n        notifyObservers(notification);\n    }\n\n    public String getId() { return id; }\n    public Member getAuthor() { return author; }\n    public String getContent() { return content; }\n    public LocalDateTime getCreatedAt() { return createdAt; }\n    public List<Like> getLikes() { return likes; }\n    public List<Comment> getComments() { return comments; }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/entities/Profile.java",
    "content": "package linkedin.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Profile {\n    private String summary;\n    private final List<Experience> experiences = new ArrayList<>();\n    private final List<Education> educations = new ArrayList<>();\n\n    public void setSummary(String summary) { this.summary = summary; }\n    public void addExperience(Experience experience) { experiences.add(experience); }\n    public void addEducation(Education education) { educations.add(education); }\n\n    public void display() {\n        System.out.println(\"  Summary: \" + (summary != null ? summary : \"N/A\"));\n\n        System.out.println(\"  Experience:\");\n        if (experiences.isEmpty())\n            System.out.println(\"    - None\");\n        else\n            experiences.forEach(exp -> System.out.println(\"    - \" + exp));\n\n        System.out.println(\"  Education:\");\n        if (educations.isEmpty())\n            System.out.println(\"    - None\");\n        else\n            educations.forEach(edu -> System.out.println(\"    - \" + edu));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/enums/ConnectionStatus.java",
    "content": "package linkedin.enums;\n\npublic enum ConnectionStatus {\n    PENDING,\n    ACCEPTED,\n    REJECTED,\n    WITHDRAWN\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/enums/NotificationType.java",
    "content": "package linkedin.enums;\n\npublic enum NotificationType {\n    CONNECTION_REQUEST,\n    POST_LIKE,\n    POST_COMMENT\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/observer/NotificationObserver.java",
    "content": "package linkedin.observer;\n\nimport linkedin.entities.Notification;\n\npublic interface NotificationObserver {\n    void update(Notification notification);\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/observer/Subject.java",
    "content": "package linkedin.observer;\n\nimport linkedin.entities.Notification;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class Subject {\n    private final List<NotificationObserver> observers = new ArrayList<>();\n\n    public void addObserver(NotificationObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(NotificationObserver observer) {\n        observers.remove(observer);\n    }\n\n    public void notifyObservers(Notification notification) {\n        for (NotificationObserver observer : observers) {\n            observer.update(notification);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/services/ConnectionService.java",
    "content": "package linkedin.services;\n\nimport linkedin.enums.ConnectionStatus;\nimport linkedin.enums.NotificationType;\nimport linkedin.entities.Connection;\nimport linkedin.entities.Member;\nimport linkedin.entities.Notification;\n\nimport java.util.Map;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class ConnectionService {\n    private final NotificationService notificationService;\n    // Simulates a DB table for connection requests\n    private final Map<String, Connection> connectionRequests = new ConcurrentHashMap<>();\n\n    public ConnectionService(NotificationService notificationService) {\n        this.notificationService = notificationService;\n    }\n\n    public String sendRequest(Member from, Member to) {\n        Connection connection = new Connection(from, to);\n        String requestId = UUID.randomUUID().toString();\n        connectionRequests.put(requestId, connection);\n\n        System.out.printf(\"%s sent a connection request to %s.%n\", from.getName(), to.getName());\n\n        Notification notification = new Notification(\n                to.getId(),\n                NotificationType.CONNECTION_REQUEST,\n                from.getName() + \" wants to connect with you. Request ID: \" + requestId\n        );\n        notificationService.sendNotification(to, notification);\n\n        return requestId;\n    }\n\n    public void acceptRequest(String requestId) {\n        Connection request = connectionRequests.get(requestId);\n        if (request != null && request.getStatus() == ConnectionStatus.PENDING) {\n            request.setStatus(ConnectionStatus.ACCEPTED);\n\n            Member from = request.getFromMember();\n            Member to = request.getToMember();\n\n            from.addConnection(to);\n            to.addConnection(from);\n\n            System.out.printf(\"%s accepted the connection request from %s.%n\", to.getName(), from.getName());\n            connectionRequests.remove(requestId); // Clean up\n        } else {\n            System.out.println(\"Invalid or already handled request ID.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/services/NewsFeedService.java",
    "content": "package linkedin.services;\n\nimport linkedin.entities.Member;\nimport linkedin.entities.NewsFeed;\nimport linkedin.entities.Post;\nimport linkedin.strategy.FeedSortingStrategy;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class NewsFeedService {\n    private final Map<String, List<Post>> allPosts; // A map of memberId -> list of their posts\n\n    public NewsFeedService() {\n        this.allPosts = new ConcurrentHashMap<>();\n    }\n\n    public void addPost(Member member, Post post) {\n        String memberId = member.getId();\n        if(!allPosts.containsKey(memberId)) {\n            allPosts.put(memberId, new ArrayList<>());\n        }\n        allPosts.get(memberId).add(post);\n    }\n\n    public List<Post> getMemberPosts(Member member) {\n        return allPosts.getOrDefault(member.getId(), new ArrayList<>());\n    }\n\n    public void displayFeedForMember(Member member, FeedSortingStrategy feedSortingStrategy) {\n        List<Post> feedPosts = new ArrayList<>();\n        // Add posts from the member's connections\n        for (Member connection : member.getConnections()) {\n            List<Post> connectionPosts = allPosts.get(connection.getId());\n            if (connectionPosts != null) {\n                feedPosts.addAll(connectionPosts);\n            }\n        }\n\n        NewsFeed feed = new NewsFeed(feedPosts);\n        feed.display(feedSortingStrategy);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/services/NotificationService.java",
    "content": "package linkedin.services;\n\nimport linkedin.entities.Member;\nimport linkedin.entities.Notification;\n\npublic class NotificationService {\n    public void sendNotification(Member member, Notification notification) {\n        // In a real system, this would push to a queue or a websocket.\n        // Here, we directly call the member's update method.\n        member.update(notification);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/services/SearchService.java",
    "content": "package linkedin.services;\n\nimport linkedin.entities.Member;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\npublic class SearchService {\n    private final Collection<Member> members;\n\n    public SearchService(Collection<Member> members) {\n        this.members = members;\n    }\n\n    public List<Member> searchByName(String name) {\n        List<Member> result = new ArrayList<>();\n        members.stream()\n            .filter(member -> member.getName().toLowerCase().contains(name.toLowerCase())) // substring search\n            .forEach(result::add);\n        return result;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/strategy/ChronologicalSortStrategy.java",
    "content": "package linkedin.strategy;\n\nimport linkedin.entities.Post;\n\nimport java.util.ArrayList;\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class ChronologicalSortStrategy implements FeedSortingStrategy {\n    @Override\n    public List<Post> sort(List<Post> posts) {\n        List<Post> result = new ArrayList<>();\n        posts.stream()\n            .sorted(Comparator.comparing(Post::getCreatedAt).reversed())\n            .forEach(result::add);\n        return result;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/linkedin/strategy/FeedSortingStrategy.java",
    "content": "package linkedin.strategy;\n\nimport linkedin.entities.Post;\n\nimport java.util.List;\n\npublic interface FeedSortingStrategy {\n    List<Post> sort(List<Post> posts);\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/AsyncLogProcessor.java",
    "content": "package loggingframework;\n\nimport loggingframework.entities.LogMessage;\nimport loggingframework.strategies.appender.LogAppender;\n\nimport java.util.List;\nimport java.util.concurrent.*;\n\nclass AsyncLogProcessor {\n    private final ExecutorService executor;\n\n    public AsyncLogProcessor() {\n        this.executor = Executors.newSingleThreadExecutor(runnable -> {\n            Thread thread = new Thread(runnable, \"AsyncLogProcessor\");\n            thread.setDaemon(true); // Don't prevent JVM exit\n            return thread;\n        });\n    }\n\n    public void process(LogMessage logMessage, List<LogAppender> appenders) {\n        if (executor.isShutdown()) {\n            System.err.println(\"Logger is shut down. Cannot process log message.\");\n            return;\n        }\n\n        // Submit a new task to the executor.\n        executor.submit(() -> {\n            for (LogAppender appender : appenders) {\n                appender.append(logMessage);\n            }\n        });\n    }\n\n    public void stop() {\n        // Disable new tasks from being submitted\n        executor.shutdown();\n        try {\n            if (!executor.awaitTermination(2, TimeUnit.SECONDS)) {\n                System.err.println(\"Logger executor did not terminate in the specified time.\");\n                // Forcibly shut down any still-running tasks.\n                executor.shutdownNow();\n            }\n        } catch (InterruptedException e) {\n            executor.shutdownNow();\n            // Preserve interrupt status\n            Thread.currentThread().interrupt();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/LogManager.java",
    "content": "package loggingframework;\n\nimport loggingframework.strategies.appender.LogAppender;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class LogManager {\n    private static final LogManager INSTANCE = new LogManager();\n    private final Map<String, Logger> loggers = new ConcurrentHashMap<>();\n    private final Logger rootLogger;\n    private final AsyncLogProcessor processor;\n\n    private LogManager() {\n        this.rootLogger = new Logger(\"root\", null);\n        this.loggers.put(\"root\", rootLogger);\n        this.processor = new AsyncLogProcessor();\n    }\n\n    public static LogManager getInstance() {\n        return INSTANCE;\n    }\n\n    public Logger getLogger(String name) {\n        return loggers.computeIfAbsent(name, this::createLogger);\n    }\n\n    private Logger createLogger(String name) {\n        if (name.equals(\"root\")) {\n            return rootLogger;\n        }\n        int lastDot = name.lastIndexOf('.');\n        String parentName = (lastDot == -1) ? \"root\" : name.substring(0, lastDot);\n        Logger parent = getLogger(parentName);\n        return new Logger(name, parent);\n    }\n\n    public Logger getRootLogger() {\n        return rootLogger;\n    }\n\n    AsyncLogProcessor getProcessor() {\n        return processor;\n    }\n\n    public void shutdown() {\n        // Stop the processor first to ensure all logs are written.\n        processor.stop();\n\n        // Then, close all appenders.\n        loggers.values().stream()\n                .flatMap(logger -> logger.getAppenders().stream())\n                .distinct()\n                .forEach(LogAppender::close);\n        System.out.println(\"Logging framework shut down gracefully.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/Logger.java",
    "content": "package loggingframework;\n\nimport loggingframework.entities.LogMessage;\nimport loggingframework.enums.LogLevel;\nimport loggingframework.strategies.appender.LogAppender;\nimport java.util.List;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\npublic class Logger {\n    private final String name;\n    private LogLevel level;\n    private final Logger parent;\n    private final List<LogAppender> appenders;\n    private boolean additivity = true;\n\n    Logger(String name, Logger parent) {\n        this.name = name;\n        this.parent = parent;\n        this.appenders = new CopyOnWriteArrayList<>();\n    }\n\n    public void addAppender(LogAppender appender) {\n        appenders.add(appender);\n    }\n\n    public List<LogAppender> getAppenders() {\n        return appenders;\n    }\n\n    public void setLevel(LogLevel minLevel) {\n        this.level = minLevel;\n    }\n\n    public void setAdditivity(boolean additivity) {\n        this.additivity = additivity;\n    }\n\n    public LogLevel getEffectiveLevel() {\n        for (Logger logger = this; logger != null; logger = logger.parent) {\n            LogLevel currentLevel = logger.level;\n            if (currentLevel != null) {\n                return currentLevel;\n            }\n        }\n        return LogLevel.DEBUG; // Default root level\n    }\n\n    public void log(LogLevel messageLevel, String message) {\n        if (messageLevel.isGreaterOrEqual(getEffectiveLevel())) {\n            LogMessage logMessage = new LogMessage(messageLevel, this.name, message);\n            callAppenders(logMessage);\n        }\n    }\n\n    private void callAppenders(LogMessage logMessage) {\n        if (!appenders.isEmpty()) {\n            LogManager.getInstance().getProcessor().process(logMessage, this.appenders);\n        }\n        if (additivity && parent != null) {\n            parent.callAppenders(logMessage);\n        }\n    }\n\n    public void debug(String message) {\n        log(LogLevel.DEBUG, message);\n    }\n    public void info(String message) {\n        log(LogLevel.INFO, message);\n    }\n    public void warn(String message) {\n        log(LogLevel.WARN, message);\n    }\n    public void error(String message) {\n        log(LogLevel.ERROR, message);\n    }\n    public void fatal(String message) {\n        log(LogLevel.FATAL, message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/LoggingFrameworkDemo.java",
    "content": "package loggingframework;\n\nimport loggingframework.enums.LogLevel;\nimport loggingframework.strategies.appender.ConsoleAppender;\n\npublic class LoggingFrameworkDemo {\n    public static void main(String[] args) {\n        // --- 1. Initial Configuration ---\n        LogManager logManager = LogManager.getInstance();\n        Logger rootLogger = logManager.getRootLogger();\n        rootLogger.setLevel(LogLevel.INFO); // Set global minimum level to INFO\n\n        // Add a console appender to the root logger\n        rootLogger.addAppender(new ConsoleAppender());\n\n        System.out.println(\"--- Initial Logging Demo ---\");\n        Logger mainLogger = logManager.getLogger(\"com.example.Main\");\n        mainLogger.info(\"Application starting up.\");\n        mainLogger.debug(\"This is a debug message, it should NOT appear.\"); // Below root level\n        mainLogger.warn(\"This is a warning message.\");\n\n        // --- 2. Hierarchy and Additivity Demo ---\n        System.out.println(\"\\n--- Logger Hierarchy Demo ---\");\n        Logger dbLogger = logManager.getLogger(\"com.example.db\");\n        // dbLogger inherits level and appenders from root\n        dbLogger.info(\"Database connection pool initializing.\");\n\n        // Let's create a more specific logger and override its level\n        Logger serviceLogger = logManager.getLogger(\"com.example.service.UserService\");\n        serviceLogger.setLevel(LogLevel.DEBUG); // More verbose logging for this specific service\n        serviceLogger.info(\"User service starting.\");\n        serviceLogger.debug(\"This debug message SHOULD now appear for the service logger.\");\n\n        // --- 3. Dynamic Configuration Change ---\n        System.out.println(\"\\n--- Dynamic Configuration Demo ---\");\n        System.out.println(\"Changing root log level to DEBUG...\");\n        rootLogger.setLevel(LogLevel.DEBUG);\n        mainLogger.debug(\"This debug message should now be visible.\");\n\n        try {\n            Thread.sleep(500);\n            logManager.shutdown();\n        } catch (Exception e) {\n            System.out.println(\"Caught exception\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/loggingframework/README.md",
    "content": "# Logging Framework (LLD)\n\n## Problem Statement\n\nDesign and implement a flexible and extensible logging framework that can be used by applications to log messages at different levels (INFO, DEBUG, ERROR, etc.), support multiple output destinations (console, file, etc.), and allow for custom formatting of log messages.\n\n---\n\n## Requirements\n\n- **Log Levels:** Support for multiple log levels (INFO, DEBUG, ERROR, etc.).\n- **Multiple Appenders:** Ability to log to different destinations (console, file, etc.).\n- **Custom Formatting:** Support for custom log message formatting.\n- **Configuration:** Ability to configure loggers and appenders.\n- **Thread Safety:** Should be thread-safe for concurrent logging.\n- **Extensibility:** Easy to add new log levels, appenders, or formatters.\n\n---\n\n## Core Entities\n\n- **Logger:** Main class used by clients to log messages.\n- **LogLevel:** Enum representing different log levels.\n- **LogMessage:** Encapsulates the details of a log event.\n- **LogFormatter:** Interface for formatting log messages.\n- **DefaultFormatter:** Default implementation of `LogFormatter`.\n- **LoggerConfig:** Holds configuration for the logger (appenders, formatters, etc.).\n- **LogAppender (in `logappender/`):** Interface and implementations for output destinations (e.g., ConsoleAppender, FileAppender).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/loggingframework-class-diagram.png)\n\n### 1. Logger\n- **Methods:**\n  - `log(LogLevel level, String message)`\n  - `info(String message)`\n  - `debug(String message)`\n  - `error(String message)`\n  - `setConfig(LoggerConfig config)`\n\n### 2. LogLevel\n- Enum for log levels (INFO, DEBUG, ERROR, etc.)\n\n### 3. LogMessage\n- Fields: `level`, `message`, `timestamp`, etc.\n\n### 4. LogFormatter (Interface)\n- `String format(LogMessage message)`\n\n### 5. DefaultFormatter\n- Implements `LogFormatter` with a default format.\n\n### 6. LoggerConfig\n- Holds configuration for loggers (appenders, formatters, log level).\n\n### 7. LogAppender (in `logappender/`)\n- Interface for appenders.\n- Implementations: `ConsoleAppender`, `FileAppender`, etc.\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** For interchangeable log formatters and appenders.\n- **Singleton Pattern:** (If used) For global logger instance.\n- **Factory Pattern:** (Optional) For creating appenders/formatters based on config.\n- **Observer Pattern:** (Conceptually, for notifying multiple appenders.)\n\n---\n\n## Example Usage\n\n```java\nLogger logger = new Logger();\nlogger.setConfig(new LoggerConfig(...));\nlogger.info(\"Application started\");\nlogger.error(\"An error occurred\");\n```\n\n---\n\n## Demo\n\nSee `LoggingFrameworkDemo.java` for a sample usage of the logging framework.\n\n---\n\n## Extending the Framework\n\n- **Add a new log level:** Update `LogLevel.java`.\n- **Add a new appender:** Implement the `LogAppender` interface in `logappender/`.\n- **Add a new formatter:** Implement the `LogFormatter` interface.\n\n---"
  },
  {
    "path": "solutions/java/src/loggingframework/entities/LogMessage.java",
    "content": "package loggingframework.entities;\n\nimport loggingframework.enums.LogLevel;\n\nimport java.time.LocalDateTime;\n\npublic final class LogMessage {\n    private final LocalDateTime timestamp;\n    private final LogLevel level;\n    private final String loggerName;\n    private final String threadName;\n    private final String message;\n\n    public LogMessage(LogLevel level, String loggerName, String message) {\n        this.timestamp = LocalDateTime.now();\n        this.level = level;\n        this.loggerName = loggerName;\n        this.message = message;\n        this.threadName = Thread.currentThread().getName();\n    }\n\n    // Getters for all fields\n    public LocalDateTime getTimestamp() { return timestamp; }\n    public LogLevel getLevel() { return level; }\n    public String getLoggerName() { return loggerName; }\n    public String getThreadName() { return threadName; }\n    public String getMessage() { return message; }\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/enums/LogLevel.java",
    "content": "package loggingframework.enums;\n\npublic enum LogLevel {\n    DEBUG(1), INFO(2), WARN(3), ERROR(4), FATAL(5);\n\n    private final int level;\n\n    LogLevel(int level) {\n        this.level = level;\n    }\n\n    public boolean isGreaterOrEqual(LogLevel other) {\n        return this.level >= other.level;\n    }\n}"
  },
  {
    "path": "solutions/java/src/loggingframework/strategies/appender/ConsoleAppender.java",
    "content": "package loggingframework.strategies.appender;\n\nimport loggingframework.strategies.formatter.LogFormatter;\nimport loggingframework.entities.LogMessage;\nimport loggingframework.strategies.formatter.SimpleTextFormatter;\n\npublic class ConsoleAppender implements LogAppender {\n    private LogFormatter formatter;\n\n    public ConsoleAppender() {\n        this.formatter = new SimpleTextFormatter();\n    }\n\n    @Override\n    public void append(LogMessage logMessage) {\n        System.out.println(formatter.format(logMessage));\n    }\n\n    @Override\n    public void close() {}\n\n    @Override\n    public void setFormatter(LogFormatter formatter) {\n        this.formatter = formatter;\n    }\n\n    @Override\n    public LogFormatter getFormatter() {\n        return formatter;\n    }\n}"
  },
  {
    "path": "solutions/java/src/loggingframework/strategies/appender/FileAppender.java",
    "content": "package loggingframework.strategies.appender;\n\nimport loggingframework.strategies.formatter.LogFormatter;\nimport loggingframework.entities.LogMessage;\nimport loggingframework.strategies.formatter.SimpleTextFormatter;\n\nimport java.io.FileWriter;\nimport java.io.IOException;\n\npublic class FileAppender implements LogAppender {\n    private FileWriter writer;\n    private LogFormatter formatter;\n\n    public FileAppender(String filePath) {\n        this.formatter = new SimpleTextFormatter();\n        try {\n            this.writer = new FileWriter(filePath, true);\n        } catch (Exception e) {\n            System.out.println(\"Failed to create writer for file logs, exception: \" + e.getMessage());\n        }\n    }\n\n    @Override\n    public synchronized void append(LogMessage logMessage) {\n        try {\n            writer.write(formatter.format(logMessage) + \"\\n\");\n            writer.flush();\n        } catch (IOException e) {\n            System.out.println(\"Failed to write logs to file, exception: \" + e.getMessage());\n        }\n    }\n\n    @Override\n    public void close() {\n        try {\n            writer.close();\n        } catch (IOException e) {\n            System.out.println(\"Failed to close logs file, exception: \" + e.getMessage());\n        }\n    }\n\n    @Override\n    public void setFormatter(LogFormatter formatter) {\n        this.formatter = formatter;\n    }\n\n    @Override\n    public LogFormatter getFormatter() {\n        return formatter;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/strategies/appender/LogAppender.java",
    "content": "package loggingframework.strategies.appender;\n\nimport loggingframework.entities.LogMessage;\nimport loggingframework.strategies.formatter.LogFormatter;\n\npublic interface LogAppender {\n    void append(LogMessage logMessage);\n    void close();\n    LogFormatter getFormatter();\n    void setFormatter(LogFormatter formatter);\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/strategies/formatter/LogFormatter.java",
    "content": "package loggingframework.strategies.formatter;\n\nimport loggingframework.entities.LogMessage;\n\npublic interface LogFormatter {\n    String format(LogMessage logMessage);\n}\n"
  },
  {
    "path": "solutions/java/src/loggingframework/strategies/formatter/SimpleTextFormatter.java",
    "content": "package loggingframework.strategies.formatter;\n\nimport loggingframework.entities.LogMessage;\n\nimport java.time.format.DateTimeFormatter;\n\npublic class SimpleTextFormatter implements LogFormatter {\n    private static final DateTimeFormatter DATE_TIME_FORMATTER =\n            DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss.SSS\");\n\n    @Override\n    public String format(LogMessage logMessage) {\n        return String.format(\"%s [%s] %s - %s: %s\\n\",\n                logMessage.getTimestamp().format(DATE_TIME_FORMATTER),\n                logMessage.getThreadName(),\n                logMessage.getLevel(),\n                logMessage.getLoggerName(),\n                logMessage.getMessage());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/lrucache/DoublyLinkedList.java",
    "content": "package lrucache;\n\nclass DoublyLinkedList<K, V> {\n    private final Node<K, V> head;\n    private final Node<K, V> tail;\n\n    public DoublyLinkedList() {\n        head = new Node<>(null, null); // Dummy head\n        tail = new Node<>(null, null); // Dummy tail\n        head.next = tail;\n        tail.prev = head;\n    }\n\n    public void addFirst(Node<K, V> node) {\n        node.next = head.next;\n        node.prev = head;\n        head.next.prev = node;\n        head.next = node;\n    }\n\n    public void remove(Node<K, V> node) {\n        node.prev.next = node.next;\n        node.next.prev = node.prev;\n    }\n\n    public void moveToFront(Node<K, V> node) {\n        remove(node);\n        addFirst(node);\n    }\n\n    public Node<K, V> removeLast() {\n        if (tail.prev == head) return null;\n        Node<K, V> last = tail.prev;\n        remove(last);\n        return last;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/lrucache/LRUCache.java",
    "content": "package lrucache;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class LRUCache<K, V> {\n    private final int capacity;\n    private final Map<K, Node<K, V>> map;\n    private final DoublyLinkedList<K, V> dll;\n\n    public LRUCache(int capacity) {\n        this.capacity = capacity;\n        this.map = new HashMap<>();\n        this.dll = new DoublyLinkedList<>();\n    }\n\n    public synchronized V get(K key) {\n        if (!map.containsKey(key)) return null;\n        Node<K, V> node = map.get(key);\n        dll.moveToFront(node);\n        return node.value;\n    }\n\n    public synchronized void put(K key, V value) {\n        if (map.containsKey(key)) {\n            Node<K, V> node = map.get(key);\n            node.value = value;\n            dll.moveToFront(node);\n        } else {\n            if (map.size() == capacity) {\n                Node<K, V> lru = dll.removeLast();\n                if (lru != null) map.remove(lru.key);\n            }\n            Node<K, V> newNode = new Node<>(key, value);\n            dll.addFirst(newNode);\n            map.put(key, newNode);\n        }\n    }\n\n    public synchronized void remove(K key) {\n        if (!map.containsKey(key)) return;\n        Node<K, V> node = map.get(key);\n        dll.remove(node);\n        map.remove(key);\n    }\n}"
  },
  {
    "path": "solutions/java/src/lrucache/LRUCacheDemo.java",
    "content": "package lrucache;\n\npublic class LRUCacheDemo {\n    public static void run() {\n        LRUCache<String, Integer> cache = new LRUCache<>(3);\n\n        cache.put(\"a\", 1);\n        cache.put(\"b\", 2);\n        cache.put(\"c\", 3);\n\n        System.out.println(cache.get(\"a\")); // 1\n\n        cache.put(\"d\", 4);\n        \n        System.out.println(cache.get(\"b\")); // null\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/lrucache/Node.java",
    "content": "package lrucache;\n\nclass Node<K, V> {\n    K key;\n    V value;\n    Node<K, V> prev, next;\n\n    public Node(K key, V value) {\n        this.key = key;\n        this.value = value;\n    }\n}"
  },
  {
    "path": "solutions/java/src/lrucache/README.md",
    "content": "# LRU Cache (LLD)\n\n## Problem Statement\n\nDesign and implement an LRU (Least Recently Used) Cache with a fixed capacity. The cache should support fast retrieval and insertion, and automatically evict the least recently used item when the capacity is exceeded.\n\n---\n\n## Requirements\n\n- **Fixed Capacity:** The cache has a maximum size. When full, the least recently used item is evicted on insertion.\n- **Fast Operations:** Both `get(key)` and `put(key, value)` operations should be O(1).\n- **Eviction Policy:** The least recently used item is removed when the cache exceeds its capacity.\n- **Extensibility:** Easy to change the eviction policy or underlying data structures.\n\n---\n\n## Core Entities\n\n- **LRUCache:** Main class implementing the cache logic, manages storage and eviction.\n- **Node:** Represents a doubly-linked list node for fast removal and insertion.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/lrucache-class-diagram.png)\n\n### 1. LRUCache\n- **Fields:** capacity, Map<K, Node<K, V>>, head/tail pointers for the doubly-linked list\n- **Methods:**\n  - `get(K key)`: Returns the value for the key if present, else -1/null. Moves the node to the front (most recently used).\n  - `put(K key, V value)`: Inserts or updates the value for the key. Moves the node to the front. If the cache exceeds capacity, evicts the least recently used node.\n  - `removeNode(Node)`, `addToFront(Node)`, `moveToFront(Node)`, `evictLRU()`: Helper methods for list management.\n\n### 2. Node\n- **Fields:** key, value, prev, next\n\n---\n\n## Design Patterns Used\n\n- **Doubly Linked List:** For O(1) removal and insertion of nodes.\n- **Hash Map:** For O(1) access to nodes by key.\n- **Separation of Concerns:** Node and cache logic are separated.\n\n---\n\n## Example Usage\n\n```java\nLRUCache cache = new LRUCache(2);\ncache.put(1, 1); // cache: {1=1}\ncache.put(2, 2); // cache: {1=1, 2=2}\ncache.get(1);    // returns 1, cache: {2=2, 1=1}\ncache.put(3, 3); // evicts key 2, cache: {1=1, 3=3}\ncache.get(2);    // returns -1 (not found)\n```\n\n---\n\n## Demo\n\nSee `LRUCacheDemo.java` for a sample usage and simulation of the LRU cache.\n\n---\n\n## Extending the Framework\n\n- **Change eviction policy:** Implement a different policy (e.g., LFU) by modifying the eviction logic.\n- **Change data structures:** Use other structures for different performance characteristics.\n\n---"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/BookingManager.java",
    "content": "package movieticketbookingsystem;\n\nimport movieticketbookingsystem.enums.PaymentStatus;\nimport movieticketbookingsystem.entities.*;\nimport movieticketbookingsystem.strategy.payment.PaymentStrategy;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic class BookingManager {\n    private final SeatLockManager seatLockManager;\n\n    public BookingManager(SeatLockManager seatLockManager) {\n        this.seatLockManager = seatLockManager;\n    }\n\n    public Optional<Booking> createBooking(User user, Show show, List<Seat> seats, PaymentStrategy paymentStrategy) {\n        // 1. Lock the seats\n        seatLockManager.lockSeats(show, seats, user.getId());\n\n        // 2. Calculate the total price\n        double totalAmount = show.getPricingStrategy().calculatePrice(seats);\n\n        // 3. Process Payment\n        Payment payment = paymentStrategy.pay(totalAmount);\n\n        // 4. If payment is successful, create the booking\n        if (payment.getStatus() == PaymentStatus.SUCCESS) {\n            Booking booking = new Booking.BookingBuilder()\n                    .setUser(user)\n                    .setShow(show)\n                    .setSeats(seats)\n                    .setTotalAmount(totalAmount)\n                    .setPayment(payment)\n                    .build();\n\n            // 5. Confirm the booking (mark seats as BOOKED)\n            booking.confirmBooking();\n\n            // Clean up the lock map\n            seatLockManager.unlockSeats(show, seats, user.getId());\n\n            return Optional.of(booking);\n        } else {\n            System.out.println(\"Payment failed. Please try again.\");\n            return Optional.empty();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/MovieBookingDemo.java",
    "content": "package movieticketbookingsystem;\n\nimport movieticketbookingsystem.enums.SeatStatus;\nimport movieticketbookingsystem.enums.SeatType;\nimport movieticketbookingsystem.entities.*;\nimport movieticketbookingsystem.observer.UserObserver;\nimport movieticketbookingsystem.strategy.payment.CreditCardPaymentStrategy;\nimport movieticketbookingsystem.strategy.pricing.WeekdayPricingStrategy;\n\nimport java.time.LocalDateTime;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\npublic class MovieBookingDemo {\n    public static void main (String[]args){\n        // Setup\n        MovieBookingService service = MovieBookingService.getInstance();\n\n        City nyc = service.addCity(\"city1\", \"New York\");\n        City la = service.addCity(\"city2\", \"Los Angeles\");\n\n        // 2. Add movies\n        Movie matrix = new Movie(\"M1\", \"The Matrix\", 120);\n        Movie avengers = new Movie(\"M2\", \"Avengers: Endgame\", 170);\n        service.addMovie(matrix);\n        service.addMovie(avengers);\n\n        // Add Seats for a Screen\n        Screen screen1 = new Screen(\"S1\");\n\n        for (int i = 1; i <= 10; i++) {\n            screen1.addSeat(new Seat(\"A\" + i, 1, i, i <= 5 ? SeatType.REGULAR : SeatType.PREMIUM));\n            screen1.addSeat(new Seat(\"B\" + i, 2, i, i <= 5 ? SeatType.REGULAR : SeatType.PREMIUM));\n        }\n\n        // Add Cinemas\n        Cinema amcNYC = service.addCinema(\"cinema1\", \"AMC Times Square\", nyc.getId(), List.of(screen1));\n\n        // Add Shows\n        Show matrixShow = service.addShow(\"show1\", matrix, screen1, LocalDateTime.now().plusHours(2), new WeekdayPricingStrategy());\n        Show avengersShow = service.addShow(\"show2\", avengers, screen1, LocalDateTime.now().plusHours(5), new WeekdayPricingStrategy());\n\n        // --- User and Observer Setup ---\n        User alice = service.createUser(\"Alice\", \"alice@example.com\");\n        UserObserver aliceObserver = new UserObserver(alice);\n        avengers.addObserver(aliceObserver);\n\n        // Simulate movie release\n        System.out.println(\"\\n--- Notifying Observers about Movie Release ---\");\n        avengers.notifyObservers();\n\n        // --- User Story: Alice books tickets ---\n        System.out.println(\"\\n--- Alice's Booking Flow ---\");\n        String cityName = \"New York\";\n        String movieTitle = \"Avengers: Endgame\";\n\n        // 1. Search for shows\n        List<Show> availableShows = service.findShows(movieTitle, cityName);\n        if (availableShows.isEmpty()) {\n            System.out.println(\"No shows found for \" + movieTitle + \" in \" + cityName);\n            return;\n        }\n        Show selectedShow = availableShows.get(0); // Alice selects the first show\n\n        // 2. View available seats\n        List<Seat> availableSeats = selectedShow.getScreen().getSeats().stream()\n                .filter(seat -> seat.getStatus() == SeatStatus.AVAILABLE)\n                .toList();\n        System.out.printf(\"Available seats for '%s' at %s: %s%n\",\n                selectedShow.getMovie().getTitle(),\n                selectedShow.getStartTime(),\n                availableSeats.stream().map(Seat::getId).collect(Collectors.toList()));\n\n        // 3. Select seats\n        List<Seat> desiredSeats = List.of(availableSeats.get(2), availableSeats.get(3));\n        System.out.println(\"Alice selects seats: \" + desiredSeats.stream().map(Seat::getId).toList());\n\n        // 4. Book Tickets\n        Optional<Booking> bookingOpt = service.bookTickets(\n                alice.getId(),\n                selectedShow.getId(),\n                desiredSeats,\n                new CreditCardPaymentStrategy(\"1234-5678-9876-5432\", \"123\")\n        );\n\n        if (bookingOpt.isPresent()) {\n            Booking booking = bookingOpt.get();\n            System.out.println(\"\\n--- Booking Successful! ---\");\n            System.out.println(\"Booking ID: \" + booking.getId());\n            System.out.println(\"User: \" + booking.getUser().getName());\n            System.out.println(\"Movie: \" + booking.getShow().getMovie().getTitle());\n            System.out.println(\"Seats: \" + booking.getSeats().stream().map(Seat::getId).toList());\n            System.out.println(\"Total Amount: $\" + booking.getTotalAmount());\n            System.out.println(\"Payment Status: \" + booking.getPayment().getStatus());\n        } else {\n            System.out.println(\"Booking failed.\");\n        }\n\n        // 5. Verify seat status after booking\n        System.out.println(\"\\nSeat status after Alice's booking:\");\n        desiredSeats.forEach(seat -> System.out.printf(\"Seat %s status: %s%n\", seat.getId(), seat.getStatus()));\n\n        // 6. Shut down the system to release resources like the scheduler.\n        service.shutdown();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/MovieBookingService.java",
    "content": "package movieticketbookingsystem;\n\nimport movieticketbookingsystem.entities.*;\nimport movieticketbookingsystem.strategy.payment.PaymentStrategy;\nimport movieticketbookingsystem.strategy.pricing.PricingStrategy;\n\nimport java.time.LocalDateTime;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class MovieBookingService {\n    private static volatile MovieBookingService instance;\n\n    private final Map<String, City> cities;\n    private final Map<String, Cinema> cinemas;\n    private final Map<String, Movie> movies;\n    private final Map<String, User> users;\n    private final Map<String, Show> shows;\n\n    // Core services - managed by the system\n    private final SeatLockManager seatLockManager;\n    private final BookingManager bookingManager;\n\n\n    private MovieBookingService() {\n        this.cities = new ConcurrentHashMap<>();\n        this.cinemas = new ConcurrentHashMap<>();\n        this.movies = new ConcurrentHashMap<>();\n        this.users = new ConcurrentHashMap<>();\n        this.shows = new ConcurrentHashMap<>();\n\n        this.seatLockManager = new SeatLockManager();\n        this.bookingManager = new BookingManager(seatLockManager);\n    }\n\n    public static MovieBookingService getInstance() {\n        if (instance == null) {\n            synchronized (MovieBookingService.class) {\n                if (instance == null) {\n                    instance = new MovieBookingService();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public BookingManager getBookingManager() {\n        return bookingManager;\n    }\n\n    // --- Data Management Methods ---\n    public City addCity(String id, String name) {\n        City city = new City(id, name);\n        cities.put(city.getId(), city);\n        return city;\n    }\n\n    public Cinema addCinema(String id, String name, String cityId, List<Screen> screens) {\n        City city = cities.get(cityId);\n        Cinema cinema = new Cinema(id, name, city, screens);\n        cinemas.put(cinema.getId(), cinema);\n        return cinema;\n    }\n\n    public void addMovie(Movie movie) {\n        this.movies.put(movie.getId(), movie);\n    }\n\n    public Show addShow(String id, Movie movie, Screen screen, LocalDateTime startTime, PricingStrategy pricingStrategy) {\n        Show show = new Show(id, movie, screen, startTime, pricingStrategy);\n        shows.put(show.getId(), show);\n        return show;\n    }\n\n    public User createUser(String name, String email) {\n        User user = new User(name, email);\n        users.put(user.getId(), user);\n        return user;\n    }\n\n    public Optional<Booking> bookTickets(String userId, String showId, List<Seat> desiredSeats, PaymentStrategy paymentStrategy) {\n        return bookingManager.createBooking(\n                users.get(userId),\n                shows.get(showId),\n                desiredSeats,\n                paymentStrategy\n        );\n    }\n\n    // --- Search Functionality ---\n    public List<Show> findShows(String movieTitle, String cityName) {\n        List<Show> result = new ArrayList<>();\n        shows.values().stream()\n            .filter(show -> show.getMovie().getTitle().equalsIgnoreCase(movieTitle))\n            .filter(show -> {\n                Cinema cinema = findCinemaForShow(show);\n                return cinema != null && cinema.getCity().getName().equalsIgnoreCase(cityName);\n            })\n            .forEach(result::add);\n        return result;\n    }\n\n    private Cinema findCinemaForShow(Show show) {\n        // This is inefficient. In a real system, shows would have a direct link to the cinema.\n        // For this example, we traverse the cinema list.\n        return cinemas.values().stream()\n                .filter(cinema -> cinema.getScreens().contains(show.getScreen()))\n                .findFirst()\n                .orElse(null);\n    }\n\n    public void shutdown() {\n        this.seatLockManager.shutdown();\n        System.out.println(\"MovieTicketBookingSystem has been shut down.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/README.md",
    "content": "# Movie Ticket Booking System (LLD)\n\n## Problem Statement\n\nDesign and implement a Movie Ticket Booking System that allows users to book movie tickets, select seats, and manage shows. The system should handle movie schedules, theater management, and seat reservations.\n\n---\n\n## Requirements\n\n1. **Movie Management:**\n   - Store movie information (title, duration, language)\n   - Manage movie schedules and shows\n   - Track movie availability\n\n2. **Theater Management:**\n   - Manage theater information\n   - Handle multiple shows per theater\n   - Track theater capacity\n\n3. **Show Management:**\n   - Schedule shows for movies\n   - Manage show timings\n   - Handle show availability\n\n4. **Seat Management:**\n   - Track seat availability\n   - Handle seat selection\n   - Manage different seat types\n\n5. **Booking Management:**\n   - Process parkingTicket bookings\n   - Handle booking cancellations\n   - Manage booking status\n\n---\n\n## Core Entities\n\n### 1. MovieTicketBookingSystem\n- **Fields:** List<Movie> movies, List<Theater> theaters, List<Show> shows\n- **Methods:** \n  - addMovie()\n  - addTheater()\n  - addShow()\n  - bookTicket()\n  - cancelBooking()\n  - getAvailableShows()\n\n### 2. Movie\n- **Fields:** String id, String title, int duration, String language\n- **Methods:** \n  - getShows()\n  - isAvailable()\n\n### 3. Theater\n- **Fields:** String id, String name, String location\n- **Methods:** \n  - addShow()\n  - getShows()\n  - getCapacity()\n\n### 4. Show\n- **Fields:** String id, Movie movie, Theater theater, Date showTime, List<Seat> seats\n- **Methods:** \n  - getAvailableSeats()\n  - bookSeat()\n  - cancelSeat()\n\n### 5. User\n- **Fields:** String id, String name, String email\n- **Methods:** \n  - getBookings()\n  - updateProfile()\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/MovieTicketBookingSystem-class-diagram.png)\n---\n\n## Example Usage\n\n```java\nMovieTicketBookingSystem system = new MovieTicketBookingSystem();\n\n// Add a movie\nMovie movie = system.addMovie(\"Inception\", 150, \"English\");\n\n// Add a theater\nTheater theater = system.addTheater(\"Cineplex\", \"Downtown\");\n\n// Add a show\nShow show = system.addShow(movie, theater, showTime);\n\n// Book tickets\nUser user = new User(\"John Doe\", \"john@example.com\");\nBooking booking = system.bookTicket(user, show, seats);\n```\n\n---\n\n## Demo\n\nSee `MovieTicketBookingDemo.java` for a sample usage and simulation of the movie parkingTicket booking system.\n\n---\n\n## Extending the Framework\n\n- **Add payment processing:** Integrate payment gateway for parkingTicket purchases\n- **Add seat selection UI:** Implement interactive seat selection interface\n- **Add pricing tiers:** Support different pricing for different seat types\n- **Add show scheduling:** Implement advanced show scheduling algorithms\n- **Add notification system:** Send booking confirmations and reminders\n- **Add user reviews:** Allow users to rate and review movies\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For the booking system instance\n- **Factory Pattern:** For creating different types of seats\n- **Observer Pattern:** For seat availability updates\n- **Strategy Pattern:** For different pricing strategies\n\n---\n\n## Exception Handling\n\n- **SeatNotAvailableException:** Thrown when trying to book an unavailable seat\n- **InvalidShowException:** Thrown when show details are invalid\n- **BookingFailedException:** Thrown when booking process fails\n- **CancellationFailedException:** Thrown when cancellation process fails\n\n---"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/SeatLockManager.java",
    "content": "package movieticketbookingsystem;\n\nimport movieticketbookingsystem.enums.SeatStatus;\nimport movieticketbookingsystem.entities.Show;\nimport movieticketbookingsystem.entities.Seat;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\npublic class SeatLockManager {\n    private final Map<Show, Map<Seat, String>> lockedSeats = new ConcurrentHashMap<>();\n    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);\n    private static final long LOCK_TIMEOUT_MS = 500; // 0.5 seconds. In real world, timeout would be in minutes\n\n    public void lockSeats(Show show, List<Seat> seats, String userId) {\n        synchronized (show) { // Synchronize on the show to ensure atomicity for that specific show\n            // Check if any of the requested seats are already locked or booked\n            for (Seat seat : seats) {\n                if (seat.getStatus() != SeatStatus.AVAILABLE) {\n                    System.out.println(\"Seat \" + seat.getId() + \" is not available.\");\n                    return;\n                }\n            }\n\n            // Lock the seats\n            for (Seat seat : seats) {\n                seat.setStatus(SeatStatus.LOCKED);\n            }\n\n            lockedSeats.computeIfAbsent(show, k -> new ConcurrentHashMap<>());\n            for (Seat seat : seats) {\n                lockedSeats.get(show).put(seat, userId);\n            }\n\n            // Schedule a task to unlock the seats after a timeout\n            scheduler.schedule(() -> unlockSeats(show, seats, userId), LOCK_TIMEOUT_MS, TimeUnit.MILLISECONDS);\n            System.out.println(\"Locked seats: \" + seats.stream().map(Seat::getId).toList() + \" for user \" + userId);\n        }\n    }\n\n    public void unlockSeats(Show show, List<Seat> seats, String userId) {\n        synchronized (show) {\n            Map<Seat, String> showLocks = lockedSeats.get(show);\n            if (showLocks != null) {\n                for (Seat seat : seats) {\n                    // Only unlock if it's still locked by the same user (prevents race conditions)\n                    if (showLocks.containsKey(seat) && showLocks.get(seat).equals(userId)) {\n                        showLocks.remove(seat);\n                        if(seat.getStatus() == SeatStatus.LOCKED) {\n                            seat.setStatus(SeatStatus.AVAILABLE);\n                            System.out.println(\"Unlocked seat: \" + seat.getId() + \" due to timeout.\");\n                        } else {\n                            showLocks.remove(seat);\n                            System.out.println(\"Unlocked seat: \" + seat.getId() + \" due to booking completion.\");\n                        }\n                    }\n                }\n                if (showLocks.isEmpty()) {\n                    lockedSeats.remove(show);\n                }\n            }\n        }\n    }\n\n    public void shutdown() {\n        System.out.println(\"Shutting down SeatLockProvider scheduler.\");\n        scheduler.shutdown();\n        try {\n            if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {\n                scheduler.shutdownNow();\n            }\n        } catch (InterruptedException e) {\n            scheduler.shutdownNow();\n            Thread.currentThread().interrupt();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Booking.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport movieticketbookingsystem.enums.SeatStatus;\n\nimport java.util.List;\n\npublic class Booking {\n    private final String id;\n    private final User user;\n    private final Show show;\n    private final List<Seat> seats;\n    private final double totalAmount;\n    private final Payment payment;\n\n    // Private constructor to be used by the Builder\n    private Booking(String id, User user, Show show, List<Seat> seats, double totalAmount, Payment payment) {\n        this.id = id;\n        this.user = user;\n        this.show = show;\n        this.seats = seats;\n        this.totalAmount = totalAmount;\n        this.payment = payment;\n    }\n\n    // Marks seats as BOOKED upon successful booking creation\n    public void confirmBooking() {\n        for (Seat seat : seats) {\n            seat.setStatus(SeatStatus.BOOKED);\n        }\n    }\n\n    public String getId() { return id; }\n    public User getUser() { return user; }\n    public Show getShow() { return show; }\n    public List<Seat> getSeats() { return seats; }\n    public double getTotalAmount() { return totalAmount; }\n    public Payment getPayment() { return payment; }\n\n    // Static inner Builder class\n    public static class BookingBuilder {\n        private String id;\n        private User user;\n        private Show show;\n        private List<Seat> seats;\n        private double totalAmount;\n        private Payment payment;\n\n        public BookingBuilder setId(String id) {\n            this.id = id;\n            return this;\n        }\n\n        public BookingBuilder setUser(User user) {\n            this.user = user;\n            return this;\n        }\n\n        public BookingBuilder setShow(Show show) {\n            this.show = show;\n            return this;\n        }\n\n        public BookingBuilder setSeats(List<Seat> seats) {\n            this.seats = seats;\n            return this;\n        }\n\n        public BookingBuilder setTotalAmount(double totalAmount) {\n            this.totalAmount = totalAmount;\n            return this;\n        }\n\n        public BookingBuilder setPayment(Payment payment) {\n            this.payment = payment;\n            return this;\n        }\n\n        public Booking build() {\n            // Validations can be added here\n            return new Booking(id, user, show, seats, totalAmount, payment);\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Cinema.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport java.util.List;\n\npublic class Cinema {\n    private final String id;\n    private final String name;\n    private final City city;\n    private final List<Screen> screens;\n\n    public Cinema(String id, String name, City city, List<Screen> screens) {\n        this.id = id;\n        this.name = name;\n        this.city = city;\n        this.screens = screens;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public City getCity() { return city; }\n    public List<Screen> getScreens() { return screens; }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/City.java",
    "content": "package movieticketbookingsystem.entities;\n\npublic class City {\n    private final String id;\n    private final String name;\n\n    public City(String id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n}"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Movie.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport movieticketbookingsystem.observer.MovieSubject;\n\npublic class Movie extends MovieSubject {\n    private final String id;\n    private final String title;\n    private final int durationInMinutes;\n\n    public Movie(String id, String title, int durationInMinutes) {\n        this.id = id;\n        this.title = title;\n        this.durationInMinutes = durationInMinutes;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getTitle() {\n        return title;\n    }\n\n    // Additional movie details like genre, language etc. can be added here\n}"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Payment.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport movieticketbookingsystem.enums.PaymentStatus;\n\nimport java.util.UUID;\n\npublic class Payment {\n    private final String id;\n    private final double amount;\n    private final PaymentStatus status;\n    private final String transactionId;\n\n    public Payment(double amount, PaymentStatus status, String transactionId) {\n        this.id = UUID.randomUUID().toString();\n        this.amount = amount;\n        this.status = status;\n        this.transactionId = transactionId;\n    }\n\n    public PaymentStatus getStatus() { return status; }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Screen.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Screen {\n    private final String id;\n    private final List<Seat> seats;\n\n    public Screen(String id) {\n        this.id = id;\n        this.seats = new ArrayList<>();\n    }\n\n    public void addSeat(Seat seat) {\n        seats.add(seat);\n    }\n\n    public String getId() { return id; }\n    public List<Seat> getSeats() { return seats; }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Seat.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport movieticketbookingsystem.enums.SeatStatus;\nimport movieticketbookingsystem.enums.SeatType;\n\npublic class Seat {\n    private final String id;\n    private final int row;\n    private final int col;\n    private final SeatType type;\n    private SeatStatus status;\n\n    public Seat(String id, int row, int col, SeatType type) {\n        this.id = id;\n        this.row = row;\n        this.col = col;\n        this.type = type;\n        this.status = SeatStatus.AVAILABLE;\n    }\n\n    // Getters and a setter for status\n    public String getId() { return id; }\n    public int getRow() { return row; }\n    public int getCol() { return col; }\n    public SeatType getType() { return type; }\n    public SeatStatus getStatus() { return status; }\n    public void setStatus(SeatStatus status) { this.status = status; }\n}"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/Show.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport movieticketbookingsystem.strategy.pricing.PricingStrategy;\n\nimport java.time.LocalDateTime;\n\npublic class Show {\n    private final String id;\n    private final Movie movie;\n    private final Screen screen;\n    private final LocalDateTime startTime;\n    private final PricingStrategy pricingStrategy;\n\n    public Show(String id, Movie movie, Screen screen, LocalDateTime startTime, PricingStrategy pricingStrategy) {\n        this.id = id;\n        this.movie = movie;\n        this.screen = screen;\n        this.startTime = startTime;\n        this.pricingStrategy = pricingStrategy;\n    }\n\n    public String getId() { return id; }\n    public Movie getMovie() { return movie; }\n    public Screen getScreen() { return screen; }\n    public LocalDateTime getStartTime() { return startTime; }\n    public PricingStrategy getPricingStrategy() { return pricingStrategy; }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/entities/User.java",
    "content": "package movieticketbookingsystem.entities;\n\nimport java.util.UUID;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final String email;\n\n    public User(String name, String email) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/enums/PaymentStatus.java",
    "content": "package movieticketbookingsystem.enums;\n\npublic enum PaymentStatus {\n    SUCCESS,\n    FAILURE,\n    PENDING\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/enums/SeatStatus.java",
    "content": "package movieticketbookingsystem.enums;\n\npublic enum SeatStatus {\n    AVAILABLE,\n    BOOKED,\n    LOCKED // Temporarily held during booking process\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/enums/SeatType.java",
    "content": "package movieticketbookingsystem.enums;\n\npublic enum SeatType {\n    REGULAR(50.0),\n    PREMIUM(80.0),\n    RECLINER(120.0);\n\n    private final double price;\n\n    SeatType(double price) {\n        this.price = price;\n    }\n\n    public double getPrice() {\n        return price;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/observer/MovieObserver.java",
    "content": "package movieticketbookingsystem.observer;\n\nimport movieticketbookingsystem.entities.Movie;\n\npublic interface MovieObserver {\n    void update(Movie movie);\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/observer/MovieSubject.java",
    "content": "package movieticketbookingsystem.observer;\n\nimport movieticketbookingsystem.entities.Movie;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class MovieSubject {\n    private final List<MovieObserver> observers = new ArrayList<>();\n\n    public void addObserver(MovieObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(MovieObserver observer) {\n        observers.remove(observer);\n    }\n\n    public void notifyObservers() {\n        for (MovieObserver observer : observers) {\n            observer.update((Movie) this);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/observer/UserObserver.java",
    "content": "package movieticketbookingsystem.observer;\n\nimport movieticketbookingsystem.entities.Movie;\nimport movieticketbookingsystem.entities.User;\n\npublic class UserObserver implements MovieObserver {\n    private final User user;\n\n    public UserObserver(User user) {\n        this.user = user;\n    }\n\n    @Override\n    public void update(Movie movie) {\n        System.out.printf(\"Notification for %s (%s): Movie '%s' is now available for booking!%n\",\n                user.getName(), user.getId(), movie.getTitle());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/strategy/payment/CreditCardPaymentStrategy.java",
    "content": "package movieticketbookingsystem.strategy.payment;\n\nimport movieticketbookingsystem.enums.PaymentStatus;\nimport movieticketbookingsystem.entities.Payment;\n\nimport java.util.UUID;\n\npublic class CreditCardPaymentStrategy implements PaymentStrategy {\n    private final String cardNumber;\n    private final String cvv;\n\n    public CreditCardPaymentStrategy(String cardNumber, String cvv) {\n        this.cardNumber = cardNumber;\n        this.cvv = cvv;\n    }\n\n    @Override\n    public Payment pay(double amount) {\n        System.out.printf(\"Processing credit card payment of $%.2f%n\", amount);\n        // Simulate payment gateway interaction\n        boolean paymentSuccess = Math.random() > 0.05; // 95% success rate\n        return new Payment(\n                amount,\n                paymentSuccess ? PaymentStatus.SUCCESS : PaymentStatus.FAILURE,\n                \"TXN_\" + UUID.randomUUID()\n        );\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/strategy/payment/PaymentStrategy.java",
    "content": "package movieticketbookingsystem.strategy.payment;\n\nimport movieticketbookingsystem.entities.Payment;\n\npublic interface PaymentStrategy {\n    Payment pay(double amount);\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/strategy/pricing/PricingStrategy.java",
    "content": "package movieticketbookingsystem.strategy.pricing;\n\nimport movieticketbookingsystem.entities.Seat;\n\nimport java.util.List;\n\npublic interface PricingStrategy {\n    double calculatePrice(List<Seat> seats);\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/strategy/pricing/WeekdayPricingStrategy.java",
    "content": "package movieticketbookingsystem.strategy.pricing;\n\nimport movieticketbookingsystem.entities.Seat;\n\nimport java.util.List;\n\npublic class WeekdayPricingStrategy implements PricingStrategy {\n    @Override\n    public double calculatePrice(List<Seat> seats) {\n        return seats.stream().mapToDouble(seat -> seat.getType().getPrice()).sum();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/movieticketbookingsystem/strategy/pricing/WeekendPricingStrategy.java",
    "content": "package movieticketbookingsystem.strategy.pricing;\n\nimport movieticketbookingsystem.entities.Seat;\n\nimport java.util.List;\n\npublic class WeekendPricingStrategy implements PricingStrategy {\n    private static final double WEEKEND_SURCHARGE = 1.2; // 20% surcharge\n\n    @Override\n    public double calculatePrice(List<Seat> seats) {\n        double basePrice = seats.stream().mapToDouble(seat -> seat.getType().getPrice()).sum();\n        return basePrice * WEEKEND_SURCHARGE;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/MusicStreamingDemo.java",
    "content": "package musicstreamingservice;\n\n\nimport musicstreamingservice.command.NextTrackCommand;\nimport musicstreamingservice.command.PauseCommand;\nimport musicstreamingservice.command.PlayCommand;\nimport musicstreamingservice.enums.SubscriptionTier;\nimport musicstreamingservice.entities.*;\n\nimport java.util.List;\n\npublic class MusicStreamingDemo {\n    public static void main(String[] args) throws InterruptedException {\n        MusicStreamingSystem system = MusicStreamingSystem.getInstance();\n\n        // --- Setup Catalog ---\n        Artist daftPunk = new Artist(\"art1\", \"Daft Punk\");\n        system.addArtist(daftPunk);\n\n        Album discovery = new Album(\"Discovery\");\n        Song s1 = system.addSong(\"s1\", \"One More Time\", daftPunk.getId(), 320);\n        Song s2 = system.addSong(\"s2\", \"Aerodynamic\", daftPunk.getId(), 212);\n        Song s3 = system.addSong(\"s3\", \"Digital Love\", daftPunk.getId(), 301);\n        Song s4 = system.addSong(\"s4\", \"Radioactive\", daftPunk.getId(), 311);\n        discovery.addTrack(s1);\n        discovery.addTrack(s2);\n        discovery.addTrack(s3);\n        discovery.addTrack(s4);\n\n        // --- Register Users (Builder Pattern) ---\n        User freeUser = new User.Builder(\"Alice\").withSubscription(SubscriptionTier.FREE, 0).build();\n        User premiumUser = new User.Builder(\"Bob\").withSubscription(SubscriptionTier.PREMIUM, 0).build();\n        system.registerUser(freeUser);\n        system.registerUser(premiumUser);\n\n        // --- Observer Pattern: User follows artist ---\n        System.out.println(\"--- Observer Pattern Demo ---\");\n        premiumUser.followArtist(daftPunk);\n        daftPunk.releaseAlbum(discovery); // This will notify Bob\n        System.out.println();\n\n        // --- Strategy Pattern: Playback behavior ---\n        System.out.println(\"--- Strategy Pattern (Free vs Premium) & State Pattern (Player) Demo ---\");\n        Player player = system.getPlayer();\n        player.load(discovery, freeUser);\n\n        // --- Command Pattern: Controlling the player ---\n        PlayCommand play = new PlayCommand(player);\n        PauseCommand pause = new PauseCommand(player);\n        NextTrackCommand next = new NextTrackCommand(player);\n\n        play.execute(); // Plays song 1\n        next.execute(); // Plays song 2\n        pause.execute(); // Pauses song 2\n        play.execute(); // Resumes song 2\n        next.execute(); // Plays song 3\n        next.execute(); // Plays song 4 (ad for free user)\n        System.out.println();\n\n        // --- Premium user experience (no ads) ---\n        System.out.println(\"--- Premium User Experience ---\");\n        player.load(discovery, premiumUser);\n        play.execute();\n        next.execute();\n        System.out.println();\n\n        // --- Composite Pattern: Play a playlist ---\n        System.out.println(\"--- Composite Pattern Demo ---\");\n        Playlist myPlaylist = new Playlist(\"My Awesome Mix\");\n        myPlaylist.addTrack(s3); // Digital Love\n        myPlaylist.addTrack(s1); // One More Time\n\n        player.load(myPlaylist, premiumUser);\n        play.execute();\n        next.execute();\n        System.out.println();\n\n        // --- Search and Recommendation ---\n        System.out.println(\"--- Search and Recommendation Service Demo ---\");\n        List<Song> searchResults = system.searchSongsByTitle(\"love\");\n        System.out.println(\"Search results for 'love': \" + searchResults);\n\n        List<Song> recommendations = system.getSongRecommendations();\n        System.out.println(\"Your daily recommendations: \" + recommendations);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/MusicStreamingSystem.java",
    "content": "package musicstreamingservice;\n\nimport musicstreamingservice.entities.Artist;\nimport musicstreamingservice.entities.Player;\nimport musicstreamingservice.entities.Song;\nimport musicstreamingservice.entities.User;\nimport musicstreamingservice.services.RecommendationService;\nimport musicstreamingservice.services.SearchService;\nimport musicstreamingservice.strategies.recommendation.GenreBasedRecommendationStrategy;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class MusicStreamingSystem {\n    private static volatile MusicStreamingSystem instance;\n\n    private final Map<String, User> users = new HashMap<>();\n    private final Map<String, Song> songs = new HashMap<>();\n    private final Map<String, Artist> artists = new HashMap<>();\n\n    private final Player player;\n    private final SearchService searchService;\n    private final RecommendationService recommendationService;\n\n    private MusicStreamingSystem() {\n        this.player = new Player();\n        this.searchService = new SearchService();\n        this.recommendationService = new RecommendationService(new GenreBasedRecommendationStrategy());\n    }\n    public static MusicStreamingSystem getInstance() {\n        if (instance == null) {\n            synchronized (MusicStreamingSystem.class) {\n                if (instance == null) {\n                    instance = new MusicStreamingSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void registerUser(User user) {\n        users.put(user.getId(), user);\n    }\n\n    public Song addSong(String id, String title, String artistId, int duration) {\n        Song song = new Song(id, title, artists.get(artistId), duration);\n        songs.put(song.getId(), song);\n        return song;\n    }\n\n    public void addArtist(Artist artist) {\n        artists.put(artist.getId(), artist);\n    }\n\n    public List<Song> searchSongsByTitle(String title) {\n        return searchService.searchSongsByTitle(new ArrayList<>(songs.values()), title);\n    }\n\n    public List<Song> getSongRecommendations() {\n        return recommendationService.generateRecommendations(new ArrayList<>(songs.values()));\n    }\n\n    public Player getPlayer() { return player; }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/README.md",
    "content": "# Music Streaming Service (LLD)\n\n## Problem Statement\n\nDesign and implement an online music streaming service (like Spotify) that allows users to browse, search, and play songs, manage playlists, follow artists, and receive recommendations.\n\n---\n\n## Requirements\n\n- **User Management:** Users can register, log in, and manage their profiles.\n- **Browse & Search:** Users can browse and search for songs, albums, and artists.\n- **Playlists:** Users can create, update, and manage playlists.\n- **Playback Controls:** Users can play, pause, skip, and seek within songs.\n- **Recommendations:** The system recommends songs and playlists based on user preferences and listening history.\n- **Follow Artists:** Users can follow artists to get updates and recommendations.\n- **Concurrency:** The system handles concurrent requests and smooth streaming for multiple users.\n- **Scalability:** The system is scalable to handle a large volume of songs and users.\n- **Extensibility:** Easy to add features like social sharing, offline playback, or collaborative playlists.\n\n---\n\n## Core Entities\n\n- **Song:** Represents a song with properties like ID, title, artist, album, and duration.\n- **Album:** Represents an album containing multiple songs and associated with an artist.\n- **Artist:** Represents a music artist, with a list of albums and songs.\n- **User:** Represents a user with ID, username, password, playlists, and listening history.\n- **Playlist:** Represents a user-created playlist containing a list of songs.\n- **MusicLibrary:** Central repository for storing and managing songs, albums, and artists (Singleton).\n- **UserManager:** Handles user registration, login, and user-related operations (Singleton).\n- **MusicPlayer:** Handles music playback (play, pause, skip, seek).\n- **MusicRecommender:** Generates song and playlist recommendations based on user preferences and history (Singleton).\n- **MusicStreamingService:** Main entry point, initializes components, handles user requests, and manages overall functionality.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/musicstreamingservice-class-diagram.png)\n\n### 1. Song\n- **Fields:** int id, String title, Artist artist, Album album, int duration\n- **Methods:** getId(), getTitle(), getArtist(), getAlbum(), getDuration()\n\n### 2. Album\n- **Fields:** int id, String title, Artist artist, List<Song> songs\n- **Methods:** getId(), getTitle(), getArtist(), getSongs()\n\n### 3. Artist\n- **Fields:** int id, String name, List<Album> albums, List<Song> songs\n- **Methods:** getId(), getName(), getAlbums(), getSongs()\n\n### 4. User\n- **Fields:** int id, String username, String password, List<Playlist> playlists, List<Song> listeningHistory, List<Artist> followedArtists\n- **Methods:** getId(), getUsername(), getPlaylists(), followArtist(Artist), etc.\n\n### 5. Playlist\n- **Fields:** int id, String name, List<Song> songs\n- **Methods:** addSong(Song), removeSong(Song), getSongs()\n\n### 6. MusicLibrary (Singleton)\n- **Fields:** Map<Integer, Song> songs, Map<Integer, Album> albums, Map<Integer, Artist> artists\n- **Methods:** addSong(Song), addAlbum(Album), addArtist(Artist), searchSongs(String), searchAlbums(String), searchArtists(String)\n\n### 7. UserManager (Singleton)\n- **Fields:** Map<Integer, User> users\n- **Methods:** registerUser(...), login(...), getUser(int id)\n\n### 8. MusicPlayer\n- **Fields:** Song currentSong, int currentPosition, boolean isPlaying\n- **Methods:** play(Song), pause(), skip(), seek(int position)\n\n### 9. MusicRecommender (Singleton)\n- **Methods:** recommendSongs(User), recommendPlaylists(User)\n\n### 10. MusicStreamingService\n- **Fields:** MusicLibrary library, UserManager userManager, MusicPlayer player, MusicRecommender recommender\n- **Methods:** initialize(), handleUserRequest(...), etc.\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For `MusicLibrary`, `UserManager`, and `MusicRecommender` to ensure a single instance.\n---\n\n## Example Usage\n\n```java\nMusicStreamingService service = new MusicStreamingService();\nservice.initialize();\n\nUser alice = service.getUserManager().registerUser(\"alice\", \"password\");\nArtist artist = new Artist(1, \"The Beatles\");\nAlbum album = new Album(1, \"Abbey Road\", artist);\nSong song = new Song(1, \"Come Together\", artist, album, 259);\n\nservice.getLibrary().addArtist(artist);\nservice.getLibrary().addAlbum(album);\nservice.getLibrary().addSong(song);\n\nalice.getPlaylists().add(new Playlist(1, \"Favorites\"));\nalice.getPlaylists().get(0).addSong(song);\n\nservice.getPlayer().play(song);\n```\n\n---\n\n## Demo\n\nSee `MusicStreamingServiceDemo.java` for a sample usage and simulation of the music streaming service.\n\n---\n\n## Extending the Framework\n\n- **Add social features:** Allow users to share playlists or follow each other.\n- **Add offline playback:** Support downloading songs for offline listening.\n- **Add collaborative playlists:** Allow multiple users to edit a playlist.\n\n---"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/command/Command.java",
    "content": "package musicstreamingservice.command;\n\npublic interface Command {\n    void execute();\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/command/NextTrackCommand.java",
    "content": "package musicstreamingservice.command;\n\nimport musicstreamingservice.entities.Player;\n\npublic class NextTrackCommand implements Command {\n    private final Player player;\n\n    public NextTrackCommand(Player player) { this.player = player; }\n\n    @Override\n    public void execute() { player.clickNext(); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/command/PauseCommand.java",
    "content": "package musicstreamingservice.command;\n\nimport musicstreamingservice.entities.Player;\n\npublic class PauseCommand implements Command {\n    private final Player player;\n\n    public PauseCommand(Player player) { this.player = player; }\n\n    @Override\n    public void execute() { player.clickPause(); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/command/PlayCommand.java",
    "content": "package musicstreamingservice.command;\n\nimport musicstreamingservice.entities.Player;\n\npublic class PlayCommand implements Command {\n    private final Player player;\n\n    public PlayCommand(Player player) { this.player = player; }\n\n    @Override\n    public void execute() { player.clickPlay(); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Album.java",
    "content": "package musicstreamingservice.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Album implements Playable {\n    private final String title;\n    private final List<Song> tracks = new ArrayList<>();\n\n    public Album(String title) {\n        this.title = title;\n    }\n    public void addTrack(Song song) { tracks.add(song); }\n\n    @Override\n    public List<Song> getTracks() { return List.copyOf(tracks); }\n\n    public String getTitle() { return title; }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Artist.java",
    "content": "package musicstreamingservice.entities;\n\nimport musicstreamingservice.observer.Subject;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Artist extends Subject {\n    private final String id;\n    private final String name;\n    private final List<Album> discography = new ArrayList<>();\n\n    public Artist(String id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n    public void releaseAlbum(Album album) {\n        discography.add(album);\n        System.out.printf(\"[System] Artist %s has released a new album: %s%n\", name, album.getTitle());\n        notifyObservers(this, album);\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Playable.java",
    "content": "package musicstreamingservice.entities;\n\nimport java.util.List;\n\npublic interface Playable {\n    List<Song> getTracks();\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Player.java",
    "content": "package musicstreamingservice.entities;\n\nimport musicstreamingservice.enums.PlayerStatus;\nimport musicstreamingservice.state.PlayerState;\nimport musicstreamingservice.state.StoppedState;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Player {\n    private PlayerState state;\n    private PlayerStatus status;\n    private List<Song> queue = new ArrayList<>();\n    private int currentIndex = -1;\n    private Song currentSong;\n    private User currentUser;\n\n    public Player() {\n        this.state = new StoppedState();\n        this.status = PlayerStatus.STOPPED;\n    }\n\n    public void load(Playable playable, User user) {\n        this.currentUser = user;\n        this.queue = playable.getTracks();\n        this.currentIndex = 0;\n        System.out.printf(\"Loaded %d tracks for user %s.%n\", queue.size(), user.getName());\n        this.state = new StoppedState();\n    }\n\n    public void playCurrentSongInQueue() {\n        if (currentIndex >= 0 && currentIndex < queue.size()) {\n            Song songToPlay = queue.get(currentIndex);\n            currentUser.getPlaybackStrategy().play(songToPlay, this);\n        }\n    }\n\n    // Methods for state transitions\n    public void clickPlay() { state.play(this); }\n    public void clickPause() { state.pause(this); }\n\n    public void clickNext() {\n        if (currentIndex < queue.size() - 1) {\n            currentIndex++;\n            playCurrentSongInQueue();\n        } else {\n            System.out.println(\"End of queue.\");\n            state.stop(this);\n        }\n    }\n\n    // Getters and Setters used by States\n    public void changeState(PlayerState state) { this.state = state; }\n    public void setStatus(PlayerStatus status) { this.status = status; }\n    public void setCurrentSong(Song song) { this.currentSong = song; }\n    public boolean hasQueue() { return !queue.isEmpty(); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Playlist.java",
    "content": "package musicstreamingservice.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Playlist implements Playable {\n    private final String name;\n    private final List<Song> tracks = new ArrayList<>();\n\n    public Playlist(String name) { this.name = name; }\n\n    public void addTrack(Song song) { tracks.add(song); }\n\n    @Override\n    public List<Song> getTracks() { return List.copyOf(tracks); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/Song.java",
    "content": "package musicstreamingservice.entities;\n\nimport java.util.Collections;\nimport java.util.List;\n\npublic class Song implements Playable {\n    private final String id;\n    private final String title;\n    private final Artist artist;\n    private final int durationInSeconds;\n\n    public Song(String id, String title, Artist artist, int durationInSeconds) {\n        this.id = id;\n        this.title = title;\n        this.artist = artist;\n        this.durationInSeconds = durationInSeconds;\n    }\n\n    @Override\n    public List<Song> getTracks() {\n        return Collections.singletonList(this);\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"'%s' by %s\", title, artist.getName());\n    }\n\n    public String getId() { return id; }\n    public String getTitle() { return title; }\n    public Artist getArtist() { return artist; }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/entities/User.java",
    "content": "package musicstreamingservice.entities;\n\nimport musicstreamingservice.enums.SubscriptionTier;\nimport musicstreamingservice.observer.ArtistObserver;\nimport musicstreamingservice.strategies.playback.PlaybackStrategy;\n\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.UUID;\n\npublic class User implements ArtistObserver {\n    private final String id;\n    private final String name;\n    private final PlaybackStrategy playbackStrategy;\n    private final Set<Artist> followedArtists = new HashSet<>();\n\n    private User(String id, String name, PlaybackStrategy strategy) {\n        this.id = id;\n        this.name = name;\n        this.playbackStrategy = strategy;\n    }\n\n    public void followArtist(Artist artist) {\n        followedArtists.add(artist);\n        artist.addObserver(this);\n    }\n\n    @Override\n    public void update(Artist artist, Album newAlbum) {\n        System.out.printf(\"[Notification for %s] Your followed artist %s just released a new album: %s!%n\",\n                this.name, artist.getName(), newAlbum.getTitle());\n    }\n\n    public PlaybackStrategy getPlaybackStrategy() { return playbackStrategy; }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n\n    // Builder Pattern\n    public static class Builder {\n        private final String id;\n        private final String name;\n        private PlaybackStrategy playbackStrategy;\n\n        public Builder(String name) {\n            this.id = UUID.randomUUID().toString();\n            this.name = name;\n        }\n        public Builder withSubscription(SubscriptionTier tier, int songsPlayed) {\n            this.playbackStrategy = PlaybackStrategy.getStrategy(tier, songsPlayed);\n            return this;\n        }\n        public User build() {\n            return new User(id, name, playbackStrategy);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/enums/PlayerStatus.java",
    "content": "package musicstreamingservice.enums;\n\npublic enum PlayerStatus {\n    PLAYING,\n    PAUSED,\n    STOPPED\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/enums/SubscriptionTier.java",
    "content": "package musicstreamingservice.enums;\n\npublic enum SubscriptionTier {\n    FREE,\n    PREMIUM\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/observer/ArtistObserver.java",
    "content": "package musicstreamingservice.observer;\n\nimport musicstreamingservice.entities.Album;\nimport musicstreamingservice.entities.Artist;\n\npublic interface ArtistObserver {\n    void update(Artist artist, Album newAlbum);\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/observer/Subject.java",
    "content": "package musicstreamingservice.observer;\n\nimport musicstreamingservice.entities.Album;\nimport musicstreamingservice.entities.Artist;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class Subject {\n    private final List<ArtistObserver> observers = new ArrayList<>();\n\n    public void addObserver(ArtistObserver observer) { observers.add(observer); }\n\n    public void removeObserver(ArtistObserver observer) { observers.remove(observer); }\n\n    public void notifyObservers(Artist artist, Album album) {\n        for (ArtistObserver observer : observers) {\n            observer.update(artist, album);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/services/RecommendationService.java",
    "content": "package musicstreamingservice.services;\n\nimport musicstreamingservice.entities.Song;\nimport musicstreamingservice.strategies.recommendation.RecommendationStrategy;\n\nimport java.util.List;\n\npublic class RecommendationService {\n    private RecommendationStrategy strategy;\n\n    public RecommendationService(RecommendationStrategy strategy) { this.strategy = strategy; }\n\n    public void setStrategy(RecommendationStrategy strategy) { this.strategy = strategy; }\n\n    public List<Song> generateRecommendations(List<Song> allSongs) {\n        return strategy.recommend(allSongs);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/services/SearchService.java",
    "content": "package musicstreamingservice.services;\n\nimport musicstreamingservice.entities.Artist;\nimport musicstreamingservice.entities.Song;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class SearchService {\n    public List<Song> searchSongsByTitle(List<Song> songs, String query) {\n        return songs.stream()\n                .filter(s -> s.getTitle().toLowerCase().contains(query.toLowerCase()))\n                .collect(Collectors.toList());\n    }\n    public List<Artist> searchArtistsByName(List<Artist> artists, String query) {\n        return artists.stream()\n                .filter(a -> a.getName().toLowerCase().contains(query.toLowerCase()))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/state/PausedState.java",
    "content": "package musicstreamingservice.state;\n\nimport musicstreamingservice.enums.PlayerStatus;\nimport musicstreamingservice.entities.Player;\n\npublic class PausedState implements PlayerState {\n    @Override\n    public void play(Player player) {\n        System.out.println(\"Resuming playback.\");\n        player.changeState(new PlayingState());\n        player.setStatus(PlayerStatus.PLAYING);\n    }\n\n    @Override\n    public void pause(Player player) { System.out.println(\"Already paused.\"); }\n\n    @Override\n    public void stop(Player player) {\n        System.out.println(\"Stopping playback from paused state.\");\n        player.changeState(new StoppedState());\n        player.setStatus(PlayerStatus.STOPPED);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/state/PlayerState.java",
    "content": "package musicstreamingservice.state;\n\nimport musicstreamingservice.entities.Player;\n\npublic interface PlayerState {\n    void play(Player player);\n    void pause(Player player);\n    void stop(Player player);\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/state/PlayingState.java",
    "content": "package musicstreamingservice.state;\n\nimport musicstreamingservice.enums.PlayerStatus;\nimport musicstreamingservice.entities.Player;\n\npublic class PlayingState implements PlayerState {\n    @Override\n    public void play(Player player) { System.out.println(\"Already playing.\"); }\n\n    @Override\n    public void pause(Player player) {\n        System.out.println(\"Pausing playback.\" + player);\n        player.changeState(new PausedState());\n        player.setStatus(PlayerStatus.PAUSED);\n    }\n\n    @Override\n    public void stop(Player player) {\n        System.out.println(\"Stopping playback.\");\n        player.changeState(new StoppedState());\n        player.setStatus(PlayerStatus.STOPPED);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/state/StoppedState.java",
    "content": "package musicstreamingservice.state;\n\nimport musicstreamingservice.enums.PlayerStatus;\nimport musicstreamingservice.entities.Player;\n\npublic class StoppedState implements PlayerState {\n    @Override\n    public void play(Player player) {\n        if (player.hasQueue()) {\n            System.out.println(\"Starting playback.\");\n            player.changeState(new PlayingState());\n            player.setStatus(PlayerStatus.PLAYING);\n            player.playCurrentSongInQueue();\n        } else {\n            System.out.println(\"Queue is empty. Load songs to play.\");\n        }\n    }\n\n    @Override\n    public void pause(Player player) { System.out.println(\"Cannot pause. Player is stopped.\"); }\n\n    @Override\n    public void stop(Player player) { System.out.println(\"Already stopped.\"); }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/strategies/playback/FreePlaybackStrategy.java",
    "content": "package musicstreamingservice.strategies.playback;\n\nimport musicstreamingservice.entities.Player;\nimport musicstreamingservice.entities.Song;\n\npublic class FreePlaybackStrategy implements PlaybackStrategy {\n    private int songsPlayed;\n    private static final int SONGS_BEFORE_AD = 3;\n\n    public FreePlaybackStrategy(int initialSongsPlayed) {\n        this.songsPlayed = initialSongsPlayed;\n    }\n\n    @Override\n    public void play(Song song, Player player) {\n        if (songsPlayed > 0 && songsPlayed % SONGS_BEFORE_AD == 0) {\n            System.out.println(\"\\n>>> Playing Advertisement: 'Buy Spotify Premium for ad-free music!' <<<\\n\");\n        }\n        player.setCurrentSong(song);\n        System.out.printf(\"Free User is now playing: %s%n\", song);\n        songsPlayed++;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/strategies/playback/PlaybackStrategy.java",
    "content": "package musicstreamingservice.strategies.playback;\n\nimport musicstreamingservice.enums.SubscriptionTier;\nimport musicstreamingservice.entities.Player;\nimport musicstreamingservice.entities.Song;\n\npublic interface PlaybackStrategy {\n    void play(Song song, Player player);\n\n    // Simple Factory method to get the correct strategy\n    static PlaybackStrategy getStrategy(SubscriptionTier tier, int songsPlayed) {\n        return tier == SubscriptionTier.PREMIUM ? new PremiumPlaybackStrategy() : new FreePlaybackStrategy(songsPlayed);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/strategies/playback/PremiumPlaybackStrategy.java",
    "content": "package musicstreamingservice.strategies.playback;\n\nimport musicstreamingservice.entities.Player;\nimport musicstreamingservice.entities.Song;\n\npublic class PremiumPlaybackStrategy implements PlaybackStrategy {\n    @Override\n    public void play(Song song, Player player) {\n        player.setCurrentSong(song);\n        System.out.printf(\"Premium User is now playing: %s%n\", song);\n    }\n}"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/strategies/recommendation/GenreBasedRecommendationStrategy.java",
    "content": "package musicstreamingservice.strategies.recommendation;\n\nimport musicstreamingservice.entities.Song;\n\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class GenreBasedRecommendationStrategy implements RecommendationStrategy {\n    // In a real system, songs would have genres. We simulate this.\n    @Override\n    public List<Song> recommend(List<Song> allSongs) {\n        System.out.println(\"Generating genre-based recommendations (simulated)...\");\n        List<Song> shuffled = new java.util.ArrayList<>(allSongs);\n        Collections.shuffle(shuffled);\n        return shuffled.stream().limit(5).collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/musicstreamingservice/strategies/recommendation/RecommendationStrategy.java",
    "content": "package musicstreamingservice.strategies.recommendation;\n\nimport musicstreamingservice.entities.Song;\n\nimport java.util.List;\n\npublic interface RecommendationStrategy {\n    List<Song> recommend(List<Song> allSongs);\n}\n"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/AuctionService.java",
    "content": "package onlineauctionsystem;\n\nimport onlineauctionsystem.entities.Auction;\nimport onlineauctionsystem.entities.User;\n\nimport java.math.BigDecimal;\nimport java.time.LocalDateTime;\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.ScheduledExecutorService;\nimport java.util.concurrent.TimeUnit;\n\npublic class AuctionService {\n    private static AuctionService instance;\n    private final Map<String, User> users;\n    private final Map<String, Auction> auctions;\n    private final ScheduledExecutorService scheduler;\n\n    private AuctionService() {\n        users = new ConcurrentHashMap<>();\n        auctions = new ConcurrentHashMap<>();\n        this.scheduler = Executors.newScheduledThreadPool(1);\n    }\n\n    public static synchronized AuctionService getInstance() {\n        if (instance == null) {\n            instance = new AuctionService();\n        }\n        return instance;\n    }\n\n    public User createUser(String name) {\n        User user = new User(name);\n        users.put(user.getId(), user);\n        return user;\n    }\n\n    public User getUser(String userId) {\n        return users.get(userId);\n    }\n\n    public Auction createAuction(String itemName, String description, BigDecimal startingPrice, LocalDateTime endTime) {\n        Auction auction = new Auction(itemName, description, startingPrice, endTime);\n        auctions.put(auction.getId(), auction);\n\n        // In a real system, you'd use a scheduler to automatically end auctions.\n        // This demonstrates how it would be done.\n        long delay = java.time.Duration.between(LocalDateTime.now(), endTime).toMillis();\n        scheduler.schedule(() -> endAuction(auction.getId()), delay, TimeUnit.MILLISECONDS);\n\n        System.out.printf(\"New auction created for '%s' (ID: %s), ending at %s.\\n\", itemName, auction.getId(), endTime);\n        return auction;\n    }\n\n    public List<Auction> viewActiveAuctions() {\n        return auctions.values().stream().filter(Auction::isActive).toList();\n    }\n\n    public void placeBid(String auctionId, String bidderId, BigDecimal amount) {\n        Auction auction = getAuction(auctionId);\n        auction.placeBid(users.get(bidderId), amount);\n    }\n\n    public void endAuction(String auctionId) {\n        Auction auction = getAuction(auctionId);\n        auction.endAuction();\n    }\n\n    public Auction getAuction(String auctionId) {\n        Auction auction = auctions.get(auctionId);\n        if (auction == null) {\n            throw new NoSuchElementException(\"Auction with ID \" + auctionId + \" not found.\");\n        }\n        return auction;\n    }\n\n    public void shutdown() {\n        scheduler.shutdown();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/AuctionSystemDemo.java",
    "content": "package onlineauctionsystem;\n\nimport onlineauctionsystem.entities.Auction;\nimport onlineauctionsystem.entities.User;\n\nimport java.math.BigDecimal;\nimport java.time.LocalDateTime;\n\npublic class AuctionSystemDemo {\n    public static void main(String[] args) {\n        AuctionService auctionService = AuctionService.getInstance();\n\n        // Create users\n        User alice = auctionService.createUser(\"Alice\");\n        User bob = auctionService.createUser(\"Bob\");\n        User carol = auctionService.createUser(\"Carol\");\n\n        System.out.println(\"=============================================\");\n        System.out.println(\"        Online Auction System Demo           \");\n        System.out.println(\"=============================================\");\n\n        // 2. Create an auction that will last for a short duration\n        LocalDateTime endTime = LocalDateTime.now().plusSeconds(10);\n        Auction laptopAuction = auctionService.createAuction(\n                \"Vintage Laptop\",\n                \"A rare 1990s laptop, in working condition.\",\n                new BigDecimal(\"100.00\"),\n                endTime\n        );\n        System.out.println();\n\n        // 3. Bidding war starts\n        try {\n            auctionService.placeBid(laptopAuction.getId(), alice.getId(), new BigDecimal(\"110.00\"));\n            Thread.sleep(500); // Simulate time passing\n\n            auctionService.placeBid(laptopAuction.getId(), bob.getId(), new BigDecimal(\"120.00\")); // Alice gets an outbid notification\n            Thread.sleep(500);\n\n            auctionService.placeBid(laptopAuction.getId(), carol.getId(), new BigDecimal(\"125.00\")); // Bob gets an outbid notification\n            Thread.sleep(500);                                                               // (Charlie's bid is earlier for the same amount, making him the highest bidder)\n\n            auctionService.placeBid(laptopAuction.getId(), alice.getId(), new BigDecimal(\"150.00\")); // Charlie gets an outbid notification\n\n            // 4. Wait for the auction to end automatically via the scheduler\n            System.out.println(\"\\n--- Waiting for auction to end automatically... ---\");\n            Thread.sleep(2 * 1000); // Wait longer than the auction duration\n        } catch (Exception e) {\n            System.err.println(\"An error occurred during bidding: \" + e.getMessage());\n        }\n\n        // 5. Post-auction actions\n        System.out.println(\"\\n--- Post-Auction Information ---\");\n        Auction endedAuction = auctionService.getAuction(laptopAuction.getId());\n\n        // Display winner\n        if (endedAuction.getWinningBid() != null) {\n            System.out.printf(\"Final Winner: %s\\n\", endedAuction.getWinningBid().getBidder().getName());\n            System.out.printf(\"Winning Price: $%.2f\\n\", endedAuction.getWinningBid().getAmount());\n        } else {\n            System.out.println(\"The auction ended with no winner.\");\n        }\n\n        // Display bid history\n        System.out.println(\"\\nFull Bid History:\");\n        endedAuction.getBidHistory().forEach(System.out::println);\n\n        // 6. Try to bid on an ended auction\n        System.out.println(\"\\n--- Attempting to bid on an ended auction ---\");\n        try {\n            auctionService.placeBid(laptopAuction.getId(), bob.getId(), new BigDecimal(\"200.00\"));\n        } catch (IllegalStateException e) {\n            System.out.println(\"CAUGHT EXPECTED ERROR: \" + e.getMessage());\n        }\n\n        // 7. Shutdown the scheduler\n        auctionService.shutdown();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/README.md",
    "content": "# Online Auction System (LLD)\n\n## Problem Statement\n\nDesign and implement an Online Auction System that allows users to create auctions, place bids on items, track auction status, and determine winners.\n\n---\n\n## Requirements\n\n- **User Management:** Users can register and participate in auctions.\n- **Item Management:** The system manages items that can be auctioned.\n- **Auction Creation:** Users can create auctions for items, specifying start and end times.\n- **Bidding:** Users can place bids on active auctions.\n- **Auction Status Tracking:** The system tracks the status of each auction (e.g., ACTIVE, ENDED).\n- **Winner Determination:** The system determines the winning bid and user when an auction ends.\n- **Extensibility:** Easy to add new features such as reserve prices, buy-now options, or notifications.\n\n---\n\n## Core Entities\n\n- **AuctionSystem:** Main class that manages users, items, auctions, and bidding.\n- **User:** Represents a user who can create auctions and place bids.\n- **Item:** Represents an item to be auctioned.\n- **Auction:** Represents an auction for an item, including bids, status, and winner.\n- **Bid:** Represents a bid placed by a user on an auction.\n- **AuctionStatus:** Enum for auction status (ACTIVE, ENDED).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/onlineauctionsystem-class-diagram.png)\n\n### 1. AuctionSystem\n- **Fields:** List<User> users, List<Item> items, List<Auction> auctions\n- **Methods:** registerUser(User), addItem(Item), createAuction(Item, User, Date startTime, Date endTime), placeBid(Auction, User, double amount), endAuction(Auction), getActiveAuctions(), getEndedAuctions(), etc.\n\n### 2. User\n- **Fields:** int id, String name\n\n### 3. Item\n- **Fields:** int id, String name, String description\n\n### 4. Auction\n- **Fields:** int id, Item item, User seller, List<Bid> bids, AuctionStatus status, User winner, Date startTime, Date endTime\n- **Methods:** addBid(Bid), endAuction(), getHighestBid(), getWinner()\n\n### 5. Bid\n- **Fields:** int id, User bidder, double amount, Date bidTime\n\n### 6. AuctionStatus (enum)\n- Values: ACTIVE, ENDED\n\n---\n\n## Example Usage\n\n```java\nAuctionSystem system = new AuctionSystem();\nUser alice = new User(1, \"Alice\");\nUser bob = new User(2, \"Bob\");\nsystem.registerUser(alice);\nsystem.registerUser(bob);\n\nItem painting = new Item(1, \"Painting\", \"Beautiful landscape painting\");\nsystem.addItem(painting);\n\nAuction auction = system.createAuction(painting, alice, new Date(), new Date(System.currentTimeMillis() + 3600000));\nsystem.placeBid(auction, bob, 100.0);\nsystem.placeBid(auction, alice, 120.0);\n\nsystem.endAuction(auction);\nUser winner = auction.getWinner();\nSystem.out.println(\"Winner: \" + (winner != null ? winner.getName() : \"No winner\"));\n```\n\n---\n\n## Demo\n\nSee `AuctionSystemDemo.java` for a sample usage and simulation of the online auction system.\n\n---\n\n## Extending the Framework\n\n- **Add reserve prices:** Only sell if the highest bid meets the minimum price.\n- **Add buy-now options:** Allow instant purchase at a set price.\n- **Add notifications:** Notify users of auction events or outbids.\n\n---"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/entities/Auction.java",
    "content": "package onlineauctionsystem.entities;\n\nimport onlineauctionsystem.enums.AuctionStatus;\nimport onlineauctionsystem.observer.AuctionObserver;\n\nimport java.math.BigDecimal;\nimport java.time.LocalDateTime;\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Auction {\n    private final String id;\n    private final String itemName;\n    private final String description;\n    private final BigDecimal startingPrice;\n    private final LocalDateTime endTime;\n\n    private final List<Bid> bids;\n    private final Set<AuctionObserver> observers;\n    private AuctionStatus state;\n    private Bid winningBid;\n\n    public Auction(String itemName, String description, BigDecimal startingPrice, LocalDateTime endTime) {\n        this.id = UUID.randomUUID().toString();\n        this.itemName = itemName;\n        this.description = description;\n        this.startingPrice = startingPrice;\n        this.endTime = endTime;\n        this.bids = new ArrayList<>();\n        this.observers = ConcurrentHashMap.newKeySet(); // Thread-safe set\n        this.state = AuctionStatus.ACTIVE;\n    }\n\n    // --- Core Bidding and Auction Logic ---\n\n    public synchronized void placeBid(User bidder, BigDecimal amount) {\n        if (state != AuctionStatus.ACTIVE) {\n            throw new IllegalStateException(\"Auction is not active.\");\n        }\n        if (LocalDateTime.now().isAfter(endTime)) {\n            endAuction();\n            throw new IllegalStateException(\"Auction has already ended.\");\n        }\n\n        Bid highestBid = getHighestBid();\n        BigDecimal currentMaxAmount = (highestBid == null) ? startingPrice : highestBid.getAmount();\n\n        if (amount.compareTo(currentMaxAmount) <= 0) {\n            throw new IllegalArgumentException(\"Bid must be higher than the current highest bid.\");\n        }\n\n        User previousHighestBidder = (highestBid != null) ? highestBid.getBidder() : null;\n\n        Bid newBid = new Bid(bidder, amount);\n        bids.add(newBid);\n        addObserver(bidder); // The new bidder is now an observer\n\n        System.out.printf(\"SUCCESS: %s placed a bid of $%.2f on '%s'.\\n\", bidder.getName(), amount, itemName);\n\n        // Notify the previous highest bidder that they have been outbid\n        if (previousHighestBidder != null && !previousHighestBidder.equals(bidder)) {\n            notifyObserver(previousHighestBidder, String.format(\"You have been outbid on '%s'! The new highest bid is $%.2f.\", itemName, amount));\n        }\n    }\n\n    public synchronized void endAuction() {\n        if (state != AuctionStatus.ACTIVE) {\n            return; // Already ended\n        }\n\n        this.state = AuctionStatus.CLOSED;\n        this.winningBid = getHighestBid();\n\n        String endMessage;\n        if (winningBid != null) {\n            endMessage = String.format(\"Auction for '%s' has ended. Winner is %s with a bid of $%.2f!\",\n                    itemName, winningBid.getBidder().getName(), winningBid.getAmount());\n        } else {\n            endMessage = String.format(\"Auction for '%s' has ended. There were no bids.\", itemName);\n        }\n\n        System.out.println(\"\\n\" + endMessage.toUpperCase());\n        notifyAllObservers(endMessage);\n    }\n\n    public Bid getHighestBid() {\n        if (bids.isEmpty()) {\n            return null;\n        }\n        return Collections.max(bids);\n    }\n\n    public boolean isActive() {\n        return state == AuctionStatus.ACTIVE;\n    }\n\n    // --- Observer Pattern Methods ---\n\n    private void addObserver(AuctionObserver observer) {\n        observers.add(observer);\n    }\n\n    private void notifyAllObservers(String message) {\n        for (AuctionObserver observer : observers) {\n            observer.onUpdate(this, message);\n        }\n    }\n\n    private void notifyObserver(AuctionObserver observer, String message) {\n        observer.onUpdate(this, message);\n    }\n\n    // --- Getters ---\n    public String getId() { return id; }\n    public String getItemName() { return itemName; }\n    public List<Bid> getBidHistory() { return Collections.unmodifiableList(bids); }\n    public AuctionStatus getState() { return state; }\n    public Bid getWinningBid() { return winningBid; }\n}"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/entities/Bid.java",
    "content": "package onlineauctionsystem.entities;\n\nimport java.math.BigDecimal;\nimport java.time.LocalDateTime;\n\npublic class Bid implements Comparable<Bid> {\n    private final User bidder;\n    private final BigDecimal amount;\n    private final LocalDateTime timestamp;\n\n    public Bid(User bidder, BigDecimal amount) {\n        this.bidder = bidder;\n        this.amount = amount;\n        this.timestamp = LocalDateTime.now();\n    }\n\n    public User getBidder() {\n        return bidder;\n    }\n\n    public BigDecimal getAmount() {\n        return amount;\n    }\n\n    public LocalDateTime getTimestamp() {\n        return timestamp;\n    }\n\n    @Override\n    public int compareTo(Bid other) {\n        int amountComparison = this.amount.compareTo(other.amount);\n        if (amountComparison != 0) {\n            return amountComparison;\n        }\n        return other.timestamp.compareTo(this.timestamp);\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"Bidder: %s, Amount: %.2f, Time: %s\", bidder.getName(), amount, timestamp);\n    }\n}"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/entities/User.java",
    "content": "package onlineauctionsystem.entities;\n\nimport onlineauctionsystem.observer.AuctionObserver;\n\nimport java.util.UUID;\n\npublic class User implements AuctionObserver {\n    private final String id;\n    private final String name;\n\n    public User(String name) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    @Override\n    public void onUpdate(Auction auction, String message) {\n        System.out.printf(\"--- Notification for %s ---\\n\", this.name);\n        System.out.printf(\"Auction: %s\\n\", auction.getItemName());\n        System.out.printf(\"Message: %s\\n\", message);\n        System.out.println(\"---------------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/enums/AuctionStatus.java",
    "content": "package onlineauctionsystem.enums;\n\npublic enum AuctionStatus {\n    PENDING,\n    ACTIVE,\n    CLOSED\n}\n"
  },
  {
    "path": "solutions/java/src/onlineauctionsystem/observer/AuctionObserver.java",
    "content": "package onlineauctionsystem.observer;\n\nimport onlineauctionsystem.entities.Auction;\n\npublic interface AuctionObserver {\n    void onUpdate(Auction auction, String message);\n}\n"
  },
  {
    "path": "solutions/java/src/onlinelearningplatform/README.md",
    "content": ""
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/OnlineShoppingDemo.java",
    "content": "package onlineshoppingservice;\n\nimport onlineshoppingservice.decorator.GiftWrapDecorator;\nimport onlineshoppingservice.enums.ProductCategory;\nimport onlineshoppingservice.models.*;\nimport onlineshoppingservice.strategy.CreditCardPaymentStrategy;\nimport onlineshoppingservice.strategy.UPIPaymentStrategy;\n\npublic class OnlineShoppingDemo {\n    public static void main(String[] args) {\n        // --- System Setup (Singleton and Services) ---\n        OnlineShoppingSystem system = OnlineShoppingSystem.getInstance();\n\n        // --- Create and Add Products to Catalog (Builder Pattern) ---\n        Product laptop = new Product.Builder(\"Dell XPS 15\", 1499.99)\n                .withDescription(\"A powerful and sleek laptop.\")\n                .withCategory(ProductCategory.ELECTRONICS)\n                .build();\n        Product book = new Product.Builder(\"The Pragmatic Programmer\", 45.50)\n                .withDescription(\"A classic book for software developers.\")\n                .withCategory(ProductCategory.BOOKS)\n                .build();\n\n        system.addProduct(laptop, 10); // 10 laptops in stock\n        system.addProduct(book, 50);   // 50 books in stock\n\n        // --- Register a Customer ---\n        Address aliceAddress = new Address(\"123 Main St\", \"Anytown\", \"CA\", \"12345\");\n        Customer alice = system.registerCustomer(\"Alice\", \"alice@example.com\", \"password123\", aliceAddress);\n\n        // --- Alice Shops ---\n        System.out.println(\"--- Alice starts shopping ---\");\n\n        // Alice adds a laptop to her cart\n        system.addToCart(alice.getId(), laptop.getId(), 1);\n        System.out.println(\"Alice added a laptop to her cart.\");\n\n        // Alice decides to gift-wrap the book (Decorator Pattern)\n        Product giftWrappedBook = new GiftWrapDecorator(book);\n        system.addToCart(alice.getId(), giftWrappedBook.getId(), 1);\n        System.out.printf(\"Alice added a gift-wrapped book. Original price: $%.2f, New price: $%.2f%n\",\n                book.getPrice(), giftWrappedBook.getPrice());\n\n        ShoppingCart aliceCart = system.getCustomerCart(alice.getId());\n        System.out.printf(\"Alice's cart total: $%.2f%n\", aliceCart.calculateTotal());\n\n        // --- Alice Checks Out ---\n        System.out.println(\"\\n--- Alice proceeds to checkout ---\");\n        Order aliceOrder = system.placeOrder(alice.getId(), new CreditCardPaymentStrategy(\"1234-5678-9876-5432\"));\n        if (aliceOrder == null) {\n            System.out.println(\"Order placement failed.\");\n            return;\n        }\n\n        System.out.printf(\"Order #%s placed successfully for Alice.%n\", aliceOrder.getId());\n\n        // --- Order State and Notifications (State, Observer Patterns) ---\n        System.out.println(\"\\n--- Order processing starts ---\");\n\n        // The warehouse ships the order\n        aliceOrder.shipOrder(); // This will trigger a notification to Alice\n\n        // The delivery service marks the order as delivered\n        aliceOrder.deliverOrder(); // This will also trigger a notification\n\n        // Try to cancel a delivered order (State pattern prevents this)\n        aliceOrder.cancelOrder();\n\n        System.out.println(\"\\n--- Out of Stock Scenario ---\");\n        Customer bob = system.registerCustomer(\"Bob\", \"bob@example.com\", \"pass123\", aliceAddress);\n\n        // Bob tries to buy 15 laptops, but only 9 are left (1 was bought by Alice)\n        system.addToCart(bob.getId(), laptop.getId(), 15);\n\n        Order bobOrder = system.placeOrder(bob.getId(), new UPIPaymentStrategy(\"testupi@hdfc\"));\n        if (bobOrder == null) {\n            System.out.println(\"Bob's order was correctly prevented due to insufficient stock.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/OnlineShoppingSystem.java",
    "content": "package onlineshoppingservice;\n\nimport onlineshoppingservice.models.*;\nimport onlineshoppingservice.services.InventoryService;\nimport onlineshoppingservice.services.OrderService;\nimport onlineshoppingservice.services.PaymentService;\nimport onlineshoppingservice.services.SearchService;\nimport onlineshoppingservice.strategy.PaymentStrategy;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class OnlineShoppingSystem {\n    private static volatile OnlineShoppingSystem instance;\n\n    // Data stores\n    private final Map<String, Product> products = new ConcurrentHashMap<>();\n    private final Map<String, Customer> customers = new ConcurrentHashMap<>();\n    private final Map<String, Order> orders = new ConcurrentHashMap<>();\n\n    // Services\n    private final InventoryService inventoryService;\n    private final PaymentService paymentService;\n    private final OrderService orderService;\n    private final SearchService searchService;\n\n    private OnlineShoppingSystem() {\n        this.inventoryService = new InventoryService();\n        this.paymentService = new PaymentService();\n        this.orderService = new OrderService(inventoryService);\n        this.searchService = new SearchService(products.values());\n    }\n\n    public static OnlineShoppingSystem getInstance() {\n        if (instance == null) {\n            synchronized (OnlineShoppingSystem.class) {\n                if (instance == null) {\n                    instance = new OnlineShoppingSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    // --- Facade Methods for simplified interaction ---\n    public void addProduct(Product product, int initialStock) {\n        products.put(product.getId(), product);\n        inventoryService.addStock(product, initialStock);\n    }\n\n    public Customer registerCustomer(String name, String email, String password, Address address) {\n        Customer customer = new Customer(name, email, password, address);\n        customers.put(customer.getId(), customer);\n        return customer;\n    }\n\n    public void addToCart(String customerId, String productId, int quantity) {\n        Customer customer = customers.get(customerId);\n        Product product = products.get(productId);\n        customer.getAccount().getCart().addItem(product, quantity);\n    }\n\n    public ShoppingCart getCustomerCart(String customerId) {\n        Customer customer = customers.get(customerId);\n        return customer.getAccount().getCart();\n    }\n\n    public List<Product> searchProducts(String name) {\n        return searchService.searchByName(name);\n    }\n\n    public Order placeOrder(String customerId, PaymentStrategy paymentStrategy) {\n        Customer customer = customers.get(customerId);\n        ShoppingCart cart = customer.getAccount().getCart();\n        if (cart.getItems().isEmpty()) {\n            System.out.println(\"Cannot place an order with an empty cart.\");\n            return null;\n        }\n\n        // 1. Process payment\n        boolean paymentSuccess = paymentService.processPayment(paymentStrategy, cart.calculateTotal());\n        if (!paymentSuccess) {\n            System.out.println(\"Payment failed. Please try again.\");\n            return null;\n        }\n\n        // 2. Create order and update inventory\n        try {\n            Order order = orderService.createOrder(customer, cart);\n            orders.put(order.getId(), order);\n\n            // 3. Clear the cart\n            cart.clearCart();\n\n            return order;\n        } catch (Exception e) {\n            System.err.println(\"Order placement failed: \" + e.getMessage());\n            // In a real system, we would trigger a refund here.\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/README.md",
    "content": "# Online Shopping Service (LLD)\n\n## Problem Statement\n\nDesign and implement an Online Shopping Service that allows users to browse products, add items to a cart, place orders, make payments, and track order status.\n\n---\n\n## Requirements\n\n- **User Management:** Users can register, log in, and manage their profiles.\n- **Product Catalog:** The system manages a catalog of products with details and prices.\n- **Cart Management:** Users can add, update, or remove products in their shopping cart.\n- **Order Placement:** Users can place orders for products in their cart.\n- **Order Tracking:** The system tracks the status of each order (e.g., PLACED, SHIPPED, DELIVERED, CANCELLED).\n- **Payment Processing:** Users can pay for their orders using different payment methods.\n- **Extensibility:** Easy to add new features such as discounts, reviews, or wishlists.\n\n---\n\n## Core Entities\n\n- **OnlineShoppingService:** Main class that manages users, products, carts, orders, and payments.\n- **User:** Represents a user with a unique ID, name, and cart.\n- **Product:** Represents a product with ID, name, description, and price.\n- **Cart:** Represents a user's shopping cart containing order items.\n- **Order:** Represents an order placed by a user, including items, status, and payment.\n- **OrderItem:** Represents an item in an order or cart.\n- **OrderStatus:** Enum for order status (PLACED, SHIPPED, DELIVERED, CANCELLED).\n- **Payment (in payment/):** Represents a payment transaction for an order.\n- **PaymentProcessor (in payment/):** Handles payment logic and validation.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/OnlineShoppingService-class-diagram.png)\n\n### 1. OnlineShoppingService\n- **Fields:** List<User> users, List<Product> products, List<Order> orders, PaymentProcessor paymentProcessor\n- **Methods:** registerUser(User), addProduct(Product), addToCart(User, Product, int quantity), placeOrder(User), processPayment(Order, Payment), updateOrderStatus(Order, OrderStatus), etc.\n\n### 2. User\n- **Fields:** int id, String name, Cart cart\n\n### 3. Product\n- **Fields:** int id, String name, String description, double price\n\n### 4. Cart\n- **Fields:** List<OrderItem> items\n- **Methods:** addItem(Product, int quantity), removeItem(Product), updateQuantity(Product, int quantity), getItems()\n\n### 5. Order\n- **Fields:** int id, User user, List<OrderItem> items, OrderStatus status, Payment payment\n\n### 6. OrderItem\n- **Fields:** Product product, int quantity\n\n### 7. OrderStatus (enum)\n- Values: PLACED, SHIPPED, DELIVERED, CANCELLED\n\n### 8. Payment (in payment/)\n- **Fields:** int id, double amount, String method, PaymentStatus status\n\n### 9. PaymentProcessor (in payment/)\n- **Methods:** process(Payment), validate(Payment)\n\n---\n\n## Example Usage\n\n```java\nOnlineShoppingService service = new OnlineShoppingService();\nUser alice = new User(1, \"Alice\");\nProduct phone = new Product(1, \"Smartphone\", \"Latest model\", 699.0);\n\nservice.registerUser(alice);\nservice.addProduct(phone);\nservice.addToCart(alice, phone, 1);\n\nOrder order = service.placeOrder(alice);\nPayment payment = new Payment(1, 699.0, \"CREDIT_CARD\");\nservice.processPayment(order, payment);\n```\n\n---\n\n## Demo\n\nSee `OnlineShoppingServiceDemo.java` for a sample usage and simulation of the online shopping service.\n\n---\n\n## Extending the Framework\n\n- **Add discounts or coupons:** Support promotional pricing.\n- **Add product reviews:** Allow users to review and rate products.\n- **Add wishlists:** Allow users to save products for later.\n\n---"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/decorator/GiftWrapDecorator.java",
    "content": "package onlineshoppingservice.decorator;\n\nimport onlineshoppingservice.models.Product;\n\npublic class GiftWrapDecorator extends ProductDecorator {\n    private static final double GIFT_WRAP_COST = 5.00;\n\n    public GiftWrapDecorator(Product product) {\n        super(product);\n    }\n\n    @Override\n    public double getPrice() {\n        return super.getPrice() + GIFT_WRAP_COST;\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \" (Gift Wrapped)\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/decorator/ProductDecorator.java",
    "content": "package onlineshoppingservice.decorator;\n\nimport onlineshoppingservice.enums.ProductCategory;\nimport onlineshoppingservice.models.Product;\n\npublic abstract class ProductDecorator extends Product {\n    protected Product decoratedProduct;\n\n    public ProductDecorator(Product product) {\n        this.decoratedProduct = product;\n    }\n\n    @Override public String getId() { return decoratedProduct.getId(); }\n\n    @Override public String getName() { return decoratedProduct.getName(); }\n\n    @Override public double getPrice() { return decoratedProduct.getPrice(); }\n\n    @Override public String getDescription() { return decoratedProduct.getDescription(); }\n\n    @Override public ProductCategory getCategory() { return decoratedProduct.getCategory(); }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/enums/OrderStatus.java",
    "content": "package onlineshoppingservice.enums;\n\npublic enum OrderStatus {\n    PENDING_PAYMENT,\n    PLACED,\n    SHIPPED,\n    DELIVERED,\n    CANCELLED,\n    RETURNED\n}"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/enums/ProductCategory.java",
    "content": "package onlineshoppingservice.enums;\n\npublic enum ProductCategory {\n    ELECTRONICS,\n    BOOKS,\n    CLOTHING,\n    HOME_GOODS,\n    GROCERY\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/exceptions/OutOfStockException.java",
    "content": "package onlineshoppingservice.exceptions;\n\npublic class OutOfStockException extends RuntimeException {\n    public OutOfStockException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/Account.java",
    "content": "package onlineshoppingservice.models;\n\npublic class Account {\n    private final String username;\n    private final String password; // Hashed password in real system\n    private final ShoppingCart cart;\n\n    public Account(String username, String password) {\n        this.username = username;\n        this.password = password;\n        this.cart = new ShoppingCart();\n    }\n    public ShoppingCart getCart() { return cart; }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/Address.java",
    "content": "package onlineshoppingservice.models;\n\npublic class Address {\n    private final String street;\n    private final String city;\n    private final String state;\n    private final String zipCode;\n\n    public Address(String street, String city, String state, String zipCode) {\n        this.street = street;\n        this.city = city;\n        this.state = state;\n        this.zipCode = zipCode;\n    }\n\n    @Override\n    public String toString() {\n        return String.format(\"%s, %s, %s %s\", street, city, state, zipCode);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/CartItem.java",
    "content": "package onlineshoppingservice.models;\n\npublic class CartItem {\n    private final Product product;\n    private int quantity;\n\n    public CartItem(Product product, int quantity) {\n        this.product = product;\n        this.quantity = quantity;\n    }\n\n    public Product getProduct() { return product; }\n    public int getQuantity() { return quantity; }\n    public void incrementQuantity(int amount) { this.quantity += amount; }\n    public double getPrice() { return product.getPrice() * quantity; }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/Customer.java",
    "content": "package onlineshoppingservice.models;\n\nimport onlineshoppingservice.observer.OrderObserver;\n\nimport java.util.UUID;\n\npublic class Customer implements OrderObserver {\n    private final String id;\n    private final String name;\n    private final String email;\n    private final Account account;\n    private Address shippingAddress;\n\n    public Customer(String name, String email, String password, Address shippingAddress) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.email = email;\n        this.account = new Account(email, password);\n        this.shippingAddress = shippingAddress;\n    }\n\n    @Override\n    public void update(Order order) {\n        System.out.printf(\"[Notification for %s]: Your order #%s status has been updated to: %s.%n\",\n                this.name, order.getId(), order.getStatus());\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public Account getAccount() { return account; }\n    public Address getShippingAddress() { return shippingAddress; }\n    public void setShippingAddress(Address address) { this.shippingAddress = address; }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/Order.java",
    "content": "package onlineshoppingservice.models;\n\nimport onlineshoppingservice.enums.OrderStatus;\nimport onlineshoppingservice.observer.Subject;\nimport onlineshoppingservice.state.OrderState;\nimport onlineshoppingservice.state.PlacedState;\n\nimport java.time.LocalDateTime;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class Order extends Subject {\n    private final String id;\n    private final Customer customer;\n    private final List<OrderLineItem> items;\n    private final Address shippingAddress;\n    private final double totalAmount;\n    private final LocalDateTime orderDate;\n    private OrderStatus status;\n    private OrderState currentState;\n\n    public Order(Customer customer, List<OrderLineItem> items, Address shippingAddress, double totalAmount) {\n        this.id = UUID.randomUUID().toString().substring(0, 8);\n        this.customer = customer;\n        this.items = items;\n        this.shippingAddress = shippingAddress;\n        this.totalAmount = totalAmount;\n        this.orderDate = LocalDateTime.now();\n        this.status = OrderStatus.PLACED;\n        this.currentState = new PlacedState();\n        addObserver(customer);\n    }\n\n    // State Pattern methods\n    public void shipOrder() { currentState.ship(this); }\n    public void deliverOrder() { currentState.deliver(this); }\n    public void cancelOrder() { currentState.cancel(this); }\n\n    // Getters and Setters\n    public String getId() { return id; }\n    public OrderStatus getStatus() { return status; }\n    public void setState(OrderState state) { this.currentState = state; }\n    public void setStatus(OrderStatus status) {\n        this.status = status;\n        notifyObservers(this);\n    }\n    public List<OrderLineItem> getItems() { return items; }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/OrderLineItem.java",
    "content": "package onlineshoppingservice.models;\n\npublic class OrderLineItem {\n    private final String productId;\n    private final String productName;\n    private final int quantity;\n    private final double priceAtPurchase;\n\n    public OrderLineItem(String productId, String productName, int quantity, double priceAtPurchase) {\n        this.productId = productId;\n        this.productName = productName;\n        this.quantity = quantity;\n        this.priceAtPurchase = priceAtPurchase;\n    }\n\n    public String getProductId() { return productId; }\n    public int getQuantity() { return quantity; }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/Product.java",
    "content": "package onlineshoppingservice.models;\n\nimport onlineshoppingservice.enums.ProductCategory;\n\nimport java.util.UUID;\n\npublic abstract class Product {\n    protected String id;\n    protected String name;\n    protected String description;\n    protected double price;\n    protected ProductCategory category;\n\n    public abstract String getId();\n    public abstract String getName();\n    public abstract String getDescription();\n    public abstract double getPrice();\n    public abstract ProductCategory getCategory();\n\n    // Base implementation for the Builder\n    public static class BaseProduct extends Product {\n        private BaseProduct(String id, String name, String description, double price, ProductCategory category) {\n            this.id = id;\n            this.name = name;\n            this.description = description;\n            this.price = price;\n            this.category = category;\n        }\n        @Override public String getId() { return id; }\n        @Override public String getName() { return name; }\n        @Override public String getDescription() { return description; }\n        @Override public double getPrice() { return price; }\n        @Override public ProductCategory getCategory() { return category; }\n    }\n\n    // Builder Pattern for creating products\n    public static class Builder {\n        private final String name;\n        private final double price;\n        private String description = \"\";\n        private ProductCategory category;\n\n        public Builder(String name, double price) {\n            this.name = name;\n            this.price = price;\n        }\n        public Builder withDescription(String description) { this.description = description; return this; }\n        public Builder withCategory(ProductCategory category) { this.category = category; return this; }\n        public Product build() {\n            return new BaseProduct(UUID.randomUUID().toString(), name, description, price, category);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/models/ShoppingCart.java",
    "content": "package onlineshoppingservice.models;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ShoppingCart {\n    private final Map<String, CartItem> items = new HashMap<>();\n\n    public void addItem(Product product, int quantity) {\n        if (items.containsKey(product.getId())) {\n            items.get(product.getId()).incrementQuantity(quantity);\n        } else {\n            items.put(product.getId(), new CartItem(product, quantity));\n        }\n    }\n\n    public void removeItem(String productId) {\n        items.remove(productId);\n    }\n\n    public Map<String, CartItem> getItems() { return Map.copyOf(items); }\n\n    public double calculateTotal() {\n        return items.values().stream().mapToDouble(CartItem::getPrice).sum();\n    }\n\n    public void clearCart() {\n        items.clear();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/observer/OrderObserver.java",
    "content": "package onlineshoppingservice.observer;\n\nimport onlineshoppingservice.models.Order;\n\npublic interface OrderObserver {\n    void update(Order order);\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/observer/Subject.java",
    "content": "package onlineshoppingservice.observer;\n\nimport onlineshoppingservice.models.Order;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class Subject {\n    private final List<OrderObserver> observers = new ArrayList<>();\n\n    public void addObserver(OrderObserver observer) { observers.add(observer); }\n    public void removeObserver(OrderObserver observer) { observers.remove(observer); }\n    public void notifyObservers(Order order) {\n        for (OrderObserver observer : observers) {\n            observer.update(order);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/services/InventoryService.java",
    "content": "package onlineshoppingservice.services;\n\nimport onlineshoppingservice.exceptions.OutOfStockException;\nimport onlineshoppingservice.models.OrderLineItem;\nimport onlineshoppingservice.models.Product;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class InventoryService {\n    private final Map<String, Integer> stock; // productId -> quantity\n\n    public InventoryService() {\n        this.stock = new ConcurrentHashMap<>();\n    }\n\n    public void addStock(Product product, int quantity) {\n        stock.put(product.getId(), stock.getOrDefault(product.getId(), 0) + quantity);\n    }\n\n    public synchronized void updateStockForOrder(List<OrderLineItem> items) {\n        // First, check if all items are in stock\n        for (OrderLineItem item : items) {\n            if (stock.getOrDefault(item.getProductId(), 0) < item.getQuantity()) {\n                throw new OutOfStockException(\"Not enough stock for product ID: \" + item.getProductId());\n            }\n        }\n        // If all checks pass, deduct the stock\n        for (OrderLineItem item : items) {\n            stock.compute(item.getProductId(), (id, currentStock) -> currentStock - item.getQuantity());\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/services/OrderService.java",
    "content": "package onlineshoppingservice.services;\n\nimport onlineshoppingservice.models.Customer;\nimport onlineshoppingservice.models.Order;\nimport onlineshoppingservice.models.OrderLineItem;\nimport onlineshoppingservice.models.ShoppingCart;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class OrderService {\n    private final InventoryService inventoryService;\n\n    public OrderService(InventoryService inventoryService) {\n        this.inventoryService = inventoryService;\n    }\n\n    public Order createOrder(Customer customer, ShoppingCart cart) {\n        List<OrderLineItem> result = new ArrayList<>();\n        cart.getItems().values().stream()\n            .map(cartItem -> new OrderLineItem(\n                    cartItem.getProduct().getId(),\n                    cartItem.getProduct().getName(),\n                    cartItem.getQuantity(),\n                    cartItem.getProduct().getPrice()))\n            .forEach(result::add);\n\n        inventoryService.updateStockForOrder(result);\n\n        return new Order(customer, result, customer.getShippingAddress(), cart.calculateTotal());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/services/PaymentService.java",
    "content": "package onlineshoppingservice.services;\n\nimport onlineshoppingservice.strategy.PaymentStrategy;\n\npublic class PaymentService {\n    public boolean processPayment(PaymentStrategy strategy, double amount) {\n        return strategy.pay(amount);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/services/SearchService.java",
    "content": "package onlineshoppingservice.services;\n\nimport onlineshoppingservice.enums.ProductCategory;\nimport onlineshoppingservice.models.Product;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\npublic class SearchService {\n    private final Collection<Product> productCatalog;\n\n    public SearchService(Collection<Product> productCatalog) { this.productCatalog = productCatalog; }\n\n    public List<Product> searchByName(String name) {\n        List<Product> result = new ArrayList<>();\n        productCatalog.stream()\n            .filter(p -> p.getName().toLowerCase().contains(name.toLowerCase()))\n            .forEach(result::add);\n        return result;\n    }\n\n    public List<Product> searchByCategory(ProductCategory category) {\n        List<Product> result = new ArrayList<>();\n        productCatalog.stream()\n            .filter(p -> p.getCategory() == category)\n            .forEach(result::add);\n        return result;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/state/CancelledState.java",
    "content": "package onlineshoppingservice.state;\n\nimport onlineshoppingservice.models.Order;\n\npublic class CancelledState implements OrderState {\n    @Override\n    public void ship(Order order) { System.out.println(\"Cannot ship a cancelled order.\"); }\n\n    @Override\n    public void deliver(Order order) { System.out.println(\"Cannot deliver a cancelled order.\"); }\n\n    @Override\n    public void cancel(Order order) { System.out.println(\"Order is already cancelled.\"); }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/state/DeliveredState.java",
    "content": "package onlineshoppingservice.state;\n\nimport onlineshoppingservice.models.Order;\n\npublic class DeliveredState implements OrderState {\n    @Override\n    public void ship(Order order) { System.out.println(\"Order already delivered.\"); }\n\n    @Override\n    public void deliver(Order order) { System.out.println(\"Order already delivered.\"); }\n\n    @Override\n    public void cancel(Order order) { System.out.println(\"Cannot cancel a delivered order.\"); }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/state/OrderState.java",
    "content": "package onlineshoppingservice.state;\n\nimport onlineshoppingservice.models.Order;\n\npublic interface OrderState {\n    void ship(Order order);\n    void deliver(Order order);\n    void cancel(Order order);\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/state/PlacedState.java",
    "content": "package onlineshoppingservice.state;\n\nimport onlineshoppingservice.enums.OrderStatus;\nimport onlineshoppingservice.models.Order;\n\npublic class PlacedState implements OrderState {\n    @Override\n    public void ship(Order order) {\n        System.out.println(\"Shipping order \" + order.getId());\n        order.setStatus(OrderStatus.SHIPPED);\n        order.setState(new ShippedState());\n    }\n\n    @Override\n    public void deliver(Order order) { System.out.println(\"Cannot deliver an order that has not been shipped.\"); }\n\n    @Override\n    public void cancel(Order order) {\n        System.out.println(\"Cancelling order \" + order.getId());\n        order.setStatus(OrderStatus.CANCELLED);\n        order.setState(new CancelledState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/state/ShippedState.java",
    "content": "package onlineshoppingservice.state;\n\nimport onlineshoppingservice.enums.OrderStatus;\nimport onlineshoppingservice.models.Order;\n\npublic class ShippedState implements OrderState {\n    @Override\n    public void ship(Order order) { System.out.println(\"Order is already shipped.\"); }\n\n    @Override\n    public void deliver(Order order) {\n        System.out.println(\"Delivering order \" + order.getId());\n        order.setStatus(OrderStatus.DELIVERED);\n        order.setState(new DeliveredState());\n    }\n\n    @Override\n    public void cancel(Order order) { System.out.println(\"Cannot cancel a shipped order.\"); }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/strategy/CreditCardPaymentStrategy.java",
    "content": "package onlineshoppingservice.strategy;\n\npublic class CreditCardPaymentStrategy implements PaymentStrategy {\n    private final String cardNumber;\n\n    public CreditCardPaymentStrategy(String cardNumber) { this.cardNumber = cardNumber; }\n\n    @Override\n    public boolean pay(double amount) {\n        System.out.printf(\"Processing credit card payment of $%.2f with card %s.%n\", amount, cardNumber);\n        // Simulate payment gateway logic\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/strategy/PaymentStrategy.java",
    "content": "package onlineshoppingservice.strategy;\n\npublic interface PaymentStrategy {\n    boolean pay(double amount);\n}\n"
  },
  {
    "path": "solutions/java/src/onlineshoppingservice/strategy/UPIPaymentStrategy.java",
    "content": "package onlineshoppingservice.strategy;\n\npublic class UPIPaymentStrategy implements PaymentStrategy{\n    private final String upiId;\n\n    public UPIPaymentStrategy(String upiId) { this.upiId = upiId; }\n\n    @Override\n    public boolean pay(double amount) {\n        System.out.printf(\"Processing UPI payment of $%.2f with upi id %s.%n\", amount, upiId);\n        // Simulate payment gateway logic\n        return true;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/BuyOrder.java",
    "content": "package onlinestockbrokeragesystem;\n\npublic class BuyOrder extends Order {\n    public BuyOrder(String orderId, Account account, Stock stock, int quantity, double price) {\n        super(orderId, account, stock, quantity, price);\n    }\n\n    @Override\n    public void execute() {\n        double totalCost = quantity * price;\n        if (account.getBalance() >= totalCost) {\n            account.withdraw(totalCost);\n            // Update portfolio and perform necessary actions\n            account.getPortfolio().addStock(stock, quantity);\n            status = OrderStatus.EXECUTED;\n        } else {\n            status = OrderStatus.REJECTED;\n            throw new InsufficientFundsException(\"Insufficient funds to execute the buy order.\");\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/README.md",
    "content": "# Online Stock Brokerage System (LLD)\n\n## Problem Statement\n\nDesign and implement an Online Stock Brokerage System that allows users to buy and sell stocks, manage their portfolio, and track their investments. The system should handle order processing, account management, and stock trading.\n\n---\n\n## Requirements\n\n1. **Account Management:**\n   - Create and manage user accounts\n   - Track account balance\n   - Handle fund deposits and withdrawals\n\n2. **Stock Management:**\n   - Track available stocks\n   - Maintain stock prices\n   - Handle stock information\n\n3. **Order Management:**\n   - Process buy and sell orders\n   - Track order status\n   - Handle order execution\n\n4. **Portfolio Management:**\n   - Track user's stock holdings\n   - Calculate portfolio value\n   - Monitor investment performance\n\n5. **Trading Rules:**\n   - Validate order amounts\n   - Check sufficient funds\n   - Verify stock availability\n\n---\n\n## Core Entities\n\n### 1. StockBroker\n- **Fields:** List<Account> accounts, List<Stock> stocks, List<Order> orders\n- **Methods:** \n  - createAccount()\n  - placeBuyOrder()\n  - placeSellOrder()\n  - getPortfolio()\n  - getStockPrice()\n\n### 2. Account\n- **Fields:** String id, User user, double balance, Portfolio portfolio\n- **Methods:** \n  - deposit()\n  - withdraw()\n  - getBalance()\n  - getPortfolio()\n\n### 3. User\n- **Fields:** String id, String name, String email\n- **Methods:** \n  - getAccount()\n  - updateProfile()\n\n### 4. Stock\n- **Fields:** String symbol, String name, double currentPrice\n- **Methods:** \n  - updatePrice()\n  - getPrice()\n\n### 5. Order\n- **Fields:** String id, Account account, Stock stock, int quantity, OrderStatus status\n- **Methods:** \n  - execute()\n  - cancel()\n  - getStatus()\n\n### 6. BuyOrder\n- **Fields:** double price\n- **Methods:** \n  - validateFunds()\n  - execute()\n\n### 7. SellOrder\n- **Fields:** double price\n- **Methods:** \n  - validateStocks()\n  - execute()\n\n### 8. Portfolio\n- **Fields:** Map<Stock, Integer> holdings\n- **Methods:** \n  - addStock()\n  - removeStock()\n  - getValue()\n\n### 9. OrderStatus (Enum)\n- **Values:** PENDING, EXECUTED, CANCELLED, FAILED\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/onlineStockBrokerageSystem-class-diagram.png)\n---\n\n## Example Usage\n\n```java\nStockBroker pubSubService = new StockBroker();\n\n// Create a user account\nUser user = new User(\"John Doe\", \"john@example.com\");\nAccount account = pubSubService.createAccount(user);\n\n// Deposit funds\naccount.deposit(10000.0);\n\n// Place a buy order\nStock stock = pubSubService.getStock(\"AAPL\");\nBuyOrder buyOrder = pubSubService.placeBuyOrder(account, stock, 10);\n\n// Place a sell order\nSellOrder sellOrder = pubSubService.placeSellOrder(account, stock, 5);\n\n// Get portfolio\nPortfolio portfolio = account.getPortfolio();\n```\n\n---\n\n## Demo\n\nSee `StockBrokerageSystemDemo.java` for a sample usage and simulation of the stock brokerage system.\n\n---\n\n## Extending the Framework\n\n- **Add real-time market data:** Integrate with market data providers\n- **Add order types:** Support limit orders, stop-loss orders\n- **Add trading strategies:** Implement automated trading strategies\n- **Add transaction history:** Track all trading activities\n- **Add reporting system:** Generate investment reports\n- **Add notification system:** Send price alerts and order updates\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For the stock pubSubService instance\n- **Factory Pattern:** For creating different types of orders\n- **Observer Pattern:** For stock price updates\n- **Strategy Pattern:** For different order execution strategies\n\n---\n\n## Exception Handling\n\n- **InsufficientFundsException:** Thrown when account has insufficient funds\n- **InsufficientStockException:** Thrown when portfolio has insufficient stocks\n- **InvalidOrderException:** Thrown when order details are invalid\n- **OrderExecutionException:** Thrown when order execution fails\n\n---"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/SellOrder.java",
    "content": "package onlinestockbrokeragesystem;\n\npublic class SellOrder extends Order {\n    public SellOrder(String orderId, Account account, Stock stock, int quantity, double price) {\n        super(orderId, account, stock, quantity, price);\n    }\n\n    @Override\n    public void execute() {\n        // Check if the user has sufficient quantity of the stock to sell\n        // Update portfolio and perform necessary actions\n        double totalProceeds = quantity * price;\n        account.deposit(totalProceeds);\n        status = OrderStatus.EXECUTED;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/StockBrokerageSystem.java",
    "content": "package onlinestockbrokeragesystem;\n\nimport onlinestockbrokeragesystem.command.BuyStockCommand;\nimport onlinestockbrokeragesystem.command.OrderCommand;\nimport onlinestockbrokeragesystem.command.SellStockCommand;\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.entities.Stock;\nimport onlinestockbrokeragesystem.entities.User;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class StockBrokerageSystem {\n    private static volatile StockBrokerageSystem instance;\n    private final Map<String, User> users;\n    private final Map<String, Stock> stocks;\n\n    private StockBrokerageSystem() {\n        this.users = new ConcurrentHashMap<>();\n        this.stocks = new ConcurrentHashMap<>();\n    }\n\n    public static StockBrokerageSystem getInstance() {\n        if (instance == null) {\n            synchronized (StockBrokerageSystem.class) {\n                if (instance == null) {\n                    instance = new StockBrokerageSystem();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public User registerUser(String name, double initialAmount) {\n        User user = new User(name, initialAmount);\n        users.put(user.getUserId(), user);\n        return user;\n    }\n\n    public Stock addStock(String symbol, double initialPrice) {\n        Stock stock = new Stock(symbol, initialPrice);\n        stocks.put(stock.getSymbol(), stock);\n        return stock;\n    }\n\n    public void placeBuyOrder(Order order) {\n        User user = order.getUser();\n        OrderCommand command = new BuyStockCommand(user.getAccount(), order);\n        command.execute();\n    }\n\n    public void placeSellOrder(Order order) {\n        User user = order.getUser();\n        OrderCommand command = new SellStockCommand(user.getAccount(), order);\n        command.execute();\n    }\n\n    public void cancelOrder(Order order) {\n        order.cancel();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/StockBrokerageSystemDemo.java",
    "content": "package onlinestockbrokeragesystem;\n\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.entities.OrderBuilder;\nimport onlinestockbrokeragesystem.entities.Stock;\nimport onlinestockbrokeragesystem.entities.User;\n\npublic class StockBrokerageSystemDemo {\n    public static void main(String[] args) throws InterruptedException {\n        // --- System Setup ---\n        StockBrokerageSystem system = StockBrokerageSystem.getInstance();\n\n        // --- Create Stocks ---\n        Stock apple = system.addStock(\"AAPL\", 150.00);\n        Stock google = system.addStock(\"GOOG\", 2800.00);\n\n        // --- Create Members (Users) ---\n        User alice = system.registerUser(\"Alice\", 20000.00);\n        User bob = system.registerUser(\"Bob\", 25000.00);\n\n        // Bob already owns some Apple stock\n        bob.getAccount().addStock(\"AAPL\", 50);\n\n        // --- Members subscribe to stock notifications (Observer Pattern) ---\n        apple.addObserver(alice);\n        google.addObserver(alice);\n        apple.addObserver(bob);\n\n        System.out.println(\"--- Initial State ---\");\n        printAccountStatus(alice);\n        printAccountStatus(bob);\n\n        System.out.println(\"\\n--- Trading Simulation Starts ---\\n\");\n\n        // --- SCENARIO 1: Limit Order Match ---\n        System.out.println(\"--- SCENARIO 1: Alice places a limit buy, Bob places a limit sell that matches ---\");\n\n        // Alice wants to buy 10 shares of AAPL if the price is $150.50 or less\n        Order aliceBuyOrder = new OrderBuilder()\n                .forUser(alice)\n                .buy(10)\n                .withStock(apple)\n                .withLimit(150.50)\n                .build();\n        system.placeBuyOrder(aliceBuyOrder);\n\n        // Bob wants to sell 20 of his shares if the price is $150.50 or more\n        Order bobSellOrder = new OrderBuilder()\n                .forUser(bob)\n                .sell(20)\n                .withStock(apple)\n                .withLimit(150.50)\n                .build();\n        system.placeSellOrder(bobSellOrder);\n\n        // The exchange will automatically match and execute this trade.\n        // Let's check the status after the trade.\n        Thread.sleep(100); // Give time for notifications to print\n        System.out.println(\"\\n--- Account Status After Trade 1 ---\");\n        printAccountStatus(alice);\n        printAccountStatus(bob);\n\n        // --- SCENARIO 2: Price Update triggers notifications ---\n        System.out.println(\"\\n--- SCENARIO 2: Market price of GOOG changes ---\");\n        google.setPrice(2850.00); // Alice will get a notification\n\n        // --- SCENARIO 3: Order Cancellation (State Pattern) ---\n        System.out.println(\"\\n--- SCENARIO 3: Alice places an order and then cancels it ---\");\n        Order aliceCancelOrder = new OrderBuilder()\n                .forUser(alice)\n                .buy(5)\n                .withStock(google)\n                .withLimit(2700.00) // Price is too low, so it won't execute immediately\n                .build();\n        system.placeBuyOrder(aliceCancelOrder);\n\n        System.out.println(\"Order status before cancellation: \" + aliceCancelOrder.getStatus());\n        system.cancelOrder(aliceCancelOrder);\n        System.out.println(\"Order status after cancellation attempt: \" + aliceCancelOrder.getStatus());\n\n        // Now try to cancel an already filled order\n        System.out.println(\"\\n--- Trying to cancel an already FILLED order (State Pattern) ---\");\n        System.out.println(\"Bob's sell order status: \" + bobSellOrder.getStatus());\n        system.cancelOrder(bobSellOrder); // This should fail\n        System.out.println(\"Bob's sell order status after cancel attempt: \" + bobSellOrder.getStatus());\n    }\n\n    private static void printAccountStatus(User user) {\n        System.out.printf(\"Member: %s, Cash: $%.2f, Portfolio: %s%n\",\n                user.getName(),\n                user.getAccount().getBalance(),\n                user.getAccount().getPortfolio());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/StockExchange.java",
    "content": "package onlinestockbrokeragesystem;\n\nimport onlinestockbrokeragesystem.enums.OrderStatus;\nimport onlinestockbrokeragesystem.enums.OrderType;\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.entities.Stock;\nimport onlinestockbrokeragesystem.entities.User;\nimport onlinestockbrokeragesystem.state.FilledState;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\npublic class StockExchange {\n    private static volatile StockExchange instance;\n    private final Map<String, List<Order>> buyOrders;\n    private final Map<String, List<Order>> sellOrders;\n\n    private StockExchange() {\n        this.buyOrders = new ConcurrentHashMap<>();\n        this.sellOrders = new ConcurrentHashMap<>();\n    }\n\n    public static StockExchange getInstance() {\n        if (instance == null) {\n            synchronized (StockExchange.class) {\n                if (instance == null) {\n                    instance = new StockExchange();\n                }\n            }\n        }\n        return instance;\n    }\n\n    public void placeBuyOrder(Order order) {\n        buyOrders.computeIfAbsent(order.getStock().getSymbol(), k -> new CopyOnWriteArrayList<>()).add(order);\n        matchOrders(order.getStock());\n    }\n\n    public void placeSellOrder(Order order) {\n        sellOrders.computeIfAbsent(order.getStock().getSymbol(), k -> new CopyOnWriteArrayList<>()).add(order);\n        matchOrders(order.getStock());\n    }\n\n    private void matchOrders(Stock stock) {\n        synchronized (this) { // Critical section to prevent race conditions during matching\n            List<Order> buys = buyOrders.get(stock.getSymbol());\n            List<Order> sells = sellOrders.get(stock.getSymbol());\n\n            if (buys == null || sells == null) return;\n\n            boolean matchFound;\n            do {\n                matchFound = false;\n                Order bestBuy = findBestBuy(buys);\n                Order bestSell = findBestSell(sells);\n\n                if (bestBuy != null && bestSell != null) {\n                    double buyPrice = bestBuy.getType() == OrderType.MARKET ? stock.getPrice() : bestBuy.getPrice();\n                    double sellPrice = bestSell.getType() == OrderType.MARKET ? stock.getPrice() : bestSell.getPrice();\n\n                    if (buyPrice >= sellPrice) {\n                        executeTrade(bestBuy, bestSell, sellPrice); // Trade at the seller's asking price\n                        matchFound = true;\n                    }\n                }\n            } while (matchFound);\n        }\n    }\n\n    private void executeTrade(Order buyOrder, Order sellOrder, double tradePrice) {\n        System.out.printf(\"--- Executing Trade for %s at $%.2f ---%n\", buyOrder.getStock(), tradePrice);\n\n        User buyer = buyOrder.getUser();\n        User seller = sellOrder.getUser();\n\n        int tradeQuantity = Math.min(buyOrder.getQuantity(), sellOrder.getQuantity());\n        double totalCost = tradeQuantity * tradePrice;\n\n        // Perform transaction\n        buyer.getAccount().debit(totalCost);\n        buyer.getAccount().addStock(buyOrder.getStock().getSymbol(), tradeQuantity);\n\n        seller.getAccount().credit(totalCost);\n        seller.getAccount().removeStock(sellOrder.getStock().getSymbol(), tradeQuantity);\n\n        // Update orders\n        updateOrderStatus(buyOrder, tradeQuantity);\n        updateOrderStatus(sellOrder, tradeQuantity);\n\n        // Update stock's market price to last traded price\n        buyOrder.getStock().setPrice(tradePrice);\n\n        System.out.println(\"--- Trade Complete ---\");\n    }\n\n    private void updateOrderStatus(Order order, int quantityTraded) {\n        // This is a simplified update logic. A real system would handle partial fills.\n        order.setStatus(OrderStatus.FILLED);\n        order.setState(new FilledState());\n        String stockSymbol = order.getStock().getSymbol();\n        // Remove from books\n        if (buyOrders.get(stockSymbol) != null)\n            buyOrders.get(stockSymbol).remove(order);\n        if (sellOrders.get(stockSymbol) != null)\n            sellOrders.get(stockSymbol).remove(order);\n    }\n\n    private Order findBestBuy(List<Order> buys) {\n        return buys.stream()\n                .filter(o -> o.getStatus() == OrderStatus.OPEN)\n                .max(Comparator.comparingDouble(Order::getPrice)) // Highest limit price is best\n                .orElse(null);\n    }\n\n    private Order findBestSell(List<Order> sells) {\n        return sells.stream()\n                .filter(o -> o.getStatus() == OrderStatus.OPEN)\n                .min(Comparator.comparingDouble(Order::getPrice)) // Lowest limit price is best\n                .orElse(null);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/command/BuyStockCommand.java",
    "content": "package onlinestockbrokeragesystem.command;\n\nimport onlinestockbrokeragesystem.StockExchange;\nimport onlinestockbrokeragesystem.entities.Account;\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.enums.OrderType;\nimport onlinestockbrokeragesystem.exceptions.InsufficientFundsException;\n\npublic class BuyStockCommand implements OrderCommand {\n    private final Account account;\n    private final Order order;\n    private final StockExchange stockExchange;\n\n    public BuyStockCommand(Account account, Order order) {\n        this.account = account;\n        this.order = order;\n        this.stockExchange = StockExchange.getInstance();\n    }\n\n    @Override\n    public void execute() {\n        // For market order, we can't pre-check funds perfectly.\n        // For limit order, we can pre-authorize the amount.\n        double estimatedCost = order.getQuantity() * order.getPrice();\n        if (order.getType() == OrderType.LIMIT && account.getBalance() < estimatedCost) {\n            throw new InsufficientFundsException(\"Not enough cash to place limit buy order.\");\n        }\n        System.out.printf(\"Placing BUY order %s for %d shares of %s.%n\", order.getOrderId(), order.getQuantity(), order.getStock());\n        stockExchange.placeBuyOrder(order);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/command/OrderCommand.java",
    "content": "package onlinestockbrokeragesystem.command;\n\npublic interface OrderCommand {\n    void execute();\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/command/SellStockCommand.java",
    "content": "package onlinestockbrokeragesystem.command;\n\nimport onlinestockbrokeragesystem.StockExchange;\nimport onlinestockbrokeragesystem.entities.Account;\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.exceptions.InsufficientStockException;\n\npublic class SellStockCommand implements OrderCommand {\n    private final Account account;\n    private final Order order;\n    private final StockExchange stockExchange;\n\n    public SellStockCommand(Account account, Order order) {\n        this.account = account;\n        this.order = order;\n        this.stockExchange = StockExchange.getInstance();\n    }\n\n    @Override\n    public void execute() {\n        if (account.getStockQuantity(order.getStock().getSymbol()) < order.getQuantity()) {\n            throw new InsufficientStockException(\"Not enough stock to place sell order.\");\n        }\n        System.out.printf(\"Placing SELL order %s for %d shares of %s.%n\", order.getOrderId(), order.getQuantity(), order.getStock());\n        stockExchange.placeSellOrder(order);\n    }\n}"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/entities/Account.java",
    "content": "package onlinestockbrokeragesystem.entities;\n\nimport onlinestockbrokeragesystem.exceptions.InsufficientFundsException;\nimport onlinestockbrokeragesystem.exceptions.InsufficientStockException;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Account {\n    private double balance;\n    private final Map<String, Integer> portfolio; // Stock symbol -> quantity\n\n    public Account(double initialCash) {\n        this.balance = initialCash;\n        this.portfolio = new ConcurrentHashMap<>();\n    }\n\n    public synchronized void debit(double amount) {\n        if (balance < amount) {\n            throw new InsufficientFundsException(\"Insufficient funds to debit \" + amount);\n        }\n        balance -= amount;\n    }\n\n    public synchronized void credit(double amount) {\n        balance += amount;\n    }\n\n    public synchronized void addStock(String symbol, int quantity) {\n        portfolio.put(symbol, portfolio.getOrDefault(symbol, 0) + quantity);\n    }\n\n    public synchronized void removeStock(String symbol, int quantity) {\n        int currentQuantity = portfolio.getOrDefault(symbol, 0);\n        if (currentQuantity < quantity) {\n            throw new InsufficientStockException(\"Not enough \" + symbol + \" stock to sell.\");\n        }\n        portfolio.put(symbol, currentQuantity - quantity);\n    }\n\n    public double getBalance() { return balance; }\n    public Map<String, Integer> getPortfolio() { return Map.copyOf(portfolio); }\n    public int getStockQuantity(String symbol) { return portfolio.getOrDefault(symbol, 0); }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/entities/Order.java",
    "content": "package onlinestockbrokeragesystem.entities;\n\nimport onlinestockbrokeragesystem.enums.OrderStatus;\nimport onlinestockbrokeragesystem.enums.OrderType;\nimport onlinestockbrokeragesystem.state.OpenState;\nimport onlinestockbrokeragesystem.state.OrderState;\nimport onlinestockbrokeragesystem.strategy.ExecutionStrategy;\n\npublic class Order {\n    private final String orderId;\n    private final User user;\n    private final Stock stock;\n    private final OrderType type;\n    private final int quantity;\n    private final double price; // Limit price for Limit orders\n    private OrderStatus status;\n    private User owner;\n    private OrderState currentState;\n    private final ExecutionStrategy executionStrategy;\n\n    public Order(String orderId, User user, Stock stock, OrderType type, int quantity, double price, ExecutionStrategy strategy, User owner) {\n        this.orderId = orderId;\n        this.user = user;\n        this.stock = stock;\n        this.type = type;\n        this.quantity = quantity;\n        this.price = price;\n        this.executionStrategy = strategy;\n        this.owner = owner;\n        this.currentState = new OpenState(); // Initial state\n        this.status = OrderStatus.OPEN;\n    }\n\n    // State pattern methods\n    public void cancel() {\n        currentState.cancel(this);\n    }\n\n    // Getters\n    public String getOrderId() { return orderId; }\n    public User getUser() { return user; }\n    public Stock getStock() { return stock; }\n    public OrderType getType() { return type; }\n    public int getQuantity() { return quantity; }\n    public double getPrice() { return price; }\n    public OrderStatus getStatus() { return status; }\n    public ExecutionStrategy getExecutionStrategy() { return executionStrategy; }\n\n    // Setters for state transitions\n    public void setState(OrderState state) {\n        this.currentState = state;\n    }\n\n    public void setStatus(OrderStatus status) {\n        this.status = status;\n        notifyOwner();\n    }\n\n    private void notifyOwner() {\n        if (owner != null) {\n            owner.orderStatusUpdate(this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/entities/OrderBuilder.java",
    "content": "package onlinestockbrokeragesystem.entities;\n\nimport onlinestockbrokeragesystem.enums.OrderType;\nimport onlinestockbrokeragesystem.enums.TransactionType;\nimport onlinestockbrokeragesystem.strategy.LimitOrderStrategy;\nimport onlinestockbrokeragesystem.strategy.MarketOrderStrategy;\n\nimport java.util.UUID;\n\npublic class OrderBuilder {\n    private User user;\n    private Stock stock;\n    private OrderType type;\n    private TransactionType transactionType;\n    private int quantity;\n    private double price;\n\n    public OrderBuilder forUser(User user) {\n        this.user = user;\n        return this;\n    }\n\n    public OrderBuilder withStock(Stock stock) {\n        this.stock = stock;\n        return this;\n    }\n\n    public OrderBuilder buy(int quantity) {\n        this.transactionType = TransactionType.BUY;\n        this.quantity = quantity;\n        return this;\n    }\n\n    public OrderBuilder sell(int quantity) {\n        this.transactionType = TransactionType.SELL;\n        this.quantity = quantity;\n        return this;\n    }\n\n    public OrderBuilder atMarketPrice() {\n        this.type = OrderType.MARKET;\n        this.price = 0; // Not needed for market order\n        return this;\n    }\n\n    public OrderBuilder withLimit(double limitPrice) {\n        this.type = OrderType.LIMIT;\n        this.price = limitPrice;\n        return this;\n    }\n\n    public Order build() {\n        return new Order(\n                UUID.randomUUID().toString(),\n                user,\n                stock,\n                type,\n                quantity,\n                price,\n                type == OrderType.MARKET ? new MarketOrderStrategy() : new LimitOrderStrategy(transactionType),\n                user\n        );\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/entities/Stock.java",
    "content": "package onlinestockbrokeragesystem.entities;\n\nimport onlinestockbrokeragesystem.observer.StockObserver;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Stock {\n    private final String symbol;\n    private double price;\n    private final List<StockObserver> observers = new ArrayList<>();\n\n    public Stock(String symbol, double initialPrice) {\n        this.symbol = symbol;\n        this.price = initialPrice;\n    }\n\n    public String getSymbol() {\n        return symbol;\n    }\n\n    public double getPrice() {\n        return price;\n    }\n\n    public void setPrice(double newPrice) {\n        if (this.price != newPrice) {\n            this.price = newPrice;\n            notifyObservers();\n        }\n    }\n\n    public void addObserver(StockObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(StockObserver observer) {\n        observers.remove(observer);\n    }\n\n    private void notifyObservers() {\n        for (StockObserver observer : observers) {\n            observer.update(this);\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/entities/User.java",
    "content": "package onlinestockbrokeragesystem.entities;\n\nimport onlinestockbrokeragesystem.observer.StockObserver;\n\nimport java.util.UUID;\n\npublic class User implements StockObserver {\n    private final String userId;\n    private final String name;\n    private final Account account;\n\n    public User(String name, double initialCash) {\n        this.userId = UUID.randomUUID().toString();\n        this.name = name;\n        this.account = new Account(initialCash);\n    }\n\n    public String getUserId() { return userId; }\n    public String getName() { return name; }\n    public Account getAccount() { return account; }\n\n    @Override\n    public void update(Stock stock) {\n        System.out.printf(\"[Notification for %s] Stock %s price updated to: $%.2f%n\",\n                name, stock.getSymbol(), stock.getPrice());\n    }\n\n    public void orderStatusUpdate(Order order) {\n        System.out.printf(\"[Order Notification for %s] Order %s for %s is now %s.%n\",\n                name, order.getOrderId(), order.getStock(), order.getStatus());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/enums/OrderStatus.java",
    "content": "package onlinestockbrokeragesystem.enums;\n\npublic enum OrderStatus {\n    OPEN,\n    PARTIALLY_FILLED,\n    FILLED,\n    CANCELLED,\n    FAILED\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/enums/OrderType.java",
    "content": "package onlinestockbrokeragesystem.enums;\n\npublic enum OrderType {\n    MARKET,\n    LIMIT\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/enums/TransactionType.java",
    "content": "package onlinestockbrokeragesystem.enums;\n\npublic enum TransactionType {\n    BUY,\n    SELL\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/exceptions/InsufficientFundsException.java",
    "content": "package onlinestockbrokeragesystem.exceptions;\n\npublic class InsufficientFundsException extends RuntimeException {\n    public InsufficientFundsException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/exceptions/InsufficientStockException.java",
    "content": "package onlinestockbrokeragesystem.exceptions;\n\npublic class InsufficientStockException extends RuntimeException {\n    public InsufficientStockException(String message) {\n        super(message);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/observer/StockObserver.java",
    "content": "package onlinestockbrokeragesystem.observer;\n\nimport onlinestockbrokeragesystem.entities.Stock;\n\npublic interface StockObserver {\n    void update(Stock stock);\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/state/CancelledState.java",
    "content": "package onlinestockbrokeragesystem.state;\n\nimport onlinestockbrokeragesystem.entities.Order;\n\npublic class CancelledState implements OrderState {\n    @Override\n    public void handle(Order order) {\n        System.out.println(\"Order is cancelled.\");\n    }\n\n    @Override\n    public void cancel(Order order) {\n        System.out.println(\"Order is already cancelled.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/state/FilledState.java",
    "content": "package onlinestockbrokeragesystem.state;\n\nimport onlinestockbrokeragesystem.entities.Order;\n\npublic class FilledState implements OrderState {\n    @Override\n    public void handle(Order order) {\n        System.out.println(\"Order is already filled.\");\n    }\n\n    @Override\n    public void cancel(Order order) {\n        System.out.println(\"Cannot cancel a filled order.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/state/OpenState.java",
    "content": "package onlinestockbrokeragesystem.state;\n\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.enums.OrderStatus;\n\npublic class OpenState implements OrderState {\n    @Override\n    public void handle(Order order) {\n        System.out.println(\"Order is open and waiting for execution.\");\n    }\n\n    @Override\n    public void cancel(Order order) {\n        order.setStatus(OrderStatus.CANCELLED);\n        order.setState(new CancelledState());\n        System.out.println(\"Order \" + order.getOrderId() + \" has been cancelled.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/state/OrderState.java",
    "content": "package onlinestockbrokeragesystem.state;\n\nimport onlinestockbrokeragesystem.entities.Order;\n\npublic interface OrderState {\n    void handle(Order order);\n    void cancel(Order order);\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/strategy/ExecutionStrategy.java",
    "content": "package onlinestockbrokeragesystem.strategy;\n\nimport onlinestockbrokeragesystem.entities.Order;\n\npublic interface ExecutionStrategy {\n    boolean canExecute(Order order, double marketPrice);\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/strategy/LimitOrderStrategy.java",
    "content": "package onlinestockbrokeragesystem.strategy;\n\nimport onlinestockbrokeragesystem.entities.Order;\nimport onlinestockbrokeragesystem.enums.TransactionType;\n\npublic class LimitOrderStrategy implements ExecutionStrategy {\n    private final TransactionType type;\n\n    public LimitOrderStrategy(TransactionType type) {\n        this.type = type;\n    }\n\n    @Override\n    public boolean canExecute(Order order, double marketPrice) {\n        if (type == TransactionType.BUY) {\n            // Buy if market price is less than or equal to limit price\n            return marketPrice <= order.getPrice();\n        } else { // SELL\n            // Sell if market price is greater than or equal to limit price\n            return marketPrice >= order.getPrice();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/onlinestockbrokeragesystem/strategy/MarketOrderStrategy.java",
    "content": "package onlinestockbrokeragesystem.strategy;\n\nimport onlinestockbrokeragesystem.entities.Order;\n\npublic class MarketOrderStrategy implements ExecutionStrategy {\n    @Override\n    public boolean canExecute(Order order, double marketPrice) {\n        return true; // Market orders can always execute\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/ParkingLot.java",
    "content": "package parkinglot;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.entities.ParkingTicket;\nimport parkinglot.strategy.fee.FeeStrategy;\nimport parkinglot.strategy.fee.FlatRateFeeStrategy;\nimport parkinglot.strategy.parking.BestFitStrategy;\nimport parkinglot.strategy.parking.ParkingStrategy;\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class ParkingLot {\n    private static ParkingLot instance;\n    private final List<ParkingFloor> floors = new ArrayList<>();\n    private final Map<String, ParkingTicket> activeTickets;\n    private FeeStrategy feeStrategy;\n    private ParkingStrategy parkingStrategy;\n\n    private ParkingLot() {\n        this.feeStrategy = new FlatRateFeeStrategy();\n        this.parkingStrategy = new BestFitStrategy();\n        this.activeTickets = new ConcurrentHashMap<>();\n    }\n\n    public static synchronized ParkingLot getInstance() {\n        if (instance == null) {\n            instance = new ParkingLot();\n        }\n        return instance;\n    }\n\n    public void addFloor(ParkingFloor floor) {\n        floors.add(floor);\n    }\n\n    public void setFeeStrategy (FeeStrategy feeStrategy) {\n        this.feeStrategy = feeStrategy;\n    }\n\n    public void setParkingStrategy(ParkingStrategy parkingStrategy) {\n        this.parkingStrategy = parkingStrategy;\n    }\n\n    public Optional<ParkingTicket> parkVehicle(Vehicle vehicle) {\n        Optional<ParkingSpot> availableSpot = parkingStrategy.findSpot(floors, vehicle);\n\n        if (availableSpot.isPresent()) {\n            ParkingSpot spot = availableSpot.get();\n            spot.parkVehicle(vehicle);\n            ParkingTicket ticket = new ParkingTicket(vehicle, spot);\n            activeTickets.put(vehicle.getLicenseNumber(), ticket);\n            System.out.printf(\"%s parked at %s. Ticket: %s\\n\", vehicle.getLicenseNumber(), spot.getSpotId(), ticket.getTicketId());\n            return Optional.of(ticket);\n        }\n\n        System.out.println(\"No available spot for \" + vehicle.getLicenseNumber());\n        return Optional.empty();\n    }\n\n    public Optional<Double> unparkVehicle(String licenseNumber) {\n        ParkingTicket ticket = activeTickets.remove(licenseNumber);\n        if (ticket == null) {\n            System.out.println(\"Ticket not found\");\n            return Optional.empty();\n        }\n\n        ticket.setExitTimestamp();\n        ticket.getSpot().unparkVehicle();\n\n        Double parkingFee = feeStrategy.calculateFee(ticket);\n\n        return Optional.of(parkingFee);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/ParkingLotDemo.java",
    "content": "package parkinglot;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.entities.ParkingTicket;\nimport parkinglot.strategy.fee.VehicleBasedFeeStrategy;\nimport parkinglot.vehicle.*;\n\nimport java.util.Optional;\n\npublic class ParkingLotDemo {\n    public static void main(String[] args) {\n        ParkingLot parkingLot = ParkingLot.getInstance();\n\n        // 1. Initialize the parking lot with floors and spots\n        ParkingFloor floor1 = new ParkingFloor(1);\n        floor1.addSpot(new ParkingSpot(\"F1-S1\", VehicleSize.SMALL));\n        floor1.addSpot(new ParkingSpot(\"F1-M1\", VehicleSize.MEDIUM));\n        floor1.addSpot(new ParkingSpot(\"F1-L1\", VehicleSize.LARGE));\n\n        ParkingFloor floor2 = new ParkingFloor(2);\n        floor2.addSpot(new ParkingSpot(\"F2-M1\", VehicleSize.MEDIUM));\n        floor2.addSpot(new ParkingSpot(\"F2-M2\", VehicleSize.MEDIUM));\n\n        parkingLot.addFloor(floor1);\n        parkingLot.addFloor(floor2);\n\n        parkingLot.setFeeStrategy(new VehicleBasedFeeStrategy());\n\n        // 2. Simulate vehicle entries\n        System.out.println(\"\\n--- Vehicle Entries ---\");\n        floor1.displayAvailability();\n        floor2.displayAvailability();\n\n        Vehicle bike = new Bike(\"B-123\");\n        Vehicle car = new Car(\"C-456\");\n        Vehicle truck = new Truck(\"T-789\");\n\n        Optional<ParkingTicket> bikeTicketOpt = parkingLot.parkVehicle(bike);\n\n        Optional<ParkingTicket> carTicketOpt = parkingLot.parkVehicle(car);\n\n        Optional<ParkingTicket> truckTicketOpt = parkingLot.parkVehicle(truck);\n\n        System.out.println(\"\\n--- Availability after parking ---\");\n        floor1.displayAvailability();\n        floor2.displayAvailability();\n\n        // 3. Simulate another car entry (should go to floor 2)\n        Vehicle car2 = new Car(\"C-999\");\n        Optional<ParkingTicket> car2TicketOpt = parkingLot.parkVehicle(car2);\n\n        // 4. Simulate a vehicle entry that fails (no available spots)\n        Vehicle bike2 = new Bike(\"B-000\");\n        Optional<ParkingTicket> failedBikeTicketOpt = parkingLot.parkVehicle(bike2);\n\n        // 5. Simulate vehicle exits and fee calculation\n        System.out.println(\"\\n--- Vehicle Exits ---\");\n\n        if (carTicketOpt.isPresent()) {\n            Optional<Double> feeOpt = parkingLot.unparkVehicle(car.getLicenseNumber());\n            feeOpt.ifPresent(fee -> System.out.printf(\"Car C-456 unparked. Fee: $%.2f\\n\", fee));\n        }\n\n        System.out.println(\"\\n--- Availability after one car leaves ---\");\n        floor1.displayAvailability();\n        floor2.displayAvailability();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/README.md",
    "content": "# Parking Lot System (LLD)\n\n## Problem Statement\n\nDesign and implement a Parking Lot Management System that supports parking and unparking of vehicles, parkingTicket generation, fee calculation, and management of multiple floors and spot types.\n\n---\n\n## Requirements\n\n- **Multiple Floors:** The parking lot can have multiple floors.\n- **Parking Spots:** Each floor has multiple parking spots of different types (e.g., car, bike, truck).\n- **Vehicle Types:** Support for different vehicle types (see `vehicletype/`).\n- **Ticketing:** Generate a parkingTicket when a vehicle is parked.\n- **Unparking:** Allow vehicles to unpark and calculate the parking fee.\n- **Fee Calculation:** Support for different fee strategies (see `fee/`).\n- **Spot Allocation:** Allocate the nearest available spot of the correct type.\n- **Extensibility:** Easy to add new vehicle types, spot types, or fee strategies.\n\n---\n\n## Core Entities\n\n- **ParkingLot:** Main class managing the entire parking lot, floors, and overall operations.\n- **ParkingFloor:** Represents a single floor in the parking lot, manages its spots.\n- **ParkingSpot:** Represents an individual parking spot, knows its type and occupancy.\n- **Ticket:** Represents a parking parkingTicket issued when a vehicle is parked.\n- **VehicleType (in `vehicletype/`):** Enum or classes for different vehicle types.\n- **Fee Calculation (in `fee/`):** Classes for calculating parking fees based on duration and vehicle type.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/parkinglot-class-diagram.png)\n\n### 1. ParkingLot\n- **Methods:**\n  - `parkVehicle(Vehicle vehicle)`\n  - `unparkVehicle(String ticketId)`\n  - `addFloor(ParkingFloor floor)`\n  - `getAvailableSpots()`\n- **Fields:** List of floors, mapping of tickets, etc.\n\n### 2. ParkingFloor\n- **Methods:**\n  - `getAvailableSpot(VehicleType type)`\n  - `parkVehicle(Vehicle vehicle)`\n  - `unparkVehicle(String spotId)`\n- **Fields:** List of spots, floor number.\n\n### 3. ParkingSpot\n- **Methods:**\n  - `isAvailable()`\n  - `assignVehicle(Vehicle vehicle)`\n  - `removeVehicle()`\n- **Fields:** Spot ID, type, current vehicle.\n\n### 4. Ticket\n- **Fields:** Ticket ID, vehicle info, entry time, spot info.\n\n### 5. VehicleType (in `vehicletype/`)\n- Enum or classes for vehicle types (Car, Bike, Truck, etc.)\n\n### 6. Fee Calculation (in `fee/`)\n- **Methods:** `calculateFee(Ticket parkingTicket, Date exitTime)`\n- **Extensible:** Add new strategies for fee calculation.\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** For fee calculation strategies.\n- **Factory Pattern:** (If used) For creating vehicles or spots.\n- **Singleton Pattern:** (If used) For ParkingLot instance.\n\n---\n\n## Example Usage\n\n```java\nParkingLot lot = new ParkingLot();\nlot.addFloor(new ParkingFloor(...));\nTicket parkingTicket = lot.parkVehicle(new Car(\"KA-01-1234\"));\nlot.unparkVehicle(parkingTicket.getId());\n```\n\n---\n\n## Demo\n\nSee `ParkingLotDemo.java` for a sample usage of the parking lot system.\n\n---\n\n## Extending the Framework\n\n- **Add a new vehicle type:** Update or add to `vehicletype/`.\n- **Add a new fee strategy:** Implement a new class in `fee/`.\n- **Add new spot types or floors:** Extend `ParkingSpot` or `ParkingFloor`.\n\n---"
  },
  {
    "path": "solutions/java/src/parkinglot/entities/ParkingFloor.java",
    "content": "package parkinglot.entities;\n\nimport parkinglot.vehicle.Vehicle;\nimport parkinglot.vehicle.VehicleSize;\n\nimport java.util.Comparator;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\npublic class ParkingFloor {\n    private final int floorNumber;\n    private final Map<String, ParkingSpot> spots;\n\n    public ParkingFloor(int floorNumber) {\n        this.floorNumber = floorNumber;\n        this.spots = new ConcurrentHashMap<>();\n    }\n\n    public void addSpot(ParkingSpot spot) {\n        spots.put(spot.getSpotId(), spot);\n    }\n\n    public synchronized Optional<ParkingSpot> findAvailableSpot(Vehicle vehicle) {\n        return spots.values().stream()\n                .filter(spot -> !spot.isOccupied() && spot.canFitVehicle(vehicle))\n                .sorted(Comparator.comparing(ParkingSpot::getSpotSize))\n                .findFirst();\n    }\n\n    public void displayAvailability() {\n        System.out.printf(\"--- Floor %d Availability ---\\n\", floorNumber);\n        Map<VehicleSize, Long> availableCounts = spots.values().stream()\n                .filter(spot -> !spot.isOccupied())\n                .collect(Collectors.groupingBy(ParkingSpot::getSpotSize, Collectors.counting()));\n\n        for (VehicleSize size : VehicleSize.values()) {\n            System.out.printf(\"  %s spots: %d\\n\", size, availableCounts.getOrDefault(size, 0L));\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/entities/ParkingSpot.java",
    "content": "package parkinglot.entities;\n\nimport parkinglot.vehicle.Vehicle;\nimport parkinglot.vehicle.VehicleSize;\n\npublic class ParkingSpot {\n    private final String spotId;\n    private boolean isOccupied;\n    private Vehicle parkedVehicle;\n    private final VehicleSize spotSize;\n\n    public ParkingSpot(String spotId, VehicleSize spotSize) {\n        this.spotId = spotId;\n        this.spotSize = spotSize;\n        this.isOccupied = false;\n        this.parkedVehicle = null;\n    }\n\n    public String getSpotId() {\n        return spotId;\n    }\n\n    public VehicleSize getSpotSize() {\n        return spotSize;\n    }\n\n    public synchronized boolean isAvailable() {\n        return !isOccupied;\n    }\n\n    public boolean isOccupied() {\n        return isOccupied;\n    }\n\n    public synchronized void parkVehicle(Vehicle vehicle) {\n        this.parkedVehicle = vehicle;\n        this.isOccupied = true;\n    }\n\n    public synchronized void unparkVehicle() {\n        this.parkedVehicle = null;\n        this.isOccupied = false;\n    }\n\n    public boolean canFitVehicle(Vehicle vehicle) {\n        if (isOccupied) return false;\n\n        switch (vehicle.getSize()) {\n            case SMALL:\n                return spotSize == VehicleSize.SMALL;\n            case MEDIUM:\n                return spotSize == VehicleSize.MEDIUM || spotSize == VehicleSize.LARGE;\n            case LARGE:\n                return spotSize == VehicleSize.LARGE;\n            default:\n                return false;\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/parkinglot/entities/ParkingTicket.java",
    "content": "package parkinglot.entities;\n\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.Date;\nimport java.util.UUID;\n\npublic class ParkingTicket {\n    private final String ticketId;\n    private final Vehicle vehicle;\n    private final ParkingSpot spot;\n    private final long entryTimestamp;\n    private long exitTimestamp;\n\n    public ParkingTicket(Vehicle vehicle, ParkingSpot spot) {\n        this.ticketId = UUID.randomUUID().toString();\n        this.vehicle = vehicle;\n        this.spot = spot;\n        this.entryTimestamp = new Date().getTime();\n    }\n\n    public String getTicketId() { return ticketId; }\n    public Vehicle getVehicle() { return vehicle; }\n    public ParkingSpot getSpot() { return spot; }\n    public long getEntryTimestamp() { return entryTimestamp; }\n    public long getExitTimestamp() { return exitTimestamp; }\n\n    public void setExitTimestamp() {\n        this.exitTimestamp = new Date().getTime();\n    }\n}"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/fee/FeeStrategy.java",
    "content": "package parkinglot.strategy.fee;\n\nimport parkinglot.entities.ParkingTicket;\n\npublic interface FeeStrategy {\n    double calculateFee(ParkingTicket parkingTicket);\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/fee/FlatRateFeeStrategy.java",
    "content": "package parkinglot.strategy.fee;\n\nimport parkinglot.entities.ParkingTicket;\n\npublic class FlatRateFeeStrategy implements FeeStrategy {\n\n    private static final double RATE_PER_HOUR = 10.0;\n\n    @Override\n    public double calculateFee(ParkingTicket parkingTicket) {\n        long duration = parkingTicket.getExitTimestamp() - parkingTicket.getEntryTimestamp();\n        long hours = (duration / (1000 * 60 * 60)) + 1;\n        return hours * RATE_PER_HOUR;\n    }\n}"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/fee/VehicleBasedFeeStrategy.java",
    "content": "package parkinglot.strategy.fee;\n\nimport parkinglot.entities.ParkingTicket;\nimport parkinglot.vehicle.VehicleSize;\n\nimport java.util.Map;\n\npublic class VehicleBasedFeeStrategy implements FeeStrategy {\n    private static final Map<VehicleSize, Double> HOURLY_RATES = Map.of(\n            VehicleSize.SMALL, 10.0,\n            VehicleSize.MEDIUM, 20.0,\n            VehicleSize.LARGE, 30.0\n    );\n\n    @Override\n    public double calculateFee(ParkingTicket parkingTicket) {\n        long duration = parkingTicket.getExitTimestamp() - parkingTicket.getEntryTimestamp();\n        long hours = (duration / (1000 * 60 * 60)) + 1;\n        return hours * HOURLY_RATES.get(parkingTicket.getVehicle().getSize());\n    }\n}"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/parking/BestFitStrategy.java",
    "content": "package parkinglot.strategy.parking;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic class BestFitStrategy implements ParkingStrategy {\n    @Override\n    public Optional<ParkingSpot> findSpot(List<ParkingFloor> floors, Vehicle vehicle) {\n        Optional<ParkingSpot> bestSpot = Optional.empty();\n\n        for (ParkingFloor floor : floors) {\n            Optional<ParkingSpot> spotOnThisFloor = floor.findAvailableSpot(vehicle);\n\n            if (spotOnThisFloor.isPresent()) {\n                if (bestSpot.isEmpty()) {\n                    // If this is the first spot we've found, it's the best one so far.\n                    bestSpot = spotOnThisFloor;\n                } else {\n                    // A smaller spot size enum ordinal means a tighter fit.\n                    if (spotOnThisFloor.get().getSpotSize().ordinal() < bestSpot.get().getSpotSize().ordinal()) {\n                        bestSpot = spotOnThisFloor;\n                    }\n                }\n            }\n        }\n        return bestSpot;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/parking/FarthestFirstStrategy.java",
    "content": "package parkinglot.strategy.parking;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Optional;\n\npublic class FarthestFirstStrategy implements ParkingStrategy {\n    @Override\n    public Optional<ParkingSpot> findSpot(List<ParkingFloor> floors, Vehicle vehicle) {\n        // Create a reversed copy of the floors list to search from the top floor down.\n        List<ParkingFloor> reversedFloors = new ArrayList<>(floors);\n        Collections.reverse(reversedFloors);\n\n        for (ParkingFloor floor : reversedFloors) {\n            Optional<ParkingSpot> spot = floor.findAvailableSpot(vehicle);\n            if (spot.isPresent()) {\n                return spot;\n            }\n        }\n        return Optional.empty();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/parking/NearestFirstStrategy.java",
    "content": "package parkinglot.strategy.parking;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic class NearestFirstStrategy implements ParkingStrategy {\n    @Override\n    public Optional<ParkingSpot> findSpot(List<ParkingFloor> floors, Vehicle vehicle) {\n        for (ParkingFloor floor : floors) {\n            Optional<ParkingSpot> spot = floor.findAvailableSpot(vehicle);\n            if (spot.isPresent()) {\n                return spot;\n            }\n        }\n        return Optional.empty();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/strategy/parking/ParkingStrategy.java",
    "content": "package parkinglot.strategy.parking;\n\nimport parkinglot.entities.ParkingFloor;\nimport parkinglot.entities.ParkingSpot;\nimport parkinglot.vehicle.Vehicle;\n\nimport java.util.List;\nimport java.util.Optional;\n\npublic interface ParkingStrategy {\n    Optional<ParkingSpot> findSpot(List<ParkingFloor> floors, Vehicle vehicle);\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/vehicle/Bike.java",
    "content": "package parkinglot.vehicle;\n\npublic class Bike extends Vehicle {\n    public Bike(String licenseNumber) {\n        super(licenseNumber, VehicleSize.SMALL);\n    }\n}"
  },
  {
    "path": "solutions/java/src/parkinglot/vehicle/Car.java",
    "content": "package parkinglot.vehicle;\n\npublic class Car extends Vehicle {\n    public Car(String licenseNumber) {\n        super(licenseNumber, VehicleSize.MEDIUM);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/vehicle/Truck.java",
    "content": "package parkinglot.vehicle;\n\npublic class Truck extends Vehicle {\n    public Truck(String licenseNumber) {\n        super(licenseNumber, VehicleSize.LARGE);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/vehicle/Vehicle.java",
    "content": "package parkinglot.vehicle;\n\npublic abstract class Vehicle {\n    private final String licenseNumber;\n    private final VehicleSize size;\n\n    public Vehicle(String licenseNumber, VehicleSize size) {\n        this.licenseNumber = licenseNumber;\n        this.size = size;\n    }\n\n    public String getLicenseNumber() { return licenseNumber; }\n    public VehicleSize getSize() {\n        return size;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/parkinglot/vehicle/VehicleSize.java",
    "content": "package parkinglot.vehicle;\n\npublic enum VehicleSize {\n    SMALL,\n    MEDIUM,\n    LARGE\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/PubSubDemo.java",
    "content": "package pubsubsystem;\n\nimport pubsubsystem.entities.Message;\nimport pubsubsystem.subscriber.AlertSubscriber;\nimport pubsubsystem.subscriber.NewsSubscriber;\nimport pubsubsystem.subscriber.Subscriber;\n\npublic class PubSubDemo {\n    public static void main(String[] args) throws InterruptedException {\n        PubSubService pubSubService = PubSubService.getInstance();\n\n        // --- Create Subscribers ---\n        Subscriber sportsFan1 = new NewsSubscriber(\"SportsFan1\");\n        Subscriber sportsFan2 = new NewsSubscriber(\"SportsFan2\");\n        Subscriber techie1 = new NewsSubscriber(\"Techie1\");\n        Subscriber allNewsReader = new NewsSubscriber(\"AllNewsReader\");\n        Subscriber systemAdmin = new AlertSubscriber(\"SystemAdmin\");\n\n        // --- Create Topics and Subscriptions ---\n        final String SPORTS_TOPIC = \"SPORTS\";\n        final String TECH_TOPIC = \"TECH\";\n        final String WEATHER_TOPIC = \"WEATHER\";\n\n        pubSubService.createTopic(SPORTS_TOPIC);\n        pubSubService.createTopic(TECH_TOPIC);\n        pubSubService.createTopic(WEATHER_TOPIC);\n\n        pubSubService.subscribe(SPORTS_TOPIC, sportsFan1);\n        pubSubService.subscribe(SPORTS_TOPIC, sportsFan2);\n        pubSubService.subscribe(SPORTS_TOPIC, allNewsReader);\n        pubSubService.subscribe(SPORTS_TOPIC, systemAdmin);\n\n        pubSubService.subscribe(TECH_TOPIC, techie1);\n        pubSubService.subscribe(TECH_TOPIC, allNewsReader);\n\n        System.out.println(\"\\n--- Publishing Messages ---\");\n\n        // --- Publish to SPORTS topic ---\n        pubSubService.publish(SPORTS_TOPIC, new Message(\"Team A wins the championship!\"));\n        // Expected: SportsFan1, SportsFan2, AllNewsReader, SystemAdmin receive this.\n\n        // --- Publish to TECH topic ---\n        pubSubService.publish(TECH_TOPIC, new Message(\"New AI model released.\"));\n        // Expected: Techie1, AllNewsReader receive this.\n\n        // --- Publish to WEATHER topic (no subscribers) ---\n        pubSubService.publish(WEATHER_TOPIC, new Message(\"Sunny with a high of 75°F.\"));\n        // Expected: Message is dropped.\n\n        // Allow some time for async messages to be processed\n        Thread.sleep(500);\n\n        System.out.println(\"\\n--- Unsubscribing a user and re-publishing ---\");\n\n        // SportsFan2 gets tired of sports news\n        pubSubService.unsubscribe(SPORTS_TOPIC, sportsFan2);\n\n        // Publish another message to SPORTS\n        pubSubService.publish(SPORTS_TOPIC, new Message(\"Major player traded to Team B.\"));\n        // Expected: SportsFan1, AllNewsReader, SystemAdmin receive this. SportsFan2 does NOT.\n\n        // Give messages time to be delivered\n        Thread.sleep(500);\n\n        // --- Shutdown the service ---\n        pubSubService.shutdown();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/PubSubService.java",
    "content": "package pubsubsystem;\n\nimport pubsubsystem.entities.Message;\nimport pubsubsystem.entities.Topic;\nimport pubsubsystem.subscriber.Subscriber;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\npublic class PubSubService {\n    private static final PubSubService INSTANCE = new PubSubService();\n    private final ExecutorService deliveryExecutor;\n    private final Map<String, Topic> topicRegistry;\n\n    private PubSubService() {\n        this.topicRegistry = new ConcurrentHashMap<>();\n        // A cached thread pool is suitable for handling many short-lived, bursty tasks (message deliveries).\n        deliveryExecutor = Executors.newCachedThreadPool();\n    }\n\n    public static PubSubService getInstance() {\n        return INSTANCE;\n    }\n\n    public void createTopic(String topicName) {\n        topicRegistry.putIfAbsent(topicName, new Topic(topicName, deliveryExecutor));\n        System.out.println(\"Topic \" + topicName + \" created\");\n    }\n\n    public void subscribe(String topicName, Subscriber subscriber) {\n        Topic topic = topicRegistry.get(topicName);\n        if (topic == null)\n            throw new IllegalArgumentException(\"Topic not found: \" + topicName);\n        topic.addSubscriber(subscriber);\n        System.out.println(\"Subscriber '\" + subscriber.getId() + \"' subscribed to topic: \" + topicName);\n    }\n\n    public void unsubscribe(String topicName, Subscriber subscriber) {\n        Topic topic = topicRegistry.get(topicName);\n        if (topic != null)\n            topic.removeSubscriber(subscriber);\n        System.out.println(\"Subscriber '\" + subscriber.getId() + \"' unsubscribed from topic: \" + topicName);\n    }\n\n    public void publish(String topicName, Message message) {\n        System.out.println(\"Publishing message to topic: \" + topicName);\n        Topic topic = topicRegistry.get(topicName);\n        if (topic == null) throw new IllegalArgumentException(\"Topic not found: \" + topicName);\n        topic.broadcast(message);\n    }\n\n    public void shutdown() {\n        System.out.println(\"PubSubService shutting down...\");\n        deliveryExecutor.shutdown();\n        try {\n            // Wait a reasonable time for existing tasks to complete\n            if (!deliveryExecutor.awaitTermination(60, TimeUnit.SECONDS)) {\n                deliveryExecutor.shutdownNow();\n            }\n        } catch (InterruptedException ie) {\n            deliveryExecutor.shutdownNow();\n            Thread.currentThread().interrupt();\n        }\n        System.out.println(\"PubSubService shutdown complete.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/README.md",
    "content": "# Pub/Sub System (LLD)\n\n## Problem Statement\n\nDesign and implement a Publish-Subscribe (Pub/Sub) system that allows publishers to send messages to topics, and subscribers to receive messages from topics they are interested in. The system should support multiple topics, multiple subscribers per topic, and asynchronous message delivery.\n\n---\n\n## Requirements\n\n- **Topics:** The system supports multiple topics.\n- **Publishers:** Publishers can publish messages to any topic.\n- **Subscribers:** Subscribers can subscribe to one or more topics and receive messages published to those topics.\n- **Multiple Subscribers:** Each topic can have multiple subscribers.\n- **Asynchronous Delivery:** Messages are delivered to subscribers asynchronously.\n- **Unsubscribe:** Subscribers can unsubscribe from topics.\n- **Extensibility:** Easy to add new subscriber types or message processing logic.\n\n---\n\n## Core Entities\n\n- **Broker:** Manages topics, subscriptions, and message delivery.\n- **Topic:** Represents a topic to which messages can be published and subscribers can subscribe.\n- **Publisher:** Publishes messages to topics via the pubSubService.\n- **Subscriber (interface):** Interface for all subscribers, defines the `consume(Message)` method.\n- **PrintSubscriber:** A subscriber that prints received messages.\n- **LoggingSubscriber:** A subscriber that logs received messages.\n- **Message:** Represents a message with a payload.\n- **Dispatcher:** Handles asynchronous delivery of messages to subscribers.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/pubsubsystem-class-diagram.png)\n\n### 1. Broker\n- **Fields:** Map<String, Topic> topics\n- **Methods:** createTopic(String), subscribe(String, Subscriber), unsubscribe(String, Subscriber), publish(String, Message)\n\n### 2. Topic\n- **Fields:** String name, List<Subscriber> subscribers\n- **Methods:** addSubscriber(Subscriber), removeSubscriber(Subscriber), publish(Message)\n\n### 3. Publisher\n- **Fields:** String name, Broker pubSubService\n- **Methods:** publish(String topic, String payload)\n\n### 4. Subscriber (interface)\n- **Methods:** consume(Message)\n\n### 5. PrintSubscriber\n- **Implements:** Subscriber\n- **Behavior:** Prints received messages to the console\n\n### 6. LoggingSubscriber\n- **Implements:** Subscriber\n- **Behavior:** Logs received messages (prints with a log prefix)\n\n### 7. Message\n- **Fields:** String payload\n- **Methods:** getPayload()\n\n### 8. Dispatcher\n- **Methods:** dispatch(Subscriber, Message), shutdown()\n\n---\n\n## Design Patterns Used\n\n- **Observer Pattern:** The Pub/Sub system is a concrete implementation of the Observer pattern. Topics (subjects) maintain a list of subscribers (observers) and notify them asynchronously when a new message is published.\n## Example Usage\n\n```java\nBroker pubSubService = new Broker();\npubSubService.createTopic(\"topic1\");\npubSubService.createTopic(\"topic2\");\n\nPublisher publisher1 = new Publisher(\"publisher1\", pubSubService);\nSubscriber subscriber1 = new PrintSubscriber(\"PrintSubscriber1\");\nSubscriber subscriber2 = new LoggingSubscriber(\"LoggingSubscriber2\");\n\npubSubService.subscribe(\"topic1\", subscriber1);\npubSubService.subscribe(\"topic2\", subscriber2);\n\npublisher1.publish(\"topic1\", \"Hello Topic1!\");\npublisher1.publish(\"topic2\", \"Hello Topic2!\");\n```\n\n---\n\n## Demo\n\nSee `PubSubSystemDemo.java` for a sample usage and simulation of the pub/sub system.\n\n---\n\n## Extending the Design\n\n- **Add new subscriber types:** Implement the `Subscriber` interface for custom processing.\n- **Add new message types:** Extend the `Message` class for richer payloads.\n- **Add filtering or transformation:** Enhance the pubSubService or topic to support message filtering or transformation.\n\n---"
  },
  {
    "path": "solutions/java/src/pubsubsystem/entities/Message.java",
    "content": "package pubsubsystem.entities;\n\nimport java.time.Instant;\n\npublic class Message {\n    private final String payload;\n    private final Instant timestamp;\n\n    public Message(String payload) {\n        this.payload = payload;\n        this.timestamp = Instant.now();\n    }\n\n    public String getPayload() {\n        return payload;\n    }\n\n    @Override\n    public String toString() {\n        return \"Message{\" + \"payload='\" + payload + '\\'' + '}';\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/entities/Topic.java",
    "content": "package pubsubsystem.entities;\n\nimport pubsubsystem.subscriber.Subscriber;\n\nimport java.util.Set;\nimport java.util.concurrent.CopyOnWriteArraySet;\nimport java.util.concurrent.ExecutorService;\n\npublic class Topic {\n    private final String name;\n    private final Set<Subscriber> subscribers;\n    private final ExecutorService deliveryExecutor;\n\n    public Topic(String name, ExecutorService deliveryExecutor) {\n        this.name = name;\n        this.deliveryExecutor = deliveryExecutor;\n        this.subscribers = new CopyOnWriteArraySet<>();\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void addSubscriber(Subscriber subscriber) {\n        subscribers.add(subscriber);\n    }\n\n    public void removeSubscriber(Subscriber subscriber) {\n        subscribers.remove(subscriber);\n    }\n\n    public void broadcast(Message message) {\n        for (Subscriber subscriber : subscribers) {\n            deliveryExecutor.submit(() -> {\n                try {\n                    subscriber.onMessage(message);\n                } catch (Exception e) {\n                    System.err.println(\"Error delivering message to subscriber \" + subscriber.getId() + \": \" + e.getMessage());\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/subscriber/AlertSubscriber.java",
    "content": "package pubsubsystem.subscriber;\n\nimport pubsubsystem.entities.Message;\n\npublic class AlertSubscriber implements Subscriber {\n    private final String id;\n\n    public AlertSubscriber(String id) {\n        this.id = id;\n    }\n\n    @Override\n    public String getId() {\n        return id;\n    }\n\n    @Override\n    public void onMessage(Message message) {\n        System.out.printf(\"!!! [ALERT - %s] : '%s' !!!%n\", id, message.getPayload());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/subscriber/NewsSubscriber.java",
    "content": "package pubsubsystem.subscriber;\n\nimport pubsubsystem.entities.Message;\n\npublic class NewsSubscriber implements Subscriber {\n    private final String id;\n\n    public NewsSubscriber(String id) {\n        this.id = id;\n    }\n\n    @Override\n    public String getId() {\n        return id;\n    }\n\n    @Override\n    public void onMessage(Message message) {\n        System.out.printf(\"[Subscriber %s] received message '%s'%n\", id, message.getPayload());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/pubsubsystem/subscriber/Subscriber.java",
    "content": "package pubsubsystem.subscriber;\n\nimport pubsubsystem.entities.Message;\n\npublic interface Subscriber {\n    String getId();\n    void onMessage(Message message);\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/README.md",
    "content": "# Restaurant Management System (LLD)\n\n## Problem Statement\n\nDesign and implement a Restaurant Management System that allows customers to make reservations, place orders, manage tables, generate bills, and process payments. The system should also support staff management and menu management.\n\n---\n\n## Requirements\n\n- **Table Management:** The system manages tables, their availability, and assignments.\n- **Reservation Management:** Customers can reserve tables in advance.\n- **Menu Management:** The system manages a menu of items, including prices and descriptions.\n- **Order Placement:** Customers can place orders for menu items.\n- **Order Tracking:** The system tracks the status of each order (e.g., PLACED, PREPARING, SERVED, COMPLETED).\n- **Billing:** The system generates bills for completed orders.\n- **Payment Processing:** The system processes payments for bills.\n- **Staff Management:** The system manages staff assignments (e.g., waiters, chefs).\n- **Extensibility:** Easy to add new features such as customer feedback, loyalty programs, or online ordering.\n\n---\n\n## Core Entities\n\n- **RestaurantManagementSystem:** Main class that manages tables, reservations, orders, menu, staff, and payments.\n- **Table:** Represents a table in the restaurant, with table number, capacity, and availability.\n- **Reservation:** Represents a reservation for a table by a customer.\n- **MenuItem:** Represents an item on the menu, with name, description, and price.\n- **Order:** Represents a customer's order, including items, status, and associated table.\n- **OrderItem:** Represents an item in an order.\n- **OrderStatus:** Enum for order status (PLACED, PREPARING, SERVED, COMPLETED).\n- **Bill:** Represents the bill for an order, including total amount and payment status.\n- **Payment (in payment/):** Represents a payment transaction for a bill.\n- **Staff:** Represents a staff member (e.g., waiter, chef).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/RestaurantManagementSystem-class-diagram.png)\n\n### 1. RestaurantManagementSystem\n- **Fields:** List<Table> tables, List<Reservation> reservations, List<MenuItem> menu, List<Order> orders, List<Bill> bills, List<Staff> staff, PaymentProcessor paymentProcessor\n- **Methods:** addTable(Table), addMenuItem(MenuItem), makeReservation(Reservation), placeOrder(Order), updateOrderStatus(Order, OrderStatus), generateBill(Order), processPayment(Bill, Payment), addStaff(Staff), etc.\n\n### 2. Table\n- **Fields:** int tableNumber, int capacity, boolean isAvailable\n\n### 3. Reservation\n- **Fields:** int id, Table table, String customerName, Date reservationTime\n\n### 4. MenuItem\n- **Fields:** int id, String name, String description, double price\n\n### 5. Order\n- **Fields:** int id, Table table, List<OrderItem> items, OrderStatus status\n\n### 6. OrderItem\n- **Fields:** MenuItem menuItem, int quantity\n\n### 7. OrderStatus (enum)\n- Values: PLACED, PREPARING, SERVED, COMPLETED\n\n### 8. Bill\n- **Fields:** int id, Order order, double totalAmount, boolean isPaid\n\n### 9. Payment (in payment/)\n- **Fields:** int id, double amount, String method, PaymentStatus status\n\n### 10. Staff\n- **Fields:** int id, String name, String role\n\n### 11. PaymentProcessor (in payment/)\n- **Methods:** process(Payment), validate(Payment)\n\n---\n\n## Example Usage\n\n```java\nRestaurantManagementSystem system = new RestaurantManagementSystem();\nTable table = new Table(1, 4, true);\nsystem.addTable(table);\n\nMenuItem pizza = new MenuItem(1, \"Pizza\", \"Cheese Pizza\", 12.0);\nsystem.addMenuItem(pizza);\n\nReservation reservation = new Reservation(1, table, \"Alice\", new Date());\nsystem.makeReservation(reservation);\n\nOrder order = new Order(1, table, List.of(new OrderItem(pizza, 2)), OrderStatus.PLACED);\nsystem.placeOrder(order);\n\nBill bill = system.generateBill(order);\nPayment payment = new Payment(1, bill.getTotalAmount(), \"CREDIT_CARD\");\nsystem.processPayment(bill, payment);\n```\n\n---\n\n## Demo\n\nSee `RestaurantManagementSystemDemo.java` for a sample usage and simulation of the restaurant management system.\n\n---\n\n## Extending the Design\n\n- **Add customer feedback:** Allow customers to rate their experience.\n- **Add loyalty programs:** Track and reward repeat customers.\n- **Add online ordering:** Support for online reservations and orders.\n\n---"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/RestaurantManagementSystem.java",
    "content": "package restaurantmanagementsystem;\n\nimport restaurantmanagementsystem.payment.Payment;\n\nimport java.sql.Timestamp;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\npublic class RestaurantManagementSystem {\n    private static RestaurantManagementSystem instance;\n    private final Map<String, MenuItem> menu;\n    private final Map<String, Order> orders;\n    private final List<Reservation> reservations;\n    private final Map<Integer, Payment> payments;\n    private final List<Staff> staff;\n    private final Map<Integer, Table> tables;\n\n    private RestaurantManagementSystem() {\n        menu = new ConcurrentHashMap<>();\n        orders = new ConcurrentHashMap<>();\n        reservations = new CopyOnWriteArrayList<>();\n        payments = new ConcurrentHashMap<>();\n        staff = new CopyOnWriteArrayList<>();\n        tables = new ConcurrentHashMap<>();\n    }\n\n    public static synchronized RestaurantManagementSystem getInstance() {\n        if (instance == null) {\n            instance = new RestaurantManagementSystem();\n        }\n        return instance;\n    }\n\n    public MenuItem addMenuItem(String name, double price) {\n        MenuItem menuItem = new MenuItem(name, price);\n        menu.put(name, new MenuItem(name, price));\n        return menuItem;\n    }\n\n    public void removeMenuItem(String itemName) {\n        menu.remove(itemName);\n    }\n\n    public List<MenuItem> getMenu() {\n        return new ArrayList<>(menu.values());\n    }\n\n    public void addTable(int tableId, int capacity) {\n        tables.put(tableId, new Table(tableId, capacity));\n    }\n\n    public Table reserveTable(int tableId) {\n        Table table = tables.get(tableId);\n        if (table == null) {\n            throw new IllegalArgumentException(\"Invalid table ID\");\n        }\n        table.reserve();\n        return table;\n    }\n\n    public Order placeOrder(int tableId, List<OrderItem> items) {\n        Table table = tables.get(tableId);\n        if (table == null || !table.isAvailable()) {\n            throw new IllegalStateException(\"Table not reserved or invalid\");\n        }\n        Order order = new Order(table, items);\n        orders.put(order.getId(), order);\n        notifyKitchen(order);\n        return order;\n    }\n\n    public void markOrderPreparing(String orderId) {\n        Order order = orders.get(orderId);\n        order.markPreparing();\n        notifyKitchen(order);\n    }\n\n    public void markOrderReady(String orderId) {\n        Order order = orders.get(orderId);\n        order.markReady();\n        notifyStaff(order);\n    }\n\n    public void markOrderServed(String orderId) {\n        Order order = orders.get(orderId);\n        order.markServed();\n    }\n\n    public Bill getBill(String orderId) {\n        Order order = orders.get(orderId);\n        if (order.getStatus() == OrderStatus.PAID)\n            throw new IllegalStateException(\"Order already paid\");\n        order.markPaid();\n        return new Bill(order.getId(), order.calculateTotal());\n    }\n\n    public void makePayment(Bill bill, Payment payment) {\n        Order order = orders.get(bill.getOrderId());\n        if (payment.processPayment(bill.getTotalAmount())) {\n            bill.markPaymentCompleted();\n            order.markPaid();\n        } else {\n            bill.markPaymentFailed();\n            throw new RuntimeException(\"Payment failed for the orderId: \" + order.getId());\n        }\n    }\n\n    public Reservation makeReservation(String customerName, String contactNumber, int partySize, Timestamp reservationTime) {\n        Reservation reservation = new Reservation(customerName, contactNumber, partySize, reservationTime);\n        reservations.add(reservation);\n        return reservation;\n    }\n\n    public void cancelReservation(Reservation reservation) {\n        reservations.remove(reservation);\n    }\n\n    public void addStaff(Staff staff) {\n        this.staff.add(staff);\n    }\n\n    public void removeStaff(Staff staff) {\n        this.staff.remove(staff);\n    }\n\n    private void notifyKitchen(Order order) {\n        // Notify kitchen staff to prepare the order\n        // ...\n    }\n\n    private void notifyStaff(Order order) {\n        // Notify relevant staff about the order status update\n        // ...\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/RestaurantManagementSystemDemo.java",
    "content": "package restaurantmanagementsystem;\n\nimport restaurantmanagementsystem.payment.CreditCardPayment;\n\nimport java.sql.Timestamp;\nimport java.util.List;\n\npublic class RestaurantManagementSystemDemo {\n    public static void run() {\n        RestaurantManagementSystem restaurantManagementSystem = RestaurantManagementSystem.getInstance();\n\n        // Add menu items\n        MenuItem menuItem1 = restaurantManagementSystem.addMenuItem(\"Burger\", 9.99);\n        MenuItem menuItem2 = restaurantManagementSystem.addMenuItem(\"Pizza\", 12.99);\n        MenuItem menuItem3 = restaurantManagementSystem.addMenuItem(\"Salad\", 7.99);\n\n        // Add tables\n        restaurantManagementSystem.addTable(1, 4);\n        restaurantManagementSystem.addTable(2, 2);\n\n        // Place an order\n        Order order = restaurantManagementSystem.placeOrder(1, List.of(\n                new OrderItem(menuItem1, 1),\n                new OrderItem(menuItem3, 2)\n        ));\n\n        // Update order status\n        restaurantManagementSystem.markOrderPreparing(order.getId());\n        restaurantManagementSystem.markOrderReady(order.getId());\n        restaurantManagementSystem.markOrderServed(order.getId());\n\n        // Process payment\n        Bill bill = restaurantManagementSystem.getBill(order.getId());\n        restaurantManagementSystem.makePayment(bill, new CreditCardPayment());\n\n        // Make a reservation\n        Reservation reservation = restaurantManagementSystem.makeReservation(\"John Doe\", \"1234567890\", 4, new Timestamp(System.currentTimeMillis()));\n\n        // Add staff\n        restaurantManagementSystem.addStaff(new Staff(1, \"Alice\", \"Manager\", \"9876543210\"));\n        restaurantManagementSystem.addStaff(new Staff(2, \"Bob\", \"Chef\", \"5432109876\"));\n\n        // Get menu\n        List<MenuItem> menu = restaurantManagementSystem.getMenu();\n        System.out.println(\"Menu:\");\n        for (MenuItem item : menu) {\n            System.out.println(item.getName() + \" - $\" + item.getPrice());\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/RestaurantManagementSystemFacade.java",
    "content": "package restaurantmanagementsystem;\n\nimport restaurantmanagementsystem.command.Command;\nimport restaurantmanagementsystem.command.PrepareOrderCommand;\nimport restaurantmanagementsystem.command.ServeOrderCommand;\nimport restaurantmanagementsystem.decorator.*;\nimport restaurantmanagementsystem.model.*;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class RestaurantManagementSystemFacade {\n    private static RestaurantManagementSystemFacade instance;\n    private final Restaurant restaurant = Restaurant.getInstance();\n    private final AtomicInteger orderIdCounter;\n    private final Map<Integer, Order> orders;\n\n    private RestaurantManagementSystemFacade() {\n        this.orderIdCounter = new AtomicInteger(1);\n        this.orders = new HashMap<>();\n    }\n\n    public static synchronized RestaurantManagementSystemFacade getInstance() {\n        if (instance == null) {\n            instance = new RestaurantManagementSystemFacade();\n        }\n        return instance;\n    }\n\n    public Table addTable(int id, int capacity) {\n        Table table = new Table(id, capacity);\n        restaurant.addTable(table);\n        return table;\n    }\n\n    public Waiter addWaiter(String id, String name) {\n        Waiter waiter = new Waiter(id, name);\n        restaurant.addWaiter(waiter);\n        return waiter;\n    }\n\n    public Chef addChef(String id, String name) {\n        Chef chef = new Chef(id, name);\n        restaurant.addChef(chef);\n        return chef;\n    }\n\n    public MenuItem addMenuItem(String id, String name, double price) {\n        MenuItem item = new MenuItem(id, name, price);\n        restaurant.getMenu().addItem(item);\n        return item;\n    }\n\n    public Order takeOrder(int tableId, String waiterId, List<String> menuItemIds) {\n        Waiter waiter = restaurant.getWaiter(waiterId);\n        if (waiter == null) {\n            throw new IllegalArgumentException(\"Invalid waiter ID.\");\n        }\n        // For simplicity, we get the first available chef.\n        Chef chef = restaurant.getChefs().stream().findFirst()\n                .orElseThrow(() -> new IllegalStateException(\"No chefs available.\"));\n\n        Order order = new Order(orderIdCounter.getAndIncrement(), tableId);\n        for (String itemId : menuItemIds) {\n            MenuItem menuItem = restaurant.getMenu().getItem(itemId);\n            OrderItem orderItem = new OrderItem(menuItem, order);\n            // Waiter subscribes to each item to get notified when it's ready.\n            orderItem.addObserver(waiter);\n            order.addItem(orderItem);\n        }\n\n        // The Command pattern decouples the waiter (invoker) from the chef (receiver).\n        Command prepareOrderCommand = new PrepareOrderCommand(order, chef);\n        prepareOrderCommand.execute();\n\n        orders.put(order.getOrderId(), order);\n\n        return order;\n    }\n\n    public void markItemsAsReady(int orderId) {\n        Order order = orders.get(orderId);\n        System.out.println(\"\\nChef has finished preparing order \" + order.getOrderId());\n\n        order.getOrderItems().forEach(item -> { // Preparing -> ReadyForPickup -> Notifies Observer (Waiter)\n            item.nextState();\n            item.nextState();\n        });\n    }\n\n    public void serveOrder(String waiterId, int orderId) {\n        Order order = orders.get(orderId);\n        Waiter waiter = restaurant.getWaiter(waiterId);\n\n        Command serveOrderCommand = new ServeOrderCommand(order, waiter);\n        serveOrderCommand.execute();\n    }\n\n    public Bill generateBill(int orderId) {\n        Order order = orders.get(orderId);\n        // The Decorator pattern adds charges dynamically.\n        BillComponent billComponent = new BaseBill(order);\n        billComponent = new TaxDecorator(billComponent, 0.08); // 8% tax\n        billComponent = new ServiceChargeDecorator(billComponent, 5.00); // $5 flat service charge\n\n        return new Bill(billComponent);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/command/Command.java",
    "content": "package restaurantmanagementsystem.command;\n\npublic interface Command {\n    void execute();\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/command/PrepareOrderCommand.java",
    "content": "package restaurantmanagementsystem.command;\n\nimport restaurantmanagementsystem.model.Chef;\nimport restaurantmanagementsystem.model.Order;\n\npublic class PrepareOrderCommand implements Command {\n    private final Order order;\n    private final Chef chef;\n\n    public PrepareOrderCommand(Order order, Chef chef) {\n        this.order = order;\n        this.chef = chef;\n    }\n\n    @Override\n    public void execute() {\n        chef.prepareOrder(order);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/command/ServeOrderCommand.java",
    "content": "package restaurantmanagementsystem.command;\n\nimport restaurantmanagementsystem.model.Order;\nimport restaurantmanagementsystem.model.Waiter;\n\npublic class ServeOrderCommand implements Command{\n    private final Order order;\n    private final Waiter waiter;\n\n    public ServeOrderCommand(Order order, Waiter waiter) {\n        this.order = order;\n        this.waiter = waiter;\n    }\n\n    @Override\n    public void execute() {\n        waiter.serveOrder(order);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/BaseBill.java",
    "content": "package restaurantmanagementsystem.decorator;\n\nimport restaurantmanagementsystem.model.Order;\n\npublic class BaseBill implements BillComponent {\n    private final Order order;\n    public BaseBill(Order order) { this.order = order; }\n\n    @Override\n    public double calculateTotal() { return order.getTotalPrice(); }\n\n    @Override\n    public String getDescription() { return \"Order Items\"; }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/Bill.java",
    "content": "package restaurantmanagementsystem.decorator;\n\npublic class Bill {\n    private final BillComponent component;\n\n    public Bill(BillComponent component) {\n        this.component = component;\n    }\n\n    public void printBill() {\n        System.out.println(\"\\n--- BILL ---\");\n        System.out.printf(\"Description: %s\\n\", component.getDescription());\n        System.out.printf(\"Total: $%.2f\\n\", component.calculateTotal());\n        System.out.println(\"------------\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/BillComponent.java",
    "content": "package restaurantmanagementsystem.decorator;\n\npublic interface BillComponent {\n    double calculateTotal();\n    String getDescription();\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/BillDecorator.java",
    "content": "package restaurantmanagementsystem.decorator;\n\npublic abstract class BillDecorator implements BillComponent {\n    protected BillComponent wrapped;\n\n    public BillDecorator(BillComponent component) {\n        this.wrapped = component;\n    }\n\n    @Override\n    public double calculateTotal() {\n        return wrapped.calculateTotal();\n    }\n\n    @Override\n    public String getDescription() {\n        return wrapped.getDescription();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/ServiceChargeDecorator.java",
    "content": "package restaurantmanagementsystem.decorator;\n\npublic class ServiceChargeDecorator extends BillDecorator {\n    private final double serviceCharge;\n\n    public ServiceChargeDecorator(BillComponent component, double charge) {\n        super(component);\n        this.serviceCharge = charge;\n    }\n\n    @Override\n    public double calculateTotal() {\n        return super.calculateTotal() + serviceCharge;\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \", Service Charge\";\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/decorator/TaxDecorator.java",
    "content": "package restaurantmanagementsystem.decorator;\n\npublic class TaxDecorator extends BillDecorator {\n    private final double taxRate;\n\n    public TaxDecorator(BillComponent component, double taxRate) {\n        super(component);\n        this.taxRate = taxRate;\n    }\n\n    @Override\n    public double calculateTotal() {\n        return super.calculateTotal() * (1 + taxRate);\n    }\n\n    @Override\n    public String getDescription() {\n        return super.getDescription() + \", Tax @\" + (taxRate * 100) + \"%\";\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/enums/TableStatus.java",
    "content": "package restaurantmanagementsystem.enums;\n\npublic enum TableStatus {\n    AVAILABLE,\n    OCCUPIED,\n    RESERVED\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Chef.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport restaurantmanagementsystem.state.PreparingState;\n\npublic class Chef extends Staff {\n    public Chef(String id, String name) {\n        super(id, name);\n    }\n\n    public void prepareOrder(Order order) {\n        System.out.println(\"Chef \" + name + \" received order \" + order.getOrderId() + \" and is starting preparation.\");\n        order.getOrderItems().forEach(item -> {\n            // Chef's action triggers the first state change for each item.\n            item.changeState(new PreparingState());\n        });\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Menu.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Menu {\n    private final Map<String, MenuItem> items = new HashMap<>();\n\n    public void addItem(MenuItem item) {\n        items.put(item.getId(), item);\n    }\n\n    public MenuItem getItem(String id) {\n        MenuItem item = items.get(id);\n        if (item == null) {\n            throw new IllegalArgumentException(\"Menu item with ID \" + id + \" not found.\");\n        }\n        return item;\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/MenuItem.java",
    "content": "package restaurantmanagementsystem.model;\n\npublic class MenuItem {\n    private final String id;\n    private final String name;\n    private final double price;\n\n    public MenuItem(String id, String name, double price) {\n        this.id = id;\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public double getPrice() { return price; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Order.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Order {\n    private final int orderId;\n    private final int tableId;\n    private final List<OrderItem> items = new ArrayList<>();\n\n    public Order(int orderId, int tableId) {\n        this.orderId = orderId;\n        this.tableId = tableId;\n    }\n\n    public void addItem(OrderItem item) {\n        items.add(item);\n    }\n\n    public double getTotalPrice() {\n        return items.stream()\n                .mapToDouble(item -> item.getMenuItem().getPrice())\n                .sum();\n    }\n\n    public int getOrderId() { return orderId; }\n    public int getTableId() { return tableId; }\n    public List<OrderItem> getOrderItems() { return items; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/OrderItem.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport restaurantmanagementsystem.observer.OrderObserver;\nimport restaurantmanagementsystem.state.OrderItemState;\nimport restaurantmanagementsystem.state.OrderedState;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class OrderItem {\n    private final MenuItem menuItem;\n    private final Order order;\n    private OrderItemState state;\n    private final List<OrderObserver> observers = new ArrayList<>();\n\n    public OrderItem(MenuItem menuItem, Order order) {\n        this.menuItem = menuItem;\n        this.order = order;\n        this.state = new OrderedState();\n    }\n\n    public void changeState(OrderItemState newState) {\n        this.state = newState;\n        System.out.println(\"Item '\" + menuItem.getName() + \"' state changed to: \" + newState.getStatus());\n    }\n\n    public void nextState() {\n        state.next(this);\n    }\n\n    public void setState(OrderItemState state) {\n        this.state = state;\n    }\n\n    public void addObserver(OrderObserver observer) {\n        observers.add(observer);\n    }\n\n    public void notifyObservers() {\n        new ArrayList<>(observers).forEach(observer -> observer.update(this));\n    }\n\n    public MenuItem getMenuItem() { return menuItem; }\n    public Order getOrder() { return order; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Restaurant.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Restaurant {\n    private static final Restaurant INSTANCE = new Restaurant();\n    private final Map<String, Waiter> waiters = new HashMap<>();\n    private final Map<String, Chef> chefs = new HashMap<>();\n    private final Map<Integer, Table> tables = new HashMap<>();\n    private final Menu menu = new Menu();\n\n    private Restaurant() {}\n\n    public static Restaurant getInstance() {\n        return INSTANCE;\n    }\n\n    public void addWaiter(Waiter waiter) { waiters.put(waiter.getId(), waiter); }\n    public Waiter getWaiter(String id) { return waiters.get(id); }\n\n    public void addChef(Chef chef) { chefs.put(chef.getId(), chef); }\n    public Chef getChef(String id) { return chefs.get(id); }\n\n    public List<Chef> getChefs() {\n        return chefs.values().stream().toList();\n    }\n\n    public List<Waiter> getWaiters() {\n        return waiters.values().stream().toList();\n    }\n\n    public void addTable(Table table) { tables.put(table.getId(), table); }\n\n    public Menu getMenu() { return menu; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Staff.java",
    "content": "package restaurantmanagementsystem.model;\n\npublic abstract class Staff {\n    protected String id;\n    protected String name;\n\n    public Staff(String id, String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Table.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport restaurantmanagementsystem.enums.TableStatus;\n\npublic class Table {\n    private final int id;\n    private final int capacity;\n    private TableStatus status;\n\n    public Table(int id, int capacity) {\n        this.id = id;\n        this.capacity = capacity;\n        this.status = TableStatus.AVAILABLE;\n    }\n\n    public int getId() { return id; }\n    public int getCapacity() { return capacity; }\n    public TableStatus getStatus() { return status; }\n    public void setStatus(TableStatus status) { this.status = status; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/model/Waiter.java",
    "content": "package restaurantmanagementsystem.model;\n\nimport restaurantmanagementsystem.observer.OrderObserver;\nimport restaurantmanagementsystem.state.ServedState;\n\npublic class Waiter extends Staff implements OrderObserver {\n    public Waiter(String id, String name) {\n        super(id, name);\n    }\n\n    public void serveOrder(Order order) {\n        System.out.println(\"Waiter \" + name + \" is serving order \" + order.getOrderId());\n        order.getOrderItems().forEach(item -> {\n            item.changeState(new ServedState());\n        });\n    }\n\n    @Override\n    public void update(OrderItem item) {\n        System.out.println(\">>> WAITER \" + name + \" NOTIFIED: Item '\" +\n                item.getMenuItem().getName() + \"' for table \" +\n                item.getOrder().getTableId() + \" is READY FOR PICKUP.\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/observer/OrderObserver.java",
    "content": "package restaurantmanagementsystem.observer;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic interface OrderObserver {\n    void update(OrderItem item);\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/state/OrderItemState.java",
    "content": "package restaurantmanagementsystem.state;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic interface OrderItemState {\n    void next(OrderItem item);\n    void prev(OrderItem item);\n    String getStatus();\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/state/OrderedState.java",
    "content": "package restaurantmanagementsystem.state;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic class OrderedState implements OrderItemState {\n    @Override\n    public void next(OrderItem item) {\n        item.setState(new PreparingState());\n    }\n\n    @Override\n    public void prev(OrderItem item) {\n        System.out.println(\"This is the initial state.\");\n    }\n\n    @Override\n    public String getStatus() { return \"ORDERED\"; }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/state/PreparingState.java",
    "content": "package restaurantmanagementsystem.state;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic class PreparingState implements OrderItemState {\n    @Override\n    public void next(OrderItem item) {\n        item.setState(new ReadyForPickupState());\n    }\n\n    @Override\n    public void prev(OrderItem item) {\n        item.setState(new OrderedState());\n    }\n\n    @Override\n    public String getStatus() { return \"PREPARING\"; }\n}\n"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/state/ReadyForPickupState.java",
    "content": "package restaurantmanagementsystem.state;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic class ReadyForPickupState implements OrderItemState {\n    @Override\n    public void next(OrderItem item) {\n        // This is the key state. When it transitions, it notifies observers.\n        item.notifyObservers();\n    }\n\n    @Override\n    public void prev(OrderItem item) {\n        item.setState(new PreparingState());\n    }\n\n    @Override\n    public String getStatus() { return \"READY_FOR_PICKUP\"; }\n}"
  },
  {
    "path": "solutions/java/src/restaurantmanagementsystem/state/ServedState.java",
    "content": "package restaurantmanagementsystem.state;\n\nimport restaurantmanagementsystem.model.OrderItem;\n\npublic class ServedState implements OrderItemState {\n    @Override\n    public void next(OrderItem item) {\n        System.out.println(\"This is the final state.\");\n    }\n\n    @Override\n    public void prev(OrderItem item) {\n        System.out.println(\"Cannot revert a served item.\");\n    }\n\n    @Override\n    public String getStatus() { return \"SERVED\"; }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/README.md",
    "content": "# Ride Sharing Service (LLD)\n\n## Problem Statement\n\nDesign and implement a Ride Sharing Service that allows riders to request rides, drivers to accept trips, and the system to manage trip assignments, payments, and trip status.\n\n---\n\n## Requirements\n\n- **User Management:** The system manages both riders and drivers.\n- **Location Management:** The system tracks the current location of drivers and riders.\n- **Trip Request:** Riders can request rides by specifying pickup and drop-off locations.\n- **Driver Assignment:** The system assigns available drivers to ride requests based on proximity and availability.\n- **Trip Management:** The system tracks the status of each trip (e.g., REQUESTED, ONGOING, COMPLETED, CANCELLED).\n- **Payment Processing:** The system processes payments for completed trips.\n- **Driver Status:** The system tracks driver availability (e.g., AVAILABLE, ON_TRIP, OFFLINE).\n- **Extensibility:** Easy to add new features such as ratings, ride pooling, or surge pricing.\n\n---\n\n## Core Entities\n\n- **RideSharingService:** Main class that manages riders, drivers, trips, and payments.\n- **Rider:** Represents a rider who can request trips.\n- **Driver:** Represents a driver with current status and location.\n- **Trip:** Represents a ride, including rider, driver, locations, status, and payment.\n- **Location:** Represents a geographic location (latitude, longitude).\n- **TripStatus (enum):** REQUESTED, ONGOING, COMPLETED, CANCELLED.\n- **DriverStatus (enum):** AVAILABLE, ON_TRIP, OFFLINE.\n- **Payment (in payment/):** Represents a payment transaction for a trip.\n- **User:** Base class for Rider and Driver (if applicable).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/RideSharingService-class-diagram.png)\n\n### 1. RideSharingService\n- **Fields:** List<Rider> riders, List<Driver> drivers, List<Trip> trips, PaymentProcessor paymentProcessor\n- **Methods:** registerRider(Rider), registerDriver(Driver), requestTrip(Rider, Location, Location), assignDriver(Trip), startTrip(Trip), completeTrip(Trip), processPayment(Trip, Payment), updateDriverStatus(Driver, DriverStatus), etc.\n\n### 2. Rider\n- **Fields:** int id, String name, Location currentLocation\n\n### 3. Driver\n- **Fields:** int id, String name, Location currentLocation, DriverStatus status\n\n### 4. Trip\n- **Fields:** int id, Rider rider, Driver driver, Location pickup, Location dropoff, TripStatus status, Payment payment\n\n### 5. Location\n- **Fields:** double latitude, double longitude\n\n### 6. TripStatus (enum)\n- Values: REQUESTED, ONGOING, COMPLETED, CANCELLED\n\n### 7. DriverStatus (enum)\n- Values: AVAILABLE, ON_TRIP, OFFLINE\n\n### 8. Payment (in payment/)\n- **Fields:** int id, double amount, String method, PaymentStatus status\n\n### 9. PaymentProcessor (in payment/)\n- **Methods:** process(Payment), validate(Payment)\n\n### 10. User\n- **Fields:** int id, String name\n\n---\n\n## Example Usage\n\n```java\nRideSharingService service = new RideSharingService();\nRider alice = new Rider(1, \"Alice\", new Location(12.9716, 77.5946));\nDriver bob = new Driver(2, \"Bob\", new Location(12.9718, 77.5940), DriverStatus.AVAILABLE);\n\nservice.registerRider(alice);\nservice.registerDriver(bob);\n\nTrip trip = service.requestTrip(alice, alice.getCurrentLocation(), new Location(12.9352, 77.6245));\nservice.assignDriver(trip);\nservice.startTrip(trip);\n// ... after trip completion\nPayment payment = new Payment(1, 250.0, \"CREDIT_CARD\");\nservice.completeTrip(trip);\nservice.processPayment(trip, payment);\n```\n\n---\n\n## Demo\n\nSee `RideSharingServiceDemo.java` for a sample usage and simulation of the ride sharing service.\n\n---\n\n## Extending the Framework\n\n- **Add ratings and reviews:** Allow riders and drivers to rate each other.\n- **Add ride pooling:** Support multiple riders sharing a trip.\n- **Add surge pricing:** Adjust pricing based on demand and supply.\n\n---"
  },
  {
    "path": "solutions/java/src/ridesharingservice/RideSharingService.java",
    "content": "package ridesharingservice;\n\nimport java.util.List;\nimport java.util.Map;\nimport java.util.NoSuchElementException;\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.entities.Vehicle;\nimport ridesharingservice.enums.DriverStatus;\nimport ridesharingservice.enums.RideType;\nimport ridesharingservice.observer.Rider;\nimport ridesharingservice.strategy.matching.DriverMatchingStrategy;\nimport ridesharingservice.strategy.pricing.PricingStrategy;\n\npublic class RideSharingService {\n    private static volatile RideSharingService instance;\n    private final Map<String, Rider> riders = new ConcurrentHashMap<>();\n    private final Map<String, Driver> drivers = new ConcurrentHashMap<>();\n    private final Map<String, Trip> trips = new ConcurrentHashMap<>();\n    private PricingStrategy pricingStrategy;\n    private DriverMatchingStrategy driverMatchingStrategy;\n\n    private RideSharingService() {}\n\n    public static synchronized RideSharingService getInstance() {\n        if (instance == null) {\n            instance = new RideSharingService();\n        }\n        return instance;\n    }\n\n    // Allow changing strategies at runtime for extensibility\n    public void setPricingStrategy(PricingStrategy pricingStrategy) {\n        this.pricingStrategy = pricingStrategy;\n    }\n\n    public void setDriverMatchingStrategy(DriverMatchingStrategy driverMatchingStrategy) {\n        this.driverMatchingStrategy = driverMatchingStrategy;\n    }\n\n    public Rider registerRider(String name, String contact) {\n        Rider rider = new Rider(name, contact);\n        riders.put(rider.getId(), rider);\n        return rider;\n    }\n\n    public Driver registerDriver(String name, String contact, Vehicle vehicle, Location initialLocation) {\n        Driver driver = new Driver(name, contact, vehicle, initialLocation);\n        drivers.put(driver.getId(), driver);\n        return driver;\n    }\n\n    public Trip requestRide(String riderId, Location pickup, Location dropoff, RideType rideType) {\n        Rider rider = riders.get(riderId);\n        if (rider == null)\n            throw new NoSuchElementException(\"Rider not found\");\n\n        System.out.println(\"\\n--- New Ride Request from \" + rider.getName() + \" ---\");\n\n        // 1. Find available drivers\n        List<Driver> availableDrivers = driverMatchingStrategy.findDrivers(List.copyOf(drivers.values()), pickup, rideType);\n\n        if (availableDrivers.isEmpty()) {\n            System.out.println(\"No drivers available for your request. Please try again later.\");\n            return null;\n        }\n\n        System.out.println(\"Found \" + availableDrivers.size() + \" available driver(s).\");\n\n        // 2. Calculate fare\n        double fare = pricingStrategy.calculateFare(pickup, dropoff, rideType);\n        System.out.printf(\"Estimated fare: $%.2f%n\", fare);\n\n        // 3. Create a trip using the Builder\n        Trip trip = new Trip.TripBuilder()\n                .withRider(rider)\n                .withPickupLocation(pickup)\n                .withDropoffLocation(dropoff)\n                .withFare(fare)\n                .build();\n\n        trips.put(trip.getId(), trip);\n\n        // 4. Notify nearby drivers (in a real system, this would be a push notification)\n        System.out.println(\"Notifying nearby drivers of the new ride request...\");\n        for (Driver driver : availableDrivers) {\n            System.out.println(\" > Notifying \" + driver.getName() + \" at \" + driver.getCurrentLocation());\n            driver.onUpdate(trip);\n        }\n\n        return trip;\n    }\n\n    public void acceptRide(String driverId, String tripId) {\n        Driver driver = drivers.get(driverId);\n        Trip trip = trips.get(tripId);\n        if (driver == null || trip == null)\n            throw new NoSuchElementException(\"Driver or Trip not found\");\n\n        System.out.println(\"\\n--- Driver \" + driver.getName() + \" accepted the ride ---\");\n\n        driver.setStatus(DriverStatus.IN_TRIP);\n        trip.assignDriver(driver);\n    }\n\n    public void startTrip(String tripId) {\n        Trip trip = trips.get(tripId);\n        if (trip == null)\n            throw new NoSuchElementException(\"Trip not found\");\n        System.out.println(\"\\n--- Trip \" + trip.getId() + \" is starting ---\");\n        trip.startTrip();\n    }\n\n    public void endTrip(String tripId) {\n        Trip trip = trips.get(tripId);\n        if (trip == null)\n            throw new NoSuchElementException(\"Trip not found\");\n        System.out.println(\"\\n--- Trip \" + trip.getId() + \" is ending ---\");\n        trip.endTrip();\n\n        // Update statuses and history\n        Driver driver = trip.getDriver();\n        driver.setStatus(DriverStatus.ONLINE); // Driver is available again\n        driver.setCurrentLocation(trip.getDropoffLocation()); // Update driver location\n\n        Rider rider = trip.getRider();\n        driver.addTripToHistory(trip);\n        rider.addTripToHistory(trip);\n\n        System.out.println(\"Driver \" + driver.getName() + \" is now back online at \" + driver.getCurrentLocation());\n    }\n}"
  },
  {
    "path": "solutions/java/src/ridesharingservice/RideSharingServiceDemo.java",
    "content": "package ridesharingservice;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.entities.Vehicle;\nimport ridesharingservice.enums.DriverStatus;\nimport ridesharingservice.enums.RideType;\nimport ridesharingservice.observer.Rider;\nimport ridesharingservice.strategy.matching.NearestDriverMatchingStrategy;\nimport ridesharingservice.strategy.pricing.VehicleBasedPricingStrategy;\n\npublic class RideSharingServiceDemo {\n    public static void main(String[] args) {\n        // 1. Setup the system using singleton instance\n        RideSharingService service = RideSharingService.getInstance();\n        service.setDriverMatchingStrategy(new NearestDriverMatchingStrategy());\n        service.setPricingStrategy(new VehicleBasedPricingStrategy());\n\n        // 2. Register riders and drivers\n        Rider alice = service.registerRider(\"Alice\", \"123-456-7890\");\n\n        Driver bob = service.registerDriver(\"Bob\",\n                \"243-987-2860\",\n                new Vehicle(\"KA01-1234\", \"Toyota Prius\", RideType.SEDAN),\n                new Location(1.0, 1.0));\n\n        Driver charlie = service.registerDriver(\"Charlie\",\n                \"313-486-2691\",\n                new Vehicle(\"KA02-5678\", \"Honda CRV\", RideType.SUV),\n                new Location(2.0, 2.0));\n\n        Driver david = service.registerDriver(\"David\",\n                \"613-586-3241\",\n                new Vehicle(\"KA03-9012\", \"Honda CRV\", RideType.SEDAN),\n                new Location(1.2, 1.2));\n\n        // 3. Drivers go online\n        bob.setStatus(DriverStatus.ONLINE);\n        charlie.setStatus(DriverStatus.ONLINE);\n        david.setStatus(DriverStatus.ONLINE);\n\n        // David is online but will be too far for the first request\n        david.setCurrentLocation(new Location(10.0, 10.0));\n\n        // 4. Alice requests a ride\n        Location pickupLocation = new Location(0.0, 0.0);\n        Location dropoffLocation = new Location(5.0, 5.0);\n\n        // Rider wants a SEDAN\n        Trip trip1 = service.requestRide(alice.getId(), pickupLocation, dropoffLocation, RideType.SEDAN);\n\n        if (trip1 != null) {\n            // 5. One of the nearby drivers accepts the ride\n            // In this case, Bob (1.0, 1.0) is closer than David (10.0, 10.0 is too far).\n            // Charlie is ignored because he drives an SUV.\n            service.acceptRide(bob.getId(), trip1.getId());\n\n            // 6. The trip progresses\n            service.startTrip(trip1.getId());\n            service.endTrip(trip1.getId());\n        }\n\n        System.out.println(\"\\n--- Checking Trip History ---\");\n        System.out.println(\"Alice's trip history: \" + alice.getTripHistory());\n        System.out.println(\"Bob's trip history: \" + bob.getTripHistory());\n\n        // --- Second ride request ---\n        System.out.println(\"\\n=============================================\");\n        Rider harry = service.registerRider(\"Harry\", \"167-342-7834\");\n\n        // Harry requests an SUV\n        Trip trip2 = service.requestRide(harry.getId(),\n                new Location(2.5, 2.5),\n                new Location(8.0, 8.0),\n                RideType.SUV);\n\n        if(trip2 != null) {\n            // Only Charlie is available for an SUV ride\n            service.acceptRide(charlie.getId(), trip2.getId());\n            service.startTrip(trip2.getId());\n            service.endTrip(trip2.getId());\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/entities/Driver.java",
    "content": "package ridesharingservice.entities;\n\nimport ridesharingservice.enums.DriverStatus;\nimport ridesharingservice.enums.TripStatus;\n\npublic class Driver extends User {\n    private Vehicle vehicle;\n    private Location currentLocation;\n    private DriverStatus status;\n\n    public Driver(String name, String contact, Vehicle vehicle, Location initialLocation) {\n        super(name, contact);\n        this.vehicle = vehicle;\n        this.currentLocation = initialLocation;\n        this.status = DriverStatus.OFFLINE; // Default status\n    }\n\n    public Vehicle getVehicle() {\n        return vehicle;\n    }\n\n    public DriverStatus getStatus() {\n        return status;\n    }\n\n    public void setStatus(DriverStatus status) {\n        this.status = status;\n        System.out.println(\"Driver \" + getName() + \" is now \" + status);\n    }\n\n    public Location getCurrentLocation() {\n        return currentLocation;\n    }\n\n    public void setCurrentLocation(Location currentLocation) {\n        this.currentLocation = currentLocation;\n    }\n\n    @Override public void onUpdate(Trip trip) {\n        System.out.printf(\"--- Notification for Driver %s ---\\n\", getName());\n        System.out.printf(\"  Trip %s status: %s.\\n\", trip.getId(), trip.getStatus());\n        if (trip.getStatus() == TripStatus.REQUESTED) {\n            System.out.println(\"  A new ride is available for you to accept.\");\n        }\n        System.out.println(\"--------------------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/entities/Location.java",
    "content": "package ridesharingservice.entities;\n\npublic class Location {\n    private final double latitude;\n    private final double longitude;\n\n    public Location(double latitude, double longitude) {\n        this.latitude = latitude;\n        this.longitude = longitude;\n    }\n\n    public double distanceTo(Location other) {\n        double dx = this.latitude - other.latitude;\n        double dy = this.longitude - other.longitude;\n        return Math.sqrt(dx * dx + dy * dy); // Euclidean for simplicity\n    }\n\n    @Override\n    public String toString() {\n        return \"Location(\" + latitude + \", \" + longitude + \")\";\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/entities/Trip.java",
    "content": "package ridesharingservice.entities;\n\nimport java.util.UUID;\n\nimport ridesharingservice.enums.TripStatus;\nimport ridesharingservice.observer.Rider;\nimport ridesharingservice.observer.TripObserver;\nimport ridesharingservice.state.RequestedState;\nimport ridesharingservice.state.TripState;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class Trip {\n    private final String id;\n    private final Rider rider;\n    private Driver driver;\n    private final Location pickupLocation;\n    private final Location dropoffLocation;\n    private final double fare;\n    private TripStatus status;\n\n    private TripState currentState;\n    private final List<TripObserver> observers = new ArrayList<>();\n\n    private Trip(TripBuilder builder) {\n        this.id = builder.id;\n        this.rider = builder.rider;\n        this.pickupLocation = builder.pickupLocation;\n        this.dropoffLocation = builder.dropoffLocation;\n        this.fare = builder.fare;\n        this.status = TripStatus.REQUESTED;\n        this.currentState = new RequestedState(); // Initial state\n    }\n\n    public void addObserver(TripObserver observer) {\n        observers.add(observer);\n    }\n\n    private void notifyObservers() {\n        observers.forEach(o -> o.onUpdate(this));\n    }\n\n    public void assignDriver(Driver driver) {\n        currentState.assign(this, driver);\n        addObserver(driver);\n        notifyObservers();\n    }\n\n    public void startTrip() {\n        currentState.start(this);\n        notifyObservers();\n    }\n\n    public void endTrip() {\n        currentState.end(this);\n        notifyObservers();\n    }\n\n    // Getters\n    public String getId() { return id; }\n    public Rider getRider() { return rider; }\n    public Driver getDriver() { return driver; }\n    public Location getPickupLocation() { return pickupLocation; }\n    public Location getDropoffLocation() { return dropoffLocation; }\n    public double getFare() { return fare; }\n    public TripStatus getStatus() { return status; }\n\n    // Setters are protected, only to be called by State objects\n    public void setState(TripState state) {\n        this.currentState = state;\n    }\n\n    public void setStatus(TripStatus status) {\n        this.status = status;\n    }\n\n    public void setDriver(Driver driver) {\n        this.driver = driver;\n    }\n\n    // --- Builder Pattern ---\n    public static class TripBuilder {\n        private final String id;\n        private Rider rider;\n        private Location pickupLocation;\n        private Location dropoffLocation;\n        private double fare;\n\n        public TripBuilder() {\n            this.id = UUID.randomUUID().toString();\n        }\n\n        public TripBuilder withRider(Rider rider) {\n            this.rider = rider;\n            return this;\n        }\n\n        public TripBuilder withPickupLocation(Location pickupLocation) {\n            this.pickupLocation = pickupLocation;\n            return this;\n        }\n\n        public TripBuilder withDropoffLocation(Location dropoffLocation) {\n            this.dropoffLocation = dropoffLocation;\n            return this;\n        }\n\n        public TripBuilder withFare(double fare) {\n            this.fare = fare;\n            return this;\n        }\n\n        public Trip build() {\n            // Basic validation\n            if (rider == null || pickupLocation == null || dropoffLocation == null) {\n                throw new IllegalStateException(\"Rider, pickup, and dropoff locations are required to build a trip.\");\n            }\n            return new Trip(this);\n        }\n    }\n\n    @Override\n    public String toString() {\n        return \"Trip [id=\" + id + \", status=\" + status + \", fare=$\" + String.format(\"%.2f\", fare) + \"]\";\n    }\n}"
  },
  {
    "path": "solutions/java/src/ridesharingservice/entities/User.java",
    "content": "package ridesharingservice.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\nimport ridesharingservice.observer.TripObserver;\n\npublic abstract class User implements TripObserver {\n    private final String id;\n    private final String name;\n    private final String contact;\n    private final List<Trip> tripHistory;\n\n    public User(String name, String contact) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.contact = contact;\n        this.tripHistory = new ArrayList<>();\n    }\n\n    public void addTripToHistory(Trip trip) {\n        tripHistory.add(trip);\n    }\n\n    public List<Trip> getTripHistory() {\n        return tripHistory;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getContact() {\n        return contact;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/entities/Vehicle.java",
    "content": "package ridesharingservice.entities;\n\nimport ridesharingservice.enums.RideType;\n\npublic class Vehicle {\n    private final String licenseNumber;\n    private final String model;\n    private final RideType type;\n\n    public Vehicle(String licenseNumber, String model, RideType type) {\n        this.licenseNumber = licenseNumber;\n        this.model = model;\n        this.type = type;\n    }\n\n    public String getLicenseNumber() { return licenseNumber; }\n\n    public String getModel() { return model; }\n\n    public RideType getType() { return type; }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/enums/DriverStatus.java",
    "content": "package ridesharingservice.enums;\n\npublic enum DriverStatus {\n    ONLINE,\n    IN_TRIP,\n    OFFLINE\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/enums/RideType.java",
    "content": "package ridesharingservice.enums;\n\npublic enum RideType {\n    SEDAN,\n    SUV,\n    AUTO\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/enums/TripStatus.java",
    "content": "package ridesharingservice.enums;\n\npublic enum TripStatus {\n    REQUESTED,\n    ASSIGNED,\n    IN_PROGRESS,\n    COMPLETED,\n    CANCELLED\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/observer/Rider.java",
    "content": "package ridesharingservice.observer;\n\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.entities.User;\n\npublic class Rider extends User {\n    public Rider(String name, String contact) {\n        super(name, contact);\n    }\n\n    @Override\n    public void onUpdate(Trip trip) {\n        System.out.printf(\"--- Notification for Rider %s ---\\n\", getName());\n        System.out.printf(\"  Trip %s is now %s.\\n\", trip.getId(), trip.getStatus());\n        if (trip.getDriver() != null) {\n            System.out.printf(\"  Driver: %s in a %s (%s)\\n\",\n                    trip.getDriver().getName(), trip.getDriver().getVehicle().getModel(),\n                    trip.getDriver().getVehicle().getLicenseNumber());\n        }\n        System.out.println(\"--------------------------------\\n\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/ridesharingservice/observer/TripObserver.java",
    "content": "package ridesharingservice.observer;\n\nimport ridesharingservice.entities.Trip;\n\npublic interface TripObserver {\n    void onUpdate(Trip trip);\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/state/AssignedState.java",
    "content": "package ridesharingservice.state;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.enums.TripStatus;\n\npublic class AssignedState implements TripState {\n    @Override\n    public void request(Trip trip) {\n        System.out.println(\"Trip has already been requested and assigned.\");\n    }\n\n    @Override\n    public void assign(Trip trip, Driver driver) {\n        System.out.println(\"Trip is already assigned. To re-assign, cancel first.\");\n    }\n\n    @Override\n    public void start(Trip trip) {\n        trip.setStatus(TripStatus.IN_PROGRESS);\n        trip.setState(new InProgressState());\n    }\n\n    @Override\n    public void end(Trip trip) {\n        System.out.println(\"Cannot end a trip that has not started.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/state/CompletedState.java",
    "content": "package ridesharingservice.state;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Trip;\n\npublic class CompletedState implements TripState {\n    @Override\n    public void request(Trip trip) {\n        System.out.println(\"Cannot request a trip that is already completed.\");\n    }\n\n    @Override\n    public void assign(Trip trip, Driver driver) {\n        System.out.println(\"Cannot assign a driver to a completed trip.\");\n    }\n\n    @Override\n    public void start(Trip trip) {\n        System.out.println(\"Cannot start a completed trip.\");\n    }\n\n    @Override\n    public void end(Trip trip) {\n        System.out.println(\"Trip is already completed.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/state/InProgressState.java",
    "content": "package ridesharingservice.state;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.enums.TripStatus;\n\npublic class InProgressState implements TripState {\n    @Override\n    public void request(Trip trip) {\n        System.out.println(\"Trip is already in progress.\");\n    }\n\n    @Override\n    public void assign(Trip trip, Driver driver) {\n        System.out.println(\"Cannot assign a new driver while trip is in progress.\");\n    }\n\n    @Override\n    public void start(Trip trip) {\n        System.out.println(\"Trip is already in progress.\");\n    }\n\n    @Override\n    public void end(Trip trip) {\n        trip.setStatus(TripStatus.COMPLETED);\n        trip.setState(new CompletedState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/state/RequestedState.java",
    "content": "package ridesharingservice.state;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Trip;\nimport ridesharingservice.enums.TripStatus;\n\npublic class RequestedState implements TripState {\n    @Override\n    public void request(Trip trip) {\n        System.out.println(\"Trip is already in requested state.\");\n    }\n\n    @Override\n    public void assign(Trip trip, Driver driver) {\n        trip.setDriver(driver);\n        trip.setStatus(TripStatus.ASSIGNED);\n        trip.setState(new AssignedState());\n    }\n\n    @Override\n    public void start(Trip trip) {\n        System.out.println(\"Cannot start a trip that has not been assigned a driver.\");\n    }\n\n    @Override\n    public void end(Trip trip) {\n        System.out.println(\"Cannot end a trip that has not been assigned a driver.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/state/TripState.java",
    "content": "package ridesharingservice.state;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Trip;\n\npublic interface TripState {\n    void request(Trip trip);\n    void assign(Trip trip, Driver driver);\n    void start(Trip trip);\n    void end(Trip trip);\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/strategy/matching/DriverMatchingStrategy.java",
    "content": "package ridesharingservice.strategy.matching;\n\nimport java.util.List;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.enums.RideType;\n\npublic interface DriverMatchingStrategy {\n    List<Driver> findDrivers(List<Driver> allDrivers, Location pickupLocation, RideType rideType);\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/strategy/matching/NearestDriverMatchingStrategy.java",
    "content": "package ridesharingservice.strategy.matching;\n\nimport java.util.Comparator;\nimport java.util.List;\nimport java.util.stream.Collectors;\n\nimport ridesharingservice.entities.Driver;\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.enums.DriverStatus;\nimport ridesharingservice.enums.RideType;\n\npublic class NearestDriverMatchingStrategy implements DriverMatchingStrategy {\n    private static final double MAX_DISTANCE_KM = 5.0; // Max distance to consider a driver \"nearby\"\n\n    @Override\n    public List<Driver> findDrivers(List<Driver> allDrivers, Location pickupLocation, RideType rideType) {\n        System.out.println(\"Finding nearest drivers for ride type: \" + rideType);\n        return allDrivers.stream()\n                .filter(driver -> driver.getStatus() == DriverStatus.ONLINE)\n                .filter(driver -> driver.getVehicle().getType() == rideType)\n                .filter(driver -> pickupLocation.distanceTo(driver.getCurrentLocation()) <= MAX_DISTANCE_KM)\n                .sorted(Comparator.comparingDouble(driver -> pickupLocation.distanceTo(driver.getCurrentLocation())))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/strategy/pricing/FlatRatePricingStrategy.java",
    "content": "package ridesharingservice.strategy.pricing;\n\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.enums.RideType;\n\npublic class FlatRatePricingStrategy implements PricingStrategy {\n    private static final double BASE_FARE = 5.0;\n    private static final double FLAT_RATE = 1.5;\n\n    @Override\n    public double calculateFare(Location pickup, Location dropoff, RideType rideType) {\n        double distance = pickup.distanceTo(dropoff);\n        return BASE_FARE + distance * FLAT_RATE;\n    }\n}"
  },
  {
    "path": "solutions/java/src/ridesharingservice/strategy/pricing/PricingStrategy.java",
    "content": "package ridesharingservice.strategy.pricing;\n\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.enums.RideType;\n\npublic interface PricingStrategy {\n    double calculateFare(Location pickup, Location dropoff, RideType rideType);\n}\n"
  },
  {
    "path": "solutions/java/src/ridesharingservice/strategy/pricing/VehicleBasedPricingStrategy.java",
    "content": "package ridesharingservice.strategy.pricing;\n\nimport java.util.Map;\n\nimport ridesharingservice.entities.Location;\nimport ridesharingservice.enums.RideType;\n\npublic class VehicleBasedPricingStrategy implements PricingStrategy {\n    private static final double BASE_FARE = 2.50;\n    private static final Map<RideType, Double> RATE_PER_KM = Map.of(\n            RideType.SEDAN, 1.50,\n            RideType.SUV, 2.00,\n            RideType.AUTO, 1.00\n    );\n\n    @Override\n    public double calculateFare(Location pickup, Location dropoff, RideType rideType) {\n        return BASE_FARE + RATE_PER_KM.get(rideType) * pickup.distanceTo(dropoff);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/Game.java",
    "content": "package snakeandladdergame;\n\nimport snakeandladdergame.enums.GameStatus;\nimport snakeandladdergame.models.Board;\nimport snakeandladdergame.models.BoardEntity;\nimport snakeandladdergame.models.Dice;\nimport snakeandladdergame.models.Player;\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\n\npublic class Game {\n    private final Board board;\n    private final Queue<Player> players;\n    private final Dice dice;\n    private GameStatus status;\n    private Player winner;\n\n    private Game(Builder builder) {\n        this.board = builder.board;\n        this.players = new LinkedList<>(builder.players);\n        this.dice = builder.dice;\n        this.status = GameStatus.NOT_STARTED;\n    }\n\n    public void play() {\n        if (players.size() < 2) {\n            System.out.println(\"Cannot start game. At least 2 players are required.\");\n            return;\n        }\n\n        this.status = GameStatus.RUNNING;\n        System.out.println(\"Game started!\");\n\n        while (status == GameStatus.RUNNING) {\n            Player currentPlayer = players.poll();\n            takeTurn(currentPlayer);\n\n            // If the game is not finished and the player didn't roll a 6, add them back to the queue\n            if (status == GameStatus.RUNNING) {\n                players.add(currentPlayer);\n            }\n        }\n\n        System.out.println(\"Game Finished!\");\n        if (winner != null) {\n            System.out.printf(\"The winner is %s!\\n\", winner.getName());\n        }\n    }\n\n    private void takeTurn(Player player) {\n        int roll = dice.roll();\n        System.out.printf(\"\\n%s's turn. Rolled a %d.\\n\", player.getName(), roll);\n\n        int currentPosition = player.getPosition();\n        int nextPosition = currentPosition + roll;\n\n        if (nextPosition > board.getSize()) {\n            System.out.printf(\"Oops, %s needs to land exactly on %d. Turn skipped.\\n\", player.getName(), board.getSize());\n            return;\n        }\n\n        if (nextPosition == board.getSize()) {\n            player.setPosition(nextPosition);\n            this.winner = player;\n            this.status = GameStatus.FINISHED;\n            System.out.printf(\"Hooray! %s reached the final square %d and won!\\n\", player.getName(), board.getSize());\n            return;\n        }\n\n        int finalPosition = board.getFinalPosition(nextPosition);\n\n        if (finalPosition > nextPosition) { // Ladder\n            System.out.printf(\"Wow! %s found a ladder 🪜 at %d and climbed to %d.\\n\", player.getName(), nextPosition, finalPosition);\n        } else if (finalPosition < nextPosition) { // Snake\n            System.out.printf(\"Oh no! %s was bitten by a snake 🐍 at %d and slid down to %d.\\n\", player.getName(), nextPosition, finalPosition);\n        } else {\n            System.out.printf(\"%s moved from %d to %d.\\n\", player.getName(), currentPosition, finalPosition);\n        }\n\n        player.setPosition(finalPosition);\n\n        if (roll == 6) {\n            System.out.printf(\"%s rolled a 6 and gets another turn!\\n\", player.getName());\n            takeTurn(player);\n        }\n    }\n\n    // 🧱 Inner Builder class\n    public static class Builder {\n        private Board board;\n        private Queue<Player> players;\n        private Dice dice;\n\n        public Builder setBoard(int boardSize, List<BoardEntity> boardEntities) {\n            this.board = new Board(boardSize, boardEntities);\n            return this;\n        }\n\n        public Builder setPlayers(List<String> playerNames) {\n            this.players = new LinkedList<>();\n            for (String playerName : playerNames) {\n                players.add(new Player(playerName));\n            }\n            return this;\n        }\n\n        public Builder setDice(Dice dice) {\n            this.dice = dice;\n            return this;\n        }\n\n        public Game build() {\n            if (board == null || players == null || dice == null) {\n                throw new IllegalStateException(\"Board, Players, and Dice must be set.\");\n            }\n            return new Game(this);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/README.md",
    "content": "# Snake and Ladder Game (LLD)\n\n## Problem Statement\n\nDesign and implement a Snake and Ladder Game that allows multiple players to play on a board with snakes and ladders, simulates dice rolls, and determines the winner.\n\n---\n\n## Requirements\n\n- **Multiple Players:** The game supports two or more players.\n- **Board:** The game uses a board with a configurable size (typically 1 to 100).\n- **Snakes and Ladders:** The board contains snakes (which move players down) and ladders (which move players up).\n- **Dice Roll:** Players roll a dice to determine their move.\n- **Turn Management:** Players take turns in a round-robin fashion.\n- **Win Condition:** The first player to reach the last cell wins.\n- **Input Validation:** The game prevents invalid moves (e.g., moving beyond the last cell).\n- **Extensibility:** Easy to add new features such as multiple dice, power-ups, or custom board sizes.\n\n---\n\n## Core Entities\n\n- **SnakeAndLadderGame:** Main class that manages the game flow, player turns, and win condition.\n- **Board:** Represents the game board, including snakes, ladders, and player positions.\n- **Snake:** Represents a snake with a start and end position.\n- **Ladder:** Represents a ladder with a start and end position.\n- **Player:** Represents a player with a name and current position.\n- **Dice:** Simulates dice rolls.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/SnakeAndLadderGame-class-diagram.png)\n\n### 1. SnakeAndLadderGame\n- **Fields:** Board board, List<Player> players, Dice dice, boolean isGameOver\n- **Methods:** start(), playTurn(), movePlayer(Player, int steps), checkWin(Player), getCurrentPlayer()\n\n### 2. Board\n- **Fields:** int size, List<Snake> snakes, List<Ladder> ladders, Map<Player, Integer> playerPositions\n- **Methods:** getNextPosition(int current, int roll), addSnake(Snake), addLadder(Ladder), setPlayerPosition(Player, int position), getPlayerPosition(Player)\n\n### 3. Snake\n- **Fields:** int start, int end\n\n### 4. Ladder\n- **Fields:** int start, int end\n\n### 5. Player\n- **Fields:** String name, int position\n\n### 6. Dice\n- **Methods:** roll()\n\n---\n\n## Example Usage\n\n```java\nList<Player> players = List.of(new Player(\"Alice\"), new Player(\"Bob\"));\nList<Snake> snakes = List.of(new Snake(14, 7), new Snake(31, 26));\nList<Ladder> ladders = List.of(new Ladder(3, 22), new Ladder(5, 8));\nBoard board = new Board(100, snakes, ladders, players);\nDice dice = new Dice();\n\nSnakeAndLadderGame game = new SnakeAndLadderGame(board, players, dice);\ngame.start();\n```\n\n---\n\n## Demo\n\nSee `SnakeAndLadderDemo.java` for a sample usage and simulation of the snake and ladder game.\n\n---\n\n## Extending the Framework\n\n- **Add multiple dice:** Allow rolling more than one dice per turn.\n- **Add power-ups:** Introduce special cells with unique effects.\n- **Add custom board sizes:** Support boards larger or smaller than 100 cells.\n\n---"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/SnakeAndLadderDemo.java",
    "content": "package snakeandladdergame;\n\nimport snakeandladdergame.models.BoardEntity;\nimport snakeandladdergame.models.Dice;\nimport snakeandladdergame.models.Ladder;\nimport snakeandladdergame.models.Snake;\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class SnakeAndLadderDemo {\n    public static void main(String[] args) {\n        List<BoardEntity> boardEntities = List.of(\n                new Snake(17, 7), new Snake(54, 34),\n                new Snake(62, 19), new Snake(98, 79),\n                new Ladder(3, 38), new Ladder(24, 33),\n                new Ladder(42, 93), new Ladder(72, 84)\n        );\n\n        List<String> players = Arrays.asList(\"Alice\", \"Bob\", \"Charlie\");\n\n        Game game = new Game.Builder()\n                .setBoard(100, boardEntities)\n                .setPlayers(players)\n                .setDice(new Dice(1, 6))\n                .build();\n\n        game.play();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/enums/GameStatus.java",
    "content": "package snakeandladdergame.enums;\n\npublic enum GameStatus {\n    NOT_STARTED,\n    RUNNING,\n    FINISHED\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/Board.java",
    "content": "package snakeandladdergame.models;\n\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class Board {\n    private final int size;\n    private final Map<Integer, Integer> snakesAndLadders;\n\n    public Board(int size, List<BoardEntity> entities) {\n        this.size = size;\n        this.snakesAndLadders = new HashMap<>();\n\n        for (BoardEntity entity : entities) {\n            snakesAndLadders.put(entity.getStart(), entity.getEnd());\n        }\n    }\n\n    public int getSize() {\n        return size;\n    }\n\n    public int getFinalPosition(int position) {\n        return snakesAndLadders.getOrDefault(position, position);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/BoardEntity.java",
    "content": "package snakeandladdergame.models;\n\npublic abstract class BoardEntity {\n    private final int start;\n    private final int end;\n\n    public BoardEntity(int start, int end) {\n        this.start = start;\n        this.end = end;\n    }\n\n    public int getStart() {\n        return start;\n    }\n\n    public int getEnd() {\n        return end;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/Dice.java",
    "content": "package snakeandladdergame.models;\n\npublic class Dice {\n    private final int minValue;\n    private final int maxValue;\n\n    public Dice(int minValue, int maxValue) {\n        this.minValue = minValue;\n        this.maxValue = maxValue;\n    }\n\n    public int roll() {\n        return (int) (Math.random() * (maxValue - minValue + 1) + minValue);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/Ladder.java",
    "content": "package snakeandladdergame.models;\n\npublic class Ladder extends BoardEntity {\n    public Ladder(int start, int end) {\n        super(start, end);\n        if (start >= end) {\n            throw new IllegalArgumentException(\"Ladder bottom must be at a lower position than its top.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/Player.java",
    "content": "package snakeandladdergame.models;\n\npublic class Player {\n    private final String name;\n    private int position;\n\n    public Player(String name) {\n        this.name = name;\n        this.position = 0;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getPosition() {\n        return position;\n    }\n\n    public void setPosition(int position) {\n        this.position = position;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/snakeandladdergame/models/Snake.java",
    "content": "package snakeandladdergame.models;\n\npublic class Snake extends BoardEntity {\n    public Snake(int start, int end) {\n        super(start, end);\n        if (start <= end) {\n            throw new IllegalArgumentException(\"Snake head must be at a higher position than its tail.\");\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/README.md",
    "content": "Facade Pattern: The SocialNetworkFacade is the main entry point for the client. It provides a simple, unified interface (createPost, addFriend, getNewsFeed) to the complex subsystem of services and repositories.\n\nObserver Pattern: The PostService acts as a Subject. When a user creates a post, it notifies all registered Observers (like a NewsFeedNotifier). This decouples the action of posting from the consequence of updating news feeds.\n\nStrategy Pattern: The NewsFeedService uses a NewsFeedGenerationStrategy to generate a user's news feed. The default is a ChronologicalStrategy, but this can be easily swapped for a more complex algorithm.\n\nComposite Pattern: To model comments and replies, the Commentable interface is used. Both Post and Comment implement this interface, allowing them to be treated uniformly. A comment can be added to a post or to another comment, forming a tree structure.\n\nSingleton Pattern: The Repository classes are implemented as Singletons to provide a global, in-memory data store for this simulation.\n\nRepository Pattern: This pattern is used to abstract the data access layer. Services interact with UserRepository and PostRepository interfaces, completely decoupling them from the underlying data storage mechanism (which is a ConcurrentHashMap in this case).\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/SocialNetworkDemo.java",
    "content": "package socialnetworkingservice;\n\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\n\nimport java.util.List;\n\npublic class SocialNetworkDemo {\n    public static void main(String[] args) {\n        SocialNetworkFacade socialNetwork = new SocialNetworkFacade();\n\n        System.out.println(\"----------- 1. Creating Users -----------\");\n        User alice = socialNetwork.createUser(\"Alice\", \"alice@example.com\");\n        User bob = socialNetwork.createUser(\"Bob\", \"bob@example.com\");\n        User charlie = socialNetwork.createUser(\"Charlie\", \"charlie@example.com\");\n        System.out.println(\"Created users: \" + alice.getName() + \", \" + bob.getName() + \", \" + charlie.getName());\n\n        System.out.println(\"\\n----------- 2. Building Friendships -----------\");\n        socialNetwork.addFriend(alice.getId(), bob.getId());\n        socialNetwork.addFriend(bob.getId(), charlie.getId());\n        System.out.println(alice.getName() + \" and \" + bob.getName() + \" are now friends.\");\n        System.out.println(bob.getName() + \" and \" + charlie.getName() + \" are now friends.\");\n\n        System.out.println(\"\\n----------- 3. Users Create Posts -----------\");\n        Post alicePost = socialNetwork.createPost(alice.getId(), \"Hello from Alice!\");\n        Post bobPost = socialNetwork.createPost(bob.getId(), \"It's a beautiful day!\");\n        Post charliePost = socialNetwork.createPost(charlie.getId(), \"Thinking about design patterns.\");\n\n        System.out.println(\"\\n----------- 4. Users Interact with Posts -----------\");\n        socialNetwork.addComment(bob.getId(), alicePost.getId(), \"Hey Alice, nice to see you here!\");\n        socialNetwork.likePost(charlie.getId(), alicePost.getId());\n\n        System.out.println(\"\\n----------- 5. Viewing News Feeds (Strategy Pattern) -----------\");\n\n        System.out.println(\"\\n--- Alice's News Feed (should see Bob's post) ---\");\n        List<Post> alicesFeed = socialNetwork.getNewsFeed(alice.getId());\n        printFeed(alicesFeed);\n\n        System.out.println(\"\\n--- Bob's News Feed (should see Alice's, and Charlie's post) ---\");\n        List<Post> bobsFeed = socialNetwork.getNewsFeed(bob.getId());\n        printFeed(bobsFeed);\n\n        System.out.println(\"\\n--- Charlie's News Feed (should see Bob's post) ---\");\n        List<Post> charliesFeed = socialNetwork.getNewsFeed(charlie.getId());\n        printFeed(charliesFeed);\n    }\n\n    private static void printFeed(List<Post> feed) {\n        if (feed.isEmpty()) {\n            System.out.println(\"  No posts in the feed.\");\n            return;\n        }\n        feed.forEach(post -> {\n            System.out.println(\"  Post by \" + post.getAuthor().getName() + \" at \" + post.getTimestamp());\n            System.out.println(\"    \\\"\" + post.getContent() + \"\\\"\");\n            System.out.println(\"    Likes: \" + post.getLikes().size() + \", Comments: \" + post.getComments().size());\n        });\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/SocialNetworkFacade.java",
    "content": "package socialnetworkingservice;\n\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\nimport socialnetworkingservice.observer.UserNotifier;\nimport socialnetworkingservice.service.NewsFeedService;\nimport socialnetworkingservice.service.PostService;\nimport socialnetworkingservice.service.UserService;\n\nimport java.util.List;\n\npublic class SocialNetworkFacade {\n    private final UserService userService;\n    private final PostService postService;\n    private final NewsFeedService newsFeedService;\n\n    public SocialNetworkFacade() {\n        this.userService = new UserService();\n        this.postService = new PostService();\n        this.newsFeedService = new NewsFeedService();\n        // Wire up the observer\n        postService.addObserver(new UserNotifier());\n    }\n\n    public User createUser(String name, String email) {\n        return userService.createUser(name, email);\n    }\n\n    public void addFriend(String userId1, String userId2) {\n        userService.addFriend(userId1, userId2);\n    }\n\n    public Post createPost(String authorId, String content) {\n        User author = userService.getUserById(authorId);\n        return postService.createPost(author, content);\n    }\n\n    public void addComment(String userId, String postId, String content) {\n        User user = userService.getUserById(userId);\n        postService.addComment(user, postId, content);\n    }\n\n    public void likePost(String userId, String postId) {\n        User user = userService.getUserById(userId);\n        postService.likePost(user, postId);\n    }\n\n    public List<Post> getNewsFeed(String userId) {\n        User user = userService.getUserById(userId);\n        return newsFeedService.getNewsFeed(user);\n    }\n}\n\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/model/Comment.java",
    "content": "package socialnetworkingservice.model;\n\nimport java.util.List;\n\npublic class Comment extends CommentableEntity {\n    public Comment(User author, String content) {\n        super(author, content);\n    }\n\n    public List<Comment> getReplies() {\n        return getComments();\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/model/CommentableEntity.java",
    "content": "package socialnetworkingservice.model;\n\nimport java.time.LocalDateTime;\nimport java.util.*;\n\npublic abstract class CommentableEntity {\n    protected final String id;\n    protected final User author;\n    protected final String content;\n    protected final LocalDateTime timestamp;\n    private final Set<User> likes = new HashSet<>();\n    protected final List<Comment> comments = new ArrayList<>();\n\n    public CommentableEntity(User author, String content) {\n        this.id = UUID.randomUUID().toString();\n        this.author = author;\n        this.content = content;\n        this.timestamp = LocalDateTime.now();\n    }\n\n    public void addLike(User user) {\n        likes.add(user);\n    }\n\n    public void addComment(Comment comment) {\n        comments.add(comment);\n    }\n\n    public String getId() { return id; }\n    public User getAuthor() { return author; }\n    public String getContent() { return content; }\n    public LocalDateTime getTimestamp() { return timestamp; }\n    public List<Comment> getComments() { return comments; }\n    public Set<User> getLikes() {\n        return likes;\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/model/Post.java",
    "content": "package socialnetworkingservice.model;\n\npublic class Post extends CommentableEntity {\n    public Post(User author, String content) {\n        super(author, content);\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/model/User.java",
    "content": "package socialnetworkingservice.model;\n\nimport java.util.*;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final String email;\n    private final Set<User> friends = new HashSet<>();\n    private final List<Post> posts = new ArrayList<>();\n\n    public User(String name, String email) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.email = email;\n    }\n\n    public void addFriend(User friend) {\n        friends.add(friend);\n    }\n\n    public  void addPost(Post post) {\n        posts.add(post);\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public Set<User> getFriends() { return friends; }\n    public List<Post> getPosts() { return posts; }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/observer/PostObserver.java",
    "content": "package socialnetworkingservice.observer;\n\nimport socialnetworkingservice.model.Comment;\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\n\npublic interface PostObserver {\n    void onPostCreated(Post post);\n    void onLike(Post post, User user);\n    void onComment(Post post, Comment comment);\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/observer/UserNotifier.java",
    "content": "package socialnetworkingservice.observer;\n\nimport socialnetworkingservice.model.Comment;\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\n\npublic class UserNotifier implements PostObserver {\n    @Override\n    public void onPostCreated(Post post) {\n        User author = post.getAuthor();\n        for (User friend: author.getFriends()) {\n            System.out.println(\"Notification for \" + friend.getName() + \": \" + author.getName() + \" created a new post: \" + post.getContent());\n        }\n    }\n\n    @Override\n    public void onLike(Post post, User user) {\n        User author = post.getAuthor();\n        System.out.println(\"Notification for \" + author.getName() + \": \" + user.getName() + \" liked your post\");\n    }\n\n    @Override\n    public void onComment(Post post, Comment comment) {\n        User author = post.getAuthor();\n        System.out.println(\"Notification for \" + author.getName() + \": \" + comment.getAuthor().getName() + \" commented on your post\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/repository/PostRepository.java",
    "content": "package socialnetworkingservice.repository;\n\nimport socialnetworkingservice.model.Post;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class PostRepository {\n    private static final PostRepository INSTANCE = new PostRepository();\n    private final Map<String, Post> posts = new ConcurrentHashMap<>();\n\n    private PostRepository() {}\n\n    public static PostRepository getInstance() { return INSTANCE; }\n\n    public void save(Post post) {\n        posts.put(post.getId(), post);\n    }\n\n    public Post findById(String id) {\n        return posts.get(id);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/repository/UserRepository.java",
    "content": "package socialnetworkingservice.repository;\n\nimport socialnetworkingservice.model.User;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class UserRepository {\n    private static final UserRepository INSTANCE = new UserRepository();\n    private final Map<String, User> users = new ConcurrentHashMap<>();\n\n    private UserRepository() {}\n\n    public static UserRepository getInstance() {\n        return INSTANCE;\n    }\n\n    public void save(User user) {\n        users.put(user.getId(), user);\n    }\n\n    public User findById(String id) {\n        return users.get(id);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/service/NewsFeedService.java",
    "content": "package socialnetworkingservice.service;\n\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\nimport socialnetworkingservice.strategy.ChronologicalStrategy;\nimport socialnetworkingservice.strategy.NewsFeedGenerationStrategy;\n\nimport java.util.List;\n\npublic class NewsFeedService {\n    private NewsFeedGenerationStrategy strategy;\n\n    public NewsFeedService() {\n        this.strategy = new ChronologicalStrategy(); // Default strategy\n    }\n\n    public void setStrategy(NewsFeedGenerationStrategy strategy) {\n        this.strategy = strategy;\n    }\n\n    public List<Post> getNewsFeed(User user) {\n        return strategy.generateFeed(user);\n    }\n}"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/service/PostService.java",
    "content": "package socialnetworkingservice.service;\n\nimport socialnetworkingservice.model.Comment;\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\nimport socialnetworkingservice.observer.PostObserver;\nimport socialnetworkingservice.repository.PostRepository;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PostService {\n    private final PostRepository postRepository = PostRepository.getInstance();\n    private final List<PostObserver> observers = new ArrayList<>();\n\n    public void addObserver(PostObserver observer) { observers.add(observer); }\n\n    public Post createPost(User author, String content) {\n        Post post = new Post(author, content);\n        postRepository.save(post);\n        author.addPost(post);\n        observers.forEach(observer -> observer.onPostCreated(post)); // Notify observers\n        return post;\n    }\n\n    public void likePost(User user, String postId) {\n        Post post = postRepository.findById(postId);\n        post.addLike(user);\n        observers.forEach(observer -> observer.onLike(post, user));\n    }\n\n    public void addComment(User author, String commentableId, String content) {\n        Comment comment = new Comment(author, content);\n        Post post = postRepository.findById(commentableId);\n        post.addComment(comment);\n        observers.forEach(observer -> observer.onComment(post, comment));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/service/UserService.java",
    "content": "package socialnetworkingservice.service;\n\nimport socialnetworkingservice.model.User;\nimport socialnetworkingservice.repository.UserRepository;\n\npublic class UserService {\n    private final UserRepository userRepository = UserRepository.getInstance();\n\n    public User createUser(String name, String email) {\n        User user = new User(name, email);\n        userRepository.save(user);\n        return user;\n    }\n\n    public void addFriend(String userId1, String userId2) {\n        User user1 = userRepository.findById(userId1);\n        User user2 = userRepository.findById(userId2);\n\n        user1.addFriend(user2);\n        user2.addFriend(user1);\n    }\n\n    public User getUserById(String userId) {\n        return userRepository.findById(userId);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/strategy/ChronologicalStrategy.java",
    "content": "package socialnetworkingservice.strategy;\n\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Set;\n\npublic class ChronologicalStrategy implements NewsFeedGenerationStrategy {\n    @Override\n    public List<Post> generateFeed(User user) {\n        Set<User> friends = user.getFriends();\n        List<Post> feed = new ArrayList<>();\n\n        for (User friend: friends) {\n            feed.addAll(friend.getPosts());\n        }\n\n        // Sort posts by timestamp in reverse (most recent first)\n        feed.sort((p1, p2) -> p2.getTimestamp().compareTo(p1.getTimestamp()));\n\n        return feed;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/socialnetworkingservice/strategy/NewsFeedGenerationStrategy.java",
    "content": "package socialnetworkingservice.strategy;\n\nimport socialnetworkingservice.model.Post;\nimport socialnetworkingservice.model.User;\n\nimport java.util.List;\n\npublic interface NewsFeedGenerationStrategy {\n    List<Post> generateFeed(User user);\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/README.md",
    "content": "# Splitwise System (LLD)\n\n## Problem Statement\n\nDesign and implement a Splitwise System that allows users to split expenses among groups and individuals. The system should handle expense tracking, balance calculations, and settlement of debts between users.\n\n---\n\n## Requirements\n\n1. **User Management:**\n   - Create and manage user profiles\n   - Track user balances\n   - Handle user relationships\n\n2. **Group Management:**\n   - Create and manage groups\n   - Add/remove members\n   - Track group expenses\n\n3. **Expense Management:**\n   - Add expenses to groups or individuals\n   - Support different split types (EQUAL, EXACT, PERCENTAGE)\n   - Track expense history\n\n4. **Balance Management:**\n   - Calculate balances between users\n   - Track who owes whom\n   - Handle settlements\n\n5. **Transaction Management:**\n   - Record transactions\n   - Track payment status\n   - Generate balance reports\n\n---\n\n## Core Entities\n\n### 1. SplitwiseService\n- **Fields:** List<User> users, List<Group> groups, List<Expense> expenses\n- **Methods:** \n  - addUser()\n  - createGroup()\n  - addExpense()\n  - getBalance()\n  - settleExpense()\n\n### 2. User\n- **Fields:** String id, String name, String email, Map<User, Double> balances\n- **Methods:** \n  - updateProfile()\n  - getBalance()\n  - addBalance()\n  - subtractBalance()\n\n### 3. Group\n- **Fields:** String id, String name, List<User> members, List<Expense> expenses\n- **Methods:** \n  - addMember()\n  - removeMember()\n  - addExpense()\n  - getBalances()\n\n### 4. Expense\n- **Fields:** String id, String description, double amount, User paidBy, List<User> paidFor, SplitType splitType\n- **Methods:** \n  - calculateSplits()\n  - getAmount()\n  - getPaidBy()\n\n### 5. Transaction\n- **Fields:** String id, User from, User to, double amount\n- **Methods:** \n  - execute()\n  - getStatus()\n\n### 6. SplitType (Enum)\n- **Values:** EQUAL, EXACT, PERCENTAGE\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/splitwise-class-diagram.png)\n\n---\n\n## Example Usage\n\n```java\nSplitwiseService service = new SplitwiseService();\n\n// Create users\nUser user1 = service.addUser(\"John\", \"john@example.com\");\nUser user2 = service.addUser(\"Jane\", \"jane@example.com\");\n\n// Create a group\nGroup group = service.createGroup(\"Trip to Paris\");\ngroup.addMember(user1);\ngroup.addMember(user2);\n\n// Add an expense\nExpense expense = service.addExpense(\n    \"Dinner\", \n    100.0, \n    user1, \n    Arrays.asList(user1, user2), \n    SplitType.EQUAL\n);\n\n// Get balances\ndouble balance = service.getBalance(user1, user2);\n\n// Settle expense\nservice.settleExpense(user2, user1, 50.0);\n```\n\n---\n\n## Demo\n\nSee `SplitwiseDemo.java` for a sample usage and simulation of the Splitwise system.\n\n---\n\n## Extending the Framework\n\n- **Add expense categories:** Categorize expenses (food, travel, etc.)\n- **Add recurring expenses:** Support for regular payments\n- **Add expense comments:** Allow users to add notes to expenses\n- **Add expense attachments:** Support for receipts and documents\n- **Add payment integration:** Integrate with payment gateways\n- **Add notification system:** Send reminders for pending payments\n\n---\n\n## Design Patterns Used\n\n- **Singleton Pattern:** For the Splitwise service instance\n- **Factory Pattern:** For creating different types of splits\n- **Strategy Pattern:** For different expense splitting strategies\n- **Observer Pattern:** For balance updates and notifications\n\n---\n\n## Exception Handling\n\n- **InvalidAmountException:** Thrown when expense amount is invalid\n- **InvalidSplitException:** Thrown when split details are invalid\n- **UserNotFoundException:** Thrown when user is not found\n- **GroupNotFoundException:** Thrown when group is not found\n- **InsufficientBalanceException:** Thrown when user has insufficient balance\n\n---"
  },
  {
    "path": "solutions/java/src/splitwise/SplitwiseDemo.java",
    "content": "package splitwise;\n\n\nimport splitwise.entities.Expense;\nimport splitwise.entities.Group;\nimport splitwise.entities.Transaction;\nimport splitwise.entities.User;\nimport splitwise.strategy.EqualSplitStrategy;\nimport splitwise.strategy.ExactSplitStrategy;\nimport splitwise.strategy.PercentageSplitStrategy;\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class SplitwiseDemo {\n    public static void main(String[] args) {\n        // 1. Setup the service\n        SplitwiseService service = SplitwiseService.getInstance();\n\n        // 2. Create users and groups\n        User alice = service.addUser(\"Alice\", \"alice@a.com\");\n        User bob = service.addUser( \"Bob\", \"bob@b.com\");\n        User charlie = service.addUser(\"Charlie\", \"charlie@c.com\");\n        User david = service.addUser(\"David\", \"david@d.com\");\n\n        Group friendsGroup = service.addGroup(\"Friends Trip\", List.of(alice, bob, charlie, david));\n\n        System.out.println(\"--- System Setup Complete ---\\n\");\n\n        // 3. Use Case 1: Equal Split\n        System.out.println(\"--- Use Case 1: Equal Split ---\");\n        service.createExpense(new Expense.ExpenseBuilder()\n                .setDescription(\"Dinner\")\n                .setAmount(1000)\n                .setPaidBy(alice)\n                .setParticipants(Arrays.asList(alice, bob, charlie, david))\n                .setSplitStrategy(new EqualSplitStrategy())\n        );\n\n        service.showBalanceSheet(alice.getId());\n        service.showBalanceSheet(bob.getId());\n        System.out.println();\n\n        // 4. Use Case 2: Exact Split\n        System.out.println(\"--- Use Case 2: Exact Split ---\");\n        service.createExpense(new Expense.ExpenseBuilder()\n                .setDescription(\"Movie Tickets\")\n                .setAmount(370)\n                .setPaidBy(alice)\n                .setParticipants(Arrays.asList(bob, charlie))\n                .setSplitStrategy(new ExactSplitStrategy())\n                .setSplitValues(Arrays.asList(120.0, 250.0))\n        );\n\n        service.showBalanceSheet(alice.getId());\n        service.showBalanceSheet(bob.getId());\n        System.out.println();\n\n        // 5. Use Case 3: Percentage Split\n        System.out.println(\"--- Use Case 3: Percentage Split ---\");\n        service.createExpense(new Expense.ExpenseBuilder()\n                .setDescription(\"Groceries\")\n                .setAmount(500)\n                .setPaidBy(david)\n                .setParticipants(Arrays.asList(alice, bob, charlie))\n                .setSplitStrategy(new PercentageSplitStrategy())\n                .setSplitValues(Arrays.asList(40.0, 30.0, 30.0)) // 40%, 30%, 30%\n        );\n\n        System.out.println(\"--- Balances After All Expenses ---\");\n        service.showBalanceSheet(alice.getId());\n        service.showBalanceSheet(bob.getId());\n\n        service.showBalanceSheet(charlie.getId());\n        service.showBalanceSheet(david.getId());\n\n        System.out.println();\n\n        // 6. Use Case 4: Simplify Group Debts\n        System.out.println(\"--- Use Case 4: Simplify Group Debts for 'Friends Trip' ---\");\n        List<Transaction> simplifiedDebts = service.simplifyGroupDebts(friendsGroup.getId());\n        if (simplifiedDebts.isEmpty()) {\n            System.out.println(\"All debts are settled within the group!\");\n        } else {\n            simplifiedDebts.forEach(System.out::println);\n        }\n        System.out.println();\n\n        service.showBalanceSheet(bob.getId());\n\n        // 7. Use Case 5: Partial Settlement\n        System.out.println(\"--- Use Case 5: Partial Settlement ---\");\n        // From the simplified debts, we see Bob should pay Alice. Let's say Bob pays 100.\n        service.settleUp(bob.getId(), alice.getId(), 100);\n\n        System.out.println(\"--- Balances After Partial Settlement ---\");\n        service.showBalanceSheet(alice.getId());\n        service.showBalanceSheet(bob.getId());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/SplitwiseService.java",
    "content": "package splitwise;\n\nimport splitwise.entities.*;\n\nimport java.util.*;\nimport java.util.stream.Collectors;\n\npublic class SplitwiseService {\n    private static SplitwiseService instance;\n    private final Map<String, User> users = new HashMap<>();\n    private final Map<String, Group> groups = new HashMap<>();\n\n    private SplitwiseService() {}\n\n    public static synchronized SplitwiseService getInstance() {\n        if (instance == null) {\n            instance = new SplitwiseService();\n        }\n        return instance;\n    }\n\n    // --- Setup Methods ---\n    public User addUser(String name, String email) {\n        User user = new User(name, email);\n        users.put(user.getId(), user);\n        return user;\n    }\n\n    public Group addGroup(String name, List<User> members) {\n        Group group = new Group(name, members);\n        groups.put(group.getId(), group);\n        return group;\n    }\n\n    public User getUser(String id) { return users.get(id); }\n    public Group getGroup(String id) { return groups.get(id); }\n\n    // --- Core Functional Methods (Facade) ---\n    public synchronized void createExpense(Expense.ExpenseBuilder builder) {\n        Expense expense = builder.build();\n        User paidBy = expense.getPaidBy();\n\n        for (Split split : expense.getSplits()) {\n            User participant = split.getUser();\n            double amount = split.getAmount();\n\n            if (!paidBy.equals(participant)) {\n                paidBy.getBalanceSheet().adjustBalance(participant, amount);\n                participant.getBalanceSheet().adjustBalance(paidBy, -amount);\n            }\n        }\n        System.out.println(\"Expense '\" + expense.getDescription() + \"' of amount \" + expense.getAmount() + \" created.\");\n    }\n\n    public synchronized void settleUp(String payerId, String payeeId, double amount) {\n        User payer = users.get(payerId);\n        User payee = users.get(payeeId);\n        System.out.println(payer.getName() + \" is settling up \" + amount + \" with \" + payee.getName());\n        // Settlement is like a reverse expense. payer owes less to payee.\n\n        payee.getBalanceSheet().adjustBalance(payer, -amount);\n        payer.getBalanceSheet().adjustBalance(payee, amount);\n    }\n\n    public void showBalanceSheet(String userId) {\n        User user = users.get(userId);\n        user.getBalanceSheet().showBalances();\n    }\n\n    public List<Transaction> simplifyGroupDebts(String groupId) {\n        Group group = groups.get(groupId);\n        if (group == null) throw new IllegalArgumentException(\"Group not found\");\n\n        // Calculate net balance for each member within the group context\n        Map<User, Double> netBalances = new HashMap<>();\n        for (User member : group.getMembers()) {\n            double balance = 0;\n            for(Map.Entry<User, Double> entry : member.getBalanceSheet().getBalances().entrySet()) {\n                // Consider only balances with other group members\n                if (group.getMembers().contains(entry.getKey())) {\n                    balance += entry.getValue();\n                }\n            }\n            netBalances.put(member, balance);\n        }\n\n        // Separate into creditors and debtors\n        List<Map.Entry<User, Double>> creditors = netBalances.entrySet().stream()\n                .filter(e -> e.getValue() > 0).collect(Collectors.toList());\n        List<Map.Entry<User, Double>> debtors = netBalances.entrySet().stream()\n                .filter(e -> e.getValue() < 0).collect(Collectors.toList());\n\n        creditors.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));\n        debtors.sort(Map.Entry.comparingByValue());\n\n        List<Transaction> transactions = new ArrayList<>();\n        int i = 0, j = 0;\n        while (i < creditors.size() && j < debtors.size()) {\n            Map.Entry<User, Double> creditor = creditors.get(i);\n            Map.Entry<User, Double> debtor = debtors.get(j);\n\n            double amountToSettle = Math.min(creditor.getValue(), -debtor.getValue());\n            transactions.add(new Transaction(debtor.getKey(), creditor.getKey(), amountToSettle));\n\n            creditor.setValue(creditor.getValue() - amountToSettle);\n            debtor.setValue(debtor.getValue() + amountToSettle);\n\n            if (Math.abs(creditor.getValue()) < 0.01) i++;\n            if (Math.abs(debtor.getValue()) < 0.01) j++;\n        }\n        return transactions;\n    }\n}"
  },
  {
    "path": "solutions/java/src/splitwise/entities/BalanceSheet.java",
    "content": "package splitwise.entities;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class BalanceSheet {\n    private final User owner;\n    // A map where:\n    // Key: The user to whom the balance is related.\n    // Value: The net amount.\n    // - Positive value: The key-user owes the owner of this balance sheet money.\n    // - Negative value: The owner owes the key-user money.\n    private final Map<User, Double> balances = new ConcurrentHashMap<>();\n\n    public BalanceSheet(User owner) {\n        this.owner = owner;\n    }\n\n    public Map<User, Double> getBalances() {\n        return balances;\n    }\n\n    public synchronized void adjustBalance(User otherUser, double amount) {\n        if (owner.equals(otherUser)) {\n            return; // Cannot owe yourself\n        }\n        balances.merge(otherUser, amount, Double::sum);\n    }\n\n    public void showBalances() {\n        System.out.println(\"--- Balance Sheet for \" + owner.getName() + \" ---\");\n        if (balances.isEmpty()) {\n            System.out.println(\"All settled up!\");\n            return;\n        }\n\n        double totalOwedToMe = 0;\n        double totalIOwe = 0;\n\n        for (Map.Entry<User, Double> entry : balances.entrySet()) {\n            User otherUser = entry.getKey();\n            double amount = entry.getValue();\n\n            if (amount > 0.01) {\n                System.out.println(otherUser.getName() + \" owes \" + owner.getName() + \" $\" + String.format(\"%.2f\", amount));\n                totalOwedToMe += amount;\n            } else if (amount < -0.01) {\n                System.out.println(owner.getName() + \" owes \" + otherUser.getName() + \" $\" + String.format(\"%.2f\", -amount));\n                totalIOwe += (-amount);\n            }\n        }\n        System.out.println(\"Total Owed to \" + owner.getName() + \": $\" + String.format(\"%.2f\", totalOwedToMe));\n        System.out.println(\"Total \" + owner.getName() + \" Owes: $\" + String.format(\"%.2f\", totalIOwe));\n        System.out.println(\"---------------------------------\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/splitwise/entities/Expense.java",
    "content": "package splitwise.entities;\n\nimport splitwise.strategy.SplitStrategy;\n\nimport java.time.LocalDateTime;\nimport java.util.List;\n\npublic class Expense {\n    private final String id;\n    private final String description;\n    private final double amount;\n    private final User paidBy;\n    private final List<Split> splits;\n    private final LocalDateTime timestamp;\n\n    private Expense(ExpenseBuilder builder) {\n        this.id = builder.id;\n        this.description = builder.description;\n        this.amount = builder.amount;\n        this.paidBy = builder.paidBy;\n        this.timestamp = LocalDateTime.now();\n\n        // Use the strategy to calculate splits\n        this.splits = builder.splitStrategy.calculateSplits(builder.amount, builder.paidBy, builder.participants, builder.splitValues);\n    }\n\n    // Getters...\n    public String getId() { return id; }\n    public String getDescription() { return description; }\n    public double getAmount() { return amount; }\n    public User getPaidBy() { return paidBy; }\n    public List<Split> getSplits() { return splits; }\n\n    // --- Builder Pattern ---\n    public static class ExpenseBuilder {\n        private String id;\n        private String description;\n        private double amount;\n        private User paidBy;\n        private List<User> participants;\n        private SplitStrategy splitStrategy;\n        private List<Double> splitValues; // For EXACT and PERCENTAGE splits\n\n        public ExpenseBuilder setId(String id) { this.id = id; return this; }\n        public ExpenseBuilder setDescription(String description) { this.description = description; return this; }\n        public ExpenseBuilder setAmount(double amount) { this.amount = amount; return this; }\n        public ExpenseBuilder setPaidBy(User paidBy) { this.paidBy = paidBy; return this; }\n        public ExpenseBuilder setParticipants(List<User> participants) { this.participants = participants; return this; }\n        public ExpenseBuilder setSplitStrategy(SplitStrategy splitStrategy) { this.splitStrategy = splitStrategy; return this; }\n        public ExpenseBuilder setSplitValues(List<Double> splitValues) { this.splitValues = splitValues; return this; }\n\n        public Expense build() {\n            // Validations\n            if (splitStrategy == null) {\n                throw new IllegalStateException(\"Split strategy is required.\");\n            }\n            return new Expense(this);\n        }\n    }\n}\n\n"
  },
  {
    "path": "solutions/java/src/splitwise/entities/Group.java",
    "content": "package splitwise.entities;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\npublic class Group {\n    private final String id;\n    private final String name;\n    private final List<User> members;\n\n    public Group(String name, List<User> members) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.members = members;\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public List<User> getMembers() {\n        return new ArrayList<>(members);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/entities/Split.java",
    "content": "package splitwise.entities;\n\npublic class Split {\n    private final User user;\n    private final double amount;\n\n    public Split(User user, double amount) {\n        this.user = user;\n        this.amount = amount;\n    }\n\n    public User getUser() { return user; }\n    public double getAmount() { return amount; }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/entities/Transaction.java",
    "content": "package splitwise.entities;\n\npublic class Transaction {\n    private final User from;\n    private final User to;\n    private final double amount;\n\n    public Transaction(User from, User to, double amount) {\n        this.from = from;\n        this.to = to;\n        this.amount = amount;\n    }\n\n    @Override\n    public String toString() {\n        return from.getName() + \" should pay \" + to.getName() + \" $\" + String.format(\"%.2f\", amount);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/entities/User.java",
    "content": "package splitwise.entities;\n\nimport java.util.UUID;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final String email;\n    private final BalanceSheet balanceSheet;\n\n    public User(String name, String email) {\n        this.id = UUID.randomUUID().toString();;\n        this.name = name;\n        this.email = email;\n        this.balanceSheet = new BalanceSheet(this);\n    }\n\n    public String getId() {\n        return id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public BalanceSheet getBalanceSheet() {\n        return balanceSheet;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/strategy/EqualSplitStrategy.java",
    "content": "package splitwise.strategy;\n\nimport splitwise.entities.Split;\nimport splitwise.entities.User;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class EqualSplitStrategy implements SplitStrategy {\n    @Override\n    public List<Split> calculateSplits(double totalAmount, User paidBy, List<User> participants, List<Double> splitValues) {\n        List<Split> splits = new ArrayList<>();\n        double amountPerPerson = totalAmount / participants.size();\n        for (User participant : participants) {\n            splits.add(new Split(participant, amountPerPerson));\n        }\n        return splits;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/strategy/ExactSplitStrategy.java",
    "content": "package splitwise.strategy;\n\nimport splitwise.entities.Split;\nimport splitwise.entities.User;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class ExactSplitStrategy implements SplitStrategy {\n    @Override\n    public List<Split> calculateSplits(double totalAmount, User paidBy, List<User> participants, List<Double> splitValues) {\n        if (participants.size() != splitValues.size()) {\n            throw new IllegalArgumentException(\"Number of participants and split values must match.\");\n        }\n        if (Math.abs(splitValues.stream().mapToDouble(Double::doubleValue).sum() - totalAmount) > 0.01) {\n            throw new IllegalArgumentException(\"Sum of exact amounts must equal the total expense amount.\");\n        }\n\n        List<Split> splits = new ArrayList<>();\n        for (int i = 0; i < participants.size(); i++) {\n            splits.add(new Split(participants.get(i), splitValues.get(i)));\n        }\n        return splits;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/strategy/PercentageSplitStrategy.java",
    "content": "package splitwise.strategy;\n\nimport splitwise.entities.Split;\nimport splitwise.entities.User;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PercentageSplitStrategy implements SplitStrategy {\n    @Override\n    public List<Split> calculateSplits(double totalAmount, User paidBy, List<User> participants, List<Double> splitValues) {\n        if (participants.size() != splitValues.size()) {\n            throw new IllegalArgumentException(\"Number of participants and split values must match.\");\n        }\n        if (Math.abs(splitValues.stream().mapToDouble(Double::doubleValue).sum() - 100.0) > 0.01) {\n            throw new IllegalArgumentException(\"Sum of percentages must be 100.\");\n        }\n\n        List<Split> splits = new ArrayList<>();\n        for (int i = 0; i < participants.size(); i++) {\n            double amount = (totalAmount * splitValues.get(i)) / 100.0;\n            splits.add(new Split(participants.get(i), amount));\n        }\n        return splits;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/splitwise/strategy/SplitStrategy.java",
    "content": "package splitwise.strategy;\n\nimport splitwise.entities.Split;\nimport splitwise.entities.User;\n\nimport java.util.List;\n\npublic interface SplitStrategy {\n    List<Split> calculateSplits(double totalAmount, User paidBy, List<User> participants, List<Double> splitValues);\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/README.md",
    "content": "# StackOverflow System (LLD)\n\n## Problem Statement\n\nDesign and implement a simplified StackOverflow-like Q&A platform. The system should allow users to post questions and answers, vote on them, comment, tag questions, and track user reputation.\n\n---\n\n## Requirements\n\n- **User Management:** Users can ask questions, answer, comment, and vote.\n- **Questions & Answers:** Users can post questions and answers. Each question can have multiple answers, and one accepted answer.\n- **Voting:** Users can upvote or downvote questions and answers. Reputation is updated accordingly.\n- **Comments:** Users can comment on both questions and answers.\n- **Tags:** Questions can be tagged for categorization.\n- **Reputation:** Users gain or lose reputation based on votes and accepted answers.\n- **Accepted Answer:** The question author can mark one answer as accepted.\n\n---\n\n## Core Entities\n\n- **User:** Represents a user, tracks reputation and user details.\n- **Question:** Represents a question, holds answers, comments, tags, votes, and accepted answer.\n- **Answer:** Represents an answer to a question, holds comments, votes, and accepted status.\n- **Comment:** Represents a comment on a question or answer.\n- **Tag:** Represents a tag for categorizing questions.\n- **Vote:** Represents a vote (upvote/downvote) by a user on a question or answer.\n- **VoteType:** Enum for UPVOTE and DOWNVOTE.\n- **Votable (interface):** For entities that can be voted on.\n- **Commentable (interface):** For entities that can be commented on.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/stackoverflow-class-diagram.png)\n\n### 1. User\n- **Fields:** id, name, reputation, etc.\n- **Methods:** updateReputation(int delta), getReputation(), etc.\n\n### 2. Question\n- **Fields:** id, title, content, author, creationDate, answers, comments, tags, votes, acceptedAnswer\n- **Methods:** addAnswer(Answer), acceptAnswer(Answer), vote(User, VoteType), getVoteCount(), addComment(Comment), getComments(), etc.\n\n### 3. Answer\n- **Fields:** id, content, author, question, isAccepted, creationDate, comments, votes\n- **Methods:** vote(User, VoteType), getVoteCount(), addComment(Comment), getComments(), markAsAccepted(), etc.\n\n### 4. Comment\n- **Fields:** id, content, author, creationDate\n\n### 5. Tag\n- **Fields:** name\n\n### 6. Vote\n- **Fields:** voter, type (VoteType)\n- **Methods:** getVoter(), getType()\n\n### 7. VoteType\n- Enum: UPVOTE, DOWNVOTE\n\n### 8. Votable (interface)\n- **Methods:** vote(User, VoteType), getVoteCount()\n\n### 9. Commentable (interface)\n- **Methods:** addComment(Comment), getComments()\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** For voting and commenting behaviors via interfaces.\n- **Observer Pattern:** (Conceptually) for reputation updates on votes and accepted answers.\n\n---\n\n## Example Usage\n\n```java\nUser alice = new User(\"Alice\");\nQuestion q = new Question(alice, \"What is Java?\", \"Explain Java basics.\", Arrays.asList(\"java\", \"basics\"));\nUser bob = new User(\"Bob\");\nAnswer a = new Answer(bob, q, \"Java is a programming language.\");\nq.addAnswer(a);\nq.vote(bob, VoteType.UPVOTE);\na.vote(alice, VoteType.UPVOTE);\nq.acceptAnswer(a);\n```\n\n---\n\n## Demo\n\nSee `StackOverflowDemo.java` for a sample usage of the StackOverflow system.\n\n---\n\n## Extending the Framework\n\n- **Add new features:** Such as badges, user profiles, or advanced search.\n- **Add new vote types:** Extend `VoteType` and update logic in `vote()` methods.\n- **Add moderation:** Implement admin/moderator roles for content management.\n\n---"
  },
  {
    "path": "solutions/java/src/stackoverflow/StackOverflowDemo.java",
    "content": "package stackoverflow;\n\nimport stackoverflow.enums.VoteType;\nimport stackoverflow.entities.Answer;\nimport stackoverflow.entities.Question;\nimport stackoverflow.entities.Tag;\nimport stackoverflow.entities.User;\nimport stackoverflow.strategy.SearchStrategy;\nimport stackoverflow.strategy.TagSearchStrategy;\nimport stackoverflow.strategy.UserSearchStrategy;\n\nimport java.util.List;\nimport java.util.Set;\n\npublic class StackOverflowDemo {\n    public static void main(String[] args) {\n        StackOverflowService service = new StackOverflowService();\n\n        // 1. Create Users\n        User alice = service.createUser(\"Alice\");\n        User bob = service.createUser(\"Bob\");\n        User charlie = service.createUser(\"Charlie\");\n\n        // 2. Alice posts a question\n        System.out.println(\"--- Alice posts a question ---\");\n        Tag javaTag = new Tag(\"java\");\n        Tag designPatternsTag = new Tag(\"design-patterns\");\n        Set<Tag> tags = Set.of(javaTag, designPatternsTag);\n        Question question = service.postQuestion(alice.getId(), \"How to implement Observer Pattern?\", \"Details about Observer Pattern...\", tags);\n        printReputations(alice, bob, charlie);\n\n        // 3. Bob and Charlie post answers\n        System.out.println(\"\\n--- Bob and Charlie post answers ---\");\n        Answer bobAnswer = service.postAnswer(bob.getId(), question.getId(), \"You can use the java.util.Observer interface.\");\n        Answer charlieAnswer = service.postAnswer(charlie.getId(), question.getId(), \"A better way is to create your own Observer interface.\");\n        printReputations(alice, bob, charlie);\n\n        // 4. Voting happens\n        System.out.println(\"\\n--- Voting Occurs ---\");\n        service.voteOnPost(alice.getId(), question.getId(), VoteType.UPVOTE); // Alice upvotes her own question\n        service.voteOnPost(bob.getId(), charlieAnswer.getId(), VoteType.UPVOTE); // Bob upvotes Charlie's answer\n        service.voteOnPost(alice.getId(), bobAnswer.getId(), VoteType.DOWNVOTE); // Alice downvotes Bob's answer\n        printReputations(alice, bob, charlie);\n\n        // 5. Alice accepts Charlie's answer\n        System.out.println(\"\\n--- Alice accepts Charlie's answer ---\");\n        service.acceptAnswer(question.getId(), charlieAnswer.getId());\n        printReputations(alice, bob, charlie);\n\n        // 6. Search for questions\n        System.out.println(\"\\n--- (C) Combined Search: Questions by 'Alice' with tag 'java' ---\");\n        List<SearchStrategy> filtersC = List.of(\n                new UserSearchStrategy(alice),\n                new TagSearchStrategy(javaTag)\n        );\n        List<Question> searchResults = service.searchQuestions(filtersC);\n        searchResults.forEach(q -> System.out.println(\"  - Found: \" + q.getTitle()));\n    }\n\n    private static void printReputations(User... users) {\n        System.out.println(\"--- Current Reputations ---\");\n        for(User user : users) {\n            System.out.printf(\"%s: %d\\n\", user.getName(), user.getReputation());\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/StackOverflowService.java",
    "content": "package stackoverflow;\n\nimport stackoverflow.enums.VoteType;\nimport stackoverflow.entities.*;\nimport stackoverflow.observer.PostObserver;\nimport stackoverflow.observer.ReputationManager;\nimport stackoverflow.strategy.SearchStrategy;\n\nimport java.util.*;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class StackOverflowService {\n    private final Map<String, User> users = new ConcurrentHashMap<>();\n    private final Map<String, Question> questions = new ConcurrentHashMap<>();\n    private final Map<String, Answer> answers = new ConcurrentHashMap<>();\n    private final PostObserver reputationManager = new ReputationManager();\n\n    public User createUser(String name) {\n        User user = new User(name);\n        users.put(user.getId(), user);\n        return user;\n    }\n\n    public Question postQuestion(String userId, String title, String body, Set<Tag> tags) {\n        User author = users.get(userId);\n        Question question = new Question(title, body, author, tags);\n        question.addObserver(reputationManager);\n        questions.put(question.getId(), question);\n        return question;\n    }\n\n    public Answer postAnswer(String userId, String questionId, String body) {\n        User author = users.get(userId);\n        Question question = questions.get(questionId);\n        Answer answer = new Answer(body, author);\n        answer.addObserver(reputationManager);\n        question.addAnswer(answer);\n        answers.put(answer.getId(), answer);\n        return answer;\n    }\n\n    public void voteOnPost(String userId, String postId, VoteType voteType) {\n        User user = users.get(userId);\n        Post post = findPostById(postId);\n        post.vote(user, voteType);\n    }\n\n    public void acceptAnswer(String questionId, String answerId) {\n        Question question = questions.get(questionId);\n        Answer answer = answers.get(answerId);\n        question.acceptAnswer(answer);\n    }\n\n    public List<Question> searchQuestions(List<SearchStrategy> strategies) {\n        List<Question> results = new ArrayList<>(questions.values());\n\n        // Sequentially apply each filter strategy to the results of the previous one.\n        for (SearchStrategy strategy : strategies) {\n            results = strategy.filter(results);\n        }\n\n        return results;\n    }\n\n    public User getUser(String userId) {\n        return users.get(userId);\n    }\n\n    private Post findPostById(String postId) {\n        if (questions.containsKey(postId)) {\n            return questions.get(postId);\n        } else if (answers.containsKey(postId)) {\n            return answers.get(postId);\n        }\n\n        throw new NoSuchElementException(\"Post not found\");\n    }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Answer.java",
    "content": "package stackoverflow.entities;\n\nimport java.util.UUID;\n\npublic class Answer extends Post {\n    private boolean isAccepted = false;\n\n    public Answer(String body, User author) {\n        super(UUID.randomUUID().toString(), body, author);\n    }\n\n    public void setAccepted(boolean accepted) {\n        isAccepted = accepted;\n    }\n\n    public boolean isAccepted() { return isAccepted; }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Comment.java",
    "content": "package stackoverflow.entities;\n\nimport java.util.UUID;\n\npublic class Comment extends Content {\n    public Comment(String body, User author) {\n        super(UUID.randomUUID().toString(), body, author);\n    }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Content.java",
    "content": "package stackoverflow.entities;\n\nimport java.time.LocalDateTime;\n\npublic abstract class Content {\n    protected final String id;\n    protected final String body;\n    protected final User author;\n    protected final LocalDateTime creationTime;\n\n    public Content(String id, String body, User author) {\n        this.id = id;\n        this.body = body;\n        this.author = author;\n        this.creationTime = LocalDateTime.now();\n    }\n    public String getId() { return id; }\n    public String getBody() { return body; }\n    public User getAuthor() { return author; }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Event.java",
    "content": "package stackoverflow.entities;\n\nimport stackoverflow.enums.EventType;\n\npublic class Event {\n    private final EventType type;\n    private final User actor;        // user who performed the action\n    private final Post targetPost;   // post being acted on\n\n    public Event(EventType type, User actor, Post targetPost) {\n        this.type = type;\n        this.actor = actor;\n        this.targetPost = targetPost;\n    }\n\n    public EventType getType() { return type; }\n    public User getActor() { return actor; }\n    public Post getTargetPost() { return targetPost; }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Post.java",
    "content": "package stackoverflow.entities;\n\nimport stackoverflow.enums.EventType;\nimport stackoverflow.enums.VoteType;\nimport stackoverflow.observer.PostObserver;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.concurrent.CopyOnWriteArrayList;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic abstract class Post extends Content {\n    private final AtomicInteger voteCount = new AtomicInteger(0);\n    private final Map<String, VoteType> voters = new ConcurrentHashMap<>();\n    private final List<Comment> comments = new CopyOnWriteArrayList<>();\n    private final List<PostObserver> observers = new CopyOnWriteArrayList<>();\n\n    public Post(String id, String body, User author) {\n        super(id, body, author);\n    }\n\n    public void addObserver(PostObserver observer) {\n        this.observers.add(observer);\n    }\n\n    protected void notifyObservers(Event event) {\n        observers.forEach(o -> o.onPostEvent(event));\n    }\n\n    public synchronized void vote(User user, VoteType voteType) {\n        String userId = user.getId();\n        if (voters.get(userId) == voteType)\n            return; // Already voted\n\n        int scoreChange = 0;\n        if (voters.containsKey(userId)) { // User is changing their vote\n            scoreChange = (voteType == VoteType.UPVOTE) ? 2 : -2;\n        } else { // New vote\n            scoreChange = (voteType == VoteType.UPVOTE) ? 1 : -1;\n        }\n\n        voters.put(userId, voteType);\n        voteCount.addAndGet(scoreChange);\n\n        EventType eventType = EventType.UPVOTE_QUESTION;\n\n        if (this instanceof Question) {\n            eventType = (voteType == VoteType.UPVOTE ? EventType.UPVOTE_QUESTION : EventType.DOWNVOTE_QUESTION);\n        } else {\n            eventType = (voteType == VoteType.UPVOTE ? EventType.UPVOTE_ANSWER : EventType.DOWNVOTE_ANSWER);\n        }\n\n        notifyObservers(new Event(eventType, user, this));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Question.java",
    "content": "package stackoverflow.entities;\n\nimport stackoverflow.enums.EventType;\n\nimport java.util.*;\n\npublic class Question extends Post {\n    private final String title;\n    private final Set<Tag> tags;\n    private final List<Answer> answers = new ArrayList<>();\n    private Answer acceptedAnswer;\n\n    public Question(String title, String body, User author, Set<Tag> tags) {\n        super(UUID.randomUUID().toString(), body, author);\n        this.title = title;\n        this.tags = tags;\n    }\n\n    public void addAnswer(Answer answer) { this.answers.add(answer); }\n\n    public synchronized void acceptAnswer(Answer answer) {\n        if (!this.author.getId().equals(answer.getAuthor().getId()) && this.acceptedAnswer == null) {\n            this.acceptedAnswer = answer;\n            answer.setAccepted(true);\n            notifyObservers(new Event(EventType.ACCEPT_ANSWER, answer.getAuthor(), answer));\n        }\n    }\n\n    public String getTitle() { return title; }\n    public Set<Tag> getTags() { return tags; }\n    public List<Answer> getAnswers() { return answers; }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/Tag.java",
    "content": "package stackoverflow.entities;\n\npublic class Tag {\n    private final String name;\n\n    public Tag(String name) { this.name = name; }\n\n    public String getName() { return name; }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/entities/User.java",
    "content": "package stackoverflow.entities;\n\nimport java.util.UUID;\nimport java.util.concurrent.atomic.AtomicInteger;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final AtomicInteger reputation;\n\n    public User(String name) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.reputation = new AtomicInteger(0);\n    }\n\n    public void updateReputation(int change) {\n        this.reputation.addAndGet(change);\n    }\n\n    public String getId() { return id; }\n    public String getName() { return name; }\n    public int getReputation() { return reputation.get(); }\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/enums/EventType.java",
    "content": "package stackoverflow.enums;\n\npublic enum EventType {\n    UPVOTE_QUESTION,\n    DOWNVOTE_QUESTION,\n    UPVOTE_ANSWER,\n    DOWNVOTE_ANSWER,\n    ACCEPT_ANSWER\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/enums/VoteType.java",
    "content": "package stackoverflow.enums;\n\npublic enum VoteType {\n    UPVOTE, DOWNVOTE\n}"
  },
  {
    "path": "solutions/java/src/stackoverflow/observer/PostObserver.java",
    "content": "package stackoverflow.observer;\n\nimport stackoverflow.entities.Event;\n\npublic interface PostObserver {\n    void onPostEvent(Event event);\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/observer/ReputationManager.java",
    "content": "package stackoverflow.observer;\n\nimport stackoverflow.entities.Event;\nimport stackoverflow.entities.User;\n\npublic class ReputationManager implements PostObserver {\n    private static final int QUESTION_UPVOTE_REP = 5;\n    private static final int ANSWER_UPVOTE_REP = 10;\n    private static final int ACCEPTED_ANSWER_REP = 15;\n    private static final int DOWNVOTE_REP_PENALTY = -1; // Penalty for the voter\n    private static final int POST_DOWNVOTED_REP_PENALTY = -2; // Penalty for the post author\n\n    @Override\n    public void onPostEvent(Event event) {\n        User postAuthor = event.getTargetPost().getAuthor();\n        switch (event.getType()) {\n            case UPVOTE_QUESTION:\n                postAuthor.updateReputation(QUESTION_UPVOTE_REP);\n                break;\n            case DOWNVOTE_QUESTION:\n                postAuthor.updateReputation(DOWNVOTE_REP_PENALTY);\n                event.getActor().updateReputation(POST_DOWNVOTED_REP_PENALTY); // voter penalty\n                break;\n            case UPVOTE_ANSWER:\n                postAuthor.updateReputation(ANSWER_UPVOTE_REP);\n                break;\n            case DOWNVOTE_ANSWER:\n                postAuthor.updateReputation(DOWNVOTE_REP_PENALTY);\n                event.getActor().updateReputation(POST_DOWNVOTED_REP_PENALTY);\n                break;\n            case ACCEPT_ANSWER:\n                postAuthor.updateReputation(ACCEPTED_ANSWER_REP);\n                break;\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/strategy/KeywordSearchStrategy.java",
    "content": "package stackoverflow.strategy;\n\nimport stackoverflow.entities.Question;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class KeywordSearchStrategy implements SearchStrategy {\n    private final String keyword;\n\n    public KeywordSearchStrategy(String keyword) {\n        this.keyword = keyword.toLowerCase();\n    }\n\n    @Override\n    public List<Question> filter(List<Question> questions) {\n        return questions.stream()\n                .filter(q -> q.getTitle().toLowerCase().contains(keyword) ||\n                        q.getBody().toLowerCase().contains(keyword))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/strategy/SearchStrategy.java",
    "content": "package stackoverflow.strategy;\n\nimport stackoverflow.entities.Question;\n\nimport java.util.List;\n\npublic interface SearchStrategy {\n    List<Question> filter(List<Question> questions);\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/strategy/TagSearchStrategy.java",
    "content": "package stackoverflow.strategy;\n\nimport stackoverflow.entities.Question;\nimport stackoverflow.entities.Tag;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class TagSearchStrategy implements SearchStrategy {\n    private final Tag tag;\n\n    public TagSearchStrategy(Tag tag) {\n        this.tag = tag;\n    }\n\n    @Override\n    public List<Question> filter(List<Question> questions) {\n        return questions.stream()\n                .filter(q -> q.getTags().stream()\n                        .anyMatch(t -> t.getName().equalsIgnoreCase(tag.getName())))\n                .collect(Collectors.toList());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/stackoverflow/strategy/UserSearchStrategy.java",
    "content": "package stackoverflow.strategy;\n\nimport stackoverflow.entities.Question;\nimport stackoverflow.entities.User;\n\nimport java.util.List;\nimport java.util.stream.Collectors;\n\npublic class UserSearchStrategy implements SearchStrategy {\n    private final User user;\n\n    public UserSearchStrategy(User user) {\n        this.user = user;\n    }\n\n    @Override\n    public List<Question> filter(List<Question> questions) {\n        return questions.stream()\n                .filter(q -> q.getAuthor().getId().equals(user.getId()))\n                .collect(Collectors.toList());\n    }\n}"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/README.md",
    "content": "# Task Management System (LLD)\n\n## Problem Statement\n\nDesign and implement a Task Management System that allows users to create, assign, update, and track tasks. The system should support task priorities, statuses, comments, and user assignment.\n\n---\n\n## Requirements\n\n- **Task Creation:** Users can create tasks with a title, description, priority, and assignee.\n- **Task Assignment:** Tasks can be assigned to users and reassigned as needed.\n- **Task Status:** Tasks can have statuses such as TODO, IN_PROGRESS, DONE, etc.\n- **Task Priority:** Tasks can have priorities such as LOW, MEDIUM, HIGH.\n- **Comments:** Users can add comments to tasks.\n- **Task Updates:** Tasks can be updated (status, priority, assignee, etc.).\n- **Task Listing:** List all tasks, or filter by status, priority, or assignee.\n- **Extensibility:** Easy to add new statuses, priorities, or features.\n\n---\n\n## Core Entities\n\n- **Task:** Represents a task with title, description, status, priority, assignee, and comments.\n- **User:** Represents a user who can create, assign, and be assigned tasks.\n- **Comment:** Represents a comment on a task.\n- **TaskStatus:** Enum for task statuses (TODO, IN_PROGRESS, DONE, etc.).\n- **TaskPriority:** Enum for task priorities (LOW, MEDIUM, HIGH).\n- **TaskManager:** Manages the collection of tasks and provides methods for task operations.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/taskmanagementsystem-class-diagram.png)\n\n### 1. Task\n- **Fields:** id, title, description, status, priority, assignee (User), List<Comment>\n- **Methods:** updateStatus(TaskStatus), updatePriority(TaskPriority), assignUser(User), addComment(Comment), etc.\n\n### 2. User\n- **Fields:** id, name\n- **Methods:** getId(), getName()\n\n### 3. Comment\n- **Fields:** id, content, author (User), timestamp\n\n### 4. TaskStatus (enum)\n- Values: TODO, IN_PROGRESS, DONE, etc.\n\n### 5. TaskPriority (enum)\n- Values: LOW, MEDIUM, HIGH\n\n### 6. TaskManager\n- **Fields:** List<Task>\n- **Methods:** createTask(...), assignTask(...), updateTaskStatus(...), updateTaskPriority(...), addCommentToTask(...), listTasks(), listTasksByStatus(...), listTasksByAssignee(...), etc.\n\n---\n\n## Design Patterns Used\n\n- **Separation of Concerns:** Each class has a single responsibility (task, user, comment, management).\n- **Manager Pattern:** `TaskManager` acts as a service/manager for all task operations.\n\n---\n\n## Example Usage\n\n```java\nTaskManager manager = new TaskManager();\nUser alice = new User(\"Alice\");\nUser bob = new User(\"Bob\");\n\nTask task = manager.createTask(\"Implement login\", \"Add login functionality\", TaskPriority.HIGH, alice);\nmanager.assignTask(task.getId(), bob);\nmanager.updateTaskStatus(task.getId(), TaskStatus.IN_PROGRESS);\nmanager.addCommentToTask(task.getId(), new Comment(\"Started working on this\", bob));\n```\n\n---\n\n## Demo\n\nSee `TaskManagementSystemDemo.java` for a sample usage and simulation of the task management system.\n\n---\n\n## Extending the Framework\n\n- **Add new statuses or priorities:** Update the `TaskStatus` or `TaskPriority` enums.\n- **Add new features:** Such as deadlines, notifications, or task dependencies.\n\n---"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/TaskManagementSystem.java",
    "content": "package taskmanagementsystem;\n\nimport taskmanagementsystem.enums.TaskPriority;\nimport taskmanagementsystem.enums.TaskStatus;\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.models.TaskList;\nimport taskmanagementsystem.models.User;\nimport taskmanagementsystem.observer.ActivityLogger;\nimport taskmanagementsystem.strategy.TaskSortStrategy;\n\nimport java.time.LocalDate;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\nimport java.util.stream.Collectors;\n\npublic class TaskManagementSystem {\n    private static TaskManagementSystem instance;\n    private final Map<String, User> users;\n    private final Map<String, Task> tasks;\n    private final Map<String, TaskList> taskLists;\n\n    private TaskManagementSystem() {\n        users = new ConcurrentHashMap<>();\n        tasks = new ConcurrentHashMap<>();\n        taskLists = new ConcurrentHashMap<>();\n    }\n\n    public static synchronized TaskManagementSystem getInstance() {\n        if (instance == null) {\n            instance = new TaskManagementSystem();\n        }\n        return instance;\n    }\n\n    public User createUser(String name, String email) {\n        User user = new User(name, email);\n        users.put(user.getId(), user);\n        return user;\n    }\n\n    public TaskList createTaskList(String listName) {\n        TaskList taskList = new TaskList(listName);\n        taskLists.put(taskList.getId(), taskList);\n        return taskList;\n    }\n\n    public Task createTask(String title, String description, LocalDate dueDate,\n                           TaskPriority priority, String createdByUserId) {\n        User createdBy = users.get(createdByUserId);\n        if (createdBy == null)\n            throw new IllegalArgumentException(\"User not found.\");\n\n        Task task = new Task.TaskBuilder(title)\n                .description(description)\n                .dueDate(dueDate)\n                .priority(priority)\n                .createdBy(createdBy)\n                .build();\n\n        task.addObserver(new ActivityLogger());\n\n        tasks.put(task.getId(), task);\n        return task;\n    }\n\n    public List<Task> listTasksByUser(String userId) {\n        User user = users.get(userId);\n        return tasks.values().stream()\n                .filter(task -> user.equals(task.getAssignee()))\n                .toList();\n    }\n\n    public List<Task> listTasksByStatus(TaskStatus status) {\n        return tasks.values().stream()\n                .filter(task -> task.getStatus() == status)\n                .collect(Collectors.toList());\n    }\n\n    public void deleteTask(String taskId) {\n        tasks.remove(taskId);\n    }\n\n    public List<Task> searchTasks(String keyword, TaskSortStrategy sortingStrategy) {\n        List<Task> matchingTasks = new ArrayList<>();\n        for (Task task : tasks.values()) {\n            if (task.getTitle().contains(keyword) || task.getDescription().contains(keyword)) {\n                matchingTasks.add(task);\n            }\n        }\n        sortingStrategy.sort(matchingTasks);\n        return matchingTasks;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/TaskManagementSystemDemo.java",
    "content": "package taskmanagementsystem;\n\nimport taskmanagementsystem.enums.TaskPriority;\nimport taskmanagementsystem.enums.TaskStatus;\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.models.TaskList;\nimport taskmanagementsystem.models.User;\nimport taskmanagementsystem.strategy.SortByDueDate;\n\nimport java.time.LocalDate;\nimport java.util.List;\n\npublic class TaskManagementSystemDemo {\n    public static void main(String[] args) {\n        TaskManagementSystem taskManagementSystem = TaskManagementSystem.getInstance();\n\n        // Create users\n        User user1 = taskManagementSystem.createUser(\"John Doe\", \"john@example.com\");\n        User user2 = taskManagementSystem.createUser(\"Jane Smith\", \"jane@example.com\");\n\n        // Create task lists\n        TaskList taskList1 = taskManagementSystem.createTaskList(\"Enhancements\");\n        TaskList taskList2 = taskManagementSystem.createTaskList(\"Bug Fix\");\n\n        // Create tasks\n        Task task1 = taskManagementSystem.createTask(\"Enhancement Task\", \"Launch New Feature\",\n                LocalDate.now().plusDays(2), TaskPriority.LOW, user1.getId());\n        Task subtask1 = taskManagementSystem.createTask( \"Enhancement sub task\", \"Design UI/UX\",\n                LocalDate.now().plusDays(1), TaskPriority.MEDIUM, user1.getId());\n        Task task2 = taskManagementSystem.createTask(\"Bug Fix Task\", \"Fix API Bug\",\n                LocalDate.now().plusDays(3), TaskPriority.HIGH, user2.getId());\n\n        task1.addSubtask(subtask1);\n\n        taskList1.addTask(task1);\n        taskList2.addTask(task2);\n\n        taskList1.display();\n\n        // Update task status\n        subtask1.startProgress();\n\n        // Assign task\n        subtask1.setAssignee(user2);\n\n        taskList1.display();\n\n        // Search tasks\n        List<Task> searchResults = taskManagementSystem.searchTasks(\"Task\", new SortByDueDate());\n        System.out.println(\"\\nTasks with keyword Task:\");\n        for (Task task : searchResults) {\n            System.out.println(task.getTitle());\n        }\n\n        // Filter tasks by status\n        List<Task> filteredTasks = taskManagementSystem.listTasksByStatus(TaskStatus.TODO);\n        System.out.println(\"\\nTODO Tasks:\");\n        for (Task task : filteredTasks) {\n            System.out.println(task.getTitle());\n        }\n\n        // Mark a task as done\n        subtask1.completeTask();\n\n        // Get tasks assigned to a user\n        List<Task> userTaskList = taskManagementSystem.listTasksByUser(user2.getId());\n        System.out.println(\"\\nTask for \" + user2.getName() + \":\");\n        for (Task task : userTaskList) {\n            System.out.println(task.getTitle());\n        }\n\n        taskList1.display();\n\n        // Delete a task\n        taskManagementSystem.deleteTask(task2.getId());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/enums/TaskPriority.java",
    "content": "package taskmanagementsystem.enums;\n\npublic enum TaskPriority {\n    LOW,\n    MEDIUM,\n    HIGH,\n    CRITICAL\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/enums/TaskStatus.java",
    "content": "package taskmanagementsystem.enums;\n\npublic enum TaskStatus {\n    TODO,\n    IN_PROGRESS,\n    DONE\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/ActivityLog.java",
    "content": "package taskmanagementsystem.models;\n\nimport java.time.LocalDateTime;\n\npublic class ActivityLog {\n    private final String description;\n    private final LocalDateTime timestamp;\n\n    public ActivityLog(String description) {\n        this.description = description;\n        this.timestamp = LocalDateTime.now();\n    }\n\n    @Override\n    public String toString() {\n        return \"[\" + timestamp + \"] \" + description;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/Comment.java",
    "content": "package taskmanagementsystem.models;\n\nimport java.util.Date;\nimport java.util.UUID;\n\npublic class Comment {\n    private final String id;\n    private final String content;\n    private final User author;\n    private final Date timestamp;\n\n    public Comment(String content, User author) {\n        this.id = UUID.randomUUID().toString();\n        this.content = content;\n        this.author = author;\n        this.timestamp = new Date();\n    }\n\n    public User getAuthor() {\n        return author;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/Tag.java",
    "content": "package taskmanagementsystem.models;\n\npublic class Tag {\n    private final String name;\n\n    public Tag(String name) { this.name = name; }\n\n    public String getName() { return name; }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/Task.java",
    "content": "package taskmanagementsystem.models;\n\nimport taskmanagementsystem.enums.TaskPriority;\nimport taskmanagementsystem.enums.TaskStatus;\nimport taskmanagementsystem.observer.TaskObserver;\nimport taskmanagementsystem.state.TaskState;\nimport taskmanagementsystem.state.TodoState;\n\nimport java.time.LocalDate;\nimport java.util.*;\n\npublic class Task {\n    private final String id;\n    private String title;\n    private String description;\n    private LocalDate dueDate;\n    private TaskPriority priority;\n    private final User createdBy;\n    private User assignee;\n    private TaskState currentState;\n    private final Set<Tag> tags;\n    private final List<Comment> comments;\n    private final List<Task> subtasks;\n    private final List<ActivityLog> activityLogs;\n    private final List<TaskObserver> observers;\n\n    private Task(TaskBuilder builder) {\n        this.id = builder.id;\n        this.title = builder.title;\n        this.description = builder.description;\n        this.dueDate = builder.dueDate;\n        this.priority = builder.priority;\n        this.createdBy = builder.createdBy;\n        this.assignee = builder.assignee;\n        this.tags = builder.tags;\n        this.currentState = new TodoState(); // Initial state\n        this.comments = new ArrayList<>();\n        this.subtasks = new ArrayList<>();\n        this.activityLogs = new ArrayList<>();\n        this.observers = new ArrayList<>();\n        addLog(\"Task created with title: \" + title);\n    }\n\n    public synchronized void setAssignee(User user) {\n        this.assignee = user;\n        addLog(\"Assigned to \" + user.getName());\n        notifyObservers(\"assignee\");\n    }\n\n    public synchronized void updatePriority(TaskPriority priority) {\n        this.priority = priority;\n        notifyObservers(\"priority\");\n    }\n\n    public synchronized void addComment(Comment comment) {\n        comments.add(comment);\n        addLog(\"Comment added by \" + comment.getAuthor().getName());\n        notifyObservers(\"comment\");\n    }\n\n    public synchronized void addSubtask(Task subtask) {\n        subtasks.add(subtask);\n        addLog(\"Subtask added: \" + subtask.getTitle());\n        notifyObservers(\"subtask_added\");\n    }\n\n    // --- State Pattern Methods ---\n    public void setState(TaskState state) {\n        this.currentState = state;\n        addLog(\"Status changed to: \" + state.getStatus());\n        notifyObservers(\"status\");\n    }\n    public void startProgress() { currentState.startProgress(this); }\n    public void completeTask() { currentState.completeTask(this); }\n    public void reopenTask() { currentState.reopenTask(this); }\n\n    // --- Observer Pattern Methods ---\n    public void addObserver(TaskObserver observer) { observers.add(observer); }\n    public void removeObserver(TaskObserver observer) { observers.remove(observer); }\n    public void notifyObservers(String changeType) {\n        for (TaskObserver observer : observers) {\n            observer.update(this, changeType);\n        }\n    }\n    public void addLog(String logDescription) {\n        this.activityLogs.add(new ActivityLog(logDescription));\n    }\n\n    public boolean isComposite() { return !subtasks.isEmpty(); }\n\n    public void display(String indent) {\n        System.out.println(indent + \"- \" + title + \" [\" + getStatus() + \", \" + priority + \", Due: \" + dueDate + \"]\");\n        if (isComposite()) {\n            for (Task subtask : subtasks) {\n                subtask.display(indent + \"  \");\n            }\n        }\n    }\n\n    // Getters and setters\n    public String getId() {\n        return id;\n    }\n    public String getTitle() {\n        return title;\n    }\n    public String getDescription() {\n        return description;\n    }\n    public TaskPriority getPriority() {\n        return priority;\n    }\n    public LocalDate getDueDate() {\n        return dueDate;\n    }\n    public User getAssignee() {\n        return assignee;\n    }\n    public void setTitle(String title) {\n        this.title = title;\n    }\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public TaskStatus getStatus() {\n        return currentState.getStatus();\n    }\n\n    // --- Builder Pattern ---\n    public static class TaskBuilder {\n        private final String id;\n        private String title;\n        private String description = \"\";\n        private LocalDate dueDate;\n        private TaskPriority priority;\n        private User createdBy;\n        private User assignee;\n        private Set<Tag> tags;\n\n        public TaskBuilder(String title) {\n            this.id = UUID.randomUUID().toString();\n            this.title = title;\n        }\n\n        public TaskBuilder description(String description) { this.description = description; return this; }\n        public TaskBuilder dueDate(LocalDate dueDate) { this.dueDate = dueDate; return this; }\n        public TaskBuilder priority(TaskPriority priority) { this.priority = priority; return this; }\n        public TaskBuilder assignee(User assignee) { this.assignee = assignee; return this; }\n        public TaskBuilder createdBy(User createdBy) { this.createdBy = createdBy; return this; }\n        public TaskBuilder tags(Set<Tag> tags) { this.tags = tags; return this; }\n\n        public Task build() {\n            return new Task(this);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/TaskList.java",
    "content": "package taskmanagementsystem.models;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\npublic class TaskList {\n    private final String id;\n    private final String name;\n    private final List<Task> tasks;\n\n    public TaskList(String name) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.tasks = new CopyOnWriteArrayList<>();\n    }\n\n    public void addTask(Task task) {\n        this.tasks.add(task);\n    }\n\n    public List<Task> getTasks() {\n        return new ArrayList<>(tasks); // Return a copy to prevent external modification\n    }\n\n    // Getters...\n    public String getId() { return id; }\n    public String getName() { return name; }\n\n    public void display() {\n        System.out.println(\"--- Task List: \" + name + \" ---\");\n        for (Task task : tasks) {\n            task.display(\"\");\n        }\n        System.out.println(\"-----------------------------------\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/models/User.java",
    "content": "package taskmanagementsystem.models;\n\nimport java.util.UUID;\n\npublic class User {\n    private final String id;\n    private final String name;\n    private final String email;\n\n    public User(String name, String email) {\n        this.id = UUID.randomUUID().toString();\n        this.name = name;\n        this.email = email;\n    }\n\n    // Getters...\n    public String getId() {\n        return id;\n    }\n\n    public String getEmail() {\n        return email;\n    }\n\n    public String getName() {\n        return name;\n    }\n}"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/observer/ActivityLogger.java",
    "content": "package taskmanagementsystem.observer;\n\nimport taskmanagementsystem.models.Task;\n\npublic class ActivityLogger implements TaskObserver {\n    @Override\n    public void update(Task task, String changeType) {\n        System.out.println(\"LOGGER: Task '\" + task.getTitle() + \"' was updated. Change: \" + changeType);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/observer/TaskObserver.java",
    "content": "package taskmanagementsystem.observer;\n\nimport taskmanagementsystem.models.Task;\n\npublic interface TaskObserver {\n    void update(Task task, String changeType);\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/state/DoneState.java",
    "content": "package taskmanagementsystem.state;\n\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.enums.TaskStatus;\n\npublic class DoneState implements TaskState {\n    @Override\n    public void startProgress(Task task) {\n        System.out.println(\"Cannot start a completed task. Reopen it first.\");\n    }\n    @Override\n    public void completeTask(Task task) {\n        System.out.println(\"Task is already done.\");\n    }\n    @Override\n    public void reopenTask(Task task) {\n        task.setState(new TodoState());\n    }\n    @Override\n    public TaskStatus getStatus() { return TaskStatus.DONE; }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/state/InProgressState.java",
    "content": "package taskmanagementsystem.state;\n\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.enums.TaskStatus;\n\npublic class InProgressState implements TaskState {\n    @Override\n    public void startProgress(Task task) {\n        System.out.println(\"Task is already in progress.\");\n    }\n    @Override\n    public void completeTask(Task task) {\n        task.setState(new DoneState());\n    }\n    @Override\n    public void reopenTask(Task task) {\n        task.setState(new TodoState());\n    }\n    @Override\n    public TaskStatus getStatus() { return TaskStatus.IN_PROGRESS; }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/state/TaskState.java",
    "content": "package taskmanagementsystem.state;\n\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.enums.TaskStatus;\n\npublic interface TaskState {\n    void startProgress(Task task);\n    void completeTask(Task task);\n    void reopenTask(Task task);\n    TaskStatus getStatus();\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/state/TodoState.java",
    "content": "package taskmanagementsystem.state;\n\nimport taskmanagementsystem.models.Task;\nimport taskmanagementsystem.enums.TaskStatus;\n\npublic class TodoState implements TaskState {\n    @Override\n    public void startProgress(Task task) {\n        task.setState(new InProgressState());\n    }\n    @Override\n    public void completeTask(Task task) {\n        System.out.println(\"Cannot complete a task that is not in progress.\");\n    }\n    @Override\n    public void reopenTask(Task task) {\n        System.out.println(\"Task is already in TO-DO state.\");\n    }\n    @Override\n    public TaskStatus getStatus() { return TaskStatus.TODO; }\n}\n"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/strategy/SortByDueDate.java",
    "content": "package taskmanagementsystem.strategy;\n\nimport taskmanagementsystem.models.Task;\n\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class SortByDueDate implements TaskSortStrategy {\n    @Override\n    public void sort(List<Task> tasks) {\n        tasks.sort(Comparator.comparing(Task::getDueDate));\n    }\n}"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/strategy/SortByPriority.java",
    "content": "package taskmanagementsystem.strategy;\n\nimport taskmanagementsystem.models.Task;\n\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class SortByPriority implements TaskSortStrategy {\n    @Override\n    public void sort(List<Task> tasks) {\n        // Higher priority (lower enum ordinal) comes first\n        tasks.sort(Comparator.comparing(Task::getPriority).reversed());\n    }\n}"
  },
  {
    "path": "solutions/java/src/taskmanagementsystem/strategy/TaskSortStrategy.java",
    "content": "package taskmanagementsystem.strategy;\n\nimport taskmanagementsystem.models.Task;\n\nimport java.util.List;\n\npublic interface TaskSortStrategy {\n    void sort(List<Task> tasks);\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/Game.java",
    "content": "package tictactoe;\n\nimport tictactoe.enums.GameStatus;\nimport tictactoe.models.Board;\nimport tictactoe.models.Player;\nimport tictactoe.observer.GameSubject;\nimport tictactoe.state.GameState;\nimport tictactoe.state.InProgressState;\nimport tictactoe.strategy.ColumnWinningStrategy;\nimport tictactoe.strategy.DiagonalWinningStrategy;\nimport tictactoe.strategy.RowWinningStrategy;\nimport tictactoe.strategy.WinningStrategy;\n\nimport java.util.List;\n\npublic class Game extends GameSubject {\n    private final Board board;\n    private final Player player1;\n    private final Player player2;\n    private Player currentPlayer;\n    private Player winner;\n    private GameStatus status;\n    private GameState state;\n    private final List<WinningStrategy> winningStrategies;\n\n    public Game(Player player1, Player player2) {\n        this.board = new Board(3);\n        this.player1 = player1;\n        this.player2 = player2;\n        this.currentPlayer = player1; // Player 1 starts\n        this.status = GameStatus.IN_PROGRESS;\n        this.state = new InProgressState();\n        this.winningStrategies = List.of(\n                new RowWinningStrategy(),\n                new ColumnWinningStrategy(),\n                new DiagonalWinningStrategy()\n        );\n    }\n\n    public void makeMove(Player player, int row, int col) {\n        state.handleMove(this, player, row, col);\n    }\n\n    public boolean checkWinner(Player player) {\n        for (WinningStrategy strategy : winningStrategies) {\n            if (strategy.checkWinner(board, player)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public void switchPlayer() {\n        this.currentPlayer = (currentPlayer == player1) ? player2 : player1;\n    }\n\n    public Board getBoard() { return board; }\n    public Player getCurrentPlayer() { return currentPlayer; }\n    public Player getWinner() { return winner; }\n    public void setWinner(Player winner) { this.winner = winner; }\n    public GameStatus getStatus() { return status; }\n    public void setState(GameState state) { this.state = state; }\n    public void setStatus(GameStatus status) {\n        this.status = status;\n        // Notify observers when the status changes to a finished state\n        if (status != GameStatus.IN_PROGRESS) {\n            notifyObservers();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/README.md",
    "content": "# Tic Tac Toe (LLD)\n\n## Problem Statement\n\nDesign and implement a Tic Tac Toe game that allows two players to play on a NxN board, alternating turns, and determines the winner or a draw.\n\n---\n\n## Requirements\n\n- **Two Players:** The game is played between two players.\n- **Board:** The game uses a NxN board.\n- **Turns:** Players take turns to place their symbol (X or O) on the board.\n- **Win Condition:** The game detects when a player has won (three in a row, column, or diagonal).\n- **Draw Condition:** The game detects when the board is full and the game is a draw.\n- **Input Validation:** The game prevents moves to already occupied cells.\n- **Extensibility:** Easy to change the board size or add new features.\n\n---\n\n## Core Entities\n\n- **Game:** Manages the game flow, player turns, and game status.\n- **Board:** Represents the NxN grid and provides methods to update and check the board.\n- **Cell:** Represents a single cell on the board.\n- **Player:** Represents a player with a name and symbol.\n- **Symbol:** Enum for X and O.\n- **GameStatus:** Enum for IN_PROGRESS, DRAW, WIN.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/tictactoe-class-diagram.png)\n\n### 1. Game\n- **Fields:** Board board, Player[] players, int currentPlayerIndex, GameStatus status\n- **Methods:** play(), makeMove(int row, int col), checkWin(), checkDraw(), switchPlayer(), getCurrentPlayer()\n\n### 2. Board\n- **Fields:** Cell[][] grid, int size\n- **Methods:** isCellEmpty(int row, int col), setCell(int row, int col, Symbol), printBoard(), isFull(), checkWin(Symbol)\n\n### 3. Cell\n- **Fields:** int row, int col, Symbol symbol\n- **Methods:** getSymbol(), setSymbol(Symbol)\n\n### 4. Player\n- **Fields:** String name, Symbol symbol\n\n### 5. Symbol (enum)\n- Values: X, O\n\n### 6. GameStatus (enum)\n- Values: IN_PROGRESS, DRAW, WIN\n\n---\n\n## Example Usage\n\n```java\nPlayer p1 = new Player(\"Alice\", Symbol.X);\nPlayer p2 = new Player(\"Bob\", Symbol.O);\nGame game = new Game(p1, p2);\ngame.play();\n```\n\n---\n\n## Demo\n\nSee `TicTacToeDemo.java` for a sample usage and simulation of the Tic Tac Toe game.\n\n---\n\n## Extending the Design\n\n- **Change board size:** Update the `Board` class to support different sizes.\n- **Add AI player:** Implement a computer player for single-player mode.\n- **Add GUI:** Build a graphical interface for the game.\n\n---"
  },
  {
    "path": "solutions/java/src/tictactoe/TicTacToeDemo.java",
    "content": "package tictactoe;\n\nimport tictactoe.enums.Symbol;\nimport tictactoe.models.Player;\n\npublic class TicTacToeDemo {\n    public static void main(String[] args) {\n        TicTacToeSystem system = TicTacToeSystem.getInstance();\n\n        Player alice = new Player(\"Alice\", Symbol.X);\n        Player bob = new Player(\"Bob\", Symbol.O);\n\n        // --- GAME 1: Alice wins ---\n        System.out.println(\"--- GAME 1: Alice (X) vs. Bob (O) ---\");\n        system.createGame(alice, bob);\n        system.printBoard();\n\n        system.makeMove(alice, 0, 0);\n        system.makeMove(bob, 1, 0);\n        system.makeMove(alice, 0, 1);\n        system.makeMove(bob, 1, 1);\n        system.makeMove(alice, 0, 2); // Alice wins, scoreboard is notified\n        System.out.println(\"----------------------------------------\\n\");\n\n        // --- GAME 2: Bob wins ---\n        System.out.println(\"--- GAME 2: Alice (X) vs. Bob (O) ---\");\n        system.createGame(alice, bob); // A new game instance\n        system.printBoard();\n\n        system.makeMove(alice, 0, 0);\n        system.makeMove(bob, 1, 0);\n        system.makeMove(alice, 0, 1);\n        system.makeMove(bob, 1, 1);\n        system.makeMove(alice, 2, 2);\n        system.makeMove(bob, 1, 2); // Bob wins, scoreboard is notified\n        System.out.println(\"----------------------------------------\\n\");\n\n        // --- GAME 3: A Draw ---\n        System.out.println(\"--- GAME 3: Alice (X) vs. Bob (O) - Draw ---\");\n        system.createGame(alice, bob);\n        system.printBoard();\n\n        system.makeMove(alice, 0, 0);\n        system.makeMove(bob, 0, 1);\n        system.makeMove(alice, 0, 2);\n        system.makeMove(bob, 1, 1);\n        system.makeMove(alice, 1, 0);\n        system.makeMove(bob, 1, 2);\n        system.makeMove(alice, 2, 1);\n        system.makeMove(bob, 2, 0);\n        system.makeMove(alice, 2, 2); // Draw, scoreboard is not notified of a winner\n        System.out.println(\"----------------------------------------\\n\");\n\n        // --- Final Scoreboard ---\n        // We get the scoreboard from the system and print its final state\n        system.printScoreBoard();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/TicTacToeSystem.java",
    "content": "package tictactoe;\n\nimport tictactoe.exceptions.InvalidMoveException;\nimport tictactoe.models.Player;\nimport tictactoe.observer.Scoreboard;\n\npublic class TicTacToeSystem {\n    private static volatile TicTacToeSystem instance;\n    private Game game;\n    private final Scoreboard scoreboard; // The system now manages a scoreboard\n\n    private TicTacToeSystem() {\n        this.scoreboard = new Scoreboard(); // Create the scoreboard on initialization\n    }\n\n    public static synchronized TicTacToeSystem getInstance() {\n        if (instance == null) {\n            instance = new TicTacToeSystem();\n        }\n        return instance;\n    }\n\n    public void createGame(Player player1, Player player2) {\n        this.game = new Game(player1, player2);\n        // Register the scoreboard as an observer for this new game\n        this.game.addObserver(this.scoreboard);\n\n        System.out.printf(\"Game started between %s (X) and %s (O).%n\", player1.getName(), player2.getName());\n    }\n\n    public void makeMove(Player player, int row, int col) {\n        if (game == null) {\n            System.out.println(\"No game in progress. Please create a game first.\");\n            return;\n        }\n        try {\n            System.out.printf(\"%s plays at (%d, %d)%n\", player.getName(), row, col);\n            game.makeMove(player, row, col);\n            printBoard();\n            System.out.println(\"Game Status: \" + game.getStatus());\n            if (game.getWinner() != null) {\n                System.out.println(\"Winner: \" + game.getWinner().getName());\n            }\n        } catch (InvalidMoveException e) {\n            System.out.println(\"Error: \" + e.getMessage());\n        }\n    }\n\n    public void printBoard() {\n        game.getBoard().printBoard();\n    }\n\n    public void printScoreBoard() {\n        scoreboard.printScores();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/enums/GameStatus.java",
    "content": "package tictactoe.enums;\n\npublic enum GameStatus {\n    IN_PROGRESS,\n    WINNER_X,\n    WINNER_O,\n    DRAW\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/enums/Symbol.java",
    "content": "package tictactoe.enums;\n\npublic enum Symbol {\n    X('X'),\n    O('O'),\n    EMPTY('_');\n\n    private final char symbol;\n\n    Symbol(char symbol) {\n        this.symbol = symbol;\n    }\n\n    public char getChar() {\n        return symbol;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/exceptions/InvalidMoveException.java",
    "content": "package tictactoe.exceptions;\n\npublic class InvalidMoveException extends RuntimeException {\n    public InvalidMoveException(String message) {\n        super(message);\n    }\n}"
  },
  {
    "path": "solutions/java/src/tictactoe/models/Board.java",
    "content": "package tictactoe.models;\n\nimport tictactoe.enums.Symbol;\nimport tictactoe.exceptions.InvalidMoveException;\n\npublic class Board {\n    private final int size;\n    private int movesCount;\n    private final Cell[][] board;\n\n    public Board(int size) {\n        this.size = size;\n        this.board = new Cell[size][size];\n        movesCount = 0;\n        initializeBoard();\n    }\n\n    private void initializeBoard() {\n        for (int row = 0; row < size; row++) {\n            for (int col = 0; col < size; col++) {\n                board[row][col] = new Cell();\n            }\n        }\n    }\n\n    public boolean placeSymbol(int row, int col, Symbol symbol) {\n        if (row < 0 || row >= size || col < 0 || col >= size) {\n            throw new InvalidMoveException(\"Invalid position: out of bounds.\");\n        }\n        if (board[row][col].getSymbol() != Symbol.EMPTY) {\n            throw new InvalidMoveException(\"Invalid position: cell is already occupied.\");\n        }\n        board[row][col].setSymbol(symbol);\n        movesCount++;\n        return true;\n    }\n\n    public Cell getCell(int row, int col) {\n        if (row < 0 || row >= size || col < 0 || col >= size) {\n            return null;\n        }\n        return board[row][col];\n    }\n\n    public boolean isFull() {\n        return movesCount == size * size;\n    }\n\n    public void printBoard() {\n        System.out.println(\"-------------\");\n        for (int i = 0; i < size; i++) {\n            System.out.print(\"| \");\n            for (int j = 0; j < size; j++) {\n                Symbol symbol = board[i][j].getSymbol();\n                System.out.print(symbol.getChar() + \" | \");\n            }\n            System.out.println(\"\\n-------------\");\n        }\n    }\n\n    public int getSize() {\n        return size;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/models/Cell.java",
    "content": "package tictactoe.models;\n\nimport tictactoe.enums.Symbol;\n\npublic class Cell {\n    private Symbol symbol;\n\n    public Cell() {\n        this.symbol = Symbol.EMPTY;\n    }\n\n    public Symbol getSymbol() {\n        return symbol;\n    }\n\n    public void setSymbol(Symbol symbol) {\n        this.symbol = symbol;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/models/Player.java",
    "content": "package tictactoe.models;\n\nimport tictactoe.enums.Symbol;\n\npublic class Player {\n    private final String name;\n    private final Symbol symbol;\n\n    public Player(String name, Symbol symbol) {\n        this.name = name;\n        this.symbol = symbol;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public Symbol getSymbol() {\n        return symbol;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/observer/GameObserver.java",
    "content": "package tictactoe.observer;\n\nimport tictactoe.Game;\n\npublic interface GameObserver {\n    void update(Game game);\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/observer/GameSubject.java",
    "content": "package tictactoe.observer;\n\nimport tictactoe.Game;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class GameSubject {\n    private final List<GameObserver> observers = new ArrayList<>();\n\n    public void addObserver(GameObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(GameObserver observer) {\n        observers.remove(observer);\n    }\n\n    public void notifyObservers() {\n        for (GameObserver observer : observers) {\n            // Pass 'this' which is the Game instance\n            observer.update((Game) this);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/observer/Scoreboard.java",
    "content": "package tictactoe.observer;\n\nimport tictactoe.Game;\n\nimport java.util.Map;\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Scoreboard implements GameObserver {\n    private final Map<String, Integer> scores;\n\n    public Scoreboard() {\n        this.scores = new ConcurrentHashMap<>();\n    }\n\n    @Override\n    public void update(Game game) {\n        // The scoreboard only cares about finished games with a winner\n        if (game.getWinner() != null) {\n            String winnerName = game.getWinner().getName();\n            scores.put(winnerName, scores.getOrDefault(winnerName, 0) + 1);\n            System.out.printf(\"[Scoreboard] %s wins! Their new score is %d.%n\", winnerName, scores.get(winnerName));\n        }\n    }\n\n    public void printScores() {\n        System.out.println(\"\\n--- Overall Scoreboard ---\");\n        if (scores.isEmpty()) {\n            System.out.println(\"No games with a winner have been played yet.\");\n            return;\n        }\n        scores.forEach((playerName, score) ->\n                System.out.printf(\"Player: %-10s | Wins: %d%n\", playerName, score)\n        );\n        System.out.println(\"--------------------------\\n\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/state/DrawState.java",
    "content": "package tictactoe.state;\n\nimport tictactoe.Game;\nimport tictactoe.exceptions.InvalidMoveException;\nimport tictactoe.models.Player;\n\npublic class DrawState implements GameState {\n    @Override\n    public void handleMove(Game game, Player player, int row, int col) {\n        throw new InvalidMoveException(\"Game is already over. It was a draw.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/state/GameState.java",
    "content": "package tictactoe.state;\n\nimport tictactoe.Game;\nimport tictactoe.models.Player;\n\npublic interface GameState {\n    void handleMove(Game game, Player player, int row, int col);\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/state/InProgressState.java",
    "content": "package tictactoe.state;\n\nimport tictactoe.Game;\nimport tictactoe.enums.GameStatus;\nimport tictactoe.enums.Symbol;\nimport tictactoe.exceptions.InvalidMoveException;\nimport tictactoe.models.Player;\n\npublic class InProgressState implements GameState {\n    @Override\n    public void handleMove(Game game, Player player, int row, int col) {\n        if (game.getCurrentPlayer() != player) {\n            throw new InvalidMoveException(\"Not your turn!\");\n        }\n\n        // Place the piece on the board\n        game.getBoard().placeSymbol(row, col, player.getSymbol());\n\n        // Check for a winner or a draw\n        if (game.checkWinner(player)) {\n            game.setWinner(player);\n            game.setStatus(player.getSymbol() == Symbol.X ? GameStatus.WINNER_X : GameStatus.WINNER_O);\n            game.setState(new WinnerState());\n        } else if (game.getBoard().isFull()) {\n            game.setStatus(GameStatus.DRAW);\n            game.setState(new DrawState());\n        } else {\n            // If the game is still in progress, switch players\n            game.switchPlayer();\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/state/WinnerState.java",
    "content": "package tictactoe.state;\n\nimport tictactoe.Game;\nimport tictactoe.exceptions.InvalidMoveException;\nimport tictactoe.models.Player;\n\npublic class WinnerState implements GameState {\n    @Override\n    public void handleMove(Game game, Player player, int row, int col) {\n        throw new InvalidMoveException(\"Game is already over. \" + game.getWinner().getName() + \" has won.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/strategy/ColumnWinningStrategy.java",
    "content": "package tictactoe.strategy;\n\nimport tictactoe.models.Board;\nimport tictactoe.models.Player;\n\npublic class ColumnWinningStrategy implements WinningStrategy {\n    @Override\n    public boolean checkWinner(Board board, Player player) {\n        for (int col = 0; col < board.getSize(); col++) {\n            boolean colWin = true;\n            for (int row = 0; row < board.getSize(); row++) {\n                if (board.getCell(row, col).getSymbol() != player.getSymbol()) {\n                    colWin = false;\n                    break;\n                }\n            }\n            if (colWin) return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/strategy/DiagonalWinningStrategy.java",
    "content": "package tictactoe.strategy;\n\nimport tictactoe.models.Board;\nimport tictactoe.models.Player;\n\npublic class DiagonalWinningStrategy implements WinningStrategy {\n    @Override\n    public boolean checkWinner(Board board, Player player) {\n        // Main diagonal\n        boolean mainDiagWin = true;\n        for (int i = 0; i < board.getSize(); i++) {\n            if (board.getCell(i, i).getSymbol() != player.getSymbol()) {\n                mainDiagWin = false;\n                break;\n            }\n        }\n        if (mainDiagWin) return true;\n\n        // Anti-diagonal\n        boolean antiDiagWin = true;\n        for (int i = 0; i < board.getSize(); i++) {\n            if (board.getCell(i, board.getSize() - 1 - i).getSymbol() != player.getSymbol()) {\n                antiDiagWin = false;\n                break;\n            }\n        }\n        return antiDiagWin;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/strategy/RowWinningStrategy.java",
    "content": "package tictactoe.strategy;\n\nimport tictactoe.models.Board;\nimport tictactoe.models.Player;\n\npublic class RowWinningStrategy implements WinningStrategy {\n    @Override\n    public boolean checkWinner(Board board, Player player) {\n        for (int row = 0; row < board.getSize(); row++) {\n            boolean rowWin = true;\n            for (int col = 0; col < board.getSize(); col++) {\n                if (board.getCell(row, col).getSymbol() != player.getSymbol()) {\n                    rowWin = false;\n                    break;\n                }\n            }\n            if (rowWin) return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/tictactoe/strategy/WinningStrategy.java",
    "content": "package tictactoe.strategy;\n\nimport tictactoe.models.Board;\nimport tictactoe.models.Player;\n\npublic interface WinningStrategy {\n    boolean checkWinner(Board board, Player player);\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/IntersectionController.java",
    "content": "package trafficsignalcontrolsystem;\n\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.observer.TrafficObserver;\nimport trafficsignalcontrolsystem.states.intersection.IntersectionState;\nimport trafficsignalcontrolsystem.states.intersection.NorthSouthGreenState;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\npublic class IntersectionController implements Runnable {\n    private final int id;\n    private final Map<Direction, TrafficLight> trafficLights;\n    private IntersectionState currentState;\n    private final long greenDuration;\n    private final long yellowDuration;\n    private volatile boolean running = true;\n\n    // Private constructor to be used by the builder\n    private IntersectionController(int id, Map<Direction, TrafficLight> trafficLights, long greenDuration, long yellowDuration) {\n        this.id = id;\n        this.trafficLights = trafficLights;\n        this.greenDuration = greenDuration;\n        this.yellowDuration = yellowDuration;\n        // Initial state for the intersection\n        this.currentState = new NorthSouthGreenState();\n    }\n\n    public int getId() { return id; }\n    public long getGreenDuration() { return greenDuration; }\n    public long getYellowDuration() { return yellowDuration; }\n    public TrafficLight getLight(Direction direction) { return trafficLights.get(direction); }\n\n    public void setState(IntersectionState state) {\n        this.currentState = state;\n    }\n\n    public void start() {\n        new Thread(this).start();\n    }\n\n    public void stop() {\n        this.running = false;\n    }\n\n    @Override\n    public void run() {\n        while (running) {\n            try {\n                currentState.handle(this);\n            } catch (InterruptedException e) {\n                Thread.currentThread().interrupt();\n                System.out.println(\"Intersection \" + id + \" was interrupted.\");\n                running = false;\n            }\n        }\n    }\n\n    // --- Builder Pattern Starts Here ---\n    public static class Builder {\n        private final int id;\n        private long greenDuration = 5000; // default 5s\n        private long yellowDuration = 2000; // default 2s\n        private final List<TrafficObserver> observers = new ArrayList<>();\n\n        public Builder(int id) {\n            this.id = id;\n        }\n\n        public Builder withDurations(long green, long yellow) {\n            this.greenDuration = green;\n            this.yellowDuration = yellow;\n            return this;\n        }\n\n        public Builder addObserver(TrafficObserver observer) {\n            this.observers.add(observer);\n            return this;\n        }\n\n        public IntersectionController build() {\n            Map<Direction, TrafficLight> lights = new HashMap<>();\n            for (Direction dir : Direction.values()) {\n                TrafficLight light = new TrafficLight(id, dir);\n                // Attach all registered observers to each light\n                observers.forEach(light::addObserver);\n                lights.put(dir, light);\n            }\n            return new IntersectionController(id, lights, greenDuration, yellowDuration);\n        }\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/README.md",
    "content": "# Traffic Signal System (LLD)\n\n## Problem Statement\n\nDesign and implement a Traffic Signal System to manage the traffic lights at an intersection. The system should support configurable signal durations for each direction and vendingMachineState, automatic cycling of signals using the State design pattern, and the ability to manually override signals as needed.\n\n---\n\n## Requirements\n\n- **Multiple Directions:** The intersection supports multiple directions (e.g., NORTH, SOUTH, EAST, WEST).\n- **Traffic Light States:** Each direction has a traffic light with states: GREEN, YELLOW, RED.\n- **Configurable Durations:** Each direction and vendingMachineState can have its own configurable duration.\n- **Automatic Cycling:** The system automatically cycles through the states for each direction in a round-robin fashion.\n- **Manual Override:** The system allows manual override to set a specific direction to GREEN at any time.\n- **Extensibility:** Easy to add new directions or states if needed.\n- **State Pattern:** Use the State design pattern to encapsulate vendingMachineState-specific behavior and transitions.\n\n---\n\n## Core Entities\n\n- **Direction:** Enum representing the directions at the intersection (NORTH, SOUTH, EAST, WEST).\n- **SignalState (interface):** Represents the vendingMachineState of a traffic light (GREEN, YELLOW, RED), with vendingMachineState-specific behavior.\n- **GreenState, YellowState, RedState:** Concrete implementations of `SignalState` for each light vendingMachineState.\n- **TrafficLight:** Represents a traffic light for a direction, maintains its current vendingMachineState and delegates behavior to the vendingMachineState.\n- **Intersection:** Represents the intersection, holds all traffic lights and their configurations, and exposes the manual override.\n- **TrafficSignalController:** Controls the cycling and overriding of traffic signals, manages timing and transitions using a scheduler.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/trafficsignalsystem-class-diagram.png)\n\n### 1. Direction\n- Enum: NORTH, SOUTH, EAST, WEST\n\n### 2. SignalState (interface)\n- **Methods:** `void handle(TrafficLight, TrafficSignalController, Direction)`, `String getName()`\n\n### 3. GreenState, YellowState, RedState\n- Implement `SignalState`\n- Each handles its own transition logic and duration\n\n### 4. TrafficLight\n- **Fields:** currentState, direction\n- **Methods:** setState(SignalState), getState(), getDirection(), handle(TrafficSignalController)\n\n### 5. Intersection\n- **Fields:** id, Map<Direction, TrafficLight> signals, Map<Direction, Map<String, Integer>> signalDurations, TrafficSignalController controller\n- **Methods:** start(Direction), manualOverride(Direction), getSignal(Direction)\n\n### 6. TrafficSignalController\n- **Fields:** Map<Direction, TrafficLight> signals, Map<Direction, Map<String, Integer>> signalDurations, scheduler\n- **Methods:** start(Direction), scheduleStateChange(...), getSignalDuration(...), getNextDirection(...), getTrafficLight(...), manualOverride(Direction)\n\n---\n\n## Design Patterns Used\n\n- **State Pattern:** Each signal vendingMachineState (GREEN, YELLOW, RED) encapsulates its own behavior and transition logic.\n- **Scheduler/Timer:** For handling timed transitions between states.\n- **Strategy Pattern:** (Conceptually) for supporting different timing strategies per direction/vendingMachineState.\n\n---\n\n## Example Usage\n\n```java\n// Configure durations per direction and vendingMachineState\nMap<Direction, Map<String, Integer>> signalDurations = new EnumMap<>(Direction.class);\nsignalDurations.put(Direction.NORTH, Map.of(\"GREEN\", 4, \"YELLOW\", 2, \"RED\", 3));\nsignalDurations.put(Direction.SOUTH, Map.of(\"GREEN\", 3, \"YELLOW\", 2, \"RED\", 4));\nsignalDurations.put(Direction.EAST, Map.of(\"GREEN\", 5, \"YELLOW\", 2, \"RED\", 3));\nsignalDurations.put(Direction.WEST, Map.of(\"GREEN\", 2, \"YELLOW\", 2, \"RED\", 5));\n\n// Initialize traffic lights\nMap<Direction, TrafficLight> signals = new EnumMap<>(Direction.class);\nfor (Direction direction : Direction.values()) {\n    signals.put(direction, new TrafficLight(direction));\n}\n\n// Create and start the intersection\nIntersection intersection = new Intersection(\"1\", signals, signalDurations);\nintersection.start(Direction.NORTH);\n\n// Manual override example\nintersection.manualOverride(Direction.EAST);\n```\n\n---\n\n## Demo\n\nSee `TrafficSignalSystemDemo.java` for a sample usage and simulation of the traffic signal system.\n\n---\n\n## Extending the Framework\n\n- **Add new directions:** Add to the `Direction` enum and update configuration.\n- **Add new states:** Add to the `SignalState` interface and implement new vendingMachineState classes.\n- **Custom timing strategies:** Implement new strategies for special intersections or adaptive signals.\n\n---"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/TrafficControlSystem.java",
    "content": "package trafficsignalcontrolsystem;\n\nimport trafficsignalcontrolsystem.observer.CentralMonitor;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.TimeUnit;\n\npublic class TrafficControlSystem {\n    private static final TrafficControlSystem INSTANCE = new TrafficControlSystem();\n    private final List<IntersectionController> intersections = new ArrayList<>();\n    private ExecutorService executorService;\n\n    private TrafficControlSystem() {}\n\n    public static TrafficControlSystem getInstance() {\n        return INSTANCE;\n    }\n\n    public void addIntersection(int intersectionId, int greenDuration, int yellowDuration) {\n        IntersectionController intersection = new IntersectionController.Builder(intersectionId)\n                .withDurations(greenDuration, yellowDuration)\n                .addObserver(new CentralMonitor())\n                .build();\n        intersections.add(intersection);\n    }\n\n    public void startSystem() {\n        if (intersections.isEmpty()) {\n            System.out.println(\"No intersections to manage. System not starting.\");\n            return;\n        }\n        System.out.println(\"--- Starting Traffic Control System ---\");\n        executorService = Executors.newFixedThreadPool(intersections.size());\n        intersections.forEach(executorService::submit);\n    }\n\n    public void stopSystem() {\n        System.out.println(\"\\n--- Shutting Down Traffic Control System ---\");\n        intersections.forEach(IntersectionController::stop);\n        executorService.shutdown();\n        try {\n            if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {\n                executorService.shutdownNow();\n            }\n        } catch (InterruptedException e) {\n            executorService.shutdownNow();\n        }\n        System.out.println(\"All intersections stopped. System shut down.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/TrafficLight.java",
    "content": "package trafficsignalcontrolsystem;\n\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.enums.LightColor;\nimport trafficsignalcontrolsystem.observer.TrafficObserver;\nimport trafficsignalcontrolsystem.states.light.GreenState;\nimport trafficsignalcontrolsystem.states.light.RedState;\nimport trafficsignalcontrolsystem.states.light.SignalState;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class TrafficLight {\n    private final Direction direction;\n    private LightColor currentColor;\n    private SignalState currentState;\n    private SignalState nextState; // The state to transition to after a timer elapses\n    private final List<TrafficObserver> observers = new ArrayList<>();\n    private final int intersectionId;\n\n    public TrafficLight(int intersectionId, Direction direction) {\n        this.intersectionId = intersectionId;\n        this.direction = direction;\n        this.currentState = new RedState(); // Default state is Red\n        this.currentState.handle(this);\n    }\n\n    // This is called by the IntersectionController to initiate a G-Y-R cycle\n    public void startGreen() {\n        this.currentState = new GreenState();\n        this.currentState.handle(this);\n    }\n\n    // This is called by the IntersectionController to transition from G->Y or Y->R\n    public void transition() {\n        this.currentState = this.nextState;\n        this.currentState.handle(this);\n    }\n\n    public void setColor(LightColor color) {\n        if (this.currentColor != color) {\n            this.currentColor = color;\n            notifyObservers();\n        }\n    }\n\n    public void setNextState(SignalState state) {\n        this.nextState = state;\n    }\n\n    public LightColor getCurrentColor() {\n        return currentColor;\n    }\n\n    public Direction getDirection() {\n        return direction;\n    }\n\n    // Observer pattern methods\n    public void addObserver(TrafficObserver observer) {\n        observers.add(observer);\n    }\n\n    public void removeObserver(TrafficObserver observer) {\n        observers.remove(observer);\n    }\n\n    private void notifyObservers() {\n        for (TrafficObserver observer : observers) {\n            observer.update(intersectionId, direction, currentColor);\n        }\n    }\n}"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/TrafficSystemDemo.java",
    "content": "package trafficsignalcontrolsystem;\n\nimport java.util.concurrent.TimeUnit;\n\npublic class TrafficSystemDemo {\n    public static void main(String[] args) {\n        // 1. Get the singleton TrafficControlSystem instance\n        TrafficControlSystem system = TrafficControlSystem.getInstance();\n\n        // 2. Add intersections to the system\n        system.addIntersection(1, 500, 200);\n        system.addIntersection(2, 700, 150);\n\n        // 3. Start the system\n        system.startSystem();\n\n        // 4. Let the simulation run for a while (e.g., 5 seconds)\n        try {\n            TimeUnit.SECONDS.sleep(5);\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n        }\n\n        // 5. Stop the system gracefully\n        system.stopSystem();\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/enums/Direction.java",
    "content": "package trafficsignalcontrolsystem.enums;\n\npublic enum Direction {\n    NORTH, SOUTH, EAST, WEST\n}"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/enums/LightColor.java",
    "content": "package trafficsignalcontrolsystem.enums;\n\npublic enum LightColor {\n    GREEN,\n    YELLOW,\n    RED\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/observer/CentralMonitor.java",
    "content": "package trafficsignalcontrolsystem.observer;\n\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class CentralMonitor implements TrafficObserver {\n    @Override\n    public void update(int intersectionId, Direction direction, LightColor color) {\n        System.out.printf(\"[MONITOR] Intersection %d: Light for %s direction changed to %s.\\n\",\n                intersectionId, direction, color);\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/observer/TrafficObserver.java",
    "content": "package trafficsignalcontrolsystem.observer;\n\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic interface TrafficObserver {\n    void update(int intersectionId, Direction direction, LightColor color);\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/intersection/EastWestGreenState.java",
    "content": "package trafficsignalcontrolsystem.states.intersection;\n\nimport trafficsignalcontrolsystem.IntersectionController;\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class EastWestGreenState implements IntersectionState {\n    @Override\n    public void handle(IntersectionController context) throws InterruptedException {\n        System.out.printf(\"\\n--- INTERSECTION %d: Cycle -> East-West GREEN ---\\n\", context.getId());\n\n        // Turn East and West green, ensure North and South are red\n        context.getLight(Direction.EAST).startGreen();\n        context.getLight(Direction.WEST).startGreen();\n        context.getLight(Direction.NORTH).setColor(LightColor.RED);\n        context.getLight(Direction.SOUTH).setColor(LightColor.RED);\n\n        // Wait for green light duration\n        Thread.sleep(context.getGreenDuration());\n\n        // Transition East and West to Yellow\n        context.getLight(Direction.EAST).transition();\n        context.getLight(Direction.WEST).transition();\n\n        // Wait for yellow light duration\n        Thread.sleep(context.getYellowDuration());\n\n        // Transition East and West to Red\n        context.getLight(Direction.EAST).transition();\n        context.getLight(Direction.WEST).transition();\n\n        // Change the intersection's state back to let North-South go\n        context.setState(new NorthSouthGreenState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/intersection/IntersectionState.java",
    "content": "package trafficsignalcontrolsystem.states.intersection;\n\nimport trafficsignalcontrolsystem.IntersectionController;\n\npublic interface IntersectionState {\n    void handle(IntersectionController context) throws InterruptedException;\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/intersection/NorthSouthGreenState.java",
    "content": "package trafficsignalcontrolsystem.states.intersection;\n\nimport trafficsignalcontrolsystem.IntersectionController;\nimport trafficsignalcontrolsystem.enums.Direction;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class NorthSouthGreenState implements IntersectionState {\n    @Override\n    public void handle(IntersectionController context) throws InterruptedException {\n        System.out.printf(\"\\n--- INTERSECTION %d: Cycle Start -> North-South GREEN ---\\n\", context.getId());\n\n        // Turn North and South green, ensure East and West are red\n        context.getLight(Direction.NORTH).startGreen();\n        context.getLight(Direction.SOUTH).startGreen();\n        context.getLight(Direction.EAST).setColor(LightColor.RED);\n        context.getLight(Direction.WEST).setColor(LightColor.RED);\n\n        // Wait for green light duration\n        Thread.sleep(context.getGreenDuration());\n\n        // Transition North and South to Yellow\n        context.getLight(Direction.NORTH).transition();\n        context.getLight(Direction.SOUTH).transition();\n\n        // Wait for yellow light duration\n        Thread.sleep(context.getYellowDuration());\n\n        // Transition North and South to Red\n        context.getLight(Direction.NORTH).transition();\n        context.getLight(Direction.SOUTH).transition();\n\n        // Change the intersection's state to let East-West go\n        context.setState(new EastWestGreenState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/light/GreenState.java",
    "content": "package trafficsignalcontrolsystem.states.light;\n\nimport trafficsignalcontrolsystem.TrafficLight;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class GreenState implements SignalState {\n    @Override\n    public void handle(TrafficLight context) {\n        context.setColor(LightColor.GREEN);\n        // After being green, the next state is yellow.\n        context.setNextState(new YellowState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/light/RedState.java",
    "content": "package trafficsignalcontrolsystem.states.light;\n\nimport trafficsignalcontrolsystem.TrafficLight;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class RedState implements SignalState {\n    @Override\n    public void handle(TrafficLight context) {\n        context.setColor(LightColor.RED);\n        // Red is a stable state, it transitions to green only when the intersection controller commands it.\n        // So, the next state is self.\n        context.setNextState(new RedState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/light/SignalState.java",
    "content": "package trafficsignalcontrolsystem.states.light;\n\nimport trafficsignalcontrolsystem.TrafficLight;\n\npublic interface SignalState {\n    void handle(TrafficLight context);\n}\n"
  },
  {
    "path": "solutions/java/src/trafficsignalcontrolsystem/states/light/YellowState.java",
    "content": "package trafficsignalcontrolsystem.states.light;\n\nimport trafficsignalcontrolsystem.TrafficLight;\nimport trafficsignalcontrolsystem.enums.LightColor;\n\npublic class YellowState implements SignalState {\n    @Override\n    public void handle(TrafficLight context) {\n        context.setColor(LightColor.YELLOW);\n        // After being yellow, the next state is red.\n        context.setNextState(new RedState());\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/README.md",
    "content": "# Vending Machine (LLD)\n\n## Problem Statement\n\nDesign and implement a Vending Machine system that allows users to select products, insert coins/notes, dispense products, and return change. The system should manage inventory, handle payments, and use the State design pattern for its operations.\n\n---\n\n## Requirements\n\n- **Product Management:** The system manages a catalog of products, each with a price and available quantity.\n- **Inventory Management:** The system tracks the quantity of each item and prevents dispensing if out of stock.\n- **Payment Handling:** The system accepts coins and notes, tracks total payment, and returns change if necessary.\n- **State Management:** The system uses the State design pattern to manage its operational states (Idle, Ready, Dispense, ReturnChange).\n- **User Interaction:** Users can select products, insert coins/notes, and receive products and change.\n- **Extensibility:** Easy to add new item types, payment methods, or states.\n\n---\n\n## Core Entities\n\n- **VendingMachine:** Main class that manages inventory, vendingMachineState transitions, item selection, and payment.\n- **Product:** Represents a item with a name and price.\n- **Inventory:** Manages the stock of products.\n- **Coin / Note:** Represents accepted denominations for payment.\n- **VendingMachineState (interface):** Interface for different machine states.\n- **IdleState, ReadyState, DispenseState, ReturnChangeState:** Concrete states implementing VendingMachineState.\n- **Singleton Pattern:** VendingMachine is implemented as a singleton.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/vendingmachine-class-diagram.png)\n\n### 1. VendingMachine\n- **Fields:** Inventory inventory, VendingMachineState idleState, readyState, dispenseState, returnChangeState, currentState, Product selectedProduct, double totalPayment\n- **Methods:** addProduct(String, double, int), selectProduct(Product), insertCoin(Coin), insertNote(Note), dispenseProduct(), returnChange(), setState(VendingMachineState), getInstance(), etc.\n\n### 2. Product\n- **Fields:** String name, double price\n\n### 3. Inventory\n- **Fields:** Map<Product, Integer> productQuantities\n- **Methods:** addProduct(Product, int), getQuantity(Product), reduceQuantity(Product), isAvailable(Product)\n\n### 4. Coin / Note\n- **Fields:** double value\n- **Methods:** getValue()\n\n### 5. VendingMachineState (interface)\n- **Methods:** selectProduct(Product), insertCoin(Coin), insertNote(Note), dispenseProduct(), returnChange()\n\n### 6. IdleState, ReadyState, DispenseState, ReturnChangeState\n- **Implements:** VendingMachineState\n- **Behavior:** Each vendingMachineState handles allowed operations and transitions.\n\n---\n\n## Example Usage\n\n```java\nVendingMachine machine = VendingMachine.getInstance();\nProduct chips = machine.addProduct(\"Chips\", 1.5, 10);\nmachine.selectProduct(chips);\nmachine.insertCoin(new Coin(1.0));\nmachine.insertCoin(new Coin(0.5));\nmachine.dispenseProduct();\nmachine.returnChange();\n```\n\n---\n\n## Demo\n\nSee your main or demo class for a sample usage and simulation of the vending machine.\n\n---\n\n## Extending the Framework\n\n- **Add new payment methods:** Support for cards, mobile payments, etc.\n- **Add new states:** Maintenance, OutOfOrder, etc.\n- **Add item categories:** Snacks, drinks, etc.\n\n---\n\n## Design Patterns Used\n\n- **State Pattern:** For managing machine states and transitions.\n- **Singleton Pattern:** For ensuring a single instance of the VendingMachine.\n\n---"
  },
  {
    "path": "solutions/java/src/vendingmachine/VendingMachine.java",
    "content": "package vendingmachine;\n\nimport vendingmachine.entity.Inventory;\nimport vendingmachine.entity.Item;\nimport vendingmachine.enums.Coin;\nimport vendingmachine.state.*;\n\npublic class VendingMachine {\n    private final static VendingMachine INSTANCE = new VendingMachine();\n    private final Inventory inventory = new Inventory();\n    private VendingMachineState currentVendingMachineState;\n    private int balance = 0;\n    private String selectedItemCode;\n\n    public VendingMachine() {\n        currentVendingMachineState = new IdleState(this);\n    }\n\n    public static VendingMachine getInstance() {\n        return INSTANCE;\n    }\n\n    public void insertCoin(Coin coin) {\n        currentVendingMachineState.insertCoin(coin);\n    }\n\n    public Item addItem(String code, String name, int price, int quantity) {\n        Item item = new Item(code, name, price);\n        inventory.addItem(code, item, quantity);\n        return item;\n    }\n\n    public void selectItem(String code) {\n        currentVendingMachineState.selectItem(code);\n    }\n\n    public void dispense() {\n        currentVendingMachineState.dispense();\n    }\n\n    public void dispenseItem() {\n        Item item = inventory.getItem(selectedItemCode);\n        if (balance >= item.getPrice()) {\n            inventory.reduceStock(selectedItemCode);\n            balance -= item.getPrice();\n            System.out.println(\"Dispensed: \" + item.getName());\n            if (balance > 0) {\n                System.out.println(\"Returning change: \" + balance);\n            }\n        }\n        reset();\n        setState(new IdleState(this));\n    }\n\n    public void refundBalance() {\n        System.out.println(\"Refunding: \" + balance);\n        balance = 0;\n    }\n\n    public void reset() {\n        selectedItemCode = null;\n        balance = 0;\n    }\n\n    public void addBalance(int value) {\n        balance += value;\n    }\n\n    public Item getSelectedItem() {\n        return inventory.getItem(selectedItemCode);\n    }\n\n    public void setSelectedItemCode(String code) {\n        this.selectedItemCode = code;\n    }\n\n    public void setState(VendingMachineState vendingMachineState) {\n        this.currentVendingMachineState = vendingMachineState;\n    }\n\n    // Getters for states and inventory\n    public Inventory getInventory() { return inventory; }\n    public int getBalance() { return balance; }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/VendingMachineDemo.java",
    "content": "package vendingmachine;\n\nimport vendingmachine.enums.Coin;\n\npublic class VendingMachineDemo {\n    public static void main(String[] args) {\n        VendingMachine vendingMachine = VendingMachine.getInstance();\n\n        // Add products to the inventory\n        vendingMachine.addItem(\"A1\", \"Coke\", 25, 3);\n        vendingMachine.addItem(\"A2\", \"Pepsi\", 25, 2);\n        vendingMachine.addItem(\"B1\", \"Water\", 10, 5);\n\n        // Select a product\n        System.out.println(\"\\n--- Step 1: Select an item ---\");\n        vendingMachine.selectItem(\"A1\");\n\n        // Insert coins\n        System.out.println(\"\\n--- Step 2: Insert coins ---\");\n        vendingMachine.insertCoin(Coin.DIME); // 10\n        vendingMachine.insertCoin(Coin.DIME); // 10\n        vendingMachine.insertCoin(Coin.NICKEL); // 5\n\n        // Dispense the product\n        System.out.println(\"\\n--- Step 3: Dispense item ---\");\n        vendingMachine.dispense(); // Should dispense Coke\n\n        // Select another item\n        System.out.println(\"\\n--- Step 4: Select another item ---\");\n        vendingMachine.selectItem(\"B1\");\n\n        // Insert more amount\n        System.out.println(\"\\n--- Step 5: Insert more than needed ---\");\n        vendingMachine.insertCoin(Coin.QUARTER); // 25\n\n        // Try to dispense the product\n        System.out.println(\"\\n--- Step 6: Dispense and return change ---\");\n        vendingMachine.dispense();\n    }\n}"
  },
  {
    "path": "solutions/java/src/vendingmachine/entity/Inventory.java",
    "content": "package vendingmachine.entity;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class Inventory {\n    private final Map<String, Item> itemMap = new HashMap<>();\n    private final Map<String, Integer> stockMap = new HashMap<>();\n\n    public void addItem(String code, Item item, int quantity) {\n        itemMap.put(code, item);\n        stockMap.put(code, quantity);\n    }\n\n    public Item getItem(String code) {\n        return itemMap.get(code);\n    }\n\n    public boolean isAvailable(String code) {\n        return stockMap.getOrDefault(code, 0) > 0;\n    }\n\n    public void reduceStock(String code) {\n        stockMap.put(code, stockMap.get(code) - 1);\n    }\n}"
  },
  {
    "path": "solutions/java/src/vendingmachine/entity/Item.java",
    "content": "package vendingmachine.entity;\n\npublic class Item {\n    private String code;\n    private String name;\n    private int price;\n\n    public Item(String code, String name, int price) {\n        this.code = code;\n        this.name = name;\n        this.price = price;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public int getPrice() {\n        return price;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/enums/Coin.java",
    "content": "package vendingmachine.enums;\n\npublic enum Coin {\n    PENNY(1),\n    NICKEL(5),\n    DIME(10),\n    QUARTER(25);\n\n    private final int value;\n\n    Coin(int value) {\n        this.value = value;\n    }\n\n    public int getValue() {\n        return value;\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/state/DispensingState.java",
    "content": "package vendingmachine.state;\n\nimport vendingmachine.enums.Coin;\nimport vendingmachine.VendingMachine;\n\npublic class DispensingState extends VendingMachineState {\n    public DispensingState(VendingMachine machine) {\n        super(machine);\n    }\n\n    @Override\n    public void insertCoin(Coin coin) {\n        System.out.println(\"Currently dispensing. Please wait.\");\n    }\n\n    @Override\n    public void selectItem(String code) {\n        System.out.println(\"Currently dispensing. Please wait.\");\n    }\n\n    @Override\n    public void dispense() {\n        // already triggered by HasMoneyState\n    }\n\n    @Override\n    public void refund() {\n        System.out.println(\"Dispensing in progress. Refund not allowed.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/state/HasMoneyState.java",
    "content": "package vendingmachine.state;\n\nimport vendingmachine.enums.Coin;\nimport vendingmachine.VendingMachine;\n\npublic class HasMoneyState extends VendingMachineState {\n    public HasMoneyState(VendingMachine machine) {\n        super(machine);\n    }\n\n    @Override\n    public void insertCoin(Coin coin) {\n        System.out.println(\"Already received full amount.\");\n    }\n\n    @Override\n    public void selectItem(String code) {\n        System.out.println(\"Item already selected.\");\n    }\n\n    @Override\n    public void dispense() {\n        machine.setState(new DispensingState(machine));\n        machine.dispenseItem();\n    }\n\n    @Override\n    public void refund() {\n        machine.refundBalance();\n        machine.reset();\n        machine.setState(new IdleState(machine));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/state/IdleState.java",
    "content": "package vendingmachine.state;\n\nimport vendingmachine.enums.Coin;\nimport vendingmachine.VendingMachine;\n\npublic class IdleState extends VendingMachineState {\n    public IdleState(VendingMachine machine) {\n        super(machine);\n    }\n\n    @Override\n    public void insertCoin(Coin coin) {\n        System.out.println(\"Please select an item before inserting money.\");\n    }\n\n    @Override\n    public void selectItem(String code) {\n        if (!machine.getInventory().isAvailable(code)) {\n            System.out.println(\"Item not available.\");\n            return;\n        }\n        machine.setSelectedItemCode(code);\n        machine.setState(new ItemSelectedState(machine));\n        System.out.println(\"Item selected: \" + code);\n    }\n\n    @Override\n    public void dispense() {\n        System.out.println(\"No item selected.\");\n    }\n\n    @Override\n    public void refund() {\n        System.out.println(\"No money to refund.\");\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/state/ItemSelectedState.java",
    "content": "package vendingmachine.state;\n\nimport vendingmachine.enums.Coin;\nimport vendingmachine.VendingMachine;\n\npublic class ItemSelectedState extends VendingMachineState {\n    public ItemSelectedState(VendingMachine machine) {\n        super(machine);\n    }\n\n    @Override\n    public void insertCoin(Coin coin) {\n        machine.addBalance(coin.getValue());\n        System.out.println(\"Coin Inserted: \" + coin.getValue());\n        int price = machine.getSelectedItem().getPrice();\n        if (machine.getBalance() >= price) {\n            System.out.println(\"Sufficient money received.\");\n            machine.setState(new HasMoneyState(machine));\n        }\n    }\n\n    @Override\n    public void selectItem(String code) {\n        System.out.println(\"Item already selected.\");\n    }\n\n    @Override\n    public void dispense() {\n        System.out.println(\"Please insert sufficient money.\");\n    }\n\n    @Override\n    public void refund() {\n        machine.reset();\n        machine.setState(new IdleState(machine));\n    }\n}\n"
  },
  {
    "path": "solutions/java/src/vendingmachine/state/VendingMachineState.java",
    "content": "package vendingmachine.state;\n\nimport vendingmachine.enums.Coin;\nimport vendingmachine.VendingMachine;\n\npublic abstract class VendingMachineState {\n    VendingMachine machine;\n\n    VendingMachineState(VendingMachine machine) {\n        this.machine = machine;\n    }\n\n    public abstract void insertCoin(Coin coin);\n    public abstract void selectItem(String code);\n    public abstract void dispense();\n    public abstract void refund();\n}"
  },
  {
    "path": "solutions/java/src/votingsystem/Candidate.java",
    "content": "package votingsystem;\r\n\r\nclass Candidate {\r\n    private final String id;\r\n    private final String name;\r\n    private final String party;\r\n\r\n    public Candidate(String id, String name, String party) {\r\n        this.id = id;\r\n        this.name = name;\r\n        this.party = party;\r\n    }\r\n\r\n    public String getId() {\r\n        return id;\r\n    }\r\n\r\n    public String getName() {\r\n        return name;\r\n    }\r\n}"
  },
  {
    "path": "solutions/java/src/votingsystem/README.md",
    "content": "# Voting System (LLD)\n\n## Problem Statement\n\nDesign and implement a Voting System that allows voters to cast votes for candidates, ensures each voter can vote only once, and provides the ability to tally and display results.\n\n---\n\n## Requirements\n\n- **Voter Registration:** The system manages a list of eligible voters.\n- **Candidate Registration:** The system manages a list of candidates.\n- **Vote Casting:** Each voter can cast a vote for a candidate, but only once.\n- **Vote Recording:** The system records each vote and prevents duplicate voting.\n- **Result Tallying:** The system can tally votes for each candidate and display the results.\n- **Extensibility:** Easy to add new features such as multiple elections, voting rounds, or different voting methods.\n\n---\n\n## Core Entities\n\n- **VotingSystem:** Main class that manages voters, candidates, vote casting, and result tallying.\n- **Voter:** Represents a voter with a unique ID and name.\n- **Candidate:** Represents a candidate with a unique ID and name.\n- **VoteRecord:** Represents a record of a vote cast by a voter for a candidate.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/votingsystem-class-diagram.png)\n\n### 1. VotingSystem\n\n- **Fields:** Map<Integer, Voter> voters, Map<Integer, Candidate> candidates, Map<Integer, VoteRecord> voteRecords\n- **Methods:** registerVoter(Voter), registerCandidate(Candidate), castVote(int voterId, int candidateId), tallyResults(), displayResults(), hasVoted(int voterId)\n\n### 2. Voter\n\n- **Fields:** int id, String name\n\n### 3. Candidate\n\n- **Fields:** int id, String name\n\n### 4. VoteRecord\n\n- **Fields:** int voterId, int candidateId\n\n---\n\n## Example Usage\n\n```java\nVotingSystem votingSystem = new VotingSystem();\nvotingSystem.registerVoter(new Voter(1, \"Alice\"));\nvotingSystem.registerVoter(new Voter(2, \"Bob\"));\nvotingSystem.registerCandidate(new Candidate(1, \"John\"));\nvotingSystem.registerCandidate(new Candidate(2, \"Jane\"));\n\nvotingSystem.castVote(1, 1); // Alice votes for John\nvotingSystem.castVote(2, 2); // Bob votes for Jane\n\nvotingSystem.displayResults();\n```\n\n---\n\n## Demo\n\nSee `VotingSystemDemo.java` for a sample usage and simulation of the voting system.\n\n---\n\n## Extending the Design\n\n- **Add multiple elections:** Support for different elections or voting rounds.\n- **Add voting methods:** Implement ranked-choice, weighted voting, etc.\n- **Add features:** Such as voter authentication, audit logs, or result export.\n\n---\n"
  },
  {
    "path": "solutions/java/src/votingsystem/VoteRecord.java",
    "content": "package votingsystem;\r\n\r\nimport java.util.Date;\r\n\r\nclass VoteRecord {\r\n    private final String voterId;\r\n    private final String candidateId;\r\n    private final long timestamp;\r\n\r\n    public VoteRecord(String voterId, String candidateId, long timestamp) {\r\n        this.voterId = voterId;\r\n        this.candidateId = candidateId;\r\n        this.timestamp = timestamp;\r\n    }\r\n\r\n    @Override\r\n    public String toString() {\r\n        return \"Vote cast by \" + voterId + \" for candidate \" + candidateId + \r\n               \" at \" + new Date(timestamp);\r\n    }\r\n}"
  },
  {
    "path": "solutions/java/src/votingsystem/Voter.java",
    "content": "package votingsystem;\r\n\r\nclass Voter {\r\n    private final String id;\r\n    private final String name;\r\n    private final String password;\r\n\r\n    public Voter(String id, String name, String password) {\r\n        this.id = id;\r\n        this.name = name;\r\n        this.password = password;\r\n    }\r\n\r\n    public String getId() {\r\n        return id;\r\n    }\r\n\r\n    public String getName() {\r\n        return name;\r\n    }\r\n}"
  },
  {
    "path": "solutions/java/src/votingsystem/VotingSystem.java",
    "content": "package votingsystem;\r\n\r\nimport java.util.*;\r\nimport java.util.concurrent.*;\r\nimport java.util.concurrent.atomic.AtomicInteger;\r\nimport java.util.concurrent.locks.ReadWriteLock;\r\nimport java.util.concurrent.locks.ReentrantReadWriteLock;\r\n\r\npublic class VotingSystem {\r\n    private static volatile VotingSystem instance;\r\n    private final Map<String, Voter> voters;\r\n    private final Map<String, Candidate> candidates;\r\n    private final Map<String, AtomicInteger> voteCount;\r\n    private final Set<String> votedVoters;\r\n    private final ReadWriteLock votingLock;\r\n    private volatile boolean isVotingOpen;\r\n    private final BlockingQueue<VoteRecord> voteAuditLog;\r\n\r\n    private VotingSystem() {\r\n        this.voters = new ConcurrentHashMap<>();\r\n        this.candidates = new ConcurrentHashMap<>();\r\n        this.voteCount = new ConcurrentHashMap<>();\r\n        this.votedVoters = ConcurrentHashMap.newKeySet();\r\n        this.votingLock = new ReentrantReadWriteLock();\r\n        this.voteAuditLog = new LinkedBlockingQueue<>();\r\n        this.isVotingOpen = false;\r\n    }\r\n\r\n    public static VotingSystem getInstance() {\r\n        VotingSystem result = instance;\r\n        if (result == null) {\r\n            synchronized (VotingSystem.class) {\r\n                if (result == null) {\r\n                    instance = result = new VotingSystem();\r\n                }\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n    public void registerVoter(String voterId, String name, String password) {\r\n        Voter voter = new Voter(voterId, name, password);\r\n        voters.putIfAbsent(voterId, voter);\r\n    }\r\n\r\n    public void registerCandidate(String candidateId, String name, String party) {\r\n        Candidate candidate = new Candidate(candidateId, name, party);\r\n        candidates.putIfAbsent(candidateId, candidate);\r\n        voteCount.putIfAbsent(candidateId, new AtomicInteger(0));\r\n    }\r\n\r\n    public void startVoting() {\r\n        votingLock.writeLock().lock();\r\n        try {\r\n            isVotingOpen = true;\r\n            System.out.println(\"Voting has started!\");\r\n        } finally {\r\n            votingLock.writeLock().unlock();\r\n        }\r\n    }\r\n\r\n    public void endVoting() {\r\n        votingLock.writeLock().lock();\r\n        try {\r\n            isVotingOpen = false;\r\n            System.out.println(\"Voting has ended!\");\r\n        } finally {\r\n            votingLock.writeLock().unlock();\r\n        }\r\n    }\r\n\r\n    public boolean castVote(String voterId, String candidateId) {\r\n        votingLock.readLock().lock();\r\n        try {\r\n            if (!isVotingOpen) {\r\n                System.out.println(\"Voting is not open!\");\r\n                return false;\r\n            }\r\n\r\n            Voter voter = voters.get(voterId);\r\n            Candidate candidate = candidates.get(candidateId);\r\n            \r\n            if (voter == null || candidate == null) {\r\n                System.out.println(\"Invalid voter or candidate ID!\");\r\n                return false;\r\n            }\r\n\r\n            if (!votedVoters.add(voterId)) {\r\n                System.out.println(\"Voter has already cast their vote!\");\r\n                return false;\r\n            }\r\n\r\n            voteCount.get(candidateId).incrementAndGet();\r\n            \r\n            voteAuditLog.offer(new VoteRecord(voterId, candidateId, System.currentTimeMillis()));\r\n            \r\n            return true;\r\n        } finally {\r\n            votingLock.readLock().unlock();\r\n        }\r\n    }\r\n\r\n    public Map<String, Integer> getCurrentResults() {\r\n        Map<String, Integer> results = new HashMap<>();\r\n        votingLock.readLock().lock();\r\n        try {\r\n            for (Map.Entry<String, AtomicInteger> entry : voteCount.entrySet()) {\r\n                results.put(candidates.get(entry.getKey()).getName(), \r\n                           entry.getValue().get());\r\n            }\r\n            return results;\r\n        } finally {\r\n            votingLock.readLock().unlock();\r\n        }\r\n    }\r\n\r\n    public List<VoteRecord> getAuditLog() {\r\n        return new ArrayList<>(voteAuditLog);\r\n    }\r\n}"
  },
  {
    "path": "solutions/java/src/votingsystem/VotingSystemDemo.java",
    "content": "package votingsystem;\r\n\r\nimport java.util.*;\r\nimport java.util.concurrent.*;\r\n\r\npublic class VotingSystemDemo {\r\n    public static void run() {\r\n        VotingSystem votingSystem = VotingSystem.getInstance();\r\n\r\n        votingSystem.registerCandidate(\"C1\", \"John Doe\", \"Party A\");\r\n        votingSystem.registerCandidate(\"C2\", \"Jane Smith\", \"Party B\");\r\n\r\n        for (int i = 1; i <= 100; i++) {\r\n            votingSystem.registerVoter(\"V\" + i, \"Voter \" + i, \"pass\" + i);\r\n        }\r\n\r\n        votingSystem.startVoting();\r\n\r\n        ExecutorService executor = Executors.newFixedThreadPool(10);\r\n        List<Future<Boolean>> futures = new ArrayList<>();\r\n\r\n        for (int i = 1; i <= 100; i++) {\r\n            final String voterId = \"V\" + i;\r\n            final String candidateId = \"C\" + ((i % 2) + 1);\r\n\r\n            futures.add(executor.submit(() -> {\r\n                try {\r\n                    Thread.sleep(new Random().nextInt(100));\r\n                    return votingSystem.castVote(voterId, candidateId);\r\n                } catch (InterruptedException e) {\r\n                    Thread.currentThread().interrupt();\r\n                    return false;\r\n                }\r\n            }));\r\n        }\r\n\r\n        for (Future<Boolean> future : futures) {\r\n            try {\r\n                future.get();\r\n            } catch (Exception e) {\r\n                e.printStackTrace();\r\n            }\r\n        }\r\n\r\n        votingSystem.endVoting();\r\n\r\n        Map<String, Integer> results = votingSystem.getCurrentResults();\r\n        System.out.println(\"\\nVoting Results:\");\r\n        results.forEach((candidate, votes) -> \r\n            System.out.println(candidate + \": \" + votes + \" votes\"));\r\n\r\n        System.out.println(\"\\nAudit Log:\");\r\n        votingSystem.getAuditLog().forEach(System.out::println);\r\n\r\n        executor.shutdown();\r\n    }\r\n}"
  },
  {
    "path": "solutions/java/test/coffeevendingmachine/CoffeeVendingMachineTest.java",
    "content": "package coffeevendingmachine;\n\nimport org.junit.jupiter.api.BeforeEach;\nimport org.junit.jupiter.api.Test;\nimport org.junit.jupiter.api.DisplayName;\n\nimport static org.junit.jupiter.api.Assertions.*;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.PrintStream;\nimport java.util.Map;\n\npublic class CoffeeVendingMachineTest {\n\n    private CoffeeVendingMachine machine;\n    private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n    private final PrintStream originalOut = System.out;\n\n    @BeforeEach\n    void setUp() {\n        machine = CoffeeVendingMachine.getInstance();\n        System.setOut(new PrintStream(outputStream));\n\n        // Reset and refill ingredients for each test\n        machine.refillIngredient(\"Water\", 150);\n        machine.refillIngredient(\"Coffee\", 100);\n        machine.refillIngredient(\"Milk\", 100);\n    }\n\n    @Test\n    @DisplayName(\"Test coffee selection\")\n    void testSelectCoffee() {\n        CoffeeRecipe espresso = machine.selectCoffee(\"Espresso\");\n        assertEquals(\"Espresso\", espresso.getName());\n        assertEquals(2.5, espresso.getPrice());\n        assertEquals(50, espresso.getRecipe().get(\"Water\"));\n        assertEquals(20, espresso.getRecipe().get(\"Coffee\"));\n    }\n\n    @Test\n    @DisplayName(\"Test invalid coffee selection\")\n    void testInvalidCoffeeSelection() {\n        Exception exception = assertThrows(RuntimeException.class, () -> {\n            machine.selectCoffee(\"MochaCoffee\");\n        });\n\n        String expectedMessage = \"Invalid coffee recipe: MochaCoffee\";\n        String actualMessage = exception.getMessage();\n\n        assertTrue(actualMessage.contains(expectedMessage));\n    }\n\n    @Test\n    @DisplayName(\"Test successful coffee dispensing\")\n    void testDispenseCoffee() {\n        CoffeeRecipe latte = machine.selectCoffee(\"Latte\");\n        machine.dispenseCoffee(latte, new Payment(4.0));\n\n        String output = outputStream.toString();\n        assertTrue(output.contains(\"Dispensing: Latte\"));\n        assertTrue(output.contains(\"Processing Payment\"));\n        assertTrue(output.contains(\"Please collect your change: $1.0\"));\n    }\n\n    @Test\n    @DisplayName(\"Test insufficient payment\")\n    void testInsufficientPayment() {\n        CoffeeRecipe cappuccino = machine.selectCoffee(\"Cappuccino\");\n\n        Exception exception = assertThrows(RuntimeException.class, () -> {\n            machine.dispenseCoffee(cappuccino, new Payment(2.0));\n        });\n\n        String expectedMessage = \"Insufficient payment for Cappuccino\";\n        String actualMessage = exception.getMessage();\n\n        assertTrue(actualMessage.contains(expectedMessage));\n    }\n\n\n\n    @Test\n    @DisplayName(\"Test ingredient consumption\")\n    void testIngredientConsumption() {\n        CoffeeRecipe latte = machine.selectCoffee(\"Latte\");\n\n        // Check initial levels\n        Map<String, Integer> beforeLevels = machine.showIngredientsMap();\n        int initialWaterLevel = beforeLevels.get(\"Water\");\n        int initialCoffeeLevel = beforeLevels.get(\"Coffee\");\n        int initialMilkLevel = beforeLevels.get(\"Milk\");\n\n        machine.dispenseCoffee(latte, new Payment(3.0));\n\n        // Check levels after dispensing\n        Map<String, Integer> afterLevels = machine.showIngredientsMap();\n        assertEquals(initialWaterLevel - 50, afterLevels.get(\"Water\").intValue());\n        assertEquals(initialCoffeeLevel - 20, afterLevels.get(\"Coffee\").intValue());\n        assertEquals(initialMilkLevel - 30, afterLevels.get(\"Milk\").intValue());\n    }\n\n    @Test\n    @DisplayName(\"Test ingredient refill\")\n    void testIngredientRefill() {\n        // First check initial level\n        Map<String, Integer> beforeLevels = machine.showIngredientsMap();\n        int initialWaterLevel = beforeLevels.get(\"Water\");\n\n        // Add more water\n        machine.refillIngredient(\"Water\", 50);\n\n        // Check after refill\n        Map<String, Integer> afterLevels = machine.showIngredientsMap();\n        assertEquals(initialWaterLevel + 50, afterLevels.get(\"Water\").intValue());\n    }\n}\n"
  },
  {
    "path": "solutions/python/.gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\ncover/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\n.pybuilder/\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n#   For a library or package, you might want to ignore these files since the code is\n#   intended to run in multiple environments; otherwise, check them in:\n# .python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# UV\n#   Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\n#uv.lock\n\n# poetry\n#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.\n#   This is especially recommended for binary packages to ensure reproducibility, and is more\n#   commonly ignored for libraries.\n#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control\n#poetry.lock\n\n# pdm\n#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.\n#pdm.lock\n#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it\n#   in version control.\n#   https://pdm.fming.dev/latest/usage/project/#working-with-version-control\n.pdm.toml\n.pdm-python\n.pdm-build/\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n\n# pytype static type analyzer\n.pytype/\n\n# Cython debug symbols\ncython_debug/\n\n# PyCharm\n#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can\n#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore\n#  and can be added to the global gitignore or merged into this file.  For a more nuclear\n#  option (not recommended) you can uncomment the following to ignore the entire idea folder.\n#.idea/\n\n# Ruff stuff:\n.ruff_cache/\n\n# PyPI configuration file\n.pypirc"
  },
  {
    "path": "solutions/python/airlinemanagementsystem/README.md",
    "content": "# Designing an Airline Management System\n\n## Requirements\n1. The airline management system should allow users to search for flights based on source, destination, and date.\n2. Users should be able to book flights, select seats, and make payments.\n3. The system should manage flight schedules, aircraft assignments, and crew assignments.\n4. The system should handle passenger information, including personal details and baggage information.\n5. The system should support different types of users, such as passengers, airline staff, and administrators.\n6. The system should be able to handle cancellations, refunds, and flight changes.\n7. The system should ensure data consistency and handle concurrent access to shared resources.\n8. The system should be scalable and extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Flight** class represents a flight in the airline management system, with properties such as flight number, source, destination, departure time, arrival time, and available seats.\n2. The **Aircraft** class represents an aircraft, with properties like tail number, model, and total seats.\n3. The **Passenger** class represents a passenger, with properties such as ID, name, email, and phone number.\n4. The **Booking** class represents a booking made by a passenger for a specific flight and seat, with properties such as booking number, flight, passenger, seat, price, and booking status.\n5. The **Seat** class represents a seat on a flight, with properties like seat number, seat type, and seat status.\n6. The **Payment** class represents a payment made for a booking, with properties such as payment ID, payment method, amount, and payment status.\n7. The **FlightSearch** class provides functionality to search for flights based on source, destination, and date.\n8. The **BookingManager** class manages the creation and cancellation of bookings. It follows the Singleton pattern to ensure a single instance of the booking manager.\n9. The **PaymentProcessor** class handles the processing of payments. It follows the Singleton pattern to ensure a single instance of the payment processor.\n10. The **AirlineManagementSystem** class serves as the main entry point of the system, combining all the components and providing methods for flight management, booking, payment processing, and other operations."
  },
  {
    "path": "solutions/python/atm/README.md",
    "content": "# Designing an ATM System\n\n## Requirements\n1. The ATM system should support basic operations such as balance inquiry, cash withdrawal, and cash deposit.\n2. Users should be able to authenticate themselves using a card and a PIN (Personal Identification Number).\n3. The system should interact with a bank's backend system to validate user accounts and perform transactions.\n4. The ATM should have a cash dispenser to dispense cash to users.\n5. The system should handle concurrent access and ensure data consistency.\n6. The ATM should have a user-friendly interface for users to interact with.\n\n## Classes, Interfaces and Enumerations\n1. The **Card** class represents an ATM card with a card number and PIN.\n2. The **Account** class represents a bank account with an account number and balance. It provides methods to debit and credit the account balance.\n3. The **Transaction** class is an abstract base class for different types of transactions, such as withdrawal and deposit. It is extended by WithdrawalTransaction and DepositTransaction classes.\n4. The **BankingService** class manages the bank accounts and processes transactions. It uses a thread-safe ConcurrentHashMap to store and retrieve account information.\n5. The **CashDispenser** class represents the ATM's cash dispenser and handles the dispensing of cash. It uses synchronization to ensure thread safety when dispensing cash.\n6. The **ATM** class serves as the main interface for ATM operations. It interacts with the BankingService and CashDispenser to perform user authentication, balance inquiry, cash withdrawal, and cash deposit.\n7. The **ATMDriver** class demonstrates the usage of the ATM system by creating sample accounts and performing ATM operations."
  },
  {
    "path": "solutions/python/carrentalsystem/README.md",
    "content": "# Designing a Car Rental System\n\n## Requirements\n1. The car rental system should allow customers to browse and reserve available cars for specific dates.\n2. Each car should have details such as make, model, year, license plate number, and rental price per day.\n3. Customers should be able to search for cars based on various criteria, such as car type, price range, and availability.\n4. The system should handle reservations, including creating, modifying, and canceling reservations.\n5. The system should keep track of the availability of cars and update their status accordingly.\n6. The system should handle customer information, including name, contact details, and driver's license information.\n7. The system should handle payment processing for reservations.\n8. The system should be able to handle concurrent reservations and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Car** class represents a car in the rental system, with properties such as make, model, year, license plate number, rental price per day, and availability status.\n2. The **Customer** class represents a customer, with properties like name, contact information, and driver's license number.\n3. The **Reservation** class represents a reservation made by a customer for a specific car and date range. It includes properties such as reservation ID, customer, car, start date, end date, and total price.\n4. The **PaymentProcessor** interface defines the contract for payment processing, and the CreditCardPaymentProcessor and PayPalPaymentProcessor classes are concrete implementations of the payment processor.\n5. The **RentalSystem** class is the core of the car rental system and follows the Singleton pattern to ensure a single instance of the rental system.\n6. The RentalSystem class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to cars and reservations.\n7. The **RentalSystem** class provides methods for adding and removing cars, searching for available cars based on criteria, making reservations, canceling reservations, and processing payments.\n8. The **CarRentalSystem** class serves as the entry point of the application and demonstrates the usage of the car rental system."
  },
  {
    "path": "solutions/python/chessgame/README.md",
    "content": "# Designing a Chess Game\n\n## Requirements\n1. The chess game should follow the standard rules of chess.\n2. The game should support two players, each controlling their own set of pieces.\n3. The game board should be represented as an 8x8 grid, with alternating black and white squares.\n4. Each player should have 16 pieces: 1 king, 1 queen, 2 rooks, 2 bishops, 2 knights, and 8 pawns.\n5. The game should validate legal moves for each piece and prevent illegal moves.\n6. The game should detect checkmate and stalemate conditions.\n7. The game should handle player turns and allow players to make moves alternately.\n8. The game should provide a user interface for players to interact with the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Piece** class is an abstract base class representing a chess piece. It contains common attributes such as color, row, and column, and declares an abstract method canMove to be implemented by each specific piece class.\n2. The **King**, **Queen**, **Rook**, **Bishop**, **Knight**, and **Pawn** classes extend the Piece class and implement their respective movement logic in the canMove method.\n3. The **Board** class represents the chess board and manages the placement of pieces. It provides methods to get and set pieces on the board, check the validity of moves, and determine checkmate and stalemate conditions.\n4. The **Player** class represents a player in the game and has a method to make a move on the board.\n5. The Move class represents a move made by a player, containing the piece being moved and the destination coordinates.\n6. The **Game** class orchestrates the overall game flow. It initializes the board, handles player turns, and determines the game result.\n7. The **ChessGame** class is the entry point of the application and starts the game."
  },
  {
    "path": "solutions/python/coffeevendingmachine/README.md",
    "content": "# Designing a Coffee Vending Machine\n\n## Requirements\n1. The coffee vending machine should support different types of coffee, such as espresso, cappuccino, and latte.\n2. Each type of coffee should have a specific price and recipe (ingredients and their quantities).\n3. The machine should have a menu to display the available coffee options and their prices.\n4. Users should be able to select a coffee type and make a payment.\n5. The machine should dispense the selected coffee and provide change if necessary.\n6. The machine should track the inventory of ingredients and notify when they are running low.\n7. The machine should handle multiple user requests concurrently and ensure thread safety.\n\n## Classes, Interfaces and Enumerations\n1. The **Coffee** class represents a coffee type with its name, price, and recipe (ingredients and their quantities).\n2. The **Ingredient** class represents an ingredient used in making coffee, with its name and quantity. It provides a synchronized method to update the quantity.\n3. The **Payment** class represents a payment made by a user, with the amount paid.\n4. The **CoffeeMachine** class is the main class that manages the coffee vending machine. It follows the Singleton pattern to ensure a single instance of the machine.\n5. The **CoffeeMachine** class initializes the coffee menu and ingredients in its constructor. It provides methods to display the menu, select a coffee, dispense coffee, and update ingredient quantities.\n6. The hasEnoughIngredients method checks if there are sufficient ingredients to make a selected coffee, while the updateIngredients method updates the ingredient quantities after dispensing a coffee.\n7. The **CoffeeVendingMachine** class is the entry point of the application and demonstrates the usage of the coffee vending machine. It creates an instance of the machine, displays the menu, and simulates concurrent user requests using an ExecutorService."
  },
  {
    "path": "solutions/python/concertticketbookingsystem/README.md",
    "content": "# Designing a Concert Ticket Booking System\n\n## Requirements\n1. The concert ticket booking system should allow users to view available concerts and their seating arrangements.\n2. Users should be able to search for concerts based on various criteria such as artist, venue, date, and time.\n3. Users should be able to select seats and purchase tickets for a specific concert.\n4. The system should handle concurrent booking requests to avoid double-booking of seats.\n5. The system should ensure fair booking opportunities for all users.\n6. The system should handle payment processing securely.\n7. The system should generate booking confirmations and send them to users via email or SMS.\n8. The system should provide a waiting list functionality for sold-out concerts.\n\n## Classes, Interfaces and Enumerations\n1. The **Concert** class represents a concert event, with properties such as ID, artist, venue, date and time, and a list of seats.\n2. The **Seat** class represents a seat in a concert, with properties like ID, seat number, seat type, price, and status. It provides methods to book and release a seat.\n3. The **SeatType** enum represents the different types of seats available, such as regular, premium, and VIP.\n4. The **SeatStatus** enum represents the status of a seat, which can be available, booked, or reserved.\n5. The **Booking** class represents a booking made by a user for a specific concert and seats. It contains properties such as ID, user, concert, seats, total price, and status. It provides methods to confirm and cancel a booking.\n6. The **BookingStatus** enum represents the status of a booking, which can be pending, confirmed, or cancelled.\n7. The **User** class represents a user of the concert ticket booking system, with properties like ID, name, and email.\n8. The **ConcertTicketBookingSystem** class is the central component of the system. It follows the Singleton pattern to ensure a single instance of the system. It manages concerts, bookings, and provides methods to add concerts, search concerts, book tickets, and cancel bookings.\n9. The **SeatNotAvailableException** is a custom exception used to handle cases where a seat is not available for booking."
  },
  {
    "path": "solutions/python/courseregistrationsystem/README.md",
    "content": "# Designing a University Course Registration System\n\n## Requirements\n1. The course registration system should allow students to register for courses and view their registered courses.\n2. Each course should have a course code, name, instructor, and maximum enrollment capacity.\n3. Students should be able to search for courses based on course code or name.\n4. The system should prevent students from registering for courses that have reached their maximum enrollment capacity.\n5. The system should handle concurrent registration requests from multiple students.\n6. The system should ensure data consistency and prevent race conditions.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Student** class represents a student in the course registration system, with properties such as ID, name, email, and a list of registered courses.\n2. The **Course** class represents a course offered in the system, with properties such as code, name, instructor, maximum capacity, and the number of enrolled students.\n3. The **Registration** class represents a registration record, associating a student with a course and capturing the registration timestamp.\n4. The **CourseRegistrationSystem** class is the main class that manages the course registration system. It follows the Singleton pattern to ensure only one instance of the system exists.\n5. The CourseRegistrationSystem class provides methods for adding courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student.\n6. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as courses and registrations.\n7. The registerCourse method is synchronized to ensure thread safety when multiple students are registering for courses simultaneously.\n8. The notifyObservers method is a placeholder for notifying observers (e.g., UI components) about updates to course enrollment.\n9. The **CourseRegistrationDemo** class demonstrates the usage of the course registration system by creating courses and students, searching for courses, registering students for courses, and retrieving registered courses for a student."
  },
  {
    "path": "solutions/python/cricinfo/README.md",
    "content": "# Designing a Cricket Information System like CricInfo\n\n## Requirements\n1. The Cricinfo system should provide information about cricket matches, teams, players, and live scores.\n2. Users should be able to view the schedule of upcoming matches and the results of completed matches.\n3. The system should allow users to search for specific matches, teams, or players.\n4. Users should be able to view detailed information about a particular match, including the scorecard, commentary, and statistics.\n5. The system should support real-time updates of live scores and match information.\n6. The system should handle concurrent access to match data and ensure data consistency.\n7. The system should be scalable and able to handle a large volume of user requests.\n8. The system should be extensible to accommodate new features and enhancements in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **Match** class represents a cricket match, with properties such as ID, title, venue, start time, teams, status, and scorecard.\n2. The **Team** class represents a cricket team, with properties like ID, name, and a list of players.\n3. The **Player** class represents a cricket player, with properties such as ID, name, and role.\n4. The **Scorecard** class represents the scorecard of a match, containing team scores and a list of innings.\n5. The **Innings** class represents an innings in a match, with properties like ID, batting team, bowling team, and a list of overs.\n6. The **Over** class represents an over in an innings, containing a list of balls.\n7. The **Ball** class represents a ball bowled in an over, with properties such as ball number, bowler, batsman, and result.\n8. The **MatchStatus** enum represents the different statuses of a match, such as scheduled, in progress, completed, or abandoned.\n9. The **MatchService** class manages the matches in the system, providing methods to add, retrieve, and update match information. It follows the Singleton pattern to ensure a single instance of the service.\n10. The **ScorecardService** class manages the scorecards of matches, allowing the creation, retrieval, and update of scorecards and their associated data, such as innings and scores. It also follows the Singleton pattern.\n11. The **CricinfoSystem** class serves as the main entry point of the system, integrating the match and scorecard services and providing high-level methods for interacting with the system."
  },
  {
    "path": "solutions/python/digitalwalletservice/README.md",
    "content": "# Designing a Digital Wallet System\n\n## Requirements\n1. The digital wallet should allow users to create an account and manage their personal information.\n2. Users should be able to add and remove payment methods, such as credit cards or bank accounts.\n3. The digital wallet should support fund transfers between users and to external accounts.\n4. The system should handle transaction history and provide a statement of transactions.\n5. The digital wallet should support multiple currencies and perform currency conversions.\n6. The system should ensure the security of user information and transactions.\n7. The digital wallet should handle concurrent transactions and ensure data consistency.\n8. The system should be scalable to handle a large number of users and transactions.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the digital wallet, with properties such as ID, name, email, password, and a list of accounts.\n2. The **Account** class represents a user's account within the digital wallet, with properties like ID, user, account number, currency, balance, and a list of transactions. It provides methods to deposit and withdraw funds.\n3. The **Transaction** class represents a financial transaction between two accounts, containing properties such as ID, source account, destination account, amount, currency, and timestamp.\n4. The **PaymentMethod** class is an abstract base class for different payment methods, such as credit cards and bank accounts. It defines the common properties and methods for processing payments.\n5. The **CreditCard** and **BankAccount** classes are concrete implementations of the PaymentMethod class, representing specific payment methods.\n6. The **Currency** enum represents different currencies supported by the digital wallet.\n7. The **CurrencyConverter** class provides a static method to convert amounts between different currencies based on predefined exchange rates.\n8. The **DigitalWallet** class is the central component of the digital wallet system. It follows the Singleton pattern to ensure only one instance of the digital wallet exists. It provides methods to create users, accounts, add payment methods, transfer funds, and retrieve transaction history. It handles concurrent access to shared resources using synchronization.\n9. The **DigitalWalletDemo** class demonstrates the usage of the digital wallet system by creating users, accounts, adding payment methods, depositing funds, transferring funds, and retrieving transaction history."
  },
  {
    "path": "solutions/python/elevatorsystem/README.md",
    "content": "# Designing an Elevator System\n\n## Requirements\n1. The elevator system should consist of multiple elevators serving multiple floors.\n2. Each elevator should have a capacity limit and should not exceed it.\n3. Users should be able to request an elevator from any floor and select a destination floor.\n4. The elevator system should efficiently handle user requests and optimize the movement of elevators to minimize waiting time.\n5. The system should prioritize requests based on the direction of travel and the proximity of the elevators to the requested floor.\n6. The elevators should be able to handle multiple requests concurrently and process them in an optimal order.\n7. The system should ensure thread safety and prevent race conditions when multiple threads interact with the elevators.\n\n## Classes, Interfaces and Enumerations\n1. The **Direction** enum represents the possible directions of elevator movement (UP or DOWN).\n2. The **Request** class represents a user request for an elevator, containing the source floor and destination floor.\n3. The **Elevator** class represents an individual elevator in the system. It has a capacity limit and maintains a list of 4. requests. The elevator processes requests concurrently and moves between floors based on the requests.\n4. The **ElevatorController** class manages multiple elevators and handles user requests. It finds the optimal elevator to serve a request based on the proximity of the elevators to the requested floor.\n5. The **ElevatorSystem** class is the entry point of the application and demonstrates the usage of the elevator system."
  },
  {
    "path": "solutions/python/fooddeliveryservice/README.md",
    "content": "# Designing an Online Food Delivery Service Like Swiggy\n\n## Requirements\n1. The food delivery service should allow customers to browse restaurants, view menus, and place orders.\n2. Restaurants should be able to manage their menus, prices, and availability.\n3. Delivery agents should be able to accept and fulfill orders.\n4. The system should handle order tracking and status updates.\n5. The system should support multiple payment methods.\n6. The system should handle concurrent orders and ensure data consistency.\n7. The system should be scalable and handle a high volume of orders.\n8. The system should provide real-time notifications to customers, restaurants, and delivery agents.\n\n## Classes, Interfaces and Enumerations\n1. The **Customer** class represents a customer who can place orders. It contains customer details such as ID, name, email, and phone number.\n2. The **Restaurant** class represents a restaurant that offers menu items. It contains restaurant details such as ID, name, address, and a list of menu items. It provides methods to add and remove menu items.\n3. The **MenuItem** class represents an item on a restaurant's menu. It contains details such as ID, name, description, price, and availability status.\n4. The **Order** class represents an order placed by a customer. It contains order details such as ID, customer, restaurant, list of order items, status, and assigned delivery agent. It provides methods to add and remove order items, update order status, and assign a delivery agent.\n5. The **OrderItem** class represents an item within an order. It contains the selected menu item and the quantity ordered.\n6. The **OrderStatus** enum represents the different statuses an order can have, such as PENDING, CONFIRMED, PREPARING, OUT_FOR_DELIVERY, DELIVERED, and CANCELLED.\n7. The **DeliveryAgent** class represents a delivery agent who fulfills orders. It contains details such as ID, name, phone number, and availability status.\n8. The **FoodDeliveryService** class is the main class that manages the food delivery service. It follows the Singleton pattern to ensure only one instance of the service exists. It provides methods to register customers, restaurants, and delivery agents, retrieve available restaurants and menus, place orders, update order status, cancel orders, and assign delivery agents to orders. It also handles notifications to customers, restaurants, and delivery agents."
  },
  {
    "path": "solutions/python/hotelmanagementsystem/README.md",
    "content": "# Designing a Hotel Management System\n\n## Requirements\n1. The hotel management system should allow guests to book rooms, check-in, and check-out.\n2. The system should manage different types of rooms, such as single, double, deluxe, and suite.\n3. The system should handle room availability and reservation status.\n4. The system should allow the hotel staff to manage guest information, room assignments, and billing.\n5. The system should support multiple payment methods, such as cash, credit card, and online payment.\n6. The system should handle concurrent bookings and ensure data consistency.\n7. The system should provide reporting and analytics features for hotel management.\n8. The system should be scalable and handle a large number of rooms and guests.\n\n## Classes, Interfaces and Enumerations\n1. The **Guest** class represents a guest of the hotel, with properties such as ID, name, email, and phone number.\n2. The **Room** class represents a room in the hotel, with properties like ID, room type, price, and status. It provides methods to book, check-in, and check-out a room.\n3. The **RoomType** enum represents the different types of rooms available in the hotel.\n4. The **RoomStatus** enum represents the status of a room, which can be available, booked, or occupied.\n5. The **Reservation** class represents a reservation made by a guest for a specific room and date range. It contains properties such as ID, guest, room, check-in date, check-out date, and status. It provides a method to cancel a reservation.\n6. The **ReservationStatus** enum represents the status of a reservation, which can be confirmed or cancelled.\n7. The **Payment** interface defines the contract for processing payments. It is implemented by concrete payment classes like CashPayment and CreditCardPayment.\n8. The **HotelManagementSystem** class is the central component of the hotel management system. It follows the Singleton pattern to ensure only one instance of the system exists. It provides methods to add guests and rooms, book rooms, cancel reservations, check-in, check-out, and process payments. It also handles concurrent access to shared resources using synchronization.\n9. The **HotelManagementSystemDemo** class demonstrates the usage of the hotel management system by creating guests, rooms, booking a room, checking in, checking out, and cancelling a reservation."
  },
  {
    "path": "solutions/python/librarymanagementsystem/README.md",
    "content": "# Designing a Library Management System\n\n## Requirements\n1. The library management system should allow librarians to manage books, members, and borrowing activities.\n2. The system should support adding, updating, and removing books from the library catalog.\n3. Each book should have details such as title, author, ISBN, publication year, and availability status.\n4. The system should allow members to borrow and return books.\n5. Each member should have details such as name, member ID, contact information, and borrowing history.\n6. The system should enforce borrowing rules, such as a maximum number of books that can be borrowed at a time and loan duration.\n7. The system should handle concurrent access to the library catalog and member records.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **Book** class represents a book in the library catalog, with properties such as ISBN, title, author, publication year, and availability status.\n2. The **Member** class represents a library member, with properties like member ID, name, contact information, and a list of borrowed books.\n3. The **LibraryManager** class is the core of the library management system and follows the Singleton pattern to ensure a single instance of the library manager.\n4. The LibraryManager class uses concurrent data structures (ConcurrentHashMap) to handle concurrent access to the library catalog and member records.\n5. The LibraryManager class provides methods for adding and removing books, registering and unregistering members, borrowing and returning books, and searching for books based on keywords.\n6. The **LibraryManagementSystemDemo** class serves as the entry point of the application and demonstrates the usage of the library management system."
  },
  {
    "path": "solutions/python/linkedin/README.md",
    "content": "# Designing a Professional Networking Platform like LinkedIn\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their professional information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their professional information, such as profile picture, headline, summary, experience, education, and skills.\n- Users should be able to update their profile information.\n#### Connections:\n- Users should be able to send connection requests to other users.\n- Users should be able to accept or decline connection requests.\n- Users should be able to view their list of connections.\n#### Messaging:\n- Users should be able to send messages to their connections.\n- Users should be able to view their inbox and sent messages.\n#### Job Postings:\n- Employers should be able to post job listings with details such as title, description, requirements, and location.\n- Users should be able to view and apply for job postings.\n#### Search Functionality:\n- Users should be able to search for other users, companies, and job postings based on relevant criteria.\n- Search results should be ranked based on relevance and user preferences.\n#### Notifications:\n- Users should receive notifications for events such as connection requests, messages, and job postings.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the LinkedIn system, containing properties such as ID, name, email, password, profile, connections, inbox, and sent messages.\n2. The **Profile** class represents a user's profile, containing properties such as profile picture, headline, summary, experiences, educations, and skills.\n3. The **Experience**, **Education**, and **Skill** classes represent different components of a user's profile.\n4. The **Connection** class represents a connection between two users, containing the user and the connection date.\n5. The **Message** class represents a message sent between users, containing properties such as ID, sender, receiver, content, and timestamp.\n6. The **JobPosting** class represents a job listing posted by an employer, containing properties such as ID, title, description, requirements, location, and post date.\n7. The **Notification** class represents a notification generated for a user, containing properties such as ID, user, notification type, content, and timestamp.\n8. The **NotificationType** enum defines the different types of notifications, such as connection request, message, and job posting.\n9. The **LinkedInService** class is the main class that manages the LinkedIn system. It follows the Singleton pattern to ensure only one instance of the service exists.\n10. The **LinkedInService** class provides methods for user registration, login, profile updates, connection requests, job postings, user and job search, messaging, and notifications.\n11. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n12. The **LinkedInDemo** class demonstrates the usage of the LinkedIn system by registering users, logging in, updating profiles, sending connection requests, posting job listings, searching for users and jobs, sending messages, and retrieving notifications."
  },
  {
    "path": "solutions/python/loggingframework/README.md",
    "content": "# Designing a Logging Framework\n\n## Requirements\n1. The logging framework should support different log levels, such as DEBUG, INFO, WARNING, ERROR, and FATAL.\n2. It should allow logging messages with a timestamp, log level, and message content.\n3. The framework should support multiple output destinations, such as console, file, and database.\n4. It should provide a configuration mechanism to set the log level and output destination.\n5. The logging framework should be thread-safe to handle concurrent logging from multiple threads.\n6. It should be extensible to accommodate new log levels and output destinations in the future.\n\n## Classes, Interfaces and Enumerations\n1. The **LogLevel** enum defines the different log levels supported by the logging framework.\n2. The **LogMessage** class represents a log message with a timestamp, log level, and message content.\n3. The **LogAppender** interface defines the contract for appending log messages to different output destinations.\n4. The **ConsoleAppender**, **FileAppender**, and **DatabaseAppender** classes are concrete implementations of the LogAppender interface, supporting logging to the console, file, and database, respectively.\n5. The **LoggerConfig** class holds the configuration settings for the logger, including the log level and the selected log appender.\n6. The **Logger** class is a singleton that provides the main logging functionality. It allows setting the configuration, logging messages at different levels, and provides convenience methods for each log level.\n7. The **LoggingExample** class demonstrates the usage of the logging framework, showcasing different log levels, changing the configuration, and logging from multiple threads."
  },
  {
    "path": "solutions/python/lrucache/README.md",
    "content": "# Designing a LRU Cache\n\n## Requirements\n1. The LRU cache should support the following operations:\n- put(key, value): Insert a key-value pair into the cache. If the cache is at capacity, remove the least recently used item before inserting the new item.\n- get(key): Get the value associated with the given key. If the key exists in the cache, move it to the front of the cache (most recently used) and return its value. If the key does not exist, return -1.\n2. The cache should have a fixed capacity, specified during initialization.\n3. The cache should be thread-safe, allowing concurrent access from multiple threads.\n4. The cache should be efficient in terms of time complexity for both put and get operations, ideally O(1).\n\n## Classes, Interfaces and Enumerations\n1. The **Node** class represents a node in the doubly linked list, containing the key, value, and references to the previous and next nodes.\n2. The **LRUCache** class implements the LRU cache functionality using a combination of a hash map (cache) and a doubly linked list (head and tail).\n3. The get method retrieves the value associated with a given key. If the key exists in the cache, it is moved to the head of the linked list (most recently used) and its value is returned. If the key does not exist, null is returned.\n4. The put method inserts a key-value pair into the cache. If the key already exists, its value is updated, and the node is moved to the head of the linked list. If the key does not exist and the cache is at capacity, the least recently used item (at the tail of the linked list) is removed, and the new item is inserted at the head.\n5. The addToHead, removeNode, moveToHead, and removeTail methods are helper methods to manipulate the doubly linked list.\n6. The synchronized keyword is used on the get and put methods to ensure thread safety, allowing concurrent access from multiple threads.\n7. The **LRUCacheDemo** class demonstrates the usage of the LRU cache by creating an instance of LRUCache with a capacity of 3, performing various put and get operations, and printing the results."
  },
  {
    "path": "solutions/python/movieticketbookingsystem/README.md",
    "content": "# Designing a Movie Ticket Booking System like BookMyShow\n\n## Requirements\n1. The system should allow users to view the list of movies playing in different theaters.\n2. Users should be able to select a movie, theater, and show timing to book tickets.\n3. The system should display the seating arrangement of the selected show and allow users to choose seats.\n4. Users should be able to make payments and confirm their booking.\n5. The system should handle concurrent bookings and ensure seat availability is updated in real-time.\n6. The system should support different types of seats (e.g., normal, premium) and pricing.\n7. The system should allow theater administrators to add, update, and remove movies, shows, and seating arrangements.\n8. The system should be scalable to handle a large number of concurrent users and bookings.\n\n## Classes, Interfaces and Enumerations\n1. The **Movie** class represents a movie with properties such as ID, title, description, and duration.\n2. The **Theater** class represents a theater with properties such as ID, name, location, and a list of shows.\n3. The **Show** class represents a movie show in a theater, with properties such as ID, movie, theater, start time, end time, and a map of seats.\n4. The **Seat** class represents a seat in a show, with properties such as ID, row, column, type, price, and status.\n5. The **SeatType** enum defines the different types of seats (normal or premium).\n6. The **SeatStatus** enum defines the different statuses of a seat (available or booked).\n7. The **Booking** class represents a booking made by a user, with properties such as ID, user, show, selected seats, total price, and status.\n8. The **BookingStatus** enum defines the different statuses of a booking (pending, confirmed, or cancelled).\n9. The **User** class represents a user of the booking system, with properties such as ID, name, and email.\n10. The **MovieTicketBookingSystem** class is the main class that manages the movie ticket booking system. It follows the Singleton pattern to ensure only one instance of the system exists.\n11. The MovieTicketBookingSystem class provides methods for adding movies, theaters, and shows, as well as booking tickets, confirming bookings, and cancelling bookings.\n12. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap to handle concurrent access to shared resources like shows and bookings.\n13. The **MovieTicketBookingDemo** class demonstrates the usage of the movie ticket booking system by adding movies, theaters, shows, booking tickets, and confirming or cancelling bookings."
  },
  {
    "path": "solutions/python/musicstreamingservice/README.md",
    "content": "# Designing an Online Music Streaming Service Like Spotify\n\n## Requirements\n1. The music streaming service should allow users to browse and search for songs, albums, and artists.\n2. Users should be able to create and manage playlists.\n3. The system should support user authentication and authorization.\n4. Users should be able to play, pause, skip, and seek within songs.\n5. The system should recommend songs and playlists based on user preferences and listening history.\n6. The system should handle concurrent requests and ensure smooth streaming experience for multiple users.\n7. The system should be scalable and handle a large volume of songs and users.\n8. The system should be extensible to support additional features such as social sharing and offline playback.\n\n## Classes, Interfaces and Enumerations\n1. The **Song**, **Album**, and **Artist** classes represent the basic entities in the music streaming service, with properties such as ID, title, artist, album, duration, and relationships between them.\n2. The **User** class represents a user of the music streaming service, with properties like ID, username, password, and a list of playlists.\n3. The **Playlist** class represents a user-created playlist, containing a list of songs.\n4. The **MusicLibrary** class serves as a central repository for storing and managing songs, albums, and artists. It follows the Singleton pattern to ensure a single instance of the music library.\n5. The **UserManager** class handles user registration, login, and other user-related operations. It also follows the Singleton pattern.\n6. The **MusicPlayer** class represents the music playback functionality, allowing users to play, pause, skip, and seek within songs.\n7. The **MusicRecommender** class generates song recommendations based on user preferences and listening history. It follows the Singleton pattern.\n8. The **MusicStreamingService** class is the main entry point of the music streaming service. It initializes the necessary components, handles user requests, and manages the overall functionality of the service."
  },
  {
    "path": "solutions/python/onlineauctionsystem/README.md",
    "content": "# Designing an Online Auction System\nIn this article, we delve into the object-oriented design and implementation of an Online Auction System using Java. \n\nThis system allows for the creation and management of auctions, user participation in bidding, and handling transactions.\n\n## Requirements\n1. The online auction system should allow users to register and log in to their accounts.\n2. Users should be able to create new auction listings with details such as item name, description, starting price, and auction duration.\n3. Users should be able to browse and search for auction listings based on various criteria (e.g., item name, category, price range).\n4. Users should be able to place bids on active auction listings.\n5. The system should automatically update the current highest bid and notify the bidders accordingly.\n6. The auction should end when the specified duration is reached, and the highest bidder should be declared the winner.\n7. The system should handle concurrent access to auction listings and ensure data consistency.\n8. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the online auction system, with properties such as id, username, and email.\n2. The **AuctionStatus** enum defines the possible states of an auction listing, such as active and closed.\n3. The **AuctionListing** class represents an auction listing in the system, with properties like id, item name, description, starting price, duration, seller, current highest bid, and a list of bids.\n4. The **Bid** class represents a bid placed by a user on an auction listing, with properties such as id, bidder, amount, and timestamp.\n5. The **AuctionSystem** class is the core of the online auction system and follows the Singleton pattern to ensure a single instance of the auction system.\n6. The AuctionSystem class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to auction listings and ensure thread safety.\n7. The AuctionSystem class provides methods for registering users, creating auction listings, searching auction listings, and placing bids.\n8. The **AuctionSystemDemo** class serves as the entry point of the application and demonstrates the usage of the online auction system."
  },
  {
    "path": "solutions/python/onlinestockbrokeragesystem/README.md",
    "content": "# Designing an Online Stock Brokerage System\n\n## Requirements\n1. The online stock brokerage system should allow users to create and manage their trading accounts.\n2. Users should be able to buy and sell stocks, as well as view their portfolio and transaction history.\n3. The system should provide real-time stock quotes and market data to users.\n4. The system should handle order placement, execution, and settlement processes.\n5. The system should enforce various business rules and validations, such as checking account balances and stock availability.\n6. The system should handle concurrent user requests and ensure data consistency and integrity.\n7. The system should be scalable and able to handle a large number of users and transactions.\n8. The system should be secure and protect sensitive user information.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the stock brokerage system, with properties such as user ID, name, and email.\n2. The **Account** class represents a user's trading account, with properties like account ID, associated user, and balance. It provides methods for depositing and withdrawing funds.\n3. The **Stock** class represents a stock that can be traded, with properties such as symbol, name, and price. It provides a method for updating the stock price.\n4. The **Order** class is an abstract base class representing an order placed by a user. It contains common properties such as order ID, associated account, stock, quantity, price, and order status. The execute() method is declared as abstract, to be implemented by concrete order classes.\n5. The **BuyOrder** and **SellOrder** classes are concrete implementations of the Order class, representing buy and sell orders respectively. They provide the implementation for the execute() method specific to each order type.\n6. The **OrderStatus** enum represents the possible statuses of an order, such as PENDING, EXECUTED, or REJECTED.\n7. The **Portfolio** class represents a user's portfolio, which holds the stocks owned by the user. It provides methods for adding and removing stocks from the portfolio.\n8. The **StockBroker** class is the central component of the stock brokerage system. It follows the Singleton pattern to ensure a single instance of the stock broker. It manages user accounts, stocks, and order processing. It provides methods for creating accounts, adding stocks, placing orders, and processing orders.\n9. The **InsufficientFundsException** and **InsufficientStockException** classes are custom exceptions used to handle insufficient funds and insufficient stock scenarios respectively.\n10. The **StockBrokerageSystem** class serves as the entry point of the application and demonstrates the usage of the stock brokerage system."
  },
  {
    "path": "solutions/python/parkinglot/README.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot should have multiple levels, each level with a certain number of parking spots.\n2. The parking lot should support different types of vehicles, such as cars, motorcycles, and trucks.\n3. Each parking spot should be able to accommodate a specific type of vehicle.\n4. The system should assign a parking spot to a vehicle upon entry and release it when the vehicle exits.\n5. The system should track the availability of parking spots and provide real-time information to customers.\n6. The system should handle multiple entry and exit points and support concurrent access.\n\n## Classes, Interfaces and Enumerations\n1. The **ParkingLot** class follows the Singleton pattern to ensure only one instance of the parking lot exists. It maintains a list of levels and provides methods to park and unpark vehicles.\n2. The **ParkingFloor** class represents a level in the parking lot and contains a list of parking spots. It handles parking and unparking of vehicles within the level.\n3. The **ParkingSpot** class represents an individual parking spot and tracks the availability and the parked vehicle.\n4. The **Vehicle** class is an abstract base class for different types of vehicles. It is extended by Car, Motorcycle, and Truck classes.\n5. The **VehicleType** enum defines the different types of vehicles supported by the parking lot.\n6. Multi-threading is achieved through the use of synchronized keyword on critical sections to ensure thread safety.\n7. The **Main** class demonstrates the usage of the parking lot system.\n\n## Design Patterns Used:\n1. Singleton Pattern: Ensures only one instance of the ParkingLot class.\n2. Factory Pattern (optional extension): Could be used for creating vehicles based on input.\n3. Observer Pattern (optional extension): Could notify customers about available spots.\n"
  },
  {
    "path": "solutions/python/pubsubsystem/README.md",
    "content": "# Designing a Pub-Sub System in Java\n\n## Requirements\n1. The Pub-Sub system should allow publishers to publish messages to specific topics.\n2. Subscribers should be able to subscribe to topics of interest and receive messages published to those topics.\n3. The system should support multiple publishers and subscribers.\n4. Messages should be delivered to all subscribers of a topic in real-time.\n5. The system should handle concurrent access and ensure thread safety.\n6. The Pub-Sub system should be scalable and efficient in terms of message delivery.\n\n## Classes, Interfaces and Enumerations\n1. The **Message** class represents a message that can be published and received by subscribers. It contains the message content.\n2. The **Topic** class represents a topic to which messages can be published. It maintains a set of subscribers and provides methods to add and remove subscribers, as well as publish messages to all subscribers.\n3. The **Subscriber** interface defines the contract for subscribers. It declares the onMessage method that is invoked when a subscriber receives a message.\n4. The **PrintSubscriber** class is a concrete implementation of the Subscriber interface. It receives messages and prints them to the console.\n5. The **Publisher** class represents a publisher that publishes messages to a specific topic.\n6. The **PubSubSystem** class is the main class that manages topics, subscribers, and message publishing. It uses a ConcurrentHashMap to store topics and an ExecutorService to handle concurrent message publishing.\n7. The **PubSubDemo** class demonstrates the usage of the Pub-Sub system by creating topics, subscribers, and publishers, and publishing messages."
  },
  {
    "path": "solutions/python/restaurantmanagementsystem/README.md",
    "content": "# Designing Restaurant Management System\n\n## Requirements\n1. The restaurant management system should allow customers to place orders, view the menu, and make reservations.\n2. The system should manage the restaurant's inventory, including ingredients and menu items.\n3. The system should handle order processing, including order preparation, billing, and payment.\n4. The system should support multiple payment methods, such as cash, credit card, and mobile payments.\n5. The system should manage staff information, including roles, schedules, and performance tracking.\n6. The system should generate reports and analytics for management, such as sales reports and inventory analysis.\n7. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **MenuItem** class represents a menu item in the restaurant, with properties such as ID, name, description, price, and availability.\n2. The **Order** class represents an order placed by a customer, with properties such as ID, list of menu items, total amount, order status, and timestamp.\n3. The **OrderStatus** enum represents the different statuses an order can have, such as pending, preparing, ready, completed, or cancelled.\n4. The **Reservation** class represents a reservation made by a customer, with properties such as ID, customer name, contact number, party size, and reservation time.\n5. The **Payment** class represents a payment made for an order, with properties such as ID, amount, payment method, and payment status.\n6. The **PaymentMethod** enum represents the different payment methods supported by the restaurant, such as cash, credit card, or mobile payment.\n7. The **PaymentStatus** enum represents the status of a payment, which can be pending, completed, or failed.\n8. The Staff class represents a staff member of the restaurant, with properties such as ID, name, role, and contact number.\n9. The **Restaurant** class is the main class that manages the restaurant operations. It follows the Singleton pattern to ensure only one instance of the restaurant exists.\n10. The Restaurant class provides methods for managing menu items, placing orders, updating order status, making reservations, processing payments, and managing staff.\n11. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to shared data, such as orders and reservations.\n12. The notifyKitchen and notifyStaff methods are placeholders for notifying relevant staff about order updates and status changes.\n13. The **RestaurantManagementDemo** class demonstrates the usage of the restaurant management system by adding menu items, placing an order, making a reservation, processing a payment, updating order status, adding staff, and retrieving the menu."
  },
  {
    "path": "solutions/python/ridesharingservice/README.md",
    "content": "# Designing a Ride-Sharing Service Like Uber\n\n## Requirements\n1. The ride sharing service should allow passengers to request rides and drivers to accept and fulfill those ride requests.\n2. Passengers should be able to specify their pickup location, destination, and desired ride type (e.g., regular, premium).\n3. Drivers should be able to see available ride requests and choose to accept or decline them.\n4. The system should match ride requests with available drivers based on proximity and other factors.\n5. The system should calculate the fare for each ride based on distance, time, and ride type.\n6. The system should handle payments and process transactions between passengers and drivers.\n7. The system should provide real-time tracking of ongoing rides and notify passengers and drivers about ride status updates.\n8. The system should handle concurrent requests and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **Passenger** class represents a passenger in the ride sharing service, with properties such as ID, name, contact information, and location.\n2. The **Driver** class represents a driver in the ride sharing service, with properties such as ID, name, contact information, license plate, location, and status (available or busy).\n3. The **Ride** class represents a ride requested by a passenger and accepted by a driver, with properties such as ID, passenger, driver, source location, destination location, status, and fare.\n4. The **Location** class represents a geographical location with latitude and longitude coordinates.\n5. The **Payment** class represents a payment made for a ride, with properties such as ID, ride, amount, and payment status.\n6. The **RideService** class is the main class that manages the ride sharing service. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The RideService class provides methods for adding passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides.\n8. Multi-threading is implemented using concurrent data structures (ConcurrentHashMap and ConcurrentLinkedQueue) to handle concurrent access to shared data, such as ride requests and driver availability.\n9. The notifyDrivers, notifyPassenger, and notifyDriver methods are placeholders for notifying relevant parties about ride status updates.\n10. The calculateFare and processPayment methods are placeholders for calculating ride fares and processing payments, respectively.\n11. The **RideSharingDemo** class demonstrates the usage of the ride sharing service by creating passengers and drivers, requesting rides, accepting rides, starting rides, completing rides, and canceling rides."
  },
  {
    "path": "solutions/python/snakeandladdergame/README.md",
    "content": "# Designing Snake and Ladder Game\n\n## Requirements\n1. The game should be played on a board with numbered cells, typically with 100 cells.\n2. The board should have a predefined set of snakes and ladders, connecting certain cells.\n3. The game should support multiple players, each represented by a unique game piece.\n4. Players should take turns rolling a dice to determine the number of cells to move forward.\n5. If a player lands on a cell with the head of a snake, they should slide down to the cell with the tail of the snake.\n6. If a player lands on a cell with the base of a ladder, they should climb up to the cell at the top of the ladder.\n7. The game should continue until one of the players reaches the final cell on the board.\n8. The game should handle multiple game sessions concurrently, allowing different groups of players to play independently.\n\n## Classes, Interfaces and Enumerations\n1. The **Board** class represents the game board with a fixed size (e.g., 100 cells). It contains the positions of snakes and ladders and provides methods to initialize them and retrieve the new position after encountering a snake or ladder.\n2. The **Player** class represents a player in the game, with properties such as name and current position on the board.\n3. The **Snake** class represents a snake on the board, with properties for the start and end positions.\n4. The **Ladder** class represents a ladder on the board, with properties for the start and end positions.\n5. The **Dice** class represents a dice used in the game, with a method to roll the dice and return a random value between 1 and 6.\n6. The **SnakeAndLadderGame** class represents a single game session. It initializes the game with a board, a list of players, and a dice. The play method handles the game loop, where players take turns rolling the dice and moving their positions on the board. It checks for snakes and ladders and updates the player's position accordingly. The game continues until a player reaches the final position on the board.\n7. The **GameManager** class is a singleton that manages multiple game sessions. It maintains a list of active games and provides a method to start a new game with a list of player names. Each game is started in a separate thread to allow concurrent game sessions.\n8. The **SnakeAndLadderDemo** class demonstrates the usage of the game by creating an instance of the GameManager and starting two separate game sessions with different sets of players."
  },
  {
    "path": "solutions/python/socialnetworkingservice/README.md",
    "content": "# Designing a Social Network Like Facebook\n\n## Requirements\n#### User Registration and Authentication:\n- Users should be able to create an account with their personal information, such as name, email, and password.\n- Users should be able to log in and log out of their accounts securely.\n#### User Profiles:\n- Each user should have a profile with their information, such as profile picture, bio, and interests.\n- Users should be able to update their profile information.\n#### Friend Connections:\n- Users should be able to send friend requests to other users.\n- Users should be able to accept or decline friend requests.\n- Users should be able to view their list of friends.\n#### Posts and Newsfeed:\n- Users should be able to create posts with text, images, or videos.\n- Users should be able to view a newsfeed consisting of posts from their friends and their own posts.\n- The newsfeed should be sorted in reverse chronological order.\n#### Likes and Comments:\n- Users should be able to like and comment on posts.\n- Users should be able to view the list of likes and comments on a post.\n#### Privacy and Security:\n- Users should be able to control the visibility of their posts and profile information.\n- The system should enforce secure access control to ensure data privacy.\n#### Notifications:\n- Users should receive notifications for events such as friend requests, likes, comments, and mentions.\n- Notifications should be delivered in real-time.\n#### Scalability and Performance:\n- The system should be designed to handle a large number of concurrent users and high traffic load.\n- The system should be scalable and efficient in terms of resource utilization.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the social networking system, containing properties such as ID, name, email, password, profile picture, bio, list of friends, and list of posts.\n2. The **Post** class represents a post created by a user, containing properties such as ID, user ID, content, image URLs, video URLs, timestamp, likes, and comments.\n3. The **Comment** class represents a comment made by a user on a post, containing properties such as ID, user ID, post ID, content, and timestamp.\n4. The **Notification** class represents a notification generated for a user, containing properties such as ID, user ID, notification type, content, and timestamp.\n5. The **NotificationType** enum defines the different types of notifications, such as friend request, friend request accepted, like, comment, and mention.\n6. The **SocialNetworkingService** class is the main class that manages the social networking system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SocialNetworkingService class provides methods for user registration, login, profile updates, friend requests, post creation, newsfeed generation, likes, comments, and notifications.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SocialNetworkingDemo** class demonstrates the usage of the social networking system by registering users, logging in, sending friend requests, creating posts, liking posts, commenting on posts, and retrieving newsfeed and notifications."
  },
  {
    "path": "solutions/python/splitwise/README.md",
    "content": "# Designing Splitwise\n\n## Requirements\n1. The system should allow users to create accounts and manage their profile information.\n2. Users should be able to create groups and add other users to the groups.\n3. Users should be able to add expenses within a group, specifying the amount, description, and participants.\n4. The system should automatically split the expenses among the participants based on their share.\n5. Users should be able to view their individual balances with other users and settle up the balances.\n6. The system should support different split methods, such as equal split, percentage split, and exact amounts.\n7. Users should be able to view their transaction history and group expenses.\n8. The system should handle concurrent transactions and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the Splitwise system, with properties such as ID, name, email, and a map to store balances with other users.\n2. The **Group** class represents a group in Splitwise, containing a list of member users and a list of expenses.\n3. The **Expense** class represents an expense within a group, with properties such as ID, amount, description, the user who paid, and a list of splits.\n4. The **Split** class is an abstract class representing the split of an expense. It is extended by EqualSplit, PercentSplit, and ExactSplit classes to handle different split methods.\n5. The **Transaction** class represents a transaction between two users, with properties such as ID, sender, receiver, and amount.\n6. The **SplitwiseService** class is the main class that manages the Splitwise system. It follows the Singleton pattern to ensure only one instance of the service exists.\n7. The SplitwiseService class provides methods for adding users, groups, and expenses, splitting expenses, updating balances, settling balances, and creating transactions.\n8. Multi-threading is achieved using concurrent data structures such as ConcurrentHashMap and CopyOnWriteArrayList to handle concurrent access to shared resources.\n9. The **SplitwiseDemo** class demonstrates the usage of the Splitwise system by creating users, a group, adding an expense, settling balances, and printing user balances."
  },
  {
    "path": "solutions/python/stackoverflow/README.md",
    "content": "# Designing Stack Overflow\n\n## Requirements\n1. Users can post questions, answer questions, and comment on questions and answers.\n2. Users can vote on questions and answers.\n3. Questions should have tags associated with them.\n4. Users can search for questions based on keywords, tags, or user profiles.\n5. The system should assign reputation score to users based on their activity and the quality of their contributions.\n6. The system should handle concurrent access and ensure data consistency.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user of the Stack Overflow system, with properties such as id, username, email, and reputation.\n2. The **Question** class represents a question posted by a user, with properties such as id, title, content, author, answers, comments, tags, votes and creation date.\n3. The **Answer** class represents an answer to a question, with properties such as id, content, author, associated question, comments, votes and creation date.\n4. The **Comment** class represents a comment on a question or an answer, with properties such as id, content, author, and creation date.\n5. The **Tag** class represents a tag associated with a question, with properties such as id and name.\n6. The **Vote** class represents vote associated with a question/answer.\n7. The **StackOverflow** class is the main class that manages the Stack Overflow system. It provides methods for creating user, posting questions, answers, and comments, voting on questions and answers, searching for questions, and retrieving questions by tags and users.\n8.  The **StackOverflowDemo** class demonstrates the usage of the Stack Overflow system by creating users, posting questions and answers, voting, searching for questions, and retrieving questions by tags and users."
  },
  {
    "path": "solutions/python/taskmanagementsystem/README.md",
    "content": "# Designing a Task Management System\n\n## Requirements\n1. The task management system should allow users to create, update, and delete tasks.\n2. Each task should have a title, description, due date, priority, and status (e.g., pending, in progress, completed).\n3. Users should be able to assign tasks to other users and set reminders for tasks.\n4. The system should support searching and filtering tasks based on various criteria (e.g., priority, due date, assigned user).\n5. Users should be able to mark tasks as completed and view their task history.\n6. The system should handle concurrent access to tasks and ensure data consistency.\n7. The system should be extensible to accommodate future enhancements and new features.\n\n## Classes, Interfaces and Enumerations\n1. The **User** class represents a user in the task management system, with properties such as id, name, and email.\n2. The **TaskStatus** enum defines the possible states of a task, such as pending, in progress, and completed.\n3. The **Task** class represents a task in the system, with properties like id, title, description, due date, priority, status, and assigned user.\n4. The **TaskManager** class is the core of the task management system and follows the Singleton pattern to ensure a single instance of the task manager.\n5. The TaskManager class uses concurrent data structures (ConcurrentHashMap and CopyOnWriteArrayList) to handle concurrent access to tasks and ensure thread safety.\n6. The TaskManager class provides methods for creating, updating, deleting, searching, and filtering tasks, as well as marking tasks as completed and retrieving task history for a user.\n7. The **TaskManagementSystem** class serves as the entry point of the application and demonstrates the usage of the task management system."
  },
  {
    "path": "solutions/python/tictactoe/README.md",
    "content": "# Designing a Tic Tac Toe Game\n\n## Requirements\n1. The Tic-Tac-Toe game should be played on a 3x3 grid.\n2. Two players take turns marking their symbols (X or O) on the grid.\n3. The first player to get three of their symbols in a row (horizontally, vertically, or diagonally) wins the game.\n4. If all the cells on the grid are filled and no player has won, the game ends in a draw.\n5. The game should have a user interface to display the grid and allow players to make their moves.\n6. The game should handle player turns and validate moves to ensure they are legal.\n7. The game should detect and announce the winner or a draw at the end of the game.\n\n## Classes, Interfaces and Enumerations\n1. The **Player** class represents a player in the game, with a name and a symbol (X or O).\n2. The **Board** class represents the game board, which is a 3x3 grid. It provides methods to make moves, check for a winner, and check if the board is full.\n3. The **Game** class manages the game flow and player interactions. It handles player turns, validates moves, and determines the winner or a draw.\n4. The **TicTacToe** class is the entry point of the application and creates instances of the players and the game."
  },
  {
    "path": "solutions/python/trafficsignalsystem/README.md",
    "content": "# Designing a Traffic Signal Control System\n\n## Requirements\n1. The traffic signal system should control the flow of traffic at an intersection with multiple roads.\n2. The system should support different types of signals, such as red, yellow, and green.\n3. The duration of each signal should be configurable and adjustable based on traffic conditions.\n4. The system should handle the transition between signals smoothly, ensuring safe and efficient traffic flow.\n5. The system should be able to detect and handle emergency situations, such as an ambulance or fire truck approaching the intersection.\n6. The system should be scalable and extensible to support additional features and functionality.\n\n## Classes, Interfaces and Enumerations\n1. The **Signal** enum represents the different states of a traffic light: red, yellow, and green.\n2. The **Road** class represents a road in the traffic signal system, with properties such as ID, name, and an associated traffic light.\n3. The **TrafficLight** class represents a traffic light, with properties such as ID, current signal, and durations for each signal state. It provides methods to change the signal and notify observers (e.g., roads) about signal changes.\n4. The **TrafficController** class serves as the central controller for the traffic signal system. It follows the Singleton pattern to ensure a single instance of the controller. It manages the roads and their associated traffic lights, starts the traffic control process, and handles emergency situations.\n5. The **TrafficSignalSystemDemo** class is the main entry point of the application. It demonstrates the usage of the traffic signal system by creating roads, traffic lights, assigning traffic lights to roads, and starting the traffic control process."
  },
  {
    "path": "solutions/python/vendingmachine/README.md",
    "content": "# Designing a Vending Machine\n\n## Requirements\n1. The vending machine should support multiple products with different prices and quantities.\n1. The machine should accept coins and notes of different denominations.\n1. The machine should dispense the selected product and return change if necessary.\n1. The machine should keep track of the available products and their quantities.\n1. The machine should handle multiple transactions concurrently and ensure data consistency.\n1. The machine should provide an interface for restocking products and collecting money.\n1. The machine should handle exceptional scenarios, such as insufficient funds or out-of-stock products.\n\n## Classes, Interfaces and Enumerations\n1. The **Product** class represents a product in the vending machine, with properties such as name and price.\n2. The **Coin** and **Note** enums represent the different denominations of coins and notes accepted by the vending machine.\n3. The **Inventory** class manages the available products and their quantities in the vending machine. It uses a concurrent hash map to ensure thread safety.\n4. The **VendingMachineState** interface defines the behavior of the vending machine in different states, such as idle, ready, and dispense.\n5. The **IdleState**, **ReadyState**, and **DispenseState** classes implement the VendingMachineState interface and define the specific behaviors for each state.\n6. The **VendingMachine** class is the main class that represents the vending machine. It follows the Singleton pattern to ensure only one instance of the vending machine exists.\n7. The VendingMachine class maintains the current state, selected product, total payment, and provides methods for state transitions and payment handling.\n8. The **VendingMachineDemo** class demonstrates the usage of the vending machine by adding products to the inventory, selecting products, inserting coins and notes, dispensing products, and returning change."
  },
  {
    "path": "solutions/python/votingsystem/README.md",
    "content": "### Airline Management System\n\nThis is a simple airline management system that allows you to manage flights, passengers, and bookings."
  },
  {
    "path": "solutions/typescript/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\n# Diagnostic reports (https://nodejs.org/api/report.html)\nreport.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n*.lcov\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# Snowpack dependency directory (https://snowpack.dev/)\nweb_modules/\n\n# TypeScript cache\n*.tsbuildinfo\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional stylelint cache\n.stylelintcache\n\n# Microbundle cache\n.rpt2_cache/\n.rts2_cache_cjs/\n.rts2_cache_es/\n.rts2_cache_umd/\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variable files\n.env\n.env.development.local\n.env.test.local\n.env.production.local\n.env.local\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n.parcel-cache\n\n# Next.js build output\n.next\nout\n\n# Nuxt.js build / generate output\n.nuxt\ndist\n\n# Gatsby files\n.cache/\n# Comment in the public line in if your project uses Gatsby and not Next.js\n# https://nextjs.org/blog/next-9-1#public-directory-support\n# public\n\n# vuepress build output\n.vuepress/dist\n\n# vuepress v2.x temp and cache directory\n.temp\n.cache\n\n# Docusaurus cache and generated files\n.docusaurus\n\n# Serverless directories\n.serverless/\n\n# FuseBox cache\n.fusebox/\n\n# DynamoDB Local files\n.dynamodb/\n\n# TernJS port file\n.tern-port\n\n# Stores VSCode versions used for testing VSCode extensions\n.vscode-test\n\n# yarn v2\n.yarn/cache\n.yarn/unplugged\n.yarn/build-state.yml\n.yarn/install-state.gz\n.pnp.*"
  },
  {
    "path": "solutions/typescript/README.md",
    "content": "## How to use\n\n```bash\nnpm i\nnpx tsx src/lldrunner.ts\n```\n"
  },
  {
    "path": "solutions/typescript/package.json",
    "content": "{\n  \"name\": \"nodejs-typescript\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"src/LLDRunner.ts\",\n  \"scripts\": {\n    \"dev\": \"tsx src/LLDRunner.ts\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"node-fetch\": \"^3.3.1\",\n    \"uuid\": \"^11.1.0\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.10.0\",\n    \"tsx\": \"^4.7.1\"\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/CoffeeRecipe.ts",
    "content": "class CoffeeRecipe {\n  private name: string;\n  private price: number;\n  private recipe: Map<string, number>;\n\n  constructor(name: string, price: number, recipe: Map<string, number>) {\n    this.name = name;\n    this.price = price;\n    this.recipe = recipe;\n  }\n\n  public getName(): string {\n    return this.name;\n  }\n\n  public getPrice(): number {\n    return this.price;\n  }\n\n  public getRecipe() {\n    return this.recipe;\n  }\n}\nexport default CoffeeRecipe;\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/CoffeeVendingMachine.ts",
    "content": "import CoffeeRecipe from \"./CoffeeRecipe\";\nimport Dispenser from \"./Dispenser\";\nimport IngredientStore from \"./IngredientStore\";\nimport Payment from \"./Payment\";\nimport PaymentProcessor from \"./PaymentProcessor\";\n\nclass CoffeeVendingMachine {\n  private static instance: CoffeeVendingMachine | null;\n  private recipes: Map<string, CoffeeRecipe>;\n  private ingredientStore: IngredientStore;\n  private dispenser: Dispenser;\n  private paymentProcessor: PaymentProcessor;\n\n  private constructor() {\n    this.ingredientStore = new IngredientStore();\n    this.dispenser = new Dispenser();\n    this.paymentProcessor = new PaymentProcessor();\n    this.recipes = new Map();\n    this.addDefaultRecipes();\n  }\n\n  private addDefaultRecipes(): void {\n    this.recipes.set(\n      \"Latte\",\n      new CoffeeRecipe(\n        \"Latte\",\n        3.0,\n        new Map([\n          [\"Water\", 50],\n          [\"Coffee\", 20],\n          [\"Milk\", 30],\n        ]),\n      ),\n    );\n    this.recipes.set(\n      \"Espresso\",\n      new CoffeeRecipe(\n        \"Espresso\",\n        3.5,\n        new Map([\n          [\"Water\", 50],\n          [\"Coffee\", 20],\n        ]),\n      ),\n    );\n    this.recipes.set(\n      \"Cappuccino\",\n      new CoffeeRecipe(\n        \"Cappuccino\",\n        3.5,\n        new Map([\n          [\"Water\", 50],\n          [\"Coffee\", 20],\n          [\"Milk\", 40],\n        ]),\n      ),\n    );\n  }\n\n  public static getInstance(): CoffeeVendingMachine {\n    if (!CoffeeVendingMachine.instance) {\n      CoffeeVendingMachine.instance = new CoffeeVendingMachine();\n    }\n    return CoffeeVendingMachine.instance;\n  }\n\n  public displayMenu(): void {\n    console.log(\"Coffee Menu:\");\n    for (const recipe of this.recipes.keys()) {\n        console.log(recipe + \" - $\" + this.recipes.get(recipe)?.getPrice());\n    }\n  }\n\n  public selectCoffee(coffeeName: string): CoffeeRecipe {\n    const recipe = this.recipes.get(coffeeName);\n    if (!recipe) throw new Error(`Invalid coffee recipe: ${coffeeName}`);\n    console.log('Selected Coffee : ',coffeeName)\n    return recipe;\n  }\n\n  public dispenseCoffee(recipe: CoffeeRecipe, payment: Payment): void {\n    if (payment.getAmount() < recipe.getPrice()) {\n      console.error(\n        `Insufficient payment for ${recipe.getName()}. Required: ${recipe.getPrice()}`,\n      );\n      return;\n    }\n\n    if (!this.ingredientStore.hasEnoughIngredient(recipe.getRecipe())) {\n      console.error(`Insufficient ingredients to make ${recipe.getName()}`);\n      return;\n    }\n\n    this.ingredientStore.consume(recipe.getRecipe());\n    this.dispenser.prepareDrink(recipe);\n\n    const change = this.paymentProcessor.process(\n      recipe.getPrice(),\n      payment.getAmount(),\n    );\n    if (change > 0) {\n      console.log(`Please collect your change: $${change}`);\n    }\n  }\n\n  public refillIngredient(ingredient: string, quantity: number): void {\n    this.ingredientStore.refill(ingredient, quantity);\n  }\n\n  public showIngredients(): void {\n    console.log(\"Ingredient Levels:\");\n    const ingredients = this.ingredientStore.getAllIngredients();\n    for (const [name, quantity] of Object.entries(ingredients)) {\n      console.log(`${name}: ${quantity}`);\n    }\n  }\n}\nexport default CoffeeVendingMachine;\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/CoffeeVendingMachineDemo.ts",
    "content": "import CoffeeVendingMachine from \"./CoffeeVendingMachine\";\nimport Payment from \"./Payment\";\n\nexport default class CoffeeVendingMachineDemo {\n  static run() {\n    const coffeeVendingMachine = CoffeeVendingMachine.getInstance();\n\n    coffeeVendingMachine.refillIngredient(\"Water\", 120);\n    coffeeVendingMachine.refillIngredient(\"Milk\", 70);\n    coffeeVendingMachine.refillIngredient(\"Coffee\", 150);\n\n    coffeeVendingMachine.displayMenu();\n\n    const espresso = coffeeVendingMachine.selectCoffee(\"Espresso\");\n    coffeeVendingMachine.dispenseCoffee(espresso, new Payment(3.0));\n\n    const cappuccino = coffeeVendingMachine.selectCoffee(\"Cappuccino\");\n    coffeeVendingMachine.dispenseCoffee(cappuccino, new Payment(3.5));\n\n    const latte = coffeeVendingMachine.selectCoffee(\"Latte\");\n    coffeeVendingMachine.dispenseCoffee(latte, new Payment(4.0));\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/Dispenser.ts",
    "content": "import CoffeeRecipe from \"./CoffeeRecipe\";\n\nclass Dispenser {\n  public prepareDrink(recipe: CoffeeRecipe): void {\n    console.log(`Dispensing: ${recipe.getName()}`);\n  }\n}\nexport default Dispenser;"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/IngredientStore.ts",
    "content": "class IngredientStore {\n  private inventory: Map<string, number>;\n\n  constructor() {\n    this.inventory = new Map();\n  }\n\n  public refill(ingredient: string, quantity: number): void {\n    this.inventory.set(\n      ingredient,\n      (this.inventory.get(ingredient) || 0) + quantity,\n    );\n  }\n\n  public hasEnoughIngredient(required: Map<string, number>): boolean {\n    for (const [ingredient, quantity] of required) {\n      if ((this.inventory.get(ingredient) || 0) < quantity) return false;\n    }\n    return true;\n  }\n\n  public consume(required: Map<string, number>): void {\n    for (const [ingredient, quantity] of required) {\n      const currentStock = this.inventory.get(ingredient) || 0;\n      if (currentStock < quantity) {\n        throw new Error(`Not enough ${ingredient} to consume`);\n      }\n      this.inventory.set(ingredient, currentStock - quantity);\n    }\n  }\n\n  public getLevel(ingredient: string): number {\n    return this.inventory.get(ingredient) || 0;\n  }\n\n  public getAllIngredients(): Map<string, number> {\n    return { ...this.inventory };\n  }\n}\nexport default IngredientStore;\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/Payment.ts",
    "content": "export default class Payment {\n  private amount: number;\n\n  constructor(amount: number) {\n    this.amount = amount;\n  }\n\n  public getAmount(): number {\n    return this.amount;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/PaymentProcessor.ts",
    "content": "class PaymentProcessor {\n  public process(price: number, paid: number): number {\n    console.log(\"Processing Payment...\");\n    return paid - price;\n  }\n}\nexport default PaymentProcessor;"
  },
  {
    "path": "solutions/typescript/src/CoffeeVendingMachine/README.md",
    "content": "# Coffee Vending Machine (LLD)\n\n## Problem Statement\n\nDesign and implement a Coffee Vending Machine system that can serve different types of coffee, manage ingredient inventory, process payments, and handle user interactions such as selecting coffee and refilling ingredients.\n\n---\n\n## Requirements\n\n- **Multiple Coffee Types:** The machine should support multiple coffee recipes (e.g., Espresso, Latte, Cappuccino).\n- **Ingredient Management:** The machine should track and manage ingredient levels, and prevent dispensing if ingredients are insufficient.\n- **Payment Processing:** The machine should process payments before dispensing coffee.\n- **Refill Ingredients:** The machine should allow refilling of ingredients.\n- **Extensibility:** Easy to add new coffee types or payment methods.\n\n---\n\n## Core Entities\n\n- **CoffeeVendingMachine:** Main class that manages the overall operation, user interaction, and coordinates other components.\n- **CoffeeRecipe:** Represents a coffee recipe, including required ingredients and their quantities.\n- **IngredientStore:** Manages the inventory of ingredients, supports checking and refilling.\n- **Dispenser:** Handles the dispensing of coffee after successful payment and ingredient check.\n- **PaymentProcessor:** Handles payment logic and validation.\n- **Payment:** Represents a payment transaction.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/coffeevendingmachine-class-diagram.png)\n\n### 1. CoffeeVendingMachine\n- **Fields:** ingredientStore, paymentProcessor, Map<String, CoffeeRecipe> recipes, Dispenser\n- **Methods:** selectCoffee(String), makeCoffee(String, Payment), refillIngredient(String, int), addRecipe(CoffeeRecipe), etc.\n\n### 2. CoffeeRecipe\n- **Fields:** name, Map<String, Integer> ingredients\n- **Methods:** getName(), getIngredients()\n\n### 3. IngredientStore\n- **Fields:** Map<String, Integer> ingredientLevels\n- **Methods:** hasIngredients(Map<String, Integer>), useIngredients(Map<String, Integer>), refill(String, int), getLevel(String)\n\n### 4. Dispenser\n- **Methods:** dispense(String)\n\n### 5. PaymentProcessor\n- **Methods:** processPayment(Payment)\n\n### 6. Payment\n- **Fields:** amount, paymentType, etc.\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** (Conceptually) for supporting different payment methods or coffee recipes.\n- **Separation of Concerns:** Each class has a single responsibility (inventory, payment, dispensing, etc.).\n\n---\n\n## Example Usage\n\n```ts\nconst coffeeVendingMachine = CoffeeVendingMachine.getInstance();\n\ncoffeeVendingMachine.refillIngredient(\"Milk\", 70);\ncoffeeVendingMachine.refillIngredient(\"Coffee\", 150);\n\ncoffeeVendingMachine.displayMenu();\n\nconst espresso = coffeeVendingMachine.selectCoffee(\"Espresso\");\ncoffeeVendingMachine.dispenseCoffee(espresso, new Payment(3.0));\n```\n\n---\n\n## Demo\n\nSee `CoffeeVendingMachineDemo.ts` for a sample usage and simulation of the coffee vending machine.\n\n---\n\n## Extending the Framework\n\n- **Add new coffee types:** Create new `CoffeeRecipe` instances and add them to the machine.\n- **Add new payment methods:** Extend `PaymentProcessor` to support new payment types.\n- **Add new ingredients:** Update `IngredientStore` and recipes as needed.\n\n---"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/Appender/ConsoleLogAppender.ts",
    "content": "import LogFormatter from \"../LogFormatter/LogFormatter\";\nimport LogMessage from \"../LogMessage\";\nimport LogAppender from \"./LogAppender\";\n\nexport default class ConsoleLogAppender implements LogAppender {\n  private formatter: LogFormatter;\n\n  constructor(formatter: LogFormatter) {\n    this.formatter = formatter;\n  }\n\n  append(logMessage: LogMessage) {\n    console.log(this.formatter.format(logMessage));\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/Appender/FileLogAppender.ts",
    "content": "import * as fs from \"fs\";\nimport * as path from \"path\";\nimport LogAppender from \"./LogAppender\";\nimport LogMessage from \"../LogMessage\";\nimport LogFormatter from \"../LogFormatter/LogFormatter\";\n\nexport default class FileLogAppender implements LogAppender {\n  private writer!: fs.WriteStream;\n  private formatter: LogFormatter;\n\n  constructor(filePath: string, formatter: LogFormatter) {\n    this.formatter = formatter;\n    const dir = path.dirname(filePath);\n\n    if (!fs.existsSync(dir)) {\n      fs.mkdirSync(dir, { recursive: true });\n    }\n\n    try {\n      this.writer = fs.createWriteStream(filePath, { flags: \"a\" });\n    } catch (e) {\n      console.error(\"Failed to create writer for file logs, exception:\", e);\n    }\n  }\n\n  public append(logMessage: LogMessage): void {\n    try {\n      const formattedMessage = this.formatter.format(logMessage);\n      this.writer.write(formattedMessage + \"\\n\");\n    } catch (e) {\n      console.error(\"Failed to write logs to file, exception:\", e);\n    }\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/Appender/LogAppender.ts",
    "content": "import LogMessage from \"../LogMessage\";\n\nexport default interface LogAppender {\n  append(logMessage: LogMessage): void;\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LogFormatter/LogFormatter.ts",
    "content": "import LogMessage from \"../LogMessage\";\n\nexport default interface LogFormatter {\n  format(message: LogMessage): string;\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LogFormatter/SimpleLogFormatter.ts",
    "content": "import LogMessage from \"../LogMessage\";\nimport LogFormatter from \"./LogFormatter\";\n\nexport default class SimpleLogFormatter implements LogFormatter {\n  format(message: LogMessage): string {\n    return `[${message.getTimeStamp()}] - [${message.getLogLevel()}] - [${message.getMessage()}]`;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LogLevel.ts",
    "content": "export enum LogLevelEnum {\n  DEBUG, // 0\n  INFO, // 1\n  WARN, // 2\n  ERROR, // 3\n  FATAL, // 4\n}\n\nexport function isAsSevereAs(\n  level1: LogLevelEnum,\n  level2: LogLevelEnum,\n): boolean {\n  return level1 >= level2;\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LogManager.ts",
    "content": "import ConsoleLogAppender from \"./Appender/ConsoleLogAppender\";\nimport FileLogAppender from \"./Appender/FileLogAppender\";\nimport LogAppender from \"./Appender/LogAppender\";\nimport SimpleLogFormatter from \"./LogFormatter/SimpleLogFormatter\";\nimport Logger from \"./Logger\";\nimport { LogLevelEnum } from \"./LogLevel\";\n\nexport default class LogManager {\n    private static logger: Logger;\n\n    static getLogger() {\n        if (this.logger == null) {\n            this.logger = new LogManager.LoggerBuilder()\n                .setLevel(LogLevelEnum.DEBUG)\n                .addAppender(new ConsoleLogAppender(new SimpleLogFormatter()))\n                .addAppender(\n                    new FileLogAppender(\"log.txt\", new SimpleLogFormatter()),\n                )\n                .build();\n        }\n        return this.logger;\n    }\n\n    static LoggerBuilder = class {\n        private level: LogLevelEnum = LogLevelEnum.INFO;\n        private appenders: LogAppender[] = [];\n\n        setLevel(level: LogLevelEnum): this {\n            this.level = level;\n            return this;\n        }\n\n        addAppender(appender: LogAppender): this {\n            this.appenders.push(appender);\n            return this;\n        }\n\n        build(): Logger {\n            return new Logger(this.level, this.appenders);\n        }\n    };\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LogMessage.ts",
    "content": "import { LogLevelEnum } from \"./LogLevel\";\n\nexport default class LogMessage {\n  private logLevel: LogLevelEnum;\n  private message: string;\n  private timestamp: number;\n\n  constructor(logLevel: LogLevelEnum, message: string) {\n    this.logLevel = logLevel;\n    this.message = message;\n    this.timestamp = Date.now();\n  }\n\n  getMessage() {\n    return this.message;\n  }\n\n  getLogLevel() {\n    return this.logLevel;\n  }\n\n  getTimeStamp() {\n    return this.timestamp;\n  }\n\n  toString() {\n    return \"[\" + this.logLevel + \"] \" + this.timestamp + \" - \" + this.message;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/Logger.ts",
    "content": "import LogAppender from \"./Appender/LogAppender\";\nimport { isAsSevereAs, LogLevelEnum } from \"./LogLevel\";\nimport LogMessage from \"./LogMessage\";\n\nexport default class Logger {\n  private minLevel: LogLevelEnum;\n  private appenders: LogAppender[];\n\n  public constructor(minLevel: LogLevelEnum, appenders: LogAppender[]) {\n    this.minLevel = minLevel;\n    this.appenders = appenders;\n  }\n\n  log(level: LogLevelEnum, msg: string) {\n    if (!isAsSevereAs( level,this.minLevel)) return;\n    const message = new LogMessage(level, msg);\n    this.appenders.forEach((a) => a.append(message));\n  }\n\n  setMinLevel(minLevel: LogLevelEnum) {\n    this.minLevel = minLevel;\n  }\n\n  debug(message: string) {\n    this.log(LogLevelEnum.DEBUG, message);\n  }\n  info(message: string) {\n    this.log(LogLevelEnum.INFO, message);\n  }\n  warn(message: string) {\n    this.log(LogLevelEnum.WARN, message);\n  }\n  error(message: string) {\n    this.log(LogLevelEnum.ERROR, message);\n  }\n  fatal(message: string) {\n    this.log(LogLevelEnum.FATAL, message);\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/LoggingFrameworkDemo.ts",
    "content": "import { LogLevelEnum } from \"./LogLevel\";\nimport LogManager from \"./LogManager\";\n\nexport default class LogginFrameworkDemo {\n  static run() {\n    const logger = LogManager.getLogger();\n\n    // Logging with default configuration\n    // Should log debug and above log levels\n    logger.info(\"This is an information message\");\n    logger.warn(\"This is a warning message\");\n    logger.error(\"This is an error message\");\n\n    // Changing log level\n    logger.setMinLevel(LogLevelEnum.WARN);\n\n    // Should only log warn and above\n    logger.debug(\"This is a debug message\");\n    logger.info(\"This is an information message\");\n    logger.warn(\"This is a warning message\");\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/LoggingFramework/README.md",
    "content": "# Logging Framework (LLD)\n\n## Problem Statement\n\nDesign and implement a flexible and extensible logging framework that can be used by applications to log messages at different levels (INFO, DEBUG, ERROR, etc.), support multiple output destinations (console, file, etc.), and allow for custom formatting of log messages.\n\n---\n\n## Requirements\n\n- **Log Levels:** Support for multiple log levels (INFO, DEBUG, ERROR, etc.).\n- **Multiple Appenders:** Ability to log to different destinations (console, file, etc.).\n- **Custom Formatting:** Support for custom log message formatting.\n- **Configuration:** Ability to configure loggers and appenders.\n- **Thread Safety:** Should be thread-safe for concurrent logging.\n- **Extensibility:** Easy to add new log levels, appenders, or formatters.\n\n---\n\n## Core Entities\n\n- **Logger:** Main class used by clients to log messages.\n- **LogLevel:** Enum representing different log levels.\n- **LogMessage:** Encapsulates the details of a log event.\n- **LogFormatter:** Interface for formatting log messages.\n- **DefaultFormatter:** Default implementation of `LogFormatter`.\n- **LoggerConfig:** Holds configuration for the logger (appenders, formatters, etc.).\n- **LogAppender (in `logappender/`):** Interface and implementations for output destinations (e.g., ConsoleAppender, FileAppender).\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/loggingframework-class-diagram.png)\n\n### 1. Logger\n- **Methods:**\n  - `log(LogLevel level, String message)`\n  - `info(String message)`\n  - `debug(String message)`\n  - `error(String message)`\n  - `setConfig(LoggerConfig config)`\n\n### 2. LogLevel\n- Enum for log levels (INFO, DEBUG, ERROR, etc.)\n\n### 3. LogMessage\n- Fields: `level`, `message`, `timestamp`, etc.\n\n### 4. LogFormatter (Interface)\n- `String format(LogMessage message)`\n\n### 5. DefaultFormatter\n- Implements `LogFormatter` with a default format.\n\n### 6. LoggerConfig\n- Holds configuration for loggers (appenders, formatters, log level).\n\n### 7. LogAppender (in `logappender/`)\n- Interface for appenders.\n- Implementations: `ConsoleAppender`, `FileAppender`, etc.\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** For interchangeable log formatters and appenders.\n- **Singleton Pattern:** For global logger instance.\n- **Factory Pattern:** (Optional) For creating appenders/formatters based on config.\n- **Observer Pattern:** (Conceptually, for notifying multiple appenders.)\n\n---\n\n## Example Usage\n\n```ts\nconst logger = LogManager.getLogger();\nlogger.info(\"This is an information message\");\nlogger.setMinLevel(LogLevelEnum.WARN);\nlogger.warn(\"This is a warning message\");\n```\n\n---\n\n## Demo\n\nSee `LoggingFrameworkDemo.ts` for a sample usage of the logging framework.\n\n---\n\n## Extending the Framework\n\n- **Add a new log level:** Update `LogLevel.java`.\n- **Add a new appender:** Implement the `LogAppender` interface in `logappender/`.\n- **Add a new formatter:** Implement the `LogFormatter` interface.\n\n---"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/Floor.ts",
    "content": "import ParkingSpot from \"./Spot\";\nimport { carType } from \"./types\";\nimport AbstractVehicle from \"./Vehicle\";\n\ntype carWiseSpot = Record<carType, ParkingSpot[]>\n\n\nclass ParkingFloor {\n  floor: string;\n  spots: ParkingSpot[];\n\n  constructor(floor: string) {\n    this.floor = floor\n    this.spots = []\n  }\n\n  addSpot(spot: ParkingSpot) {\n    this.spots.push(spot)\n  }\n\n  reportAvailability(): carWiseSpot {\n    const carWiseSpots: carWiseSpot = {\n      \"Car\": [],\n      \"Truck\": [],\n      \"Bike\": []\n    }\n\n    for (let spot of this.spots) {\n      if (spot.isAvailable) {\n        carWiseSpots[spot.getSpotType].push(spot)\n      }\n    }\n    return carWiseSpots\n  }\n\n  findAvailableSpot(vehicle: AbstractVehicle): ParkingSpot | null {\n    for (let spot of this.spots) {\n      if (spot.canFit(vehicle) && spot.isAvailable) {\n        return spot\n      }\n    }\n    return null\n  }\n}\n\nexport default ParkingFloor"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/Main.ts",
    "content": "import ParkingLot from \"./ParkingLot\"\nimport ParkingFloor from \"./Floor\"\nimport ParkingSpot from \"./Spot\"\nimport { Car } from \"./Vehicle\"\n\nconst parkYourCar = ParkingLot.getInstance(\"ParkYourCar\")\nconsole.log(parkYourCar.name)\n\nconst car1 = new Car(\"car-1\")\nconst car2 = new Car(\"car-2\")\nconst car3 = new Car(\"car-3\")\nconst car4 = new Car(\"car-4\")\n\nconst a1 = new ParkingSpot('a-1', \"Car\")\n// const a2 = new ParkingSpot('a-2', \"Truck\")\nconst a3 = new ParkingSpot('a-3', \"Bike\")\nconst a4 = new ParkingSpot('a-4', \"Car\")\n// const a5 = new ParkingSpot('a-5', \"Car\")\n\n\nconst f1 = new ParkingFloor(\"1\")\nf1.addSpot(a1)\n// f1.addSpot(a2)\nf1.addSpot(a3)\nf1.addSpot(a4)\n// f1.addSpot(a5)\n\nconst b1 = new ParkingSpot('b-1', \"Car\")\nconst b2 = new ParkingSpot('b-2', \"Truck\")\n// const b3 = new ParkingSpot('b-3', \"Bike\")\nconst b4 = new ParkingSpot('b-4', \"Car\")\n// const b5 = new ParkingSpot('b-5', \"Car\")\n\n\nconst f2 = new ParkingFloor(\"2\")\nf2.addSpot(b1)\nf2.addSpot(b2)\n// f2.addSpot(b3)\nf2.addSpot(b4)\n// f2.addSpot(b5)\n\nparkYourCar.addFloor(f1)\nparkYourCar.addFloor(f2)\nparkYourCar.spotAvailability()\n\nparkYourCar.parkCar(car1)\nparkYourCar.parkCar(car2)\nparkYourCar.spotAvailability()"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/ParkingLot.ts",
    "content": "import ParkingFloor from \"./Floor\";\nimport ParkingSpot from \"./Spot\";\nimport AbstractVehicle from \"./Vehicle\";\n\nclass ParkingLot {\n  private static instance: ParkingLot;\n  private floors: ParkingFloor[]\n  name : string;\n  protected carSpotMap: Record<string,ParkingSpot> \n\n  constructor(name: string){\n    this.name = name\n    this.floors = []\n    this.carSpotMap = {}\n  }\n\n  static getInstance(name: string = \"Default\"): ParkingLot{\n    if(!ParkingLot.instance){\n      this.instance = new ParkingLot(name)\n    }\n    return ParkingLot.instance\n  }\n\n  parkCar(vehicle: AbstractVehicle): void{\n    for(let floor of this.floors){\n      const availableSpot = floor.findAvailableSpot(vehicle)\n      if(availableSpot){\n        availableSpot.parkCar(vehicle)\n        console.log(`${vehicle.getNumber()} parked on ${availableSpot.spotName}`)\n        return \n      }\n    }\n  }\n\n  unparkCar(vehicle: AbstractVehicle){\n    const spot = this.carSpotMap[vehicle.getNumber()] \n    if(!spot){\n      throw new Error(`${vehicle.getNumber()} is not Parked.`)\n    }\n    spot.unparkCar()\n    delete this.carSpotMap[vehicle.getNumber()];\n  }\n\n  spotAvailability(){\n    for(let floor of this.floors){\n      const availability = floor.reportAvailability()\n      console.log(`${floor.floor} : `, availability)\n    }\n  }\n\n  addFloor(floor : ParkingFloor){\n    this.floors.push(floor)\n  }\n}\n\nexport default ParkingLot"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/Spot.ts",
    "content": "import { carType } from \"./types\";\nimport AbstractVehicle from \"./Vehicle\";\n\nclass ParkingSpot {\n  spotName: string;\n  protected type: carType;\n  protected parkedCar: AbstractVehicle | null;\n\n  constructor(spotName: string, type: carType) {\n    this.spotName = spotName;\n    this.type = type;\n  }\n\n  get isAvailable(): boolean {\n    return !this.parkedCar;\n  }\n\n  canFit(car: AbstractVehicle): boolean {\n    return car.getType() === this.type;\n  }\n\n  parkCar(car: AbstractVehicle): void {\n    if (!this.isAvailable) {\n      throw new Error(\"Spot already occupied.\");\n    }\n\n    if (!this.canFit(car)) {\n      throw new Error(`${car.getNumber()} can't fit in this spot.`);\n    }\n\n    this.parkedCar = car;\n    console.log(`Parked car${car.getNumber()}.`);\n  }\n\n  unparkCar(): void {\n    this.parkedCar = null;\n  }\n\n  getVehicle(): AbstractVehicle | null {\n    return this.parkedCar;\n  }\n\n  get getSpotType(): carType {\n    return this.type;\n  }\n}\n\nexport default ParkingSpot;\n"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/Vehicle.ts",
    "content": "import { carType } from \"./types\";\n\ninterface Vehicle {\n  getNumber(): string;\n  getType(): carType;\n}\n\n\nabstract class AbstractVehicle implements Vehicle {\n  protected number: string;\n  protected type: carType;\n\n  constructor(number: string, type: carType) {\n    this.number = number;\n    this.type = type;\n  }\n\n  getNumber(): string {\n    return this.number;\n  }\n\n  getType(): carType {\n    return this.type;\n  }\n}\n\nclass Car extends AbstractVehicle {\n  constructor(number: string) {\n    super(number, \"Car\");\n  }\n}\n\nclass Bike extends AbstractVehicle {\n  constructor(number: string) {\n    super(number, \"Bike\");\n  }\n}\n\nclass Truck extends AbstractVehicle {\n  constructor(number: string) {\n    super(number, \"Truck\");\n  }\n}\n\n\nexport default AbstractVehicle\nexport {Car, Bike, Truck}"
  },
  {
    "path": "solutions/typescript/src/ParkingLot/readme.md",
    "content": "# Designing a Parking Lot System\n\n## Requirements\n1. The parking lot consists of multiple levels, and each level has a configurable number of parking spots.\n2. The system must support various types of vehicles: Car, Motorcycle, and Truck.\n3. Each parking spot supports a specific vehicle type.\n4. The system should be able to:\n5. Assign a parking spot to an incoming vehicle.\n6. Free a spot when a vehicle exits.\n7. Track and report spot availability in real time.\n8. The system should support multiple entry and exit points with concurrent access handling (simulate multi-threading behavior where needed).\n9. The design must showcase solid TypeScript OOP principles: classes, interfaces, abstract classes, and enums.\n\n\n## Design Patterns Used:\n1. Use TypeScript with classes, interfaces, and enums.\n    * `Singleton`: Ensure only one instance of the ParkingLot exists.\n    * `Factory(optional)`: For creating vehicles dynamically.\n    * `Observer(optional)`: To notify users when a spot becomes available.\n2. Ensure thread-safety where required using appropriate concurrency-safe constructs (e.g., Mutex simulation, Promise control).\n\n3. Build a simple `Main.ts` file or script to demonstrate usage."
  },
  {
    "path": "solutions/typescript/src/ParkingLot/types.ts",
    "content": "export type carType = \"Car\" | \"Truck\" | \"Bike\";\n\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Answer.ts",
    "content": "import { v4 as uuidv4 } from \"uuid\";\nimport User from \"./User\";\nimport Question from \"./Question\";\nimport Comment from \"./Comment\";\nimport Vote from \"./Vote\";\nimport Votable from \"./Votable\";\nimport Commentable from \"./Commentable\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\nimport { ReputationTypeEnum } from \"./ReputationType\";\n\nexport default class Answer implements Votable, Commentable {\n  private id: string;\n  private content: string;\n  private author: User;\n  private question: Question;\n  private isAccepted: boolean;\n  private creationDate: Date;\n  private comments: Comment[];\n  private votes: Vote[];\n\n  constructor(author: User, question: Question, content: string) {\n    this.id = uuidv4();\n    this.author = author;\n    this.question = question;\n    this.content = content;\n    this.creationDate = new Date();\n    this.votes = [];\n    this.comments = [];\n    this.isAccepted = false;\n  }\n\n  vote(voter: User, type: VoteTypeEnum) {\n    this.votes = this.votes.filter(\n      (v) => v.getVoter().getUserId() != voter.getUserId(),\n    );\n    this.votes.push(new Vote(voter, type));\n    this.author.updateReputation(\n      type == VoteTypeEnum.UPVOTE\n        ? ReputationTypeEnum.ANSWER_UPVOTE\n        : ReputationTypeEnum.ANSWER_DOWNVOTE,\n    );\n  }\n\n  getVoteCount() {\n    return this.votes.reduce((sum, vote) => sum + vote.getVoteType(), 0);\n  }\n\n  addComment(comment: Comment) {\n    this.comments.push(comment);\n  }\n\n  getComments() {\n    return this.comments;\n  }\n\n  getQuestion() {\n    return this.question;\n  }\n\n  markAsAccepted() {\n    if (this.isAccepted) {\n      throw new Error(\"This answer is already accepted\");\n    }\n    this.isAccepted = true;\n    this.author.updateReputation(ReputationTypeEnum.ANSWER_ACCEPTED);\n  }\n\n  getId() {\n    return this.id;\n  }\n  getAuthor() {\n    return this.author;\n  }\n  getContent() {\n    return this.content;\n  }\n  getIsAccepted() {\n    return this.isAccepted;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Comment.ts",
    "content": "import User from \"./User\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport default class Comment {\n  private id: string;\n  private content: string;\n  private author: User;\n  private creationDate: Date;\n\n  constructor(author: User, content: string) {\n    this.id = uuidv4();\n    this.author = author;\n    this.content = content;\n    this.creationDate = new Date();\n  }\n\n  getId() {\n    return this.id;\n  }\n  getAuthor() {\n    return this.author;\n  }\n  getContent() {\n    return this.content;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Commentable.ts",
    "content": "import Comment from \"./Comment\";\n\nexport default interface Commentable {\n    addComment(comment: Comment): void;\n    getComments(): Comment[];\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Question.ts",
    "content": "import Answer from \"./Answer\";\nimport User from \"./User\";\nimport Vote from \"./Vote\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\nimport Comment from \"./Comment\";\nimport Tag from \"./Tag\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { ReputationTypeEnum } from \"./ReputationType\";\n\nexport default class Question {\n  private id: string;\n  private title: string;\n  private content: string;\n  private author: User;\n  private creationDate: Date;\n  private answers: Answer[];\n  private comments: Comment[];\n  private tags: Tag[];\n  private votes: Vote[];\n  private acceptedAnswer: Answer | null;\n\n  constructor(author: User, title: string, content: string, tags: Tag[]) {\n    this.id = uuidv4();\n    this.author = author;\n    this.title = title;\n    this.content = content;\n    this.creationDate = new Date();\n    this.answers = [];\n    this.votes = [];\n    this.comments = [];\n    this.tags = tags;\n    this.acceptedAnswer = null;\n  }\n\n  addAnswer(answer: Answer) {\n    this.answers.push(answer);\n  }\n\n  acceptAnswer(answer: Answer) {\n    this.acceptedAnswer = answer;\n  }\n\n  vote(voter: User, type: VoteTypeEnum) {\n    this.votes = this.votes.filter(\n      (v) => v.getVoter().getUserId() != voter.getUserId(),\n    );\n\n    this.votes.push(new Vote(voter, type));\n    this.author.updateReputation(\n      type == VoteTypeEnum.UPVOTE\n        ? ReputationTypeEnum.QUESTION_UPVOTE\n        : ReputationTypeEnum.QUESTION_DOWNVOTE,\n    );\n  }\n\n  getVoteCount() {\n    return this.votes.reduce((sum, vote) => sum + vote.getVoteType(), 0);\n  }\n\n  addComment(comment: Comment) {\n    this.comments.push(comment);\n  }\n\n  getComments() {\n    return this.comments;\n  }\n\n  getId() {\n    return this.id;\n  }\n  getAuthor() {\n    return this.author;\n  }\n  getTitle() {\n    return this.title;\n  }\n  getContent() {\n    return this.content;\n  }\n  getTags() {\n    return this.tags;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/README.md",
    "content": "# StackOverflow System (LLD)\n\n## Problem Statement\n\nDesign and implement a simplified StackOverflow-like Q&A platform. The system should allow users to post questions and answers, vote on them, comment, tag questions, and track user reputation.\n\n---\n\n## Requirements\n\n- **User Management:** Users can ask questions, answer, comment, and vote.\n- **Questions & Answers:** Users can post questions and answers. Each question can have multiple answers, and one accepted answer.\n- **Voting:** Users can upvote or downvote questions and answers. Reputation is updated accordingly.\n- **Comments:** Users can comment on both questions and answers.\n- **Tags:** Questions can be tagged for categorization.\n- **Reputation:** Users gain or lose reputation based on votes and accepted answers.\n- **Accepted Answer:** The question author can mark one answer as accepted.\n\n---\n\n## Core Entities\n\n- **User:** Represents a user, tracks reputation and user details.\n- **Question:** Represents a question, holds answers, comments, tags, votes, and accepted answer.\n- **Answer:** Represents an answer to a question, holds comments, votes, and accepted status.\n- **Comment:** Represents a comment on a question or answer.\n- **Tag:** Represents a tag for categorizing questions.\n- **Vote:** Represents a vote (upvote/downvote) by a user on a question or answer.\n- **VoteType:** Enum for UPVOTE and DOWNVOTE.\n- **Votable (interface):** For entities that can be voted on.\n- **Commentable (interface):** For entities that can be commented on.\n\n---\n\n## Class Design\n\n## UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/stackoverflow-class-diagram.png)\n\n### 1. User\n- **Fields:** id, name, reputation, etc.\n- **Methods:** updateReputation(int delta), getReputation(), etc.\n\n### 2. Question\n- **Fields:** id, title, content, author, creationDate, answers, comments, tags, votes, acceptedAnswer\n- **Methods:** addAnswer(Answer), acceptAnswer(Answer), vote(User, VoteType), getVoteCount(), addComment(Comment), getComments(), etc.\n\n### 3. Answer\n- **Fields:** id, content, author, question, isAccepted, creationDate, comments, votes\n- **Methods:** vote(User, VoteType), getVoteCount(), addComment(Comment), getComments(), markAsAccepted(), etc.\n\n### 4. Comment\n- **Fields:** id, content, author, creationDate\n\n### 5. Tag\n- **Fields:** name\n\n### 6. Vote\n- **Fields:** voter, type (VoteType)\n- **Methods:** getVoter(), getType()\n\n### 7. VoteType\n- Enum: UPVOTE, DOWNVOTE\n\n### 8. Votable (interface)\n- **Methods:** vote(User, VoteType), getVoteCount()\n\n### 9. Commentable (interface)\n- **Methods:** addComment(Comment), getComments()\n\n---\n\n## Design Patterns Used\n\n- **Strategy Pattern:** For voting and commenting behaviors via interfaces.\n- **Observer Pattern:** (Conceptually) for reputation updates on votes and accepted answers.\n\n---\n\n## Example Usage\n\n```ts\nconst stackOverflow = StackOverflow.getInstance();\nconst alice = stackOverflow.createUser(\"Alice\", \"alice@example.com\");\nconst q = stackOverflow.postQuestion(alice, \"What is JavaScript?\", \"Explain JavaScript basics.\", [\"javascript\", \"basics\"]);\nconst bob = stackOverflow.createUser(\"Bob\", \"bob@example.com\");\nconst a = stackOverflow.postAnswer(bob.getUserId(), q.getId(), \"JavaScript is a programming language.\");\nstackOverflow.vote(bob.getUserId(), q, VoteTypeEnum.UPVOTE);\nstackOverflow.acceptAnswer(a.getId());\n```\n\n---\n\n## Demo\n\nSee `StackOverflowDemo.ts` for a sample usage of the StackOverflow system.\n\n---\n\n## Extending the Framework\n\n- **Add new features:** Such as badges, user profiles, or advanced search.\n- **Add new vote types:** Extend `VoteType` and update logic in `vote()` methods.\n- **Add moderation:** Implement admin/moderator roles for content management.\n\n---"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/ReputationType.ts",
    "content": "export enum ReputationTypeEnum {\n  QUESTION_UPVOTE = 5,\n  QUESTION_DOWNVOTE = -2,\n  ANSWER_UPVOTE = 10,\n  ANSWER_DOWNVOTE = -2,\n  ANSWER_ACCEPTED = 15,\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/StackOverflow.ts",
    "content": "import Answer from \"./Answer\";\nimport Comment from \"./Comment\";\nimport Commentable from \"./Commentable\";\nimport Question from \"./Question\";\nimport Tag from \"./Tag\";\nimport User from \"./User\";\nimport Votable from \"./Votable\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\n\nexport default class StackOverflow {\n  private static instance: StackOverflow;\n  private users: Map<String, User>;\n  private questions: Map<String, Question>;\n  private answers: Map<String, Answer>;\n  private tags: Map<String, Tag>;\n\n  private constructor() {\n    this.users = new Map();\n    this.questions = new Map();\n    this.answers = new Map();\n    this.tags = new Map();\n  }\n\n  static getInstance() {\n    if (StackOverflow.instance == null) {\n      StackOverflow.instance = new StackOverflow();\n    }\n    return StackOverflow.instance;\n  }\n\n  createUser(username: string, email: string) {\n    const user = new User(username, email);\n    this.users.set(user.getUserId(), user);\n    return user;\n  }\n\n  postQuestion(\n    userId: string,\n    title: string,\n    content: string,\n    questionTags: string[],\n  ) {\n    const author = this.getUser(userId);\n\n    const tagList = [];\n    for (const qTag of questionTags) {\n      let tag = this.tags.get(qTag); // Check if tag already exists\n      if (!tag) {\n        tag = new Tag(qTag); // Create new Tag if not found\n      }\n      tagList.push(tag);\n      this.tags.set(tag.getId(), tag);\n    }\n    const question = new Question(author, title, content, tagList);\n    this.questions.set(question.getId(), question);\n    return question;\n  }\n\n  postAnswer(userId: string, questionId: string, content: string) {\n    const author = this.getUser(userId);\n    const question = this.questions.get(questionId);\n    if (!question) throw new Error(\"Question Does Not Exist\");\n\n    const answer = new Answer(author, question, content);\n    question.addAnswer(answer);\n    this.answers.set(answer.getId(), answer);\n    return answer;\n  }\n\n  getUser(userId: string) {\n    const user = this.users.get(userId);\n    if (!user) throw new Error(\"User Does Not Exist\");\n\n    return user;\n  }\n\n  addComment(userId: string, commentable: Commentable, content: string) {\n    const author = this.getUser(userId);\n    const comment = new Comment(author, content);\n    commentable.addComment(new Comment(author, content));\n    return comment;\n  }\n\n  vote(userId: string, votable: Votable, voteType: VoteTypeEnum) {\n    const user = this.getUser(userId);\n    votable.vote(user, voteType);\n  }\n\n  acceptAnswer(answerId: string) {\n    const answer = this.answers.get(answerId);\n    if (!answer) throw new Error(\"Answer Not Found\");\n\n    const question = answer.getQuestion();\n    answer.markAsAccepted();\n    question.acceptAnswer(answer);\n  }\n\n  searchQuestions(query: string) {\n    const lowerQuery = query.toLowerCase();\n\n    return [...this.questions.values()].filter(\n      (q) =>\n        q.getTitle().toLowerCase().includes(lowerQuery) ||\n        q.getContent().toLowerCase().includes(lowerQuery) ||\n        q.getTags().some((t) => t.getName().toLowerCase() === lowerQuery),\n    );\n  }\n\n  getQuestionsByUser(userId: string) {\n    return [...this.questions.values()].filter(\n      (q) => q.getAuthor().getUserId() === userId,\n    );\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/StackOverflowDemo.ts",
    "content": "import StackOverflow from \"./StackOverflow\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\n\nexport default class StackOverflowDemo {\n  static run() {\n    const stackOverflow = StackOverflow.getInstance();\n\n    // Create users\n    const alice = stackOverflow.createUser(\"Alice\", \"alice@example.com\");\n    const bob = stackOverflow.createUser(\"Bob\", \"bob@example.com\");\n    const charlie = stackOverflow.createUser(\"Charlie\", \"charlie@example.com\");\n\n    // Alice asks a question\n    const javaQuestion = stackOverflow.postQuestion(\n      alice.getUserId(),\n      \"Why does typeof null return 'object'?\",\n      \"I tried `typeof null` and got 'object'. I expected 'null'. Is this a bug or feature?\",\n      [\"javascript\", \"typeof\", \"null\"],\n    );\n\n    // Bob answers Alice's question\n    const bobAnswer = stackOverflow.postAnswer(\n      bob.getUserId(),\n      javaQuestion.getId(),\n      \"`typeof null` returns 'object' due to a bug in JavaScript's early implementation. It’s now a legacy quirk, and changing it would break existing code.\",\n    );\n\n    // Charlie comments on the question\n    stackOverflow.addComment(\n      charlie.getUserId(),\n      javaQuestion,\n      \"Welcome to JavaScript! Where 'null' is an object and 'undefined' means everything and nothing. 😅\",\n    );\n\n    // Alice comments on Bob's answer\n    stackOverflow.addComment(\n      alice.getUserId(),\n      bobAnswer,\n      \"Wow, that's weird but helpful. Thanks Bob!\",\n    );\n\n    // Charlie votes on the question and answer\n    stackOverflow.vote(charlie.getUserId(), javaQuestion, VoteTypeEnum.UPVOTE);\n    stackOverflow.vote(charlie.getUserId(), bobAnswer, VoteTypeEnum.UPVOTE);\n\n    // Alice accepts Bob's answer\n    stackOverflow.acceptAnswer(bobAnswer.getId());\n\n    // Print out the current state\n    console.log(\"Question: \" + javaQuestion.getTitle());\n    console.log(\"Asked by: \" + javaQuestion.getAuthor().getName());\n    console.log(\n      \"Tags: \" +\n        javaQuestion\n          .getTags()\n          .map((tag) => tag.getName())\n          .join(\", \"),\n    );\n    console.log(\"Votes: \" + javaQuestion.getVoteCount());\n    console.log(\"Comments: \" + javaQuestion.getComments().length);\n    console.log(\"\\nAnswer by \" + bobAnswer.getAuthor().getName() + \":\");\n    console.log(bobAnswer.getContent());\n    console.log(\"Votes: \" + bobAnswer.getVoteCount());\n    console.log(\"Accepted: \" + bobAnswer.getIsAccepted());\n    console.log(\"Comments: \" + bobAnswer.getComments().length);\n\n    console.log(\"\\nUser Reputations:\");\n    console.log(\"Alice: \" + alice.getReputation());\n    console.log(\"Bob: \" + bob.getReputation());\n    console.log(\"Charlie: \" + charlie.getReputation());\n\n    // Search questions by keyword\n    console.log(\"\\nSearch Results for 'javascript':\");\n    const searchResults = stackOverflow.searchQuestions(\"javascript\");\n    for (const q of searchResults) {\n      console.log(q.getTitle());\n    }\n\n    // Search questions by user\n    console.log(\"\\nAlice's Questions:\");\n    const bobQuestions = stackOverflow.getQuestionsByUser(alice.getUserId());\n    for (const q of bobQuestions) {\n      console.log(q.getTitle());\n    }\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Tag.ts",
    "content": "import { v4 as uuidv4 } from \"uuid\";\n\nexport default class Tag {\n    private id: string;\n    private name: string;\n\n    constructor(name: string) {\n        this.id = uuidv4();\n        this.name = name;\n    }\n\n    getId() {\n        return this.id;\n    }\n    getName() {\n        return this.name;\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/User.ts",
    "content": "import { v4 as uuidv4 } from \"uuid\";\n\nexport default class User {\n  private userId: string;\n  private name: string;\n  private email: string;\n  private reputation: number;\n\n  constructor(name: string, email: string) {\n    this.userId = uuidv4();\n    this.name = name;\n    this.email = email;\n    this.reputation = 0;\n  }\n\n  updateReputation(value: number) {\n    this.reputation += value;\n    if (this.reputation < 0) {\n      this.reputation = 0;\n    }\n  }\n\n  getUserId() {\n    return this.userId;\n  }\n  getName() {\n    return this.name;\n  }\n  getReputation() {\n    return this.reputation;\n  }\n  getEmail() {\n    return this.email;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Votable.ts",
    "content": "import User from \"./User\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\n\nexport default interface Votable {\n    vote(voter: User, type: VoteTypeEnum): void;\n    getVoteCount(): number;\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/Vote.ts",
    "content": "import User from \"./User\";\nimport { VoteTypeEnum } from \"./VoteTypeEnum\";\n\nexport default class Vote {\n  private voter: User;\n  private type: VoteTypeEnum;\n\n  constructor(voter: User, type: VoteTypeEnum) {\n    this.voter = voter;\n    this.type = type;\n  }\n\n  getVoter() {\n    return this.voter;\n  }\n\n  getVoteType() {\n    return this.type;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/StackOverflow/VoteTypeEnum.ts",
    "content": "export enum VoteTypeEnum {\n  UPVOTE = 1,\n  DOWNVOTE = -1,\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/ActivityLog.ts",
    "content": "import User from \"./User\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport default class ActivityLog {\n    private logId: string;\n    private action: string;\n    private performedBy: User;\n    private timestamp: Date;\n\n    constructor(action: string, performedBy: User) {\n        this.logId = uuidv4();\n        this.action = action;\n        this.performedBy = performedBy;\n        this.timestamp = new Date();\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/Comment.ts",
    "content": "import User from \"./User\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport default class Comment {\n    private id: string;\n    private content: string;\n    private author: User;\n    private timestamp: Date;\n\n    constructor(content: string, author: User) {\n        this.id = uuidv4();\n        this.content = content;\n        this.author = author;\n        this.timestamp = new Date();\n    }\n\n    getAuthor() {\n        return this.author;\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/README.md",
    "content": "# Task Management System (LLD)\n\n## Problem Statement\n\nDesign and implement a Task Management System that allows users to create, assign, update, and track tasks. The system should support task priorities, statuses, comments, and user assignment.\n\n---\n\n## Requirements\n\n- **Task Creation:** Users can create tasks with a title, description, priority, and assignee.\n- **Task Assignment:** Tasks can be assigned to users and reassigned as needed.\n- **Task Status:** Tasks can have statuses such as TODO, IN_PROGRESS, DONE, etc.\n- **Task Priority:** Tasks can have priorities such as LOW, MEDIUM, HIGH.\n- **Comments:** Users can add comments to tasks.\n- **Task Updates:** Tasks can be updated (status, priority, assignee, etc.).\n- **Task Listing:** List all tasks, or filter by status, priority, or assignee.\n- **Extensibility:** Easy to add new statuses, priorities, or features.\n\n---\n\n## Core Entities\n\n- **Task:** Represents a task with title, description, status, priority, assignee, and comments.\n- **User:** Represents a user who can create, assign, and be assigned tasks.\n- **Comment:** Represents a comment on a task.\n- **TaskStatus:** Enum for task statuses (TODO, IN_PROGRESS, DONE, etc.).\n- **TaskPriority:** Enum for task priorities (LOW, MEDIUM, HIGH).\n- **TaskManager:** Manages the collection of tasks and provides methods for task operations.\n\n---\n\n## Class Design\n\n### UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/taskmanagementsystem-class-diagram.png)\n\n### 1. Task\n- **Fields:** id, title, description, status, priority, assignee (User), List<Comment>\n- **Methods:** updateStatus(TaskStatus), updatePriority(TaskPriority), assignUser(User), addComment(Comment), etc.\n\n### 2. User\n- **Fields:** id, name\n- **Methods:** getId(), getName()\n\n### 3. Comment\n- **Fields:** id, content, author (User), timestamp\n\n### 4. TaskStatus (enum)\n- Values: TODO, IN_PROGRESS, DONE, etc.\n\n### 5. TaskPriority (enum)\n- Values: LOW, MEDIUM, HIGH\n\n### 6. TaskManager\n- **Fields:** List<Task>\n- **Methods:** createTask(...), assignTask(...), updateTaskStatus(...), updateTaskPriority(...), addCommentToTask(...), listTasks(), listTasksByStatus(...), listTasksByAssignee(...), etc.\n\n---\n\n## Design Patterns Used\n\n- **Separation of Concerns:** Each class has a single responsibility (task, user, comment, management).\n- **Manager Pattern:** `TaskManager` acts as a service/manager for all task operations.\n\n---\n\n## Example Usage\n\n```ts\nconst taskManagementSystem = TaskManagementSystem.getInstance();\nUser alice = taskManagementSystem.createUser(\"Alice\",\"alice@example.com\");\nUser bob = taskManagementSystem.createUser(\"Bob\",\"bob@example.com\");\n\nconst taskList = taskManagementSystem.createTaskList(\"Enhancements\");\nconst task = taskManagementSystem.createTask( taskList.getId(), \"Task 1\", \"Description 1\", new Date(), TaskPriorityEnum.LOW, alice.getId());\n\ntaskManagementSystem.assignTask(task.getId(), bob.getId());\ntaskManagementSystem.updateTaskStatus(task.getId(), TaskStatus.IN_PROGRESS);\n```\n\n---\n\n## Demo\n\nSee `TaskManagementSystemDemo.ts` for a sample usage and simulation of the task management system.\n\n---\n\n## Extending the Framework\n\n- **Add new statuses or priorities:** Update the `TaskStatus` or `TaskPriority` enums.\n- **Add new features:** Such as deadlines, notifications, or task dependencies.\n\n---"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/SortingStrategy/SortByDueDate.ts",
    "content": "import Task from \"../Task\";\nimport TaskSortingStrategy from \"./TaskSortingStrategy\";\n\nexport default class SortByDueDate implements TaskSortingStrategy {\n  sort(tasks: Task[]) {\n    tasks.sort((taskA, taskB) => {\n      const dueDateA = taskA.getDueDate();\n      const dueDateB = taskB.getDueDate();\n\n      // Sort in ascending order (earliest due date first)\n      return dueDateA.getTime() - dueDateB.getTime();\n    });\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/SortingStrategy/SortByPriority.ts",
    "content": "import Task from \"../Task\";\nimport TaskSortingStrategy from \"./TaskSortingStrategy\";\n\nexport default class SortByPriority implements TaskSortingStrategy {\n  private priorityOrder = {\n    LOW: 1,\n    MEDIUM: 2,\n    HIGH: 3,\n    CRITICAL: 4,\n  };\n\n  sort(tasks: Task[]): void {\n    tasks.sort((taskA, taskB) => {\n      const priorityA = this.priorityOrder[taskA.getPriority()];\n      const priorityB = this.priorityOrder[taskB.getPriority()];\n\n      // Sort in descending order (Critical > High > Medium > Low)\n      return priorityB - priorityA;\n    });\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/SortingStrategy/TaskSortingStrategy.ts",
    "content": "import Task from \"../Task\";\n\nexport default interface TaskSortingStrategy {\n  sort(tasks: Task[]): void;\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/Task.ts",
    "content": "import { TaskPriorityEnum } from \"./TaskPriorityEnum\";\nimport { TaskStatusEnum } from \"./TaskStatusEnum\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport User from \"./User\";\nimport Comment from \"./Comment\";\nimport ActivityLog from \"./ActivityLog\";\n\nexport default class Task {\n  private id: string;\n  private title: string;\n  private description: string;\n  private priority: TaskPriorityEnum;\n  private status: TaskStatusEnum;\n  private dueDate: Date;\n  private createdBy: User;\n  private assignedTo: User | null;\n\n  private comments: Comment[];\n  private subtasks: Task[];\n  private history: ActivityLog[];\n\n  constructor(\n    title: string,\n    description: string,\n    dueDate: Date,\n    priority: TaskPriorityEnum,\n    createdBy: User,\n  ) {\n    this.id = uuidv4(); // from uuid package\n    this.title = title;\n    this.description = description;\n    this.priority = priority;\n    this.dueDate = dueDate;\n    this.createdBy = createdBy;\n\n    this.status = TaskStatusEnum.TODO;\n    this.assignedTo = null;\n    this.comments = [];\n    this.subtasks = [];\n    this.history = [];\n    this.logActivity(\"Created\");\n  }\n\n  addComment(comment: Comment) {\n    this.comments.push(comment);\n    this.logActivity(\"Comment added by \" + comment.getAuthor().getName());\n  }\n\n  addSubtask(subtask: Task) {\n    this.subtasks.push(subtask);\n    this.logActivity(\"Subtask added: \" + subtask.getTitle());\n  }\n\n  logActivity(action: string) {\n    this.history.push(new ActivityLog(action, this.createdBy));\n  }\n\n  updateStatus(status: TaskStatusEnum) {\n    this.status = status;\n    this.logActivity(\"Status changed to \" + status);\n  }\n\n  updatePriority(priority: TaskPriorityEnum) {\n    this.priority = priority;\n    this.logActivity(\"Priority changed to \" + priority);\n  }\n\n  assignUser(user: User) {\n    this.assignedTo = user;\n    this.logActivity(\"Assigned to \" + user.getName());\n  }\n\n  getId() {\n    return this.id;\n  }\n\n  getTitle() {\n    return this.title;\n  }\n\n  getPriority() {\n    return this.priority;\n  }\n\n  getDueDate() {\n    return this.dueDate;\n  }\n\n  getAssignedTo() {\n    return this.assignedTo;\n  }\n\n  getCreatedBy() {\n    return this.createdBy;\n  }\n\n  getDescription() {\n    return this.description;\n  }\n\n  getStatus() {\n    return this.status;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/TaskList.ts",
    "content": "import Task from \"./Task\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport default class TaskList {\n  private id: string;\n  private name: string;\n  private tasks: Task[];\n\n  constructor(name: string) {\n    this.id = uuidv4();\n    this.name = name;\n    this.tasks = [];\n  }\n\n  addTask(task: Task) {\n    this.tasks.push(task);\n  }\n\n  getTasks() {\n    return this.tasks;\n  }\n\n  getId() {\n    return this.id;\n  }\n\n  getName() {\n    return this.name;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/TaskManagementSystem.ts",
    "content": "import Task from \"./Task\";\nimport { TaskPriorityEnum } from \"./TaskPriorityEnum\";\nimport { TaskStatusEnum } from \"./TaskStatusEnum\";\nimport User from \"./User\";\nimport TaskList from \"./TaskList\";\nimport Comment from \"./Comment\";\nimport TaskSortingStrategy from \"./SortingStrategy/TaskSortingStrategy\";\n\nexport default class TaskManagementSystem {\n  private static instance: TaskManagementSystem | null;\n  private users: Map<String, User>;\n  private tasks: Map<String, Task>;\n  private taskLists: Map<String, TaskList>;\n\n  private constructor() {\n    this.users = new Map();\n    this.tasks = new Map();\n    this.taskLists = new Map();\n  }\n\n  static getInstance() {\n    if (!TaskManagementSystem.instance) {\n      TaskManagementSystem.instance = new TaskManagementSystem();\n    }\n    return TaskManagementSystem.instance;\n  }\n\n  createUser(name: string, email: string) {\n    const user = new User(name, email);\n    this.users.set(user.getId(), user);\n    return user;\n  }\n\n  createTaskList(listName: string) {\n    const taskList = new TaskList(listName);\n    this.taskLists.set(taskList.getId(), taskList);\n    return taskList;\n  }\n\n  createTask(\n    listId: string,\n    title: string,\n    description: string,\n    dueDate: Date,\n    priority: TaskPriorityEnum,\n    createdByUserId: string,\n  ) {\n    const taskList = this.taskLists.get(listId);\n    if (taskList == null) throw new Error(\"TaskList not found.\");\n\n    const createdBy = this.users.get(createdByUserId);\n    if (createdBy == null) throw new Error(\"User not found.\");\n\n    const task = new Task(title, description, dueDate, priority, createdBy);\n\n    this.tasks.set(task.getId(), task);\n    taskList.addTask(task);\n    return task;\n  }\n\n  getTaskById(taskId: string) {\n    const task = this.tasks.get(taskId);\n    if (!task) {\n      throw new Error(\"Task not found: \" + taskId);\n    }\n    return task;\n  }\n\n  updateTaskStatus(taskId: string, status: TaskStatusEnum) {\n    this.getTaskById(taskId).updateStatus(status);\n  }\n\n  updateTaskPriority(taskId: string, priority: TaskPriorityEnum) {\n    this.getTaskById(taskId).updatePriority(priority);\n  }\n\n  assignTask(taskId: string, userId: string) {\n    const user = this.users.get(userId);\n    if (user == null) throw new Error(\"User not found.\");\n    this.getTaskById(taskId).assignUser(user);\n  }\n\n  addComment(taskId: string, commentText: string, author: User) {\n    const task = this.getTaskById(taskId);\n    task.addComment(new Comment(commentText, author));\n  }\n\n  listTasksByUser(userId: string) {\n    return [...this.tasks.values()].filter(\n      (task) => userId == task.getAssignedTo()?.getId(),\n    );\n  }\n\n  listTasksByStatus(status: TaskStatusEnum) {\n    return [...this.tasks.values()].filter(\n      (task) => task.getStatus() == status,\n    );\n  }\n\n  deleteTask(taskId: string) {\n    this.tasks.delete(taskId);\n  }\n\n  searchTasks(keyword: string, sortingStrategy: TaskSortingStrategy) {\n    const matchingTasks = [];\n    for (const task of this.tasks.values()) {\n      if (\n        task.getTitle().includes(keyword) ||\n        task.getDescription().includes(keyword)\n      ) {\n        matchingTasks.push(task);\n      }\n    }\n    sortingStrategy.sort(matchingTasks);\n    return matchingTasks;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/TaskManagementSystemDemo.ts",
    "content": "import SortByDueDate from \"./SortingStrategy/SortByDueDate\";\nimport TaskManagementSystem from \"./TaskManagementSystem\";\nimport { TaskPriorityEnum } from \"./TaskPriorityEnum\";\nimport { TaskStatusEnum } from \"./TaskStatusEnum\";\n\nexport default class TaskManagementDemo {\n  static run() {\n    const taskManagementSystem = TaskManagementSystem.getInstance();\n\n    // Create users\n    const user1 = taskManagementSystem.createUser(\n      \"John Doe\",\n      \"john@example.com\",\n    );\n    const user2 = taskManagementSystem.createUser(\n      \"Jane Smith\",\n      \"jane@example.com\",\n    );\n\n    // Create task lists\n    const taskList1 = taskManagementSystem.createTaskList(\"Enhancements\");\n    const taskList2 = taskManagementSystem.createTaskList(\"Bug Fix\");\n\n    // Create tasks\n    const task1 = taskManagementSystem.createTask(\n      taskList1.getId(),\n      \"Task 1\",\n      \"Description 1\",\n      new Date(),\n      TaskPriorityEnum.LOW,\n      user1.getId(),\n    );\n    const task2 = taskManagementSystem.createTask(\n      taskList1.getId(),\n      \"Task 2\",\n      \"Description 2\",\n      new Date(),\n      TaskPriorityEnum.MEDIUM,\n      user1.getId(),\n    );\n    const task3 = taskManagementSystem.createTask(\n      taskList2.getId(),\n      \"Task 3\",\n      \"Description 3\",\n      new Date(),\n      TaskPriorityEnum.HIGH,\n      user2.getId(),\n    );\n\n    // Update task status\n    taskManagementSystem.updateTaskStatus(\n      task2.getId(),\n      TaskStatusEnum.IN_PROGRESS,\n    );\n\n    // Assign task\n    taskManagementSystem.assignTask(task2.getId(), user2.getId());\n\n    // Search tasks\n    const searchResults = taskManagementSystem.searchTasks(\n      \"Task\",\n      new SortByDueDate(),\n    );\n    console.log(\"\\nTasks with keyword Task:\");\n    for (const task of searchResults) {\n      console.log(task.getTitle());\n    }\n\n    // Filter tasks by status\n    const filteredTasks = taskManagementSystem.listTasksByStatus(\n      TaskStatusEnum.TODO,\n    );\n    console.log(\"\\nTODO Tasks:\");\n    for (const task of filteredTasks) {\n      console.log(task.getTitle());\n    }\n\n    // Mark a task as done\n    taskManagementSystem.updateTaskStatus(task2.getId(), TaskStatusEnum.DONE);\n\n    // Get tasks assigned to a user\n    const userTaskList = taskManagementSystem.listTasksByUser(user2.getId());\n    console.log(\"\\nTask for \" + user2.getName() + \":\");\n    for (const task of userTaskList) {\n      console.log(task.getTitle());\n    }\n\n    // Delete a task\n    taskManagementSystem.deleteTask(task3.getId());\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/TaskPriorityEnum.ts",
    "content": "export enum TaskPriorityEnum {\n  LOW = \"LOW\",\n  MEDIUM = \"MEDIUM\",\n  HIGH = \"HIGH\",\n  CRITICAL = \"CRITICAL\",\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/TaskStatusEnum.ts",
    "content": "export enum TaskStatusEnum {\n  TODO = \"TODO\",\n  IN_PROGRESS = \"IN_PROGRESS\",\n  DONE = \"DONE\",\n  BLOCKED = \"BLOCKED\",\n}\n"
  },
  {
    "path": "solutions/typescript/src/TaskManagement/User.ts",
    "content": "import { v4 as uuidv4 } from \"uuid\";\n\nexport default class User {\n  private id: string;\n  private name: string;\n  private email: string;\n\n  constructor(name: string, email: string) {\n    this.id = uuidv4();\n    this.name = name;\n    this.email = email;\n  }\n\n  getName() {\n    return this.name;\n  }\n\n  getId() {\n    return this.id;\n  }\n\n  getEmail() {\n    return this.email;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/Direction.ts",
    "content": "export enum DirectionEnum {\n  NORTH = \"NORTH\",\n  SOUTH = \"SOUTH\",\n  EAST = \"EAST\",\n  WEST = \"WEST\",\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/Intersection.ts",
    "content": "import { DirectionEnum } from \"./Direction\";\nimport TrafficLight from \"./TrafficLight\";\nimport TrafficSignalController from \"./TrafficSignalController\";\n\nexport default class Intersection {\n    private id: string;\n    private signals: Map<DirectionEnum, TrafficLight>;\n    private signalDurations: Map<DirectionEnum, Map<String, number>>;\n    private controller: TrafficSignalController;\n\n    constructor(\n        id: string,\n        signals: Map<DirectionEnum, TrafficLight>,\n        signalDurations: Map<DirectionEnum, Map<String, number>>,\n    ) {\n        this.id = id;\n        this.signals = signals;\n        this.signalDurations = signalDurations;\n        this.controller = new TrafficSignalController(signals, signalDurations);\n    }\n\n    start(startDirection: DirectionEnum) {\n        this.controller.start(startDirection);\n    }\n\n    manualOverride(direction: DirectionEnum) {\n        console.log(\"Manual override: Setting \" + direction + \" to GREEN.\");\n        this.controller.manualOverride(direction);\n    }\n\n    getSignal(direction: DirectionEnum) {\n        return this.signals.get(direction);\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/README.md",
    "content": "# Traffic Signal System (LLD)\n\n## Problem Statement\n\nDesign and implement a Traffic Signal System to manage the traffic lights at an intersection. The system should support configurable signal durations for each direction and state, automatic cycling of signals using the State design pattern, and the ability to manually override signals as needed.\n\n---\n\n## Requirements\n\n- **Multiple Directions:** The intersection supports multiple directions (e.g., NORTH, SOUTH, EAST, WEST).\n- **Traffic Light States:** Each direction has a traffic light with states: GREEN, YELLOW, RED.\n- **Configurable Durations:** Each direction and state can have its own configurable duration.\n- **Automatic Cycling:** The system automatically cycles through the states for each direction in a round-robin fashion.\n- **Manual Override:** The system allows manual override to set a specific direction to GREEN at any time.\n- **Extensibility:** Easy to add new directions or states if needed.\n- **State Pattern:** Use the State design pattern to encapsulate state-specific behavior and transitions.\n\n---\n\n## Core Entities\n\n- **Direction:** Enum representing the directions at the intersection (NORTH, SOUTH, EAST, WEST).\n- **SignalState (interface):** Represents the state of a traffic light (GREEN, YELLOW, RED), with state-specific behavior.\n- **GreenState, YellowState, RedState:** Concrete implementations of `SignalState` for each light state.\n- **TrafficLight:** Represents a traffic light for a direction, maintains its current state and delegates behavior to the state.\n- **Intersection:** Represents the intersection, holds all traffic lights and their configurations, and exposes the manual override.\n- **TrafficSignalController:** Controls the cycling and overriding of traffic signals, manages timing and transitions using a scheduler.\n\n---\n\n## Class Design\n\n### UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/trafficsignalsystem-class-diagram.png)\n\n### 1. Direction\n- Enum: NORTH, SOUTH, EAST, WEST\n\n### 2. SignalState (interface)\n- **Methods:** `void handle(TrafficLight, TrafficSignalController, Direction)`, `String getName()`\n\n### 3. GreenState, YellowState, RedState\n- Implement `SignalState`\n- Each handles its own transition logic and duration\n\n### 4. TrafficLight\n- **Fields:** currentState, direction\n- **Methods:** setState(SignalState), getState(), getDirection(), handle(TrafficSignalController)\n\n### 5. Intersection\n- **Fields:** id, Map<Direction, TrafficLight> signals, Map<Direction, Map<String, Integer>> signalDurations, TrafficSignalController controller\n- **Methods:** start(Direction), manualOverride(Direction), getSignal(Direction)\n\n### 6. TrafficSignalController\n- **Fields:** Map<Direction, TrafficLight> signals, Map<Direction, Map<String, Integer>> signalDurations, scheduler\n- **Methods:** start(Direction), scheduleStateChange(...), getSignalDuration(...), getNextDirection(...), getTrafficLight(...), manualOverride(Direction)\n\n---\n\n## Design Patterns Used\n\n- **State Pattern:** Each signal state (GREEN, YELLOW, RED) encapsulates its own behavior and transition logic.\n- **Scheduler/Timer:** For handling timed transitions between states.\n- **Strategy Pattern:** (Conceptually) for supporting different timing strategies per direction/state.\n\n---\n\n## Example Usage\n\n```ts\n// Configure durations per direction and state\nconst signalDurations = new Map<Direction, Map<string, number>>([\n    [Direction.NORTH, new Map([[\"GREEN\", 4], [\"YELLOW\", 2], [\"RED\", 3]])],\n    [Direction.SOUTH, new Map([[\"GREEN\", 3], [\"YELLOW\", 2], [\"RED\", 4]])],\n    [Direction.EAST, new Map([[\"GREEN\", 5], [\"YELLOW\", 2], [\"RED\", 3]])],\n    [Direction.WEST, new Map([[\"GREEN\", 2], [\"YELLOW\", 2], [\"RED\", 5]])]\n]);\n\n// Initialize traffic lights\nconst signals = new Map<Direction, TrafficLight>();\nfor (const direction of Object.values(Direction)) {\n    signals.set(direction, new TrafficLight(direction));\n}\n\n// Create and start the controller\nconst intersection1 = new Intersection(\"1\", signals, signalDurations);\nintersection1.start(Direction.NORTH);\n```\n\n---\n\n## Demo\n\nSee `TrafficSignalSystemDemo.ts` for a sample usage and simulation of the traffic signal system.\n\n---\n\n## Extending the Framework\n\n- **Add new directions:** Add to the `Direction` enum and update configuration.\n- **Add new states:** Add to the `SignalState` interface and implement new state classes.\n- **Custom timing strategies:** Implement new strategies for special intersections or adaptive signals.\n\n---"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/SignalState/GreenState.ts",
    "content": "import { DirectionEnum } from \"../Direction\";\nimport TrafficLight from \"../TrafficLight\";\nimport TrafficSignalController from \"../TrafficSignalController\";\nimport SignalState from \"./SignalState\";\nimport YellowState from \"./YellowState\";\n\nexport default class GreenState implements SignalState {\n    handle(\n        light: TrafficLight,\n        controller: TrafficSignalController,\n        direction: DirectionEnum,\n    ) {\n        console.log(\"Direction: \" + direction + \" | State: GREEN\");\n        const duration = controller.getSignalDuration(direction, this);\n        controller.scheduleStateChange(\n            light,\n            direction,\n            new YellowState(),\n            duration,\n        );\n    }\n\n    getName() {\n        return \"GREEN\";\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/SignalState/RedState.ts",
    "content": "import { DirectionEnum } from \"../Direction\";\nimport TrafficLight from \"../TrafficLight\";\nimport TrafficSignalController from \"../TrafficSignalController\";\nimport GreenState from \"./GreenState\";\nimport SignalState from \"./SignalState\";\n\nexport default class RedState implements SignalState {\n    handle(\n        light: TrafficLight,\n        controller: TrafficSignalController,\n        direction: DirectionEnum,\n    ) {\n        console.log(\"Direction: \" + direction + \" | State: RED\");\n        const duration = controller.getSignalDuration(direction, this);\n\n        // After RED, move to next direction's GREEN\n        const nextDirection = controller.getNextDirection(direction);\n        controller.scheduleStateChange(\n            controller.getTrafficLight(nextDirection),\n            nextDirection,\n            new GreenState(),\n            duration,\n        );\n    }\n\n    getName() {\n        return \"RED\";\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/SignalState/SignalState.ts",
    "content": "import { DirectionEnum } from \"../Direction\";\nimport TrafficLight from \"../TrafficLight\";\nimport TrafficSignalController from \"../TrafficSignalController\";\n\nexport default interface SignalState {\n    handle(\n        light: TrafficLight,\n        controller: TrafficSignalController,\n        direction: DirectionEnum,\n    ): void;\n    getName(): string;\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/SignalState/YellowState.ts",
    "content": "import { DirectionEnum } from \"../Direction\";\nimport TrafficLight from \"../TrafficLight\";\nimport TrafficSignalController from \"../TrafficSignalController\";\nimport RedState from \"./RedState\";\nimport SignalState from \"./SignalState\";\n\nexport default class YellowState implements SignalState {\n    handle(\n        light: TrafficLight,\n        controller: TrafficSignalController,\n        direction: DirectionEnum,\n    ) {\n        console.log(\"Direction: \" + direction + \" | State: YELLOW\");\n        const duration = controller.getSignalDuration(direction, this);\n        controller.scheduleStateChange(\n            light,\n            direction,\n            new RedState(),\n            duration,\n        );\n    }\n\n    getName() {\n        return \"YELLOW\";\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/TrafficLight.ts",
    "content": "import { DirectionEnum } from \"./Direction\";\nimport RedState from \"./SignalState/RedState\";\nimport SignalState from \"./SignalState/SignalState\";\nimport TrafficSignalController from \"./TrafficSignalController\";\n\nexport default class TrafficLight {\n    private state: SignalState;\n    private direction: DirectionEnum;\n\n    constructor(direction: DirectionEnum) {\n        this.direction = direction;\n        this.state = new RedState(); // Default initial state\n    }\n\n    setState(state: SignalState) {\n        this.state = state;\n    }\n\n    getState() {\n        return this.state;\n    }\n\n    getDirection() {\n        return this.direction;\n    }\n\n    handle(controller: TrafficSignalController) {\n        this.state.handle(this, controller, this.direction);\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/TrafficSignalController.ts",
    "content": "import { DirectionEnum } from \"./Direction\";\nimport GreenState from \"./SignalState/GreenState\";\nimport SignalState from \"./SignalState/SignalState\";\nimport TrafficLight from \"./TrafficLight\";\n\nexport default class TrafficSignalController {\n    private signals: Map<DirectionEnum, TrafficLight>;\n    private signalDurations: Map<DirectionEnum, Map<String, number>>;\n\n    constructor(\n        signals: Map<DirectionEnum, TrafficLight>,\n        signalDurations: Map<DirectionEnum, Map<String, number>>,\n    ) {\n        this.signals = signals;\n        this.signalDurations = signalDurations;\n    }\n\n    start(startDirection: DirectionEnum) {\n        const light = this.signals.get(startDirection);\n        if (!light) return;\n        light.setState(new GreenState());\n        light.handle(this);\n    }\n\n    scheduleStateChange(\n        light: TrafficLight,\n        direction: DirectionEnum,\n        nextState: SignalState,\n        delaySeconds: number,\n    ) {\n        setTimeout(() => {\n            light.setState(nextState);\n            light.handle(this); // Handle the light after state change\n        }, delaySeconds * 1000);\n    }\n\n    getSignalDuration(direction: DirectionEnum, state: SignalState) {\n        return this.signalDurations.get(direction)?.get(state.getName()) || 0;\n    }\n\n    getNextDirection(current: DirectionEnum): DirectionEnum {\n        const directions: DirectionEnum[] = Object.values(DirectionEnum);\n        const next = (directions.indexOf(current) + 1) % directions.length;\n        return directions[next];\n    }\n\n    getTrafficLight(direction: DirectionEnum) {\n        const signal = this.signals.get(direction);\n        if (!signal) throw new Error(\"Signal Not Found.\");\n        return signal;\n    }\n\n    manualOverride(direction: DirectionEnum) {\n        // Immediately set the specified direction to GREEN and start its cycle\n        const light = this.signals.get(direction);\n        if (!light) return;\n        light.setState(new GreenState());\n        light.handle(this);\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/TrafficSignalSystem/TrafficSignalSystemDemo.ts",
    "content": "import { DirectionEnum } from \"./Direction\";\nimport Intersection from \"./Intersection\";\nimport TrafficLight from \"./TrafficLight\";\n\nexport default class TrafficSignalSystemDemo {\n    static run() {\n        // Configure durations per direction and state\n        const signalDurations = new Map<DirectionEnum, Map<string, number>>([\n            [\n                DirectionEnum.NORTH,\n                new Map([\n                    [\"GREEN\", 4],\n                    [\"YELLOW\", 2],\n                    [\"RED\", 3],\n                ]),\n            ],\n            [\n                DirectionEnum.SOUTH,\n                new Map([\n                    [\"GREEN\", 3],\n                    [\"YELLOW\", 2],\n                    [\"RED\", 4],\n                ]),\n            ],\n            [\n                DirectionEnum.EAST,\n                new Map([\n                    [\"GREEN\", 5],\n                    [\"YELLOW\", 2],\n                    [\"RED\", 3],\n                ]),\n            ],\n            [\n                DirectionEnum.WEST,\n                new Map([\n                    [\"GREEN\", 2],\n                    [\"YELLOW\", 2],\n                    [\"RED\", 5],\n                ]),\n            ],\n        ]);\n\n        // Initialize traffic lights\n        const signals = new Map<DirectionEnum, TrafficLight>();\n        for (const direction of Object.values(DirectionEnum)) {\n            signals.set(direction, new TrafficLight(direction));\n        }\n\n        // Create and start the controller\n        const intersection1 = new Intersection(\"1\", signals, signalDurations);\n        intersection1.start(DirectionEnum.NORTH);\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/Coin.ts",
    "content": "export enum Coin {\n  PENNY = 1,\n  NICKEL = 5,\n  DIME = 10,\n  QUARTER = 25,\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/Inventory.ts",
    "content": "import Item from \"./Item\";\n\nexport default class Inventory {\n  private itemMap: Map<string, Item>;\n  private stockMap: Map<string, number>;\n\n  constructor() {\n    this.itemMap = new Map();\n    this.stockMap = new Map();\n  }\n\n  addItem(code: string, item: Item, quantity: number) {\n    this.itemMap.set(code, item);\n    this.stockMap.set(code, quantity);\n  }\n\n  getItem(code: string) {\n    return this.itemMap.get(code);\n  }\n\n  isAvailable(code: string) {\n    return (this.stockMap.get(code) ?? 0) > 0;\n  }\n\n  reduceStock(code: string) {\n    const stock = this.stockMap.get(code);\n    if (!stock || stock == 0) throw new Error(\"No Stock\");\n\n    this.stockMap.set(code, stock - 1);\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/Item.ts",
    "content": "export default class Item {\n  private code: string;\n  private name: string;\n  private price: number;\n\n  constructor(code: string, name: string, price: number) {\n    this.code = code;\n    this.name = name;\n    this.price = price;\n  }\n\n  getName() {\n    return this.name;\n  }\n\n  getPrice() {\n    return this.price;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/README.md",
    "content": "# Vending Machine (LLD)\n\n## Problem Statement\n\nDesign and implement a Vending Machine system that allows users to select products, insert coins/notes, dispense products, and return change. The system should manage inventory, handle payments, and use the State design pattern for its operations.\n\n---\n\n## Requirements\n\n- **Product Management:** The system manages a catalog of products, each with a price and available quantity.\n- **Inventory Management:** The system tracks the quantity of each item and prevents dispensing if out of stock.\n- **Payment Handling:** The system accepts coins and notes, tracks total payment, and returns change if necessary.\n- **State Management:** The system uses the State design pattern to manage its operational states (Idle, Ready, Dispense, ReturnChange).\n- **User Interaction:** Users can select products, insert coins/notes, and receive products and change.\n- **Extensibility:** Easy to add new item types, payment methods, or states.\n\n---\n\n## Core Entities\n\n- **VendingMachine:** Main class that manages inventory, state transitions, item selection, and payment.\n- **Product:** Represents a item with a name and price.\n- **Inventory:** Manages the stock of products.\n- **Coin / Note:** Represents accepted denominations for payment.\n- **VendingMachineState (interface):** Interface for different machine states.\n- **IdleState, ReadyState, DispenseState, ReturnChangeState:** Concrete states implementing VendingMachineState.\n- **Singleton Pattern:** VendingMachine is implemented as a singleton.\n\n---\n\n## Class Design\n\n### UML Class Diagram\n\n![](../../../../uml-diagrams/class-diagrams/vendingmachine-class-diagram.png)\n\n### 1. VendingMachine\n- **Fields:** Inventory inventory, VendingMachineState idleState, readyState, dispenseState, returnChangeState, currentState, Product selectedProduct, double totalPayment\n- **Methods:** addProduct(String, double, int), selectProduct(Product), insertCoin(Coin), insertNote(Note), dispenseProduct(), returnChange(), setState(VendingMachineState), getInstance(), etc.\n\n### 2. Product\n- **Fields:** String name, double price\n\n### 3. Inventory\n- **Fields:** Map<Product, Integer> productQuantities\n- **Methods:** addProduct(Product, int), getQuantity(Product), reduceQuantity(Product), isAvailable(Product)\n\n### 4. Coin / Note\n- **Fields:** double value\n- **Methods:** getValue()\n\n### 5. VendingMachineState (interface)\n- **Methods:** selectProduct(Product), insertCoin(Coin), insertNote(Note), dispenseProduct(), returnChange()\n\n### 6. IdleState, ReadyState, DispenseState, ReturnChangeState\n- **Implements:** VendingMachineState\n- **Behavior:** Each state handles allowed operations and transitions.\n\n---\n\n## Example Usage\n\n```ts\nconst machine = VendingMachine.getInstance();\nconst chips = machine.addItem(\"A1\",\"Chips\", 15, 10);\nmachine.selectItem(\"A1\");\nmachine.insertCoin(COIN.DIME);\nmachine.insertCoin(COIN.NICKEL);\nmachine.dispense();\n```\n\n---\n\n## Demo\n\nSee `VendingMachineDemo` class for a sample usage and simulation of the vending machine.\n\n---\n\n## Extending the Framework\n\n- **Add new payment methods:** Support for cards, mobile payments, etc.\n- **Add new states:** Maintenance, OutOfOrder, etc.\n- **Add item categories:** Snacks, drinks, etc.\n\n---\n\n## Design Patterns Used\n\n- **State Pattern:** For managing machine states and transitions.\n- **Singleton Pattern:** For ensuring a single instance of the VendingMachine.\n\n---"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachine.ts",
    "content": "import { Coin } from \"./Coin\";\nimport Inventory from \"./Inventory\";\nimport Item from \"./Item\";\nimport DispensingState from \"./VendingMachineState/DispensingState\";\nimport HasMoneyState from \"./VendingMachineState/HasMoneyState\";\nimport IdleState from \"./VendingMachineState/IdleState\";\nimport ItemSelectedState from \"./VendingMachineState/ItemSelectedState\";\nimport VendingMachineState from \"./VendingMachineState/VendingMachineState\";\n\nexport default class VendingMachine {\n  private static instance: VendingMachine | null;\n\n  private inventory: Inventory;\n  private selectedItemCode: string | null;\n  private balance: number;\n\n  private currentState: VendingMachineState;\n  private idleState: VendingMachineState;\n  private itemSelectedState: VendingMachineState;\n  private hasMoneyState: VendingMachineState;\n  private dispensingState: VendingMachineState;\n\n  private constructor() {\n    this.inventory = new Inventory();\n    this.idleState = new IdleState(this);\n    this.itemSelectedState = new ItemSelectedState(this);\n    this.hasMoneyState = new HasMoneyState(this);\n    this.dispensingState = new DispensingState(this);\n    this.currentState = this.idleState;\n    this.balance = 0;\n    this.selectedItemCode = null;\n  }\n\n  static getInstance() {\n    if (VendingMachine.instance == null) {\n      VendingMachine.instance = new VendingMachine();\n    }\n    return VendingMachine.instance;\n  }\n\n  insertCoin(coin: Coin) {\n    this.currentState.insertCoin(coin);\n  }\n\n  addItem(code: string, name: string, price: number, quantity: number) {\n    const item = new Item(code, name, price);\n    this.inventory.addItem(code, item, quantity);\n    return item;\n  }\n\n  selectItem(code: string) {\n    this.currentState.selectItem(code);\n  }\n\n  dispense() {\n    this.currentState.dispense();\n  }\n\n  dispenseItem() {\n    if (!this.selectedItemCode) {\n      throw new Error(\"No Item Selected Yet\");\n    }\n\n    const item = this.inventory.getItem(this.selectedItemCode);\n    if (!item) {\n      throw new Error(\"Item Not In Inventory\");\n    }\n\n    if (this.balance >= item.getPrice()) {\n      this.inventory.reduceStock(this.selectedItemCode);\n      this.balance -= item.getPrice();\n      console.log(\"Dispensed: \" + item.getName());\n      if (this.balance > 0) {\n        console.log(\"Returning change: \" + this.balance);\n      }\n    }\n    this.resetToIdleState();\n    this.setState(this.getIdleState());\n  }\n\n  refundBalance() {\n    console.log(\"Refunding: \" + this.balance);\n    this.balance = 0;\n  }\n\n  resetToIdleState() {\n    this.selectedItemCode = null;\n    this.balance = 0;\n  }\n\n  addBalance(value: number) {\n    this.balance += value;\n  }\n\n  //Getter, Setters\n  getIdleState() {\n    return this.idleState;\n  }\n\n  getItemSelectedState() {\n    return this.itemSelectedState;\n  }\n\n  getHasMoneyState() {\n    return this.hasMoneyState;\n  }\n\n  getDispensingState() {\n    return this.dispensingState;\n  }\n\n  getInventory() {\n    return this.inventory;\n  }\n\n  getSelectedItem() {\n    if (!this.selectedItemCode) {\n      throw new Error(\"No Item Selected Yet\");\n    }\n    return this.inventory.getItem(this.selectedItemCode);\n  }\n\n  setSelectedItemCode(code: string) {\n    this.selectedItemCode = code;\n  }\n\n  getBalance() {\n    return this.balance;\n  }\n\n  setState(state: VendingMachineState) {\n    this.currentState = state;\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineDemo.ts",
    "content": "import { Coin } from \"./Coin\";\nimport VendingMachine from \"./VendingMachine\";\n\nexport default class VendingMachineDemo{\n  static run(){\n    const vendingMachine = VendingMachine.getInstance();\n\n    // Add products to the inventory\n    vendingMachine.addItem(\"A1\", \"Coke\", 25, 3);\n    vendingMachine.addItem(\"A2\", \"Pepsi\", 25, 2);\n    vendingMachine.addItem(\"B1\", \"Water\", 10, 5);\n\n    // Select a product\n    console.log(\"\\n--- Step 1: Select an item ---\");\n    vendingMachine.selectItem(\"A1\");\n\n    // Insert coins\n    console.log(\"\\n--- Step 2: Insert coins ---\");\n    vendingMachine.insertCoin(Coin.DIME); // 10\n    vendingMachine.insertCoin(Coin.DIME); // 10\n    vendingMachine.insertCoin(Coin.NICKEL); // 5\n\n    // Dispense the product\n    console.log(\"\\n--- Step 3: Dispense item ---\");\n    vendingMachine.dispense(); // Should dispense Coke\n\n    // Select another item\n    console.log(\"\\n--- Step 4: Select another item ---\");\n    vendingMachine.selectItem(\"B1\");\n\n    // Insert more amount\n    console.log(\"\\n--- Step 5: Insert more than needed ---\");\n    vendingMachine.insertCoin(Coin.QUARTER); // 25\n\n    // Try to dispense the product\n    console.log(\"\\n--- Step 6: Dispense and return change ---\");\n    vendingMachine.dispense();\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineState/DispensingState.ts",
    "content": "import VendingMachine from \"../VendingMachine\";\nimport VendingMachineState from \"./VendingMachineState\";\n\nexport default class DispensingState implements VendingMachineState {\n  private machine: VendingMachine;\n\n  constructor(machine: VendingMachine) {\n    this.machine = machine;\n  }\n\n  insertCoin(): void {\n    console.log(\"Currently dispensing. Please wait.\");\n  }\n\n  selectItem() {\n    console.log(\"Currently dispensing. Please wait.\");\n  }\n\n  dispense() {\n    // already triggered by HasMoneyState\n  }\n\n  refund() {\n    console.log(\"Dispensing in progress. Refund not allowed.\");\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineState/HasMoneyState.ts",
    "content": "import VendingMachine from \"../VendingMachine\";\nimport VendingMachineState from \"./VendingMachineState\";\n\nexport default class HasMoneyState implements VendingMachineState {\n  private machine: VendingMachine;\n\n  constructor(machine: VendingMachine) {\n    this.machine = machine;\n  }\n\n  insertCoin() {\n    console.log(\"Already received full amount.\");\n  }\n\n  selectItem() {\n    console.log(\"Item already selected.\");\n  }\n\n  dispense() {\n    this.machine.setState(this.machine.getDispensingState());\n    this.machine.dispenseItem();\n  }\n\n  refund() {\n    this.machine.refundBalance();\n    this.machine.resetToIdleState();\n    this.machine.setState(this.machine.getIdleState());\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineState/IdleState.ts",
    "content": "import VendingMachine from \"../VendingMachine\";\nimport VendingMachineState from \"./VendingMachineState\";\n\nexport default class IdleState implements VendingMachineState {\n  private machine: VendingMachine;\n\n  constructor(machine: VendingMachine) {\n    this.machine = machine;\n  }\n\n  selectItem(code: string): void {\n    if (!this.machine.getInventory().isAvailable(code)) {\n      console.log(\"Item not available.\");\n      return;\n    }\n\n    this.machine.setSelectedItemCode(code);\n    this.machine.setState(this.machine.getItemSelectedState());\n    console.log(\"Item Selected = \", code);\n  }\n\n  insertCoin(): void {\n    console.log(\"Please select the product first\");\n  }\n\n  dispense(): void {\n    console.log(\"Please select the product first\");\n  }\n\n  refund(): void {\n    console.log(\"Please select the product first\");\n  }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineState/ItemSelectedState.ts",
    "content": "import { Coin } from \"../Coin\";\nimport VendingMachine from \"../VendingMachine\";\nimport VendingMachineState from \"./VendingMachineState\";\n\nexport default class ItemSelectedState implements VendingMachineState {\n    private machine: VendingMachine;\n\n    constructor(machine: VendingMachine) {\n        this.machine = machine;\n    }\n\n    insertCoin(coin: Coin) {\n        const price = this.machine.getSelectedItem()?.getPrice();\n        if (!price) {\n            throw new Error(\"Item Not Selected Yet.\");\n        }\n\n        this.machine.addBalance(coin);\n        console.log(\"Coin Inserted: \" + coin);\n\n        if (this.machine.getBalance() >= price) {\n            console.log(\"Sufficient money received.\");\n            this.machine.setState(this.machine.getHasMoneyState());\n        }\n    }\n\n    selectItem() {\n        console.log(\"Item already selected.\");\n    }\n\n    dispense() {\n        console.log(\"Please insert sufficient money.\");\n    }\n\n    refund() {\n        this.machine.resetToIdleState();\n        this.machine.setState(this.machine.getIdleState());\n    }\n}\n"
  },
  {
    "path": "solutions/typescript/src/VendingMachine/VendingMachineState/VendingMachineState.ts",
    "content": "import { Coin } from \"../Coin\";\n\nexport default interface VendingMachineState {\n  insertCoin(coin: Coin): void;\n  selectItem(code: string): void;\n  dispense(): void;\n  refund(): void;\n}\n"
  },
  {
    "path": "solutions/typescript/src/lldrunner.ts",
    "content": "import ParkingLotDemo from \"./ParkingLot/ParkingLotDemo\";\nimport StackOverflowDemo from \"./StackOverflow/StackOverflowDemo\";\nimport VendingMachineDemo from \"./VendingMachine/VendingMachineDemo\";\nimport LoggingFrameworkDemo from \"./LoggingFramework/LoggingFrameworkDemo\";\nimport TrafficSignalSystemDemo from \"./TrafficSignalSystem/TrafficSignalSystemDemo\";\nimport CoffeVendingMachineDemo from \"./CoffeeVendingMachine/CoffeeVendingMachineDemo\";\nimport TaskManagementDemo from \"./TaskManagement/TaskManagementSystemDemo\";\n\n// ParkingLotDemo.run()\n// StackOverflowDemo.run()\n// VendingMachineDemo.run()\n// LoggingFrameworkDemo.run()\n// TrafficSignalSystemDemo.run()\n// CoffeVendingMachineDemo.run()\nTaskManagementDemo.run();\n"
  },
  {
    "path": "solutions/typescript/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    /* Visit https://aka.ms/tsconfig.json to read more about this file */\n    /* Basic Options */\n    // \"incremental\": true,                         /* Enable incremental compilation */\n    \"target\": \"ESNEXT\" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,\n    \"module\": \"commonjs\" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,\n    // \"lib\": [],                                   /* Specify library files to be included in the compilation. */\n    // \"allowJs\": true,                             /* Allow javascript files to be compiled. */\n    // \"checkJs\": true,                             /* Report errors in .js files. */\n    // \"jsx\": \"preserve\",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */\n    // \"declaration\": true,                         /* Generates corresponding '.d.ts' file. */\n    // \"declarationMap\": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */\n    // \"sourceMap\": true,                           /* Generates corresponding '.map' file. */\n    // \"outFile\": \"./\",                             /* Concatenate and emit output to single file. */\n    // \"outDir\": \"./\",                              /* Redirect output structure to the directory. */\n    // \"rootDir\": \"./\",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */\n    // \"composite\": true,                           /* Enable project compilation */\n    // \"tsBuildInfoFile\": \"./\",                     /* Specify file to store incremental compilation information */\n    // \"removeComments\": true,                      /* Do not emit comments to output. */\n    \"rootDir\": \"src\", // project root\n    \"outDir\": \"dist\", // compiled JS files go here\n    // \"importHelpers\": true,                       /* Import emit helpers from 'tslib'. */\n    // \"downlevelIteration\": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */\n    // \"isolatedModules\": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */\n    /* Strict Type-Checking Options */\n    \"strict\": true /* Enable all strict type-checking options. */,\n    // \"noImplicitAny\": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */\n    // \"strictNullChecks\": true,                    /* Enable strict null checks. */\n    // \"strictFunctionTypes\": true,                 /* Enable strict checking of function types. */\n    // \"strictBindCallApply\": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */\n    // \"strictPropertyInitialization\": true,        /* Enable strict checking of property initialization in classes. */\n    // \"noImplicitThis\": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */\n    // \"alwaysStrict\": true,                        /* Parse in strict mode and emit \"use strict\" for each source file. */\n    /* Additional Checks */\n    // \"noUnusedLocals\": true,                      /* Report errors on unused locals. */\n    // \"noUnusedParameters\": true,                  /* Report errors on unused parameters. */\n    // \"noImplicitReturns\": true,                   /* Report error when not all code paths in function return a value. */\n    // \"noFallthroughCasesInSwitch\": true,          /* Report errors for fallthrough cases in switch statement. */\n    // \"noUncheckedIndexedAccess\": true,            /* Include 'undefined' in index signature results */\n    // \"noImplicitOverride\": true,                  /* Ensure overriding members in derived classes are marked with an 'override' modifier. */\n    // \"noPropertyAccessFromIndexSignature\": true,  /* Require undeclared properties from index signatures to use element accesses. */\n    /* Module Resolution Options */\n    \"moduleResolution\": \"node\" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,\n    // \"baseUrl\": \"./\",                             /* Base directory to resolve non-absolute module names. */\n    // \"paths\": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */\n    // \"rootDirs\": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */\n    \"typeRoots\": [\"./node_modules/@types\"] /* List of folders to include type definitions from. */,\n    // \"types\": [],                                 /* Type declaration files to be included in compilation. */\n    // \"allowSyntheticDefaultImports\": true,        /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */\n    \"esModuleInterop\": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,\n    // \"preserveSymlinks\": true,                    /* Do not resolve the real path of symlinks. */\n    // \"allowUmdGlobalAccess\": true,                /* Allow accessing UMD globals from modules. */\n    /* Experimental Options */\n    // \"experimentalDecorators\": true,              /* Enables experimental support for ES7 decorators. */\n    // \"emitDecoratorMetadata\": true,               /* Enables experimental support for emitting type metadata for decorators. */\n    /* Advanced Options */\n    \"skipLibCheck\": true /* Skip type checking of declaration files. */,\n    \"forceConsistentCasingInFileNames\": true /* Disallow inconsistently-cased references to the same file. */\n  },\n  \"exclude\": [\"node_modules\", \".build\"],\n  \"include\": [\"src/**/*\"]\n}\n"
  }
]