java program

profileh66umi6q
algs4.jar

META-INF/MANIFEST.MF

Manifest-Version: 1.0 Created-By: 1.8.0_222 (Oracle Corporation)

COPYING

GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: <program> Copyright (C) <year> <name of author> This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>. The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.

edu/princeton/cs/algs4/Accumulator.java

edu/princeton/cs/algs4/Accumulator.java

/******************************************************************************
 *  Compilation:  javac Accumulator.java
 *  Execution:    java Accumulator < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *
 *  Mutable data type that calculates the mean, sample standard
 *  deviation, and sample variance of a stream of real numbers
 *  use a stable, one-pass algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  Accumulator} class is a data type for computing the running
 *  mean, sample standard deviation, and sample variance of a stream of real
 *  numbers. It provides an example of a mutable data type and a streaming
 *  algorithm.
 *  <p>
 *  This implementation uses a one-pass algorithm that is less susceptible
 *  to floating-point roundoff error than the more straightforward
 *  implementation based on saving the sum of the squares of the numbers.
 *  This technique is due to
 *  <a href = "https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm">B. P. Welford</a>.
 *  Each operation takes constant time in the worst case.
 *  The amount of memory is constant - the data values are not stored.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Accumulator   {
     private   int  n  =   0 ;            // number of data values
     private   double  sum  =   0.0 ;     // sample variance * (n-1)
     private   double  mu  =   0.0 ;      // sample mean

     /**
     * Initializes an accumulator.
     */
     public   Accumulator ()   {
     }

     /**
     * Adds the specified data value to the accumulator.
     *  @param   x the data value
     */
     public   void  addDataValue ( double  x )   {
        n ++ ;
         double  delta  =  x  -  mu ;
        mu   +=  delta  /  n ;
        sum  +=   ( double )   ( -   1 )   /  n  *  delta  *  delta ;
     }

     /**
     * Returns the mean of the data values.
     *  @return  the mean of the data values
     */
     public   double  mean ()   {
         return  mu ;
     }

     /**
     * Returns the sample variance of the data values.
     *  @return  the sample variance of the data values
     */
     public   double  var ()   {
         if   ( <=   1 )   return   Double . NaN ;
         return  sum  /   ( -   1 );
     }

     /**
     * Returns the sample standard deviation of the data values.
     *  @return  the sample standard deviation of the data values
     */
     public   double  stddev ()   {
         return   Math . sqrt ( this . var ());
     }

     /**
     * Returns the number of data values.
     *  @return  the number of data values
     */
     public   int  count ()   {
         return  n ;
     }

     /**
     * Returns a string representation of this accumulator.
     *  @return  a string representation of this accumulator
     */
     public   String  toString ()   {
         return   "n = "   +  n  +   ", mean = "   +  mean ()   +   ", stddev = "   +  stddev ();
     }

     /**
     * Unit tests the { @code  Accumulator} data type.
     * Reads in a stream of real number from standard input;
     * adds them to the accumulator; and prints the mean,
     * sample standard deviation, and sample variance to standard
     * output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Accumulator  stats  =   new   Accumulator ();
         while   ( ! StdIn . isEmpty ())   {
             double  x  =   StdIn . readDouble ();
            stats . addDataValue ( x );
         }

         StdOut . printf ( "n      = %d\n" ,    stats . count ());
         StdOut . printf ( "mean   = %.5f\n" ,  stats . mean ());
         StdOut . printf ( "stddev = %.5f\n" ,  stats . stddev ());
         StdOut . printf ( "var    = %.5f\n" ,  stats . var ());
         StdOut . println ( stats );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AcyclicLP.java

edu/princeton/cs/algs4/AcyclicLP.java

/******************************************************************************
 *  Compilation:  javac AcyclicLP.java
 *  Execution:    java AcyclicP V E
 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt
 *  
 *  Computes longeset paths in an edge-weighted acyclic digraph.
 *
 *  Remark: should probably check that graph is a DAG before running
 *
 *  % java AcyclicLP tinyEWDAG.txt 5
 *  5 to 0 (2.44)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->0  0.38   
 *  5 to 1 (0.32)  5->1  0.32   
 *  5 to 2 (2.77)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   7->2  0.34   
 *  5 to 3 (0.61)  5->1  0.32   1->3  0.29   
 *  5 to 4 (2.06)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   
 *  5 to 5 (0.00)  
 *  5 to 6 (1.13)  5->1  0.32   1->3  0.29   3->6  0.52   
 *  5 to 7 (2.43)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  AcyclicLP} class represents a data type for solving the
 *  single-source longest paths problem in edge-weighted directed
 *  acyclic graphs (DAGs). The edge weights can be positive, negative, or zero.
 *  <p>
 *  This implementation uses a topological-sort based algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted digraph).
 *  <p>
 *  For additional documentation,   
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of   
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   AcyclicLP   {
     private   double []  distTo ;            // distTo[v] = distance  of longest s->v path
     private   DirectedEdge []  edgeTo ;      // edgeTo[v] = last edge on longest s->v path

     /**
     * Computes a longest paths tree from { @code  s} to every other vertex in
     * the directed acyclic graph { @code  G}.
     *  @param  G the acyclic digraph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException if the digraph is not acyclic
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   AcyclicLP ( EdgeWeightedDigraph  G ,   int  s )   {
        distTo  =   new   double [ G . V ()];
        edgeTo  =   new   DirectedEdge [ G . V ()];

        validateVertex ( s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . NEGATIVE_INFINITY ;
        distTo [ s ]   =   0.0 ;

         // relax vertices in topological order
         Topological  topological  =   new   Topological ( G );
         if   ( ! topological . hasOrder ())
             throw   new   IllegalArgumentException ( "Digraph is not acyclic." );
         for   ( int  v  :  topological . order ())   {
             for   ( DirectedEdge  e  :  G . adj ( v ))
                relax ( e );
         }
     }

     // relax edge e, but update if you find a *longer* path
     private   void  relax ( DirectedEdge  e )   {
         int  v  =  e . from (),  w  =  e . to ();
         if   ( distTo [ w ]   <  distTo [ v ]   +  e . weight ())   {
            distTo [ w ]   =  distTo [ v ]   +  e . weight ();
            edgeTo [ w ]   =  e ;
         }        
     }

     /**
     * Returns the length of a longest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  the length of a longest path from the source vertex { @code  s} to vertex { @code  v};
     *         { @code  Double.NEGATIVE_INFINITY} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Is there a path from the source vertex { @code  s} to vertex { @code  v}?
     *  @param   v the destination vertex
     *  @return  { @code  true} if there is a path from the source vertex
     *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ]   >   Double . NEGATIVE_INFINITY ;
     }

     /**
     * Returns a longest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  a longest path from the source vertex { @code  s} to vertex { @code  v}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < DirectedEdge >  path  =   new   Stack < DirectedEdge > ();
         for   ( DirectedEdge  e  =  edgeTo [ v ];  e  !=   null ;  e  =  edgeTo [ e . from ()])   {
            path . push ( e );
         }
         return  path ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  AcyclicLP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         int  s  =   Integer . parseInt ( args [ 1 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );

         AcyclicLP  lp  =   new   AcyclicLP ( G ,  s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( lp . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  v ,  lp . distTo ( v ));
                 for   ( DirectedEdge  e  :  lp . pathTo ( v ))   {
                     StdOut . print ( +   "   " );
                 }
                 StdOut . println ();
             }
             else   {
                 StdOut . printf ( "%d to %d         no path\n" ,  s ,  v );
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AcyclicSP.java

edu/princeton/cs/algs4/AcyclicSP.java

/******************************************************************************
 *  Compilation:  javac AcyclicSP.java
 *  Execution:    java AcyclicSP V E
 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt
 *
 *  Computes shortest paths in an edge-weighted acyclic digraph.
 *
 *  % java AcyclicSP tinyEWDAG.txt 5
 *  5 to 0 (0.73)  5->4  0.35   4->0  0.38   
 *  5 to 1 (0.32)  5->1  0.32   
 *  5 to 2 (0.62)  5->7  0.28   7->2  0.34   
 *  5 to 3 (0.61)  5->1  0.32   1->3  0.29   
 *  5 to 4 (0.35)  5->4  0.35   
 *  5 to 5 (0.00)  
 *  5 to 6 (1.13)  5->1  0.32   1->3  0.29   3->6  0.52   
 *  5 to 7 (0.28)  5->7  0.28   
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  AcyclicSP} class represents a data type for solving the
 *  single-source shortest paths problem in edge-weighted directed acyclic
 *  graphs (DAGs). The edge weights can be positive, negative, or zero.
 *  <p>
 *  This implementation uses a topological-sort based algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted digraph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   AcyclicSP   {
     private   double []  distTo ;           // distTo[v] = distance  of shortest s->v path
     private   DirectedEdge []  edgeTo ;     // edgeTo[v] = last edge on shortest s->v path


     /**
     * Computes a shortest paths tree from { @code  s} to every other vertex in
     * the directed acyclic graph { @code  G}.
     *  @param  G the acyclic digraph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException if the digraph is not acyclic
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   AcyclicSP ( EdgeWeightedDigraph  G ,   int  s )   {
        distTo  =   new   double [ G . V ()];
        edgeTo  =   new   DirectedEdge [ G . V ()];

        validateVertex ( s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . POSITIVE_INFINITY ;
        distTo [ s ]   =   0.0 ;

         // visit vertices in topological order
         Topological  topological  =   new   Topological ( G );
         if   ( ! topological . hasOrder ())
             throw   new   IllegalArgumentException ( "Digraph is not acyclic." );
         for   ( int  v  :  topological . order ())   {
             for   ( DirectedEdge  e  :  G . adj ( v ))
                relax ( e );
         }
     }

     // relax edge e
     private   void  relax ( DirectedEdge  e )   {
         int  v  =  e . from (),  w  =  e . to ();
         if   ( distTo [ w ]   >  distTo [ v ]   +  e . weight ())   {
            distTo [ w ]   =  distTo [ v ]   +  e . weight ();
            edgeTo [ w ]   =  e ;
         }        
     }

     /**
     * Returns the length of a shortest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  the length of a shortest path from the source vertex { @code  s} to vertex { @code  v};
     *         { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Is there a path from the source vertex { @code  s} to vertex { @code  v}?
     *  @param   v the destination vertex
     *  @return  { @code  true} if there is a path from the source vertex
     *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns a shortest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  a shortest path from the source vertex { @code  s} to vertex { @code  v}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < DirectedEdge >  path  =   new   Stack < DirectedEdge > ();
         for   ( DirectedEdge  e  =  edgeTo [ v ];  e  !=   null ;  e  =  edgeTo [ e . from ()])   {
            path . push ( e );
         }
         return  path ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  AcyclicSP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         int  s  =   Integer . parseInt ( args [ 1 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );

         // find shortest path from s to each other vertex in DAG
         AcyclicSP  sp  =   new   AcyclicSP ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( sp . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  v ,  sp . distTo ( v ));
                 for   ( DirectedEdge  e  :  sp . pathTo ( v ))   {
                     StdOut . print ( +   "   " );
                 }
                 StdOut . println ();
             }
             else   {
                 StdOut . printf ( "%d to %d         no path\n" ,  s ,  v );
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.java

/******************************************************************************
 *  Compilation:  javac AdjMatrixEdgeWeightedDigraph.java
 *  Execution:    java AdjMatrixEdgeWeightedDigraph V E
 *  Dependencies: StdOut.java
 *
 *  An edge-weighted digraph, implemented using an adjacency matrix.
 *  Parallel edges are disallowed; self-loops are allowed.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  AdjMatrixEdgeWeightedDigraph} class represents a edge-weighted
 *  digraph of vertices named 0 through <em>V</em> - 1, where each
 *  directed edge is of type { @link  DirectedEdge} and has a real-valued weight.
 *  It supports the following two primary operations: add a directed edge
 *  to the digraph and iterate over all of edges incident from a given vertex.
 *  It also provides
 *  methods for returning the number of vertices <em>V</em> and the number
 *  of edges <em>E</em>. Parallel edges are disallowed; self-loops are permitted.
 *  <p>
 *  This implementation uses an adjacency-matrix representation.
 *  All operations take constant time (in the worst case) except
 *  iterating over the edges incident from a given vertex, which takes
 *  time proportional to <em>V</em>.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   AdjMatrixEdgeWeightedDigraph   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;
     private   int  E ;
     private   DirectedEdge [][]  adj ;
    
     /**
     * Initializes an empty edge-weighted digraph with { @code  V} vertices and 0 edges.
     *  @param  V the number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   AdjMatrixEdgeWeightedDigraph ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "number of vertices must be nonnegative" );
         this . =  V ;
         this . =   0 ;
         this . adj  =   new   DirectedEdge [ V ][ V ];
     }

     /**
     * Initializes a random edge-weighted digraph with { @code  V} vertices and <em>E</em> edges.
     *  @param  V the number of vertices
     *  @param  E the number of edges
     *  @throws  IllegalArgumentException if { @code  V < 0}
     *  @throws  IllegalArgumentException if { @code  E < 0}
     */
     public   AdjMatrixEdgeWeightedDigraph ( int  V ,   int  E )   {
         this ( V );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "number of edges must be nonnegative" );
         if   ( >  V * V )   throw   new   IllegalArgumentException ( "too many edges" );

         // can be inefficient
         while   ( this . !=  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  weight  =   Math . round ( 100   *   StdRandom . uniform ())   /   100.0 ;
            addEdge ( new   DirectedEdge ( v ,  w ,  weight ));
         }
     }

     /**
     * Returns the number of vertices in the edge-weighted digraph.
     *  @return  the number of vertices in the edge-weighted digraph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in the edge-weighted digraph.
     *  @return  the number of edges in the edge-weighted digraph
     */
     public   int  E ()   {
         return  E ;
     }

     /**
     * Adds the directed edge { @code  e} to the edge-weighted digraph (if there
     * is not already an edge with the same endpoints).
     *  @param  e the edge
     */
     public   void  addEdge ( DirectedEdge  e )   {
         int  v  =  e . from ();
         int  w  =  e . to ();
        validateVertex ( v );
        validateVertex ( w );
         if   ( adj [ v ][ w ]   ==   null )   {
            E ++ ;
            adj [ v ][ w ]   =  e ;
         }
     }

     /**
     * Returns the directed edges incident from vertex { @code  v}.
     *  @param  v the vertex
     *  @return  the directed edges incident from vertex { @code  v} as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  adj ( int  v )   {
        validateVertex ( v );
         return   new   AdjIterator ( v );
     }

     // support iteration over graph vertices
     private   class   AdjIterator   implements   Iterator < DirectedEdge > ,   Iterable < DirectedEdge >   {
         private   int  v ;
         private   int  w  =   0 ;

         public   AdjIterator ( int  v )   {
             this . =  v ;
         }

         public   Iterator < DirectedEdge >  iterator ()   {
             return   this ;
         }

         public   boolean  hasNext ()   {
             while   ( <  V )   {
                 if   ( adj [ v ][ w ]   !=   null )   return   true ;
                w ++ ;
             }
             return   false ;
         }

         public   DirectedEdge  next ()   {
             if   ( ! hasNext ())   {
                 throw   new   NoSuchElementException ();
             }
             return  adj [ v ][ w ++ ];
         }

         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
     }

     /**
     * Returns a string representation of the edge-weighted digraph. This method takes
     * time proportional to <em>V</em><sup>2</sup>.
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,
     *   followed by the <em>V</em> adjacency lists of edges
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " "   +  E  +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( +   ": " );
             for   ( DirectedEdge  e  :  adj ( v ))   {
                s . append ( +   "  " );
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }


     /**
     * Unit tests the { @code  AdjMatrixEdgeWeightedDigraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         AdjMatrixEdgeWeightedDigraph  G  =   new   AdjMatrixEdgeWeightedDigraph ( V ,  E );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Alphabet.java

edu/princeton/cs/algs4/Alphabet.java

/******************************************************************************
 *  Compilation:  javac Alphabet.java
 *  Execution:    java Alphabet
 *  Dependencies: StdOut.java
 *  
 *  A data type for alphabets, for use with string-processing code
 *  that must convert between an alphabet of size R and the integers
 *  0 through R-1.
 *
 *  Warning: supports only the basic multilingual plane (BMP), i.e,
 *           Unicode characters between U+0000 and U+FFFF.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

public   class   Alphabet   {

     /**
     *  The binary alphabet { 0, 1 }.
     */
     public   static   final   Alphabet  BINARY  =   new   Alphabet ( "01" );

     /**
     *  The octal alphabet { 0, 1, 2, 3, 4, 5, 6, 7 }.
     */
     public   static   final   Alphabet  OCTAL  =   new   Alphabet ( "01234567" );

     /**
     *  The decimal alphabet { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }.
     */
     public   static   final   Alphabet  DECIMAL  =   new   Alphabet ( "0123456789" );

     /**
     *  The hexadecimal alphabet { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F }.
     */
     public   static   final   Alphabet  HEXADECIMAL  =   new   Alphabet ( "0123456789ABCDEF" );

     /**
     *  The DNA alphabet { A, C, T, G }.
     */
     public   static   final   Alphabet  DNA  =   new   Alphabet ( "ACGT" );

     /**
     *  The lowercase alphabet { a, b, c, ..., z }.
     */
     public   static   final   Alphabet  LOWERCASE  =   new   Alphabet ( "abcdefghijklmnopqrstuvwxyz" );

     /**
     *  The uppercase alphabet { A, B, C, ..., Z }.
     */

     public   static   final   Alphabet  UPPERCASE  =   new   Alphabet ( "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );

     /**
     *  The protein alphabet { A, C, D, E, F, G, H, I, K, L, M, N, P, Q, R, S, T, V, W, Y }.
     */
     public   static   final   Alphabet  PROTEIN  =   new   Alphabet ( "ACDEFGHIKLMNPQRSTVWY" );

     /**
     *  The base-64 alphabet (64 characters).
     */
     public   static   final   Alphabet  BASE64  =   new   Alphabet ( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );

     /**
     *  The ASCII alphabet (0-127).
     */
     public   static   final   Alphabet  ASCII  =   new   Alphabet ( 128 );

     /**
     *  The extended ASCII alphabet (0-255).
     */
     public   static   final   Alphabet  EXTENDED_ASCII  =   new   Alphabet ( 256 );

     /**
     *  The Unicode 16 alphabet (0-65,535).
     */
     public   static   final   Alphabet  UNICODE16       =   new   Alphabet ( 65536 );


     private   char []  alphabet ;       // the characters in the alphabet
     private   int []  inverse ;         // indices
     private   final   int  R ;           // the radix of the alphabet

     /**
     * Initializes a new alphabet from the given set of characters.
     *
     *  @param  alpha the set of characters
     */
     public   Alphabet ( String  alpha )   {

         // check that alphabet contains no duplicate chars
         boolean []  unicode  =   new   boolean [ Character . MAX_VALUE ];
         for   ( int  i  =   0 ;  i  <  alpha . length ();  i ++ )   {
             char  c  =  alpha . charAt ( i );
             if   ( unicode [ c ])
                 throw   new   IllegalArgumentException ( "Illegal alphabet: repeated character = '"   +  c  +   "'" );
            unicode [ c ]   =   true ;
         }

        alphabet  =  alpha . toCharArray ();
        R  =  alpha . length ();
        inverse  =   new   int [ Character . MAX_VALUE ];
         for   ( int  i  =   0 ;  i  <  inverse . length ;  i ++ )
            inverse [ i ]   =   - 1 ;

         // can't use char since R can be as big as 65,536
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
            inverse [ alphabet [ c ]]   =  c ;
     }

     /**
     * Initializes a new alphabet using characters 0 through R-1.
     *
     *  @param  radix the number of characters in the alphabet (the radix R)
     */
     private   Alphabet ( int  radix )   {
         this . =  radix ;
        alphabet  =   new   char [ R ];
        inverse  =   new   int [ R ];

         // can't use char since R can be as big as 65,536
         for   ( int  i  =   0 ;  i  <  R ;  i ++ )
            alphabet [ i ]   =   ( char )  i ;
         for   ( int  i  =   0 ;  i  <  R ;  i ++ )
            inverse [ i ]   =  i ;
     }

     /**
     * Initializes a new alphabet using characters 0 through 255.
     */
     public   Alphabet ()   {
         this ( 256 );
     }

     /**
     * Returns true if the argument is a character in this alphabet.
     *
     *  @param   c the character
     *  @return  { @code  true} if { @code  c} is a character in this alphabet;
     *         { @code  false} otherwise
     */
     public   boolean  contains ( char  c )   {
         return  inverse [ c ]   !=   - 1 ;
     }

     /**
     * Returns the number of characters in this alphabet (the radix).
     * 
     *  @return  the number of characters in this alphabet
     *  @deprecated  Replaced by { @link  #radix()}.
     */
    @ Deprecated
     public   int  R ()   {
         return  R ;
     }

     /**
     * Returns the number of characters in this alphabet (the radix).
     * 
     *  @return  the number of characters in this alphabet
     */
     public   int  radix ()   {
         return  R ;
     }

     /**
     * Returns the binary logarithm of the number of characters in this alphabet.
     * 
     *  @return  the binary logarithm (rounded up) of the number of characters in this alphabet
     */
     public   int  lgR ()   {
         int  lgR  =   0 ;
         for   ( int  t  =  R - 1 ;  t  >=   1 ;  t  /=   2 )
            lgR ++ ;
         return  lgR ;
     }

     /**
     * Returns the index corresponding to the argument character.
     * 
     *  @param   c the character
     *  @return  the index corresponding to the character { @code  c}
     *  @throws  IllegalArgumentException unless { @code  c} is a character in this alphabet
     */
     public   int  toIndex ( char  c )   {
         if   ( >=  inverse . length  ||  inverse [ c ]   ==   - 1 )   {
             throw   new   IllegalArgumentException ( "Character "   +  c  +   " not in alphabet" );
         }
         return  inverse [ c ];
     }

     /**
     * Returns the indices corresponding to the argument characters.
     * 
     *  @param   s the characters
     *  @return  the indices corresponding to the characters { @code  s}
     *  @throws  IllegalArgumentException unless every character in { @code  s}
     *         is a character in this alphabet
     */
     public   int []  toIndices ( String  s )   {
         char []  source  =  s . toCharArray ();
         int []  target   =   new   int [ s . length ()];
         for   ( int  i  =   0 ;  i  <  source . length ;  i ++ )
            target [ i ]   =  toIndex ( source [ i ]);
         return  target ;
     }

     /**
     * Returns the character corresponding to the argument index.
     * 
     *  @param   index the index
     *  @return  the character corresponding to the index { @code  index}
     *  @throws  IllegalArgumentException unless { @code  0 <= index < R}
     */
     public   char  toChar ( int  index )   {
         if   ( index  <   0   ||  index  >=  R )   {
             throw   new   IllegalArgumentException ( "index must be between 0 and "   +  R  +   ": "   +  index );
         }
         return  alphabet [ index ];
     }

     /**
     * Returns the characters corresponding to the argument indices.
     * 
     *  @param   indices the indices
     *  @return  the characters corresponding to the indices { @code  indices}
     *  @throws  IllegalArgumentException unless { @code  0 < indices[i] < R}
     *         for every { @code  i}
     */
     public   String  toChars ( int []  indices )   {
         StringBuilder  s  =   new   StringBuilder ( indices . length );
         for   ( int  i  =   0 ;  i  <  indices . length ;  i ++ )
            s . append ( toChar ( indices [ i ]));
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  Alphabet} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int []   encoded1  =   Alphabet . BASE64 . toIndices ( "NowIsTheTimeForAllGoodMen" );
         String  decoded1  =   Alphabet . BASE64 . toChars ( encoded1 );
         StdOut . println ( decoded1 );
 
         int []   encoded2  =   Alphabet . DNA . toIndices ( "AACGAACGGTTTACCCCG" );
         String  decoded2  =   Alphabet . DNA . toChars ( encoded2 );
         StdOut . println ( decoded2 );

         int []   encoded3  =   Alphabet . DECIMAL . toIndices ( "01234567890123456789" );
         String  decoded3  =   Alphabet . DECIMAL . toChars ( encoded3 );
         StdOut . println ( decoded3 );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AmericanFlag.java

edu/princeton/cs/algs4/AmericanFlag.java

/******************************************************************************
 *  Compilation:  javac AmericanFlag.java
 *  Execution:    java AmericanFlag < input.txt
 *                java AmericanFlag int < input-non-negative-ints.txt  
 *  Dependencies: StdIn.java StdOut.java Stack.java
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *                https://algs4.cs.princeton.edu/51radix/shells.txt
 *
 *  Sort an array of strings or integers in-place using American flag sort.
 *
 *  % java AmericanFlag < shells.txt 
 *  are
 *  by
 *  sea
 *  seashells
 *  seashells
 *  sells
 *  sells
 *  she
 *  she
 *  shells
 *  shore
 *  surely
 *  the
 *  the
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  AmericanFlag} class provides static methods for sorting an
 *  array of extended ASCII strings or integers in-place using 
 *  American flag sort. This is a non-recursive implementation.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne
 *  and <a href = "http://static.usenix.org/publications/compsystems/1993/win_mcilroy.pdf">
 *  Engineering Radix Sort</a> by McIlroy and Bostic.
 *  For a version that uses only one auxilary array, see { @link  AmericanFlagX}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *   @author  Ivan Pesin
 */

public   class   AmericanFlag   {
     private   static   final   int  BITS_PER_BYTE  =     8 ;
     private   static   final   int  BITS_PER_INT   =    32 ;     // each Java int is 32 bits 
     private   static   final   int  R              =   256 ;     // extend ASCII alphabet size
     private   static   final   int  CUTOFF         =    15 ;     // cutoff to insertion sort

     // do not instantiate
     private   AmericanFlag ()   {   }  

     // return dth character of s, -1 if d = length of string
     private   static   int  charAt ( String  s ,   int  d )   {
         assert  d  >=   0   &&  d  <=  s . length ();
         if   ( ==  s . length ())   return   - 1 ;
         return  s . charAt ( d );
     }

     /**
     * Rearranges the array of extended ASCII strings in ascending order.
     * This is an unstable sorting algorithm.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( String []  a )   {
        sort ( a ,   0 ,  a . length  -   1 );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     public   static   void  sort ( String []  a ,   int  lo ,   int  hi )   {
         // one-time allocation of data structures
         Stack < Integer >  st  =   new   Stack < Integer > ();
         int []  first  =   new   int [ R + 2 ];
         int []  next   =   new   int [ R + 2 ];
         int  d  =   0 ;   // character index to sort by

        st . push ( lo );
        st . push ( hi );
        st . push ( d );
        
         while   ( ! st . isEmpty ())   {
            d  =  st . pop ();
            hi  =  st . pop ();
            lo  =  st . pop ();
        
             if   ( hi  <=  lo  +  CUTOFF )   {
                insertion ( a ,  lo ,  hi ,  d );
                 continue ;
             }

             // compute frequency counts
             for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
                 int  c  =  charAt ( a [ i ],  d )   +   1 ;   // account for -1 representing end-of-string
                first [ c + 1 ] ++ ;
             }

             // first[c] = location of first string whose dth character = c
            first [ 0 ]   =  lo ;
             for   ( int  c  =   0 ;  c  <=  R ;  c ++ )   {
                first [ c + 1 ]   +=  first [ c ];
            
                 if   ( >   0   &&  first [ c + 1 ] - 1   >  first [ c ])   {  
                     // add subproblem for character c (excludes sentinel c == 0)
                    st . push ( first [ c ]);
                    st . push ( first [ c + 1 ]   -   1 );
                    st . push ( d + 1 );  
                 }
             }

             // next[c] = location to place next string whose dth character = c
             for   ( int  c  =   0 ;  c  <  R + 2 ;  c ++ )
                next [ c ]   =  first [ c ];

             // permute data in place
             for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
                 int  c  =  charAt ( a [ k ],  d )   +   1 ;
                 while   ( first [ c ]   >  k )   {
                    exch ( a ,  k ,  next [ c ] ++ );
                    c  =  charAt ( a [ k ],  d )   +   1 ;
                 }
                next [ c ] ++ ;
             }
          
             // clear first[] and next[] arrays
             for   ( int  c  =   0 ;  c  <  R + 2 ;  c ++ )   {
                first [ c ]   =   0 ;
                next [ c ]   =   0 ;
             }
         }
     }
    
     // insertion sort a[lo..hi], starting at dth character
     private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( String []  a ,   int  i ,   int  j )   {
         String  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }

     // is v less than w, starting at character d
     private   static   boolean  less ( String  v ,   String  w ,   int  d )   {
         // assert v.substring(0, d).equals(w.substring(0, d));
         for   ( int  i  =  d ;  i  <    Math . min ( v . length (),  w . length ());  i ++ )   {
             if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;
             if   ( v . charAt ( i )   >  w . charAt ( i ))   return   false ;
         }
         return  v . length ()   <  w . length ();
     }

    /**
     * Rearranges the array of 32-bit integers in ascending order.
     * Currently assumes that the integers are nonnegative.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( int []  a )   {
        sort ( a ,   0 ,  a . length - 1 );
     }

     // MSD sort from a[lo] to a[hi]
     private   static   void  sort ( int []  a ,   int  lo ,   int  hi )   {
         // one-time allocation of data structures
         Stack < Integer >  st  =   new   Stack < Integer > ();
         int []  first  =   new   int [ R + 1 ];
         int []  next   =   new   int [ R + 1 ];
         int  mask  =  R  -   1 ;     // 0xFF;
         int  d  =   0 ;            // byte to sort by

        st . push ( lo );
        st . push ( hi );
        st . push ( d );
        
         while   ( ! st . isEmpty ())   {
            d  =  st . pop ();
            hi  =  st . pop ();
            lo  =  st . pop ();
        
             if   ( hi  <=  lo  +  CUTOFF )   {
                insertion ( a ,  lo ,  hi ,  d );
                 continue ;
             }
          
             // compute frequency counts (need R = 256)
             int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * -  BITS_PER_BYTE ;
             for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
                 int  c  =   ( a [ i ]   >>  shift )   &  mask ;
                first [ c + 1 ] ++ ;
             }

             // first[c] = location of first int whose dth byte = c
            first [ 0 ]   =  lo ;
             for   ( int  c  =   0 ;  c  <  R ;  c ++ )   {
                first [ c + 1 ]   +=  first [ c ];
            
                 if   ( <   3   &&  first [ c + 1 ] - 1   >  first [ c ])   {  
                     // add subproblem for byte c
                    st . push ( first [ c ]);
                    st . push ( first [ c + 1 ]   -   1 );
                    st . push ( d + 1 );  
                 }
             }

             // next[c] = location to place next string whose dth byte = c
             for   ( int  c  =   0 ;  c  <  R + 1 ;  c ++ )
                next [ c ]   =  first [ c ];

             // permute data in place
             for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
                 int  c  =   ( a [ k ]   >>  shift )   &  mask ;
                 while   ( first [ c ]   >  k )   {
                    exch ( a ,  k ,  next [ c ] ++ );
                    c  =   ( a [ k ]   >>  shift )   &  mask ;
                 }
                next [ c ] ++ ;
             }
          
             // clear first[] and next[] arrays
             for   ( int  c  =   0 ;  c  <  R + 1 ;  c ++ )   {
                first [ c ]   =   0 ;
                next [ c ]   =   0 ;
             }
         }
     }

     // insertion sort a[lo..hi], starting at dth byte
     private   static   void  insertion ( int []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( int []  a ,   int  i ,   int  j )   {
         int  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }
    
     // is v less than w, starting at byte d
     private   static   boolean  less ( int  v ,   int  w ,   int  d )   {
         int  mask  =  R  -   1 ;     // 0xFF;
         for   ( int  i  =  d ;  i  <   4 ;  i ++ )   {
             int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * -  BITS_PER_BYTE ;
             int  a  =   ( >>  shift )   &  mask ;
             int  b  =   ( >>  shift )   &  mask ;
             if   ( <  b )   return   true ;
             if   ( >  b )   return   false ;
         }
         return   false ;
     }
    
     /**
     * Reads in a sequence of extended ASCII strings or non-negative ints from standard input;
     * American flag sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments: "int" to read input as non-negative integers
     */
     public   static   void  main ( String []  args )   {
         if   ( args . length  >   0   &&  args [ 0 ]. equals ( "int" ))   {
             int []  a  =   StdIn . readAllInts ();
            sort ( a );

             // print results
             for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
                 StdOut . println ( a [ i ]);
         }

         else   {
             String []  a  =   StdIn . readAllStrings ();
            sort ( a );
             // print results
             for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
                 StdOut . println ( a [ i ]);
         }
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AmericanFlagX.java

edu/princeton/cs/algs4/AmericanFlagX.java

/******************************************************************************
 *  Compilation:  javac AmericanFlagX.java
 *  Execution:    java AmericanFlagX < input.txt
 *  Dependencies: StdIn.java StdOut.java Stack.java
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *                https://algs4.cs.princeton.edu/51radix/shells.txt
 *
 *  Sort an array of strings or integers in-place using American Flag sort.
 *
 *  % java AmericanFlagX < shells.txt 
 *  are
 *  by
 *  sea
 *  seashells
 *  seashells
 *  sells
 *  sells
 *  she
 *  she
 *  shells
 *  shore
 *  surely
 *  the
 *  the
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  AmericanFlagX} class provides static methods for sorting an
 *  array of extended ASCII strings or integers in-place using 
 *  American Flag sort. This implementation is non-recursive and uses only 
 *  one auxiliary array.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne
 *  and <a href = "http://static.usenix.org/publications/compsystems/1993/win_mcilroy.pdf">
 *  Engineering Radix Sort</a> by McIlroy and Bostic.
 *  For a version that uses two auxilary arrays, see { @link  AmericanFlag}.
 *
 *   @author  Ivan Pesin
 */

public   class   AmericanFlagX   {
     private   static   final   int  R       =   256 ;     // extend ASCII alphabet size
     private   static   final   int  CUTOFF  =    15 ;     // cutoff to insertion sort

     // do not instantiate
     private   AmericanFlagX ()   {   }  

     // return dth character of s, -1 if d = length of string
     private   static   int  charAt ( String  s ,   int  d )   {
         assert  d  >=   0   &&  d  <=  s . length ();
         if   ( ==  s . length ())   return   - 1 ;
         return  s . charAt ( d );
     }

     /**
     * Rearranges the array of extended ASCII strings in ascending order.
     * This is an unstable in-place sorting algorithm.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( String []  a )   {
        sort ( a ,   0 ,  a . length  -   1 );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     public   static   void  sort ( String []  a ,   int  lo ,   int  hi )   {
         // one-time allocation of data structures
         Stack < Integer >  st  =   new   Stack < Integer > ();
         int []  count  =   new   int [ R + 1 ];
         int  d  =   0 ;   // character index to sort by

        st . push ( lo );
        st . push ( hi );
        st . push ( d );
        
         while   ( ! st . isEmpty ())   {
            d  =  st . pop ();
            hi  =  st . pop ();
            lo  =  st . pop ();

             if   ( hi  <=  lo  +  CUTOFF )   {
                insertion ( a ,  lo ,  hi ,  d );
                 continue ;
             }

             // compute frequency counts
             for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
                 int  c  =  charAt ( a [ i ],  d )   +   1 ;   // account for -1 representing end-of-string
                count [ c ] ++ ;
             }

             // accumulate counts relative to a[0], so that 
             // count[c] is the number of keys <= c
            count [ 0 ]   +=  lo ;
             for   ( int  c  =   0 ;  c  <  R ;  c ++ )   {
                count [ c + 1 ]   +=  count [ c ];
            
                 if   ( >   0   &&  count [ c + 1 ] - 1   >  count [ c ])   {  
                     // add subproblem for character c (excludes sentinel c == 0)
                    st . push ( count [ c ]);
                    st . push ( count [ c + 1 ] - 1 );
                    st . push ( d + 1 );  
                 }
             }

             // permute data in place
             // for details and proof see Knuth Theorem 5.1.2B and ch 5.2 excercise 13.
             for   ( int  r  =  hi ;  r  >=  lo ;  r -- )   {

                 // locate element that must be shifted right of r
                 int  c  =  charAt ( a [ r ],  d )   +   1 ;
                 while   ( >=  lo  &&  count [ c ] - 1   <=  r )   {
                     if   ( count [ c ] - 1   ==  r )  count [ c ] -- ;
                    r -- ;
                     if   ( >=  lo )  c  =  charAt ( a [ r ],  d )   +   1 ;
                 }

                 // if r < lo the subarray is sorted.
                 if   ( <  lo )   break ;
            
                 // permute a[r] until correct element is in place
                 while   ( -- count [ c ]   !=  r )   {
                    exch ( a ,  r ,  count [ c ]);
                    c  =  charAt ( a [ r ],  d )   +   1 ;
                 }
             }
          
             // clear count[] array
             for   ( int  c  =   0 ;  c  <  R + 1 ;  c ++ )
                count [ c ]   =   0 ;
         }
     }
    
     // insertion sort a[lo..hi], starting at dth character
     private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( String []  a ,   int  i ,   int  j )   {
         String  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }

     // is v less than w, starting at character d
     private   static   boolean  less ( String  v ,   String  w ,   int  d )   {
         // assert v.substring(0, d).equals(w.substring(0, d));
         for   ( int  i  =  d ;  i  <    Math . min ( v . length (),  w . length ());  i ++ )   {
             if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;
             if   ( v . charAt ( i )   >  w . charAt ( i ))   return   false ;
         }
         return  v . length ()   <  w . length ();
     }
        
     /**
     * Reads in a sequence of extended ASCII strings or non-negative ints from standard input;
     * American flag sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {       
         String []  a  =   StdIn . readAllStrings ();
        sort ( a );
         // print results
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Arbitrage.java

edu/princeton/cs/algs4/Arbitrage.java

/******************************************************************************
 *  Compilation:  javac Arbitrage.java
 *  Execution:    java Arbitrage < input.txt
 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java
 *                BellmanFordSP.java
 *  Data file:    https://algs4.cs.princeton.edu/44sp/rates.txt
 *
 *  Arbitrage detection.
 *
 *  % more rates.txt
 *  5
 *  USD 1      0.741  0.657  1.061  1.005
 *  EUR 1.349  1      0.888  1.433  1.366
 *  GBP 1.521  1.126  1      1.614  1.538
 *  CHF 0.942  0.698  0.619  1      0.953
 *  CAD 0.995  0.732  0.650  1.049  1
 *
 *  % java Arbitrage < rates.txt
 *  1000.00000 USD =  741.00000 EUR
 *   741.00000 EUR = 1012.20600 CAD
 *  1012.20600 CAD = 1007.14497 USD
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Arbitrage} class provides a client that finds an arbitrage
 *  opportunity in a currency exchange table by constructing a
 *  complete-digraph representation of the exchange table and then finding
 *  a negative cycle in the digraph.
 *  <p>
 *  This implementation uses the Bellman-Ford algorithm to find a
 *  negative cycle in the complete digraph.
 *  The running time is proportional to <em>V</em><sup>3</sup> in the
 *  worst case, where <em>V</em> is the number of currencies.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Arbitrage   {

     // this class cannot be instantiated
     private   Arbitrage ()   {   }

     /**
     *  Reads the currency exchange table from standard input and
     *  prints an arbitrage opportunity to standard output (if one exists).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // V currencies
         int  V  =   StdIn . readInt ();
         String []  name  =   new   String [ V ];

         // create complete network
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            name [ v ]   =   StdIn . readString ();
             for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {
                 double  rate  =   StdIn . readDouble ();
                 DirectedEdge  e  =   new   DirectedEdge ( v ,  w ,   - Math . log ( rate ));
                G . addEdge ( e );
             }
         }

         // find negative cycle
         BellmanFordSP  spt  =   new   BellmanFordSP ( G ,   0 );
         if   ( spt . hasNegativeCycle ())   {
             double  stake  =   1000.0 ;
             for   ( DirectedEdge  e  :  spt . negativeCycle ())   {
                 StdOut . printf ( "%10.5f %s " ,  stake ,  name [ e . from ()]);
                stake  *=   Math . exp ( - e . weight ());
                 StdOut . printf ( "= %10.5f %s\n" ,  stake ,  name [ e . to ()]);
             }
         }
         else   {
             StdOut . println ( "No arbitrage opportunity" );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AssignmentProblem.java

edu/princeton/cs/algs4/AssignmentProblem.java

/******************************************************************************
 *  Compilation:  javac AssignmentProblem.java
 *  Execution:    java AssignmentProblem n
 *  Dependencies: DijkstraSP.java DirectedEdge.java
 *
 *  Solve an n-by-n assignment problem in n^3 log n time using the
 *  successive shortest path algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  AssignmentProblem} class represents a data type for computing
 *  an optimal solution to an <em>n</em>-by-<em>n</em> <em>assignment problem</em>.
 *  The assignment problem is to find a minimum weight matching in an
 *  edge-weighted complete bipartite graph.
 *  <p>
 *  The data type supplies methods for determining the optimal solution
 *  and the corresponding dual solution.
 *  <p>
 *  This implementation uses the <em>successive shortest paths algorithm</em>.
 *  The order of growth of the running time in the worst case is
 *  O(<em>n</em>^3 log <em>n</em>) to solve an <em>n</em>-by-<em>n</em>
 *  instance.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/65reductions">Section 6.5</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   AssignmentProblem   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-14 ;
     private   static   final   int  UNMATCHED  =   - 1 ;

     private   int  n ;                // number of rows and columns
     private   double [][]  weight ;    // the n-by-n cost matrix
     private   double  minWeight ;     // minimum value of any weight
     private   double []  px ;          // px[i] = dual variable for row i
     private   double []  py ;          // py[j] = dual variable for col j
     private   int []  xy ;             // xy[i] = j means i-j is a match
     private   int []  yx ;             // yx[j] = i means i-j is a match

     /**
     * Determines an optimal solution to the assignment problem.
     *
     *  @param   weight the <em>n</em>-by-<em>n</em> matrix of weights
     *  @throws  IllegalArgumentException unless all weights are nonnegative
     *  @throws  IllegalArgumentException if { @code  weight} is { @code  null}
     */  
     public   AssignmentProblem ( double [][]  weight )   {
         if   ( weight  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );

        n  =  weight . length ;
         this . weight  =   new   double [ n ][ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 if   ( Double . isNaN ( weight [ i ][ j ]))
                     throw   new   IllegalArgumentException ( "weight "   +  i  +   "-"   +  j   +   " is NaN" );
                 if   ( weight [ i ][ j ]   <  minWeight )  minWeight  =  weight [ i ][ j ];
                 this . weight [ i ][ j ]   =  weight [ i ][ j ];
             }
         }

         // dual variables
        px  =   new   double [ n ];
        py  =   new   double [ n ];

         // initial matching is empty
        xy  =   new   int [ n ];
        yx  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             xy [ i ]   =  UNMATCHED ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
             yx [ j ]   =  UNMATCHED ;

         // add n edges to matching
         for   ( int  k  =   0 ;  k  <  n ;  k ++ )   {
             assert  isDualFeasible ();
             assert  isComplementarySlack ();
            augment ();
         }
         assert  certifySolution ();
     }

     // find shortest augmenting path and upate
     private   void  augment ()   {

         // build residual graph
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( 2 * n + 2 );
         int  s  =   2 * n ,  t  =   2 * n + 1 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( xy [ i ]   ==  UNMATCHED )
                G . addEdge ( new   DirectedEdge ( s ,  i ,   0.0 ));
         }
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
             if   ( yx [ j ]   ==  UNMATCHED )
                G . addEdge ( new   DirectedEdge ( n + j ,  t ,  py [ j ]));
         }
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 if   ( xy [ i ]   ==  j )  G . addEdge ( new   DirectedEdge ( n + j ,  i ,   0.0 ));
                 else             G . addEdge ( new   DirectedEdge ( i ,  n + j ,  reducedCost ( i ,  j )));
             }
         }

         // compute shortest path from s to every other vertex
         DijkstraSP  spt  =   new   DijkstraSP ( G ,  s );

         // augment along alternating path
         for   ( DirectedEdge  e  :  spt . pathTo ( t ))   {
             int  i  =  e . from (),  j  =  e . to ()   -  n ;
             if   ( <  n )   {
                xy [ i ]   =  j ;
                yx [ j ]   =  i ;
             }
         }

         // update dual variables
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            px [ i ]   +=  spt . distTo ( i );
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            py [ j ]   +=  spt . distTo ( n + j );
     }

     // reduced cost of i-j
     // (subtracting off minWeight reweights all weights to be non-negative)
     private   double  reducedCost ( int  i ,   int  j )   {
         double  reducedCost  =   ( weight [ i ][ j ]   -  minWeight )   +  px [ i ]   -  py [ j ];

         // to avoid issues with floating-point precision
         double  magnitude  =   Math . abs ( weight [ i ][ j ])   +   Math . abs ( px [ i ])   +   Math . abs ( py [ j ]);
         if   ( Math . abs ( reducedCost )   <=  FLOATING_POINT_EPSILON  *  magnitude )   return   0.0 ;

         assert  reducedCost  >=   0.0 ;
         return  reducedCost ;
     }

     /**
     * Returns the dual optimal value for the specified row.
     *
     *  @param   i the row index
     *  @return  the dual optimal value for row { @code  i}
     *  @throws  IllegalArgumentException unless { @code  0 <= i < n}
     *
     */
     // dual variable for row i
     public   double  dualRow ( int  i )   {
        validate ( i );
         return  px [ i ];
     }

     /**
     * Returns the dual optimal value for the specified column.
     *
     *  @param   j the column index
     *  @return  the dual optimal value for column { @code  j}
     *  @throws  IllegalArgumentException unless { @code  0 <= j < n}
     *
     */
     public   double  dualCol ( int  j )   {
        validate ( j );
         return  py [ j ];
     }

     /**
     * Returns the column associated with the specified row in the optimal solution.
     *
     *  @param   i the row index
     *  @return  the column matched to row { @code  i} in the optimal solution
     *  @throws  IllegalArgumentException unless { @code  0 <= i < n}
     *
     */
     public   int  sol ( int  i )   {
        validate ( i );
         return  xy [ i ];
     }

     /**
     * Returns the total weight of the optimal solution
     *
     *  @return  the total weight of the optimal solution
     *
     */
     public   double  weight ()   {
         double  total  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( xy [ i ]   !=  UNMATCHED )
                total  +=  weight [ i ][ xy [ i ]];
         }
         return  total ;
     }

     private   void  validate ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ( "index is not between 0 and "   +   ( n - 1 )   +   ": "   +  i );
     }


     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // check that dual variables are feasible
     private   boolean  isDualFeasible ()   {
         // check that all edges have >= 0 reduced cost
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 if   ( reducedCost ( i ,  j )   <   0 )   {
                     StdOut . println ( "Dual variables are not feasible" );
                     return   false ;
                 }
             }
         }
         return   true ;
     }

     // check that primal and dual variables are complementary slack
     private   boolean  isComplementarySlack ()   {

         // check that all matched edges have 0-reduced cost
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   (( xy [ i ]   !=  UNMATCHED )   &&   ( reducedCost ( i ,  xy [ i ])   !=   0 ))   {
                 StdOut . println ( "Primal and dual variables are not complementary slack" );
                 return   false ;
             }
         }
         return   true ;
     }

     // check that primal variables are a perfect matching
     private   boolean  isPerfectMatching ()   {

         // check that xy[] is a perfect matching
         boolean []  perm  =   new   boolean [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( perm [ xy [ i ]])   {
                 StdOut . println ( "Not a perfect matching" );
                 return   false ;
             }
            perm [ xy [ i ]]   =   true ;
         }

         // check that xy[] and yx[] are inverses
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
             if   ( xy [ yx [ j ]]   !=  j )   {
                 StdOut . println ( "xy[] and yx[] are not inverses" );
                 return   false ;
             }
         }
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( yx [ xy [ i ]]   !=  i )   {
                 StdOut . println ( "xy[] and yx[] are not inverses" );
                 return   false ;
             }
         }

         return   true ;
     }

     // check optimality conditions
     private   boolean  certifySolution ()   {
         return  isPerfectMatching ()   &&  isDualFeasible ()   &&  isComplementarySlack ();
     }

     /**
     * Unit tests the { @code  AssignmentProblem} data type.
     * Takes a command-line argument n; creates a random n-by-n matrix;
     * solves the n-by-n assignment problem; and prints the optimal
     * solution.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create random n-by-n matrix
         int  n  =   Integer . parseInt ( args [ 0 ]);
         double [][]  weight  =   new   double [ n ][ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                weight [ i ][ j ]   =   StdRandom . uniform ( 900 )   +   100 ;    // 3 digits
             }
         }

         // solve assignment problem
         AssignmentProblem  assignment  =   new   AssignmentProblem ( weight );
         StdOut . printf ( "weight = %.0f\n" ,  assignment . weight ());
         StdOut . println ();

         // print n-by-n matrix and optimal solution
         if   ( >=   20 )   return ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 if   ( ==  assignment . sol ( i ))
                     StdOut . printf ( "*%.0f " ,  weight [ i ][ j ]);
                 else
                     StdOut . printf ( " %.0f " ,  weight [ i ][ j ]);
             }
             StdOut . println ();
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Average.java

edu/princeton/cs/algs4/Average.java

/******************************************************************************
 *  Compilation:  javac Average.java
 *  Execution:    java Average < data.txt
 *  Dependencies: StdIn.java StdOut.java
 *  
 *  Reads in a sequence of real numbers, and computes their average.
 *
 *  % java Average
 *  10.0 5.0 6.0
 *  3.0 7.0 32.0
 *  [Ctrl-d]
 *  Average is 10.5
 *
 *  Note [Ctrl-d] signifies the end of file on Unix.
 *  On windows use [Ctrl-z].
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Average} class provides a client for reading in a sequence
 *  of real numbers and printing out their average.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Average   {  

     // this class should not be instantiated
     private   Average ()   {   }

     /**
     * Reads in a sequence of real numbers from standard input and prints
     * out their average to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         int  count  =   0 ;         // number input values
         double  sum  =   0.0 ;      // sum of input values

         // read data and compute statistics
         while   ( ! StdIn . isEmpty ())   {
             double  value  =   StdIn . readDouble ();
            sum  +=  value ;
            count ++ ;
         }

         // compute the average
         double  average  =  sum  /  count ;

         // print results
         StdOut . println ( "Average is "   +  average );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/AVLTreeST.java

edu/princeton/cs/algs4/AVLTreeST.java

/******************************************************************************
 *  Compilation:  javac AVLTreeST.java
 *  Execution:    java AVLTreeST < input.txt
 *  Dependencies: StdIn.java StdOut.java  
 *  Data files:   https://algs4.cs.princeton.edu/33balanced/tinyST.txt  
 *    
 *  A symbol table implemented using an AVL tree.
 *
 *  % more tinyST.txt
 *  S E A R C H E X A M P L E
 *  
 *  % java AVLTreeST < tinyST.txt
 *  A 8
 *  C 4
 *  E 12
 *  H 5
 *  L 11
 *  M 9
 *  P 10
 *  R 3
 *  S 0
 *  X 7
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  AVLTreeST} class represents an ordered symbol table of
 *  generic key-value pairs. It supports the usual <em>put</em>, <em>get</em>,
 *  <em>contains</em>, <em>delete</em>, <em>size</em>, and <em>is-empty</em>
 *  methods. It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, and <em>ceiling</em>. It also provides a
 *  <em>keys</em> method for iterating over all of the keys. A symbol table
 *  implements the <em>associative array</em> abstraction: when associating a
 *  value with a key that is already in the symbol table, the convention is to
 *  replace the old value with the new value. Unlike { @link  java.util.Map}, this
 *  class uses the convention that values cannot be { @code  null}
 *  —setting the value associated with a key to { @code  null} is
 *  equivalent to deleting the key from the symbol table.
 *  <p>
 *  This symbol table implementation uses internally an
 *  <a href="https://en.wikipedia.org/wiki/AVL_tree"> AVL tree </a> (Georgy
 *  Adelson-Velsky and Evgenii Landis' tree) which is a self-balancing BST.
 *  In an AVL tree, the heights of the two child subtrees of any
 *  node differ by at most one; if at any time they differ by more than one,
 *  rebalancing is done to restore this property.
 *  <p>
 *  This implementation requires that the key type implements the
 *  { @code  Comparable} interface and calls the { @code  compareTo()} and
 *  method to compare two keys. It does not call either { @code  equals()} or
 *  { @code  hashCode()}. The <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>minimum</em>, <em>maximum</em>, <em>ceiling</em>, and
 *  <em>floor</em> operations each take logarithmic time in the worst case. The
 *  <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction also takes constant time.
 * 
 *  For other implementations of the same API, see { @link  ST}, { @link  BinarySearchST},
 *  { @link  SequentialSearchST}, { @link  BST}, { @link  RedBlackBST},
 *  { @link  SeparateChainingHashST}, and { @link  LinearProbingHashST}.
 * 
 *   @author  Marcelo Silva
 */

public   class   AVLTreeST < Key   extends   Comparable < Key > ,   Value >   {

     /**
     * The root node.
     */
     private   Node  root ;

     /**
     * This class represents an inner node of the AVL tree.
     */
     private   class   Node   {
         private   final   Key  key ;     // the key
         private   Value  val ;         // the associated value
         private   int  height ;        // height of the subtree
         private   int  size ;          // number of nodes in subtree
         private   Node  left ;         // left subtree
         private   Node  right ;        // right subtree

         public   Node ( Key  key ,   Value  val ,   int  height ,   int  size )   {
             this . key  =  key ;
             this . val  =  val ;
             this . size  =  size ;
             this . height  =  height ;
         }
     }

     /**
     * Initializes an empty symbol table.
     */
     public   AVLTreeST ()   {
     }

     /**
     * Checks if the symbol table is empty.
     * 
     *  @return  { @code  true} if the symbol table is empty.
     */
     public   boolean  isEmpty ()   {
         return  root  ==   null ;
     }

     /**
     * Returns the number key-value pairs in the symbol table.
     * 
     *  @return  the number key-value pairs in the symbol table
     */
     public   int  size ()   {
         return  size ( root );
     }

     /**
     * Returns the number of nodes in the subtree.
     * 
     *  @param  x the subtree
     * 
     *  @return  the number of nodes in the subtree
     */
     private   int  size ( Node  x )   {
         if   ( ==   null )   return   0 ;
         return  x . size ;
     }

     /**
     * Returns the height of the internal AVL tree. It is assumed that the
     * height of an empty tree is -1 and the height of a tree with just one node
     * is 0.
     * 
     *  @return  the height of the internal AVL tree
     */
     public   int  height ()   {
         return  height ( root );
     }

     /**
     * Returns the height of the subtree.
     * 
     *  @param  x the subtree
     * 
     *  @return  the height of the subtree.
     */
     private   int  height ( Node  x )   {
         if   ( ==   null )   return   - 1 ;
         return  x . height ;
     }

     /**
     * Returns the value associated with the given key.
     * 
     *  @param  key the key
     *  @return  the value associated with the given key if the key is in the
     *         symbol table and { @code  null} if the key is not in the
     *         symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         Node  x  =  get ( root ,  key );
         if   ( ==   null )   return   null ;
         return  x . val ;
     }

     /**
     * Returns value associated with the given key in the subtree or
     * { @code  null} if no such key.
     * 
     *  @param  x the subtree
     *  @param  key the key
     *  @return  value associated with the given key in the subtree or
     *         { @code  null} if no such key
     */
     private   Node  get ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  <   0 )   return  get ( x . left ,  key );
         else   if   ( cmp  >   0 )   return  get ( x . right ,  key );
         else   return  x ;
     }

     /**
     * Checks if the symbol table contains the given key.
     * 
     *  @param  key the key
     *  @return  { @code  true} if the symbol table contains { @code  key}
     *         and { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         return  get ( key )   !=   null ;
     }

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting
     * the old value with the new value if the symbol table already contains the
     * specified key. Deletes the specified key (and its associated value) from
     * this symbol table if the specified value is { @code  null}.
     * 
     *  @param  key the key
     *  @param  val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );
         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }
        root  =  put ( root ,  key ,  val );
         assert  check ();
     }

     /**
     * Inserts the key-value pair in the subtree. It overrides the old value
     * with the new value if the symbol table already contains the specified key
     * and deletes the specified key (and its associated value) from this symbol
     * table if the specified value is { @code  null}.
     * 
     *  @param  x the subtree
     *  @param  key the key
     *  @param  val the value
     *  @return  the subtree
     */
     private   Node  put ( Node  x ,   Key  key ,   Value  val )   {
         if   ( ==   null )   return   new   Node ( key ,  val ,   0 ,   1 );
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  <   0 )   {
            x . left  =  put ( x . left ,  key ,  val );
         }
         else   if   ( cmp  >   0 )   {
            x . right  =  put ( x . right ,  key ,  val );
         }
         else   {
            x . val  =  val ;
             return  x ;
         }
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
         return  balance ( x );
     }

     /**
     * Restores the AVL tree property of the subtree.
     * 
     *  @param  x the subtree
     *  @return  the subtree with restored AVL property
     */
     private   Node  balance ( Node  x )   {
         if   ( balanceFactor ( x )   <   - 1 )   {
             if   ( balanceFactor ( x . right )   >   0 )   {
                x . right  =  rotateRight ( x . right );
             }
            x  =  rotateLeft ( x );
         }
         else   if   ( balanceFactor ( x )   >   1 )   {
             if   ( balanceFactor ( x . left )   <   0 )   {
                x . left  =  rotateLeft ( x . left );
             }
            x  =  rotateRight ( x );
         }
         return  x ;
     }

     /**
     * Returns the balance factor of the subtree. The balance factor is defined
     * as the difference in height of the left subtree and right subtree, in
     * this order. Therefore, a subtree with a balance factor of -1, 0 or 1 has
     * the AVL property since the heights of the two child subtrees differ by at
     * most one.
     * 
     *  @param  x the subtree
     *  @return  the balance factor of the subtree
     */
     private   int  balanceFactor ( Node  x )   {
         return  height ( x . left )   -  height ( x . right );
     }

     /**
     * Rotates the given subtree to the right.
     * 
     *  @param  x the subtree
     *  @return  the right rotated subtree
     */
     private   Node  rotateRight ( Node  x )   {
         Node  y  =  x . left ;
        x . left  =  y . right ;
        y . right  =  x ;
        y . size  =  x . size ;
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
        y . height  =   1   +   Math . max ( height ( y . left ),  height ( y . right ));
         return  y ;
     }

     /**
     * Rotates the given subtree to the left.
     * 
     *  @param  x the subtree
     *  @return  the left rotated subtree
     */
     private   Node  rotateLeft ( Node  x )   {
         Node  y  =  x . right ;
        x . right  =  y . left ;
        y . left  =  x ;
        y . size  =  x . size ;
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
        y . height  =   1   +   Math . max ( height ( y . left ),  height ( y . right ));
         return  y ;
     }

     /**
     * Removes the specified key and its associated value from the symbol table
     * (if the key is in the symbol table).
     * 
     *  @param  key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );
         if   ( ! contains ( key ))   return ;
        root  =  delete ( root ,  key );
         assert  check ();
     }

     /**
     * Removes the specified key and its associated value from the given
     * subtree.
     * 
     *  @param  x the subtree
     *  @param  key the key
     *  @return  the updated subtree
     */
     private   Node  delete ( Node  x ,   Key  key )   {
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  <   0 )   {
            x . left  =  delete ( x . left ,  key );
         }
         else   if   ( cmp  >   0 )   {
            x . right  =  delete ( x . right ,  key );
         }
         else   {
             if   ( x . left  ==   null )   {
                 return  x . right ;
             }
             else   if   ( x . right  ==   null )   {
                 return  x . left ;
             }
             else   {
                 Node  y  =  x ;
                x  =  min ( y . right );
                x . right  =  deleteMin ( y . right );
                x . left  =  y . left ;
             }
         }
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
         return  balance ( x );
     }

     /**
     * Removes the smallest key and associated value from the symbol table.
     * 
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called deleteMin() with empty symbol table" );
        root  =  deleteMin ( root );
         assert  check ();
     }

     /**
     * Removes the smallest key and associated value from the given subtree.
     * 
     *  @param  x the subtree
     *  @return  the updated subtree
     */
     private   Node  deleteMin ( Node  x )   {
         if   ( x . left  ==   null )   return  x . right ;
        x . left  =  deleteMin ( x . left );
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
         return  balance ( x );
     }

     /**
     * Removes the largest key and associated value from the symbol table.
     * 
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMax ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called deleteMax() with empty symbol table" );
        root  =  deleteMax ( root );
         assert  check ();
     }

     /**
     * Removes the largest key and associated value from the given subtree.
     * 
     *  @param  x the subtree
     *  @return  the updated subtree
     */
     private   Node  deleteMax ( Node  x )   {
         if   ( x . right  ==   null )   return  x . left ;
        x . right  =  deleteMax ( x . right );
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
        x . height  =   1   +   Math . max ( height ( x . left ),  height ( x . right ));
         return  balance ( x );
     }

     /**
     * Returns the smallest key in the symbol table.
     * 
     *  @return  the smallest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called min() with empty symbol table" );
         return  min ( root ). key ;
     }

     /**
     * Returns the node with the smallest key in the subtree.
     * 
     *  @param  x the subtree
     *  @return  the node with the smallest key in the subtree
     */
     private   Node  min ( Node  x )   {
         if   ( x . left  ==   null )   return  x ;
         return  min ( x . left );
     }

     /**
     * Returns the largest key in the symbol table.
     * 
     *  @return  the largest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called max() with empty symbol table" );
         return  max ( root ). key ;
     }

     /**
     * Returns the node with the largest key in the subtree.
     * 
     *  @param  x the subtree
     *  @return  the node with the largest key in the subtree
     */
     private   Node  max ( Node  x )   {
         if   ( x . right  ==   null )   return  x ;
         return  max ( x . right );
     }

     /**
     * Returns the largest key in the symbol table less than or equal to
     * { @code  key}.
     * 
     *  @param  key the key
     *  @return  the largest key in the symbol table less than or equal to
     *         { @code  key}
     *  @throws  NoSuchElementException if the symbol table is empty
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called floor() with empty symbol table" );
         Node  x  =  floor ( root ,  key );
         if   ( ==   null )   return   null ;
         else   return  x . key ;
     }

     /**
     * Returns the node in the subtree with the largest key less than or equal
     * to the given key.
     * 
     *  @param  x the subtree
     *  @param  key the key
     *  @return  the node in the subtree with the largest key less than or equal
     *         to the given key
     */
     private   Node  floor ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  <   0 )   return  floor ( x . left ,  key );
         Node  y  =  floor ( x . right ,  key );
         if   ( !=   null )   return  y ;
         else   return  x ;
     }

     /**
     * Returns the smallest key in the symbol table greater than or equal to
     * { @code  key}.
     * 
     *  @param  key the key
     *  @return  the smallest key in the symbol table greater than or equal to
     *         { @code  key}
     *  @throws  NoSuchElementException if the symbol table is empty
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called ceiling() with empty symbol table" );
         Node  x  =  ceiling ( root ,  key );
         if   ( ==   null )   return   null ;
         else   return  x . key ;
     }

     /**
     * Returns the node in the subtree with the smallest key greater than or
     * equal to the given key.
     * 
     *  @param  x the subtree
     *  @param  key the key
     *  @return  the node in the subtree with the smallest key greater than or
     *         equal to the given key
     */
     private   Node  ceiling ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  >   0 )   return  ceiling ( x . right ,  key );
         Node  y  =  ceiling ( x . left ,  key );
         if   ( !=   null )   return  y ;
         else   return  x ;
     }

     /**
     * Returns the kth smallest key in the symbol table.
     * 
     *  @param  k the order statistic
     *  @return  the kth smallest key in the symbol table
     *  @throws  IllegalArgumentException unless { @code  k} is between 0 and
     *             { @code  size() -1 }
     */
     public   Key  select ( int  k )   {
         if   ( <   0   ||  k  >=  size ())   throw   new   IllegalArgumentException ( "k is not in range 0-"   +   ( size ()   -   1 ));
         Node  x  =  select ( root ,  k );
         return  x . key ;
     }

     /**
     * Returns the node with key the kth smallest key in the subtree.
     * 
     *  @param  x the subtree
     *  @param  k the kth smallest key in the subtree
     *  @return  the node with key the kth smallest key in the subtree
     */
     private   Node  select ( Node  x ,   int  k )   {
         if   ( ==   null )   return   null ;
         int  t  =  size ( x . left );
         if   ( >  k )   return  select ( x . left ,  k );
         else   if   ( <  k )   return  select ( x . right ,  k  -  t  -   1 );
         else   return  x ;
     }

     /**
     * Returns the number of keys in the symbol table strictly less than
     * { @code  key}.
     * 
     *  @param  key the key
     *  @return  the number of keys in the symbol table strictly less than
     *         { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   int  rank ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );
         return  rank ( key ,  root );
     }

     /**
     * Returns the number of keys in the subtree less than key.
     * 
     *  @param  key the key
     *  @param  x the subtree
     *  @return  the number of keys in the subtree less than key
     */
     private   int  rank ( Key  key ,   Node  x )   {
         if   ( ==   null )   return   0 ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  <   0 )   return  rank ( key ,  x . left );
         else   if   ( cmp  >   0 )   return   1   +  size ( x . left )   +  rank ( key ,  x . right );
         else   return  size ( x . left );
     }

     /**
     * Returns all keys in the symbol table.
     * 
     *  @return  all keys in the symbol table
     */
     public   Iterable < Key >  keys ()   {
         return  keysInOrder ();
     }

     /**
     * Returns all keys in the symbol table following an in-order traversal.
     * 
     *  @return  all keys in the symbol table following an in-order traversal
     */
     public   Iterable < Key >  keysInOrder ()   {
         Queue < Key >  queue  =   new   Queue < Key > ();
        keysInOrder ( root ,  queue );
         return  queue ;
     }

     /**
     * Adds the keys in the subtree to queue following an in-order traversal.
     * 
     *  @param  x the subtree
     *  @param  queue the queue
     */
     private   void  keysInOrder ( Node  x ,   Queue < Key >  queue )   {
         if   ( ==   null )   return ;
        keysInOrder ( x . left ,  queue );
        queue . enqueue ( x . key );
        keysInOrder ( x . right ,  queue );
     }

     /**
     * Returns all keys in the symbol table following a level-order traversal.
     * 
     *  @return  all keys in the symbol table following a level-order traversal.
     */
     public   Iterable < Key >  keysLevelOrder ()   {
         Queue < Key >  queue  =   new   Queue < Key > ();
         if   ( ! isEmpty ())   {
             Queue < Node >  queue2  =   new   Queue < Node > ();
            queue2 . enqueue ( root );
             while   ( ! queue2 . isEmpty ())   {
                 Node  x  =  queue2 . dequeue ();
                queue . enqueue ( x . key );
                 if   ( x . left  !=   null )   {
                    queue2 . enqueue ( x . left );
                 }
                 if   ( x . right  !=   null )   {
                    queue2 . enqueue ( x . right );
                 }
             }
         }
         return  queue ;
     }

     /**
     * Returns all keys in the symbol table in the given range.
     * 
     *  @param  lo the lowest key
     *  @param  hi the highest key
     *  @return  all keys in the symbol table between { @code  lo} (inclusive)
     *         and { @code  hi} (exclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *             is { @code  null}
     */
     public   Iterable < Key >  keys ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to keys() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to keys() is null" );
         Queue < Key >  queue  =   new   Queue < Key > ();
        keys ( root ,  queue ,  lo ,  hi );
         return  queue ;
     }

     /**
     * Adds the keys between { @code  lo} and { @code  hi} in the subtree
     * to the { @code  queue}.
     * 
     *  @param  x the subtree
     *  @param  queue the queue
     *  @param  lo the lowest key
     *  @param  hi the highest key
     */
     private   void  keys ( Node  x ,   Queue < Key >  queue ,   Key  lo ,   Key  hi )   {
         if   ( ==   null )   return ;
         int  cmplo  =  lo . compareTo ( x . key );
         int  cmphi  =  hi . compareTo ( x . key );
         if   ( cmplo  <   0 )  keys ( x . left ,  queue ,  lo ,  hi );
         if   ( cmplo  <=   0   &&  cmphi  >=   0 )  queue . enqueue ( x . key );
         if   ( cmphi  >   0 )  keys ( x . right ,  queue ,  lo ,  hi );
     }

     /**
     * Returns the number of keys in the symbol table in the given range.
     * 
     *  @param  lo minimum endpoint
     *  @param  hi maximum endpoint
     *  @return  the number of keys in the symbol table between { @code  lo}
     *         (inclusive) and { @code  hi} (exclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *             is { @code  null}
     */
     public   int  size ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to size() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to size() is null" );
         if   ( lo . compareTo ( hi )   >   0 )   return   0 ;
         if   ( contains ( hi ))   return  rank ( hi )   -  rank ( lo )   +   1 ;
         else   return  rank ( hi )   -  rank ( lo );
     }

     /**
     * Checks if the AVL tree invariants are fine.
     * 
     *  @return  { @code  true} if the AVL tree invariants are fine
     */
     private   boolean  check ()   {
         if   ( ! isBST ())   StdOut . println ( "Symmetric order not consistent" );
         if   ( ! isAVL ())   StdOut . println ( "AVL property not consistent" );
         if   ( ! isSizeConsistent ())   StdOut . println ( "Subtree counts not consistent" );
         if   ( ! isRankConsistent ())   StdOut . println ( "Ranks not consistent" );
         return  isBST ()   &&  isAVL ()   &&  isSizeConsistent ()   &&  isRankConsistent ();
     }

     /**
     * Checks if AVL property is consistent.
     * 
     *  @return  { @code  true} if AVL property is consistent.
     */
     private   boolean  isAVL ()   {
         return  isAVL ( root );
     }

     /**
     * Checks if AVL property is consistent in the subtree.
     * 
     *  @param  x the subtree
     *  @return  { @code  true} if AVL property is consistent in the subtree
     */
     private   boolean  isAVL ( Node  x )   {
         if   ( ==   null )   return   true ;
         int  bf  =  balanceFactor ( x );
         if   ( bf  >   1   ||  bf  <   - 1 )   return   false ;
         return  isAVL ( x . left )   &&  isAVL ( x . right );
     }

     /**
     * Checks if the symmetric order is consistent.
     * 
     *  @return  { @code  true} if the symmetric order is consistent
     */
     private   boolean  isBST ()   {
         return  isBST ( root ,   null ,   null );
     }

     /**
     * Checks if the tree rooted at x is a BST with all keys strictly between
     * min and max (if min or max is null, treat as empty constraint) Credit:
     * Bob Dondero's elegant solution
     * 
     *  @param  x the subtree
     *  @param  min the minimum key in subtree
     *  @param  max the maximum key in subtree
     *  @return  { @code  true} if if the symmetric order is consistent
     */
     private   boolean  isBST ( Node  x ,   Key  min ,   Key  max )   {
         if   ( ==   null )   return   true ;
         if   ( min  !=   null   &&  x . key . compareTo ( min )   <=   0 )   return   false ;
         if   ( max  !=   null   &&  x . key . compareTo ( max )   >=   0 )   return   false ;
         return  isBST ( x . left ,  min ,  x . key )   &&  isBST ( x . right ,  x . key ,  max );
     }

     /**
     * Checks if size is consistent.
     * 
     *  @return  { @code  true} if size is consistent
     */
     private   boolean  isSizeConsistent ()   {
         return  isSizeConsistent ( root );
     }

     /**
     * Checks if the size of the subtree is consistent.
     * 
     *  @return  { @code  true} if the size of the subtree is consistent
     */
     private   boolean  isSizeConsistent ( Node  x )   {
         if   ( ==   null )   return   true ;
         if   ( x . size  !=  size ( x . left )   +  size ( x . right )   +   1 )   return   false ;
         return  isSizeConsistent ( x . left )   &&  isSizeConsistent ( x . right );
     }

     /**
     * Checks if rank is consistent.
     * 
     *  @return  { @code  true} if rank is consistent
     */
     private   boolean  isRankConsistent ()   {
         for   ( int  i  =   0 ;  i  <  size ();  i ++ )
             if   ( !=  rank ( select ( i )))   return   false ;
         for   ( Key  key  :  keys ())
             if   ( key . compareTo ( select ( rank ( key )))   !=   0 )   return   false ;
         return   true ;
     }

     /**
     * Unit tests the { @code  AVLTreeST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         AVLTreeST < String ,   Integer >  st  =   new   AVLTreeST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }
         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
         StdOut . println ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Bag.java

edu/princeton/cs/algs4/Bag.java

/******************************************************************************
 *  Compilation:  javac Bag.java
 *  Execution:    java Bag < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *
 *  A generic bag or multiset, implemented using a singly linked list.
 *
 *  % more tobe.txt 
 *  to be or not to - be - - that - - - is
 *
 *  % java Bag < tobe.txt
 *  size of bag = 14
 *  is
 *  -
 *  -
 *  -
 *  that
 *  -
 *  -
 *  be
 *  -
 *  to
 *  not
 *  or
 *  be
 *  to
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  Bag} class represents a bag (or multiset) of 
 *  generic items. It supports insertion and iterating over the 
 *  items in arbitrary order.
 *  <p>
 *  This implementation uses a singly linked list with a static nested class Node.
 *  See { @link  LinkedBag} for the version from the
 *  textbook that uses a non-static nested class.
 *  See { @link  ResizingArrayBag} for a version that uses a resizing array.
 *  The <em>add</em>, <em>isEmpty</em>, and <em>size</em> operations
 *  take constant time. Iteration takes time proportional to the number of items.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Item> the generic type of an item in this bag
 */
public   class   Bag < Item >   implements   Iterable < Item >   {
     private   Node < Item >  first ;      // beginning of bag
     private   int  n ;                 // number of elements in bag

     // helper linked list class
     private   static   class   Node < Item >   {
         private   Item  item ;
         private   Node < Item >  next ;
     }

     /**
     * Initializes an empty bag.
     */
     public   Bag ()   {
        first  =   null ;
        n  =   0 ;
     }

     /**
     * Returns true if this bag is empty.
     *
     *  @return  { @code  true} if this bag is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in this bag.
     *
     *  @return  the number of items in this bag
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Adds the item to this bag.
     *
     *  @param   item the item to add to this bag
     */
     public   void  add ( Item  item )   {
         Node < Item >  oldfirst  =  first ;
        first  =   new   Node < Item > ();
        first . item  =  item ;
        first . next  =  oldfirst ;
        n ++ ;
     }


     /**
     * Returns an iterator that iterates over the items in this bag in arbitrary order.
     *
     *  @return  an iterator that iterates over the items in this bag in arbitrary order
     */
     public   Iterator < Item >  iterator ()    {
         return   new   ListIterator ( first );   
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node < Item >  current ;

         public   ListIterator ( Node < Item >  first )   {
            current  =  first ;
         }

         public   boolean  hasNext ()    {   return  current  !=   null ;                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }

     /**
     * Unit tests the { @code  Bag} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Bag < String >  bag  =   new   Bag < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
            bag . add ( item );
         }

         StdOut . println ( "size of bag = "   +  bag . size ());
         for   ( String  s  :  bag )   {
             StdOut . println ( s );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BellmanFordSP.java

edu/princeton/cs/algs4/BellmanFordSP.java

/******************************************************************************
 *  Compilation:  javac BellmanFordSP.java
 *  Execution:    java BellmanFordSP filename.txt s
 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Queue.java
 *                EdgeWeightedDirectedCycle.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWDn.txt
 *                https://algs4.cs.princeton.edu/44sp/mediumEWDnc.txt
 *
 *  Bellman-Ford shortest path algorithm. Computes the shortest path tree in
 *  edge-weighted digraph G from vertex s, or finds a negative cost cycle
 *  reachable from s.
 *
 *  % java BellmanFordSP tinyEWDn.txt 0
 *  0 to 0 ( 0.00)  
 *  0 to 1 ( 0.93)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   4->5  0.35   5->1  0.32
 *  0 to 2 ( 0.26)  0->2  0.26   
 *  0 to 3 ( 0.99)  0->2  0.26   2->7  0.34   7->3  0.39   
 *  0 to 4 ( 0.26)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   
 *  0 to 5 ( 0.61)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   6->4 -1.25   4->5  0.35
 *  0 to 6 ( 1.51)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   
 *  0 to 7 ( 0.60)  0->2  0.26   2->7  0.34   
 *
 *  % java BellmanFordSP tinyEWDnc.txt 0
 *  4->5  0.35
 *  5->4 -0.66
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BellmanFordSP} class represents a data type for solving the
 *  single-source shortest paths problem in edge-weighted digraphs with
 *  no negative cycles. 
 *  The edge weights can be positive, negative, or zero.
 *  This class finds either a shortest path from the source vertex <em>s</em>
 *  to every other vertex or a negative cycle reachable from the source vertex.
 *  <p>
 *  This implementation uses a queue-based implementation of 
 *  the Bellman-Ford-Moore algorithm.
 *  The constructor takes &Theta;(<em>V</em> (<em>V</em> + <em>E</em>)) time
 *  in the worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges. In practice, it performs much better.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted digraph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BellmanFordSP   {
     private   double []  distTo ;                 // distTo[v] = distance  of shortest s->v path
     private   DirectedEdge []  edgeTo ;           // edgeTo[v] = last edge on shortest s->v path
     private   boolean []  onQueue ;               // onQueue[v] = is v currently on the queue?
     private   Queue < Integer >  queue ;            // queue of vertices to relax
     private   int  cost ;                        // number of calls to relax()
     private   Iterable < DirectedEdge >  cycle ;    // negative cycle (or null if no such cycle)

     /**
     * Computes a shortest paths tree from { @code  s} to every other vertex in
     * the edge-weighted digraph { @code  G}.
     *  @param  G the acyclic digraph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   BellmanFordSP ( EdgeWeightedDigraph  G ,   int  s )   {
        distTo   =   new   double [ G . V ()];
        edgeTo   =   new   DirectedEdge [ G . V ()];
        onQueue  =   new   boolean [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . POSITIVE_INFINITY ;
        distTo [ s ]   =   0.0 ;

         // Bellman-Ford algorithm
        queue  =   new   Queue < Integer > ();
        queue . enqueue ( s );
        onQueue [ s ]   =   true ;
         while   ( ! queue . isEmpty ()   &&   ! hasNegativeCycle ())   {
             int  v  =  queue . dequeue ();
            onQueue [ v ]   =   false ;
            relax ( G ,  v );
         }

         assert  check ( G ,  s );
     }

     // relax vertex v and put other endpoints on queue if changed
     private   void  relax ( EdgeWeightedDigraph  G ,   int  v )   {
         for   ( DirectedEdge  e  :  G . adj ( v ))   {
             int  w  =  e . to ();
             if   ( distTo [ w ]   >  distTo [ v ]   +  e . weight ())   {
                distTo [ w ]   =  distTo [ v ]   +  e . weight ();
                edgeTo [ w ]   =  e ;
                 if   ( ! onQueue [ w ])   {
                    queue . enqueue ( w );
                    onQueue [ w ]   =   true ;
                 }
             }
             if   ( ++ cost  %  G . V ()   ==   0 )   {
                findNegativeCycle ();
                 if   ( hasNegativeCycle ())   return ;    // found a negative cycle
             }
         }
     }

     /**
     * Is there a negative cycle reachable from the source vertex { @code  s}?
     *  @return  { @code  true} if there is a negative cycle reachable from the
     *    source vertex { @code  s}, and { @code  false} otherwise
     */
     public   boolean  hasNegativeCycle ()   {
         return  cycle  !=   null ;
     }

     /**
     * Returns a negative cycle reachable from the source vertex { @code  s}, or { @code  null}
     * if there is no such cycle.
     *  @return  a negative cycle reachable from the soruce vertex { @code  s} 
     *    as an iterable of edges, and { @code  null} if there is no such cycle
     */
     public   Iterable < DirectedEdge >  negativeCycle ()   {
         return  cycle ;
     }

     // by finding a cycle in predecessor graph
     private   void  findNegativeCycle ()   {
         int  V  =  edgeTo . length ;
         EdgeWeightedDigraph  spt  =   new   EdgeWeightedDigraph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             if   ( edgeTo [ v ]   !=   null )
                spt . addEdge ( edgeTo [ v ]);

         EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( spt );
        cycle  =  finder . cycle ();
     }

     /**
     * Returns the length of a shortest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  the length of a shortest path from the source vertex { @code  s} to vertex { @code  v};
     *         { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  UnsupportedOperationException if there is a negative cost cycle reachable
     *         from the source vertex { @code  s}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  distTo ( int  v )   {
        validateVertex ( v );
         if   ( hasNegativeCycle ())
             throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );
         return  distTo [ v ];
     }

     /**
     * Is there a path from the source { @code  s} to vertex { @code  v}?
     *  @param   v the destination vertex
     *  @return  { @code  true} if there is a path from the source vertex
     *         { @code  s} to vertex { @code  v}, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns a shortest path from the source { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  a shortest path from the source { @code  s} to vertex { @code  v}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  UnsupportedOperationException if there is a negative cost cycle reachable
     *         from the source vertex { @code  s}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( hasNegativeCycle ())
             throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < DirectedEdge >  path  =   new   Stack < DirectedEdge > ();
         for   ( DirectedEdge  e  =  edgeTo [ v ];  e  !=   null ;  e  =  edgeTo [ e . from ()])   {
            path . push ( e );
         }
         return  path ;
     }

     // check optimality conditions: either 
     // (i) there exists a negative cycle reacheable from s
     //     or 
     // (ii)  for all edges e = v->w:            distTo[w] <= distTo[v] + e.weight()
     // (ii') for all edges e = v->w on the SPT: distTo[w] == distTo[v] + e.weight()
     private   boolean  check ( EdgeWeightedDigraph  G ,   int  s )   {

         // has a negative cycle
         if   ( hasNegativeCycle ())   {
             double  weight  =   0.0 ;
             for   ( DirectedEdge  e  :  negativeCycle ())   {
                weight  +=  e . weight ();
             }
             if   ( weight  >=   0.0 )   {
                 System . err . println ( "error: weight of negative cycle = "   +  weight );
                 return   false ;
             }
         }

         // no negative cycle reachable from source
         else   {

             // check that distTo[v] and edgeTo[v] are consistent
             if   ( distTo [ s ]   !=   0.0   ||  edgeTo [ s ]   !=   null )   {
                 System . err . println ( "distanceTo[s] and edgeTo[s] inconsistent" );
                 return   false ;
             }
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 if   ( ==  s )   continue ;
                 if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {
                     System . err . println ( "distTo[] and edgeTo[] inconsistent" );
                     return   false ;
                 }
             }

             // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( DirectedEdge  e  :  G . adj ( v ))   {
                     int  w  =  e . to ();
                     if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {
                         System . err . println ( "edge "   +  e  +   " not relaxed" );
                         return   false ;
                     }
                 }
             }

             // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( edgeTo [ w ]   ==   null )   continue ;
                 DirectedEdge  e  =  edgeTo [ w ];
                 int  v  =  e . from ();
                 if   ( !=  e . to ())   return   false ;
                 if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {
                     System . err . println ( "edge "   +  e  +   " on shortest path not tight" );
                     return   false ;
                 }
             }
         }

         StdOut . println ( "Satisfies optimality conditions" );
         StdOut . println ();
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  BellmanFordSP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         int  s  =   Integer . parseInt ( args [ 1 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );

         BellmanFordSP  sp  =   new   BellmanFordSP ( G ,  s );

         // print negative cycle
         if   ( sp . hasNegativeCycle ())   {
             for   ( DirectedEdge  e  :  sp . negativeCycle ())
                 StdOut . println ( e );
         }

         // print shortest paths
         else   {
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 if   ( sp . hasPathTo ( v ))   {
                     StdOut . printf ( "%d to %d (%5.2f)  " ,  s ,  v ,  sp . distTo ( v ));
                     for   ( DirectedEdge  e  :  sp . pathTo ( v ))   {
                         StdOut . print ( +   "   " );
                     }
                     StdOut . println ();
                 }
                 else   {
                     StdOut . printf ( "%d to %d           no path\n" ,  s ,  v );
                 }
             }
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryDump.java

edu/princeton/cs/algs4/BinaryDump.java

/******************************************************************************
 *  Compilation:  javac BinaryDump.java
 *  Execution:    java BinaryDump n < file
 *  Dependencies: BinaryStdIn.java
 *  Data file:    https://introcs.cs.princeton.edu/stdlib/abra.txt
 *  
 *  Reads in a binary file and writes out the bits, n per line.
 *
 *  % more abra.txt 
 *  ABRACADABRA!
 *
 *  % java BinaryDump 16 < abra.txt
 *  0100000101000010
 *  0101001001000001
 *  0100001101000001
 *  0100010001000001
 *  0100001001010010
 *  0100000100100001
 *  96 bits
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BinaryDump} class provides a client for displaying the contents
 *  of a binary file in binary.
 *  <p>
 *  For more full-featured versions, see the Unix utilities
 *  { @code  od} (octal dump) and { @code  hexdump} (hexadecimal dump).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  See also { @link  HexDump} and { @link  PictureDump}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BinaryDump   {

     // Do not instantiate.
     private   BinaryDump ()   {   }

     /**
     * Reads in a sequence of bytes from standard input and writes
     * them to standard output in binary, k bits per line,
     * where k is given as a command-line integer (defaults
     * to 16 if no integer is specified); also writes the number
     * of bits.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  bitsPerLine  =   16 ;
         if   ( args . length  ==   1 )   {
            bitsPerLine  =   Integer . parseInt ( args [ 0 ]);
         }

         int  count ;
         for   ( count  =   0 ;   ! BinaryStdIn . isEmpty ();  count ++ )   {
             if   ( bitsPerLine  ==   0 )   {
                 BinaryStdIn . readBoolean ();
                 continue ;
             }
             else   if   ( count  !=   0   &&  count  %  bitsPerLine  ==   0 )   StdOut . println ();
             if   ( BinaryStdIn . readBoolean ())   StdOut . print ( 1 );
             else                             StdOut . print ( 0 );
         }
         if   ( bitsPerLine  !=   0 )   StdOut . println ();
         StdOut . println ( count  +   " bits" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryIn.java

edu/princeton/cs/algs4/BinaryIn.java

/******************************************************************************
 *  Compilation:  javac BinaryIn.java
 *  Execution:    java BinaryIn input output
 *  Dependencies: none             
 *  
 *  This library is for reading binary data from an input stream.
 *
 *  % java BinaryIn https://introcs.cs.princeton.edu/java/cover.png output.png
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . BufferedInputStream ;
import  java . io . File ;
import  java . io . FileInputStream ;
import  java . io . IOException ;
import  java . io . InputStream ;
import  java . net . Socket ;
import  java . net . URL ;
import  java . net . URLConnection ;
import  java . util . NoSuchElementException ;

/**
 *  <i>Binary input</i>. This class provides methods for reading
 *  in bits from a binary input stream, either
 *  one bit at a time (as a { @code  boolean}),
 *  8 bits at a time (as a { @code  byte} or { @code  char}),
 *  16 bits at a time (as a { @code  short}),
 *  32 bits at a time (as an { @code  int} or { @code  float}), or
 *  64 bits at a time (as a { @code  double} or { @code  long}).
 *  <p>
 *  The binary input stream can be from standard input, a filename,
 *  a URL name, a Socket, or an InputStream.
 *  <p>
 *  All primitive types are assumed to be represented using their 
 *  standard Java representations, in big-endian (most significant
 *  byte first) order.
 *  <p>
 *  The client should not intermix calls to { @code  BinaryIn} with calls
 *  to { @code  In}; otherwise unexpected behavior will result.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   BinaryIn   {
     private   static   final   int  EOF  =   - 1 ;     // end of file

     private   BufferedInputStream  in ;        // the input stream
     private   int  buffer ;                    // one character buffer
     private   int  n ;                         // number of bits left in buffer

    /**
     * Initializes a binary input stream from standard input.
     */
     public   BinaryIn ()   {
        in  =   new   BufferedInputStream ( System . in );
        fillBuffer ();
     }

    /**
     * Initializes a binary input stream from an { @code  InputStream}.
     *
     *  @param  is the { @code  InputStream} object
     */
     public   BinaryIn ( InputStream  is )   {
        in  =   new   BufferedInputStream ( is );
        fillBuffer ();
     }

    /**
     * Initializes a binary input stream from a socket.
     *
     *  @param  socket the socket
     */
     public   BinaryIn ( Socket  socket )   {
         try   {
             InputStream  is  =  socket . getInputStream ();
            in  =   new   BufferedInputStream ( is );
            fillBuffer ();
         }
         catch   ( IOException  ioe )   {
             System . err . println ( "Could not open "   +  socket );
         }
     }

    /**
     * Initializes a binary input stream from a URL.
     *
     *  @param  url the URL
     */
     public   BinaryIn ( URL url )   {
         try   {
             URLConnection  site  =  url . openConnection ();
             InputStream  is      =  site . getInputStream ();
            in  =   new   BufferedInputStream ( is );
            fillBuffer ();
         }
         catch   ( IOException  ioe )   {
             System . err . println ( "Could not open "   +  url );
         }
     }

    /**
     * Initializes a binary input stream from a filename or URL name.
     *
     *  @param  name the name of the file or URL
     */
     public   BinaryIn ( String  name )   {

         try   {
             // first try to read file from local file system
             File  file  =   new   File ( name );
             if   ( file . exists ())   {
                 FileInputStream  fis  =   new   FileInputStream ( file );
                in  =   new   BufferedInputStream ( fis );
                fillBuffer ();
                 return ;
             }

             // next try for files included in jar
            URL url  =  getClass (). getResource ( name );

             // or URL from web
             if   ( url  ==   null )   {
                url  =   new  URL ( name );
             }

             URLConnection  site  =  url . openConnection ();
             InputStream  is      =  site . getInputStream ();
            in  =   new   BufferedInputStream ( is );
            fillBuffer ();
         }
         catch   ( IOException  ioe )   {
             System . err . println ( "Could not open "   +  name );
         }
     }

     private   void  fillBuffer ()   {
         try   {
            buffer  =  in . read ();
            n  =   8 ;
         }
         catch   ( IOException  e )   {
             System . err . println ( "EOF" );
            buffer  =  EOF ;
            n  =   - 1 ;
         }
     }

     /**
     * Returns true if this binary input stream exists.
     *
     *  @return  { @code  true} if this binary input stream exists;
     *         { @code  false} otherwise
     */
     public   boolean  exists ()    {
         return  in  !=   null ;
     }

    /**
     * Returns true if this binary input stream is empty.
     *
     *  @return  { @code  true} if this binary input stream is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  buffer  ==  EOF ;
     }

    /**
     * Reads the next bit of data from this binary input stream and return as a boolean.
     *
     *  @return  the next bit of data from this binary input stream as a { @code  boolean}
     *  @throws  NoSuchElementException if this binary input stream is empty
     */
     public   boolean  readBoolean ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );
        n -- ;
         boolean  bit  =   (( buffer  >>  n )   &   1 )   ==   1 ;
         if   ( ==   0 )  fillBuffer ();
         return  bit ;
     }

    /**
     * Reads the next 8 bits from this binary input stream and return as an 8-bit char.
     *
     *  @return  the next 8 bits of data from this binary input stream as a { @code  char}
     *  @throws  NoSuchElementException if there are fewer than 8 bits available
     */
     public   char  readChar ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );

         // special case when aligned byte
         if   ( ==   8 )   {
             int  x  =  buffer ;
            fillBuffer ();
             return   ( char )   ( &   0xff );
         }

         // combine last N bits of current buffer with first 8-N bits of new buffer
         int  x  =  buffer ;
        x  <<=   ( 8   -  n );
         int  oldN  =  n ;
        fillBuffer ();
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );
        n  =  oldN ;
        x  |=   ( buffer  >>>  n );
         return   ( char )   ( &   0xff );
         // the above code doesn't quite work for the last character if N = 8
         // because buffer will be -1
     }


    /**
     * Reads the next r bits from this binary input stream and return as an r-bit character.
     *
     *  @param   r number of bits to read
     *  @return  the next { @code  r} bits of data from this binary input streamt as a { @code  char}
     *  @throws  NoSuchElementException if there are fewer than { @code  r} bits available
     *  @throws  IllegalArgumentException unless { @code  1 <= r <= 16}
     */
     public   char  readChar ( int  r )   {
         if   ( <   1   ||  r  >   16 )   throw   new   IllegalArgumentException ( "Illegal value of r = "   +  r );

         // optimize r = 8 case
         if   ( ==   8 )   return  readChar ();

         char  x  =   0 ;
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
            x  <<=   1 ;
             boolean  bit  =  readBoolean ();
             if   ( bit )  x  |=   1 ;
         }
         return  x ;
     }


    /**
     * Reads the remaining bytes of data from this binary input stream and return as a string. 
     *
     *  @return  the remaining bytes of data from this binary input stream as a { @code  String}
     *  @throws  NoSuchElementException if this binary input stream is empty or if the number of bits
     *         available is not a multiple of 8 (byte-aligned)
     */
     public   String  readString ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );

         StringBuilder  sb  =   new   StringBuilder ();
         while   ( ! isEmpty ())   {
             char  c  =  readChar ();
            sb . append ( c );
         }
         return  sb . toString ();
     }


    /**
     * Reads the next 16 bits from this binary input stream and return as a 16-bit short.
     *
     *  @return  the next 16 bits of data from this binary input stream as a { @code  short}
     *  @throws  NoSuchElementException if there are fewer than 16 bits available
     */
     public   short  readShort ()   {
         short  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }

    /**
     * Reads the next 32 bits from this binary input stream and return as a 32-bit int.
     *
     *  @return  the next 32 bits of data from this binary input stream as a { @code  int}
     *  @throws  NoSuchElementException if there are fewer than 32 bits available
     */
     public   int  readInt ()   {
         int  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }

    /**
     * Reads the next r bits from this binary input stream return as an r-bit int.
     *
     *  @param   r number of bits to read
     *  @return  the next { @code  r} bits of data from this binary input stream as a { @code  int}
     *  @throws  NoSuchElementException if there are fewer than r bits available
     *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}
     */
     public   int  readInt ( int  r )   {
         if   ( <   1   ||  r  >   32 )   throw   new   IllegalArgumentException ( "Illegal value of r = "   +  r );

         // optimize r = 32 case
         if   ( ==   32 )   return  readInt ();

         int  x  =   0 ;
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
            x  <<=   1 ;
             boolean  bit  =  readBoolean ();
             if   ( bit )  x  |=   1 ;
         }
         return  x ;
     }

    /**
     * Reads the next 64 bits from this binary input stream and return as a 64-bit long.
     *
     *  @return  the next 64 bits of data from this binary input stream as a { @code  long}
     *  @throws  NoSuchElementException if there are fewer than 64 bits available
     */
     public   long  readLong ()   {
         long  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }

    /**
     * Reads the next 64 bits from this binary input stream and return as a 64-bit double.
     *
     *  @return  the next 64 bits of data from this binary input stream as a { @code  double}
     *  @throws  NoSuchElementException if there are fewer than 64 bits available
     */
     public   double  readDouble ()   {
         return   Double . longBitsToDouble ( readLong ());
     }

    /**
     * Reads the next 32 bits from this binary input stream and return as a 32-bit float.
     *
     *  @return  the next 32 bits of data from this binary input stream as a { @code  float}
     *  @throws  NoSuchElementException if there are fewer than 32 bits available
     */
     public   float  readFloat ()   {
         return   Float . intBitsToFloat ( readInt ());
     }


    /**
     * Reads the next 8 bits from this binary input stream and return as an 8-bit byte.
     *
     *  @return  the next 8 bits of data from this binary input stream as a { @code  byte}
     *  @throws  NoSuchElementException if there are fewer than 8 bits available
     */
     public   byte  readByte ()   {
         char  c  =  readChar ();
         return   ( byte )   ( &   0xff );
     }
    
    /**
     * Unit tests the { @code  BinaryIn} data type.
     * Reads the name of a file or URL (first command-line argument)
     * and writes it to a file (second command-line argument).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         BinaryIn   in   =   new   BinaryIn ( args [ 0 ]);
         BinaryOut  out  =   new   BinaryOut ( args [ 1 ]);

         // read one 8-bit char at a time
         while   ( ! in . isEmpty ())   {
             char  c  =  in . readChar ();
            out . write ( c );
         }
        out . flush ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryInsertion.java

edu/princeton/cs/algs4/BinaryInsertion.java

/******************************************************************************
 *  Compilation:  javac BinaryInsertion.java
 *  Execution:    java BinaryInsertion < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt
 *                https://algs4.cs.princeton.edu/21elementary/words3.txt
 *  
 *  Sorts a sequence of strings from standard input using 
 *  binary insertion sort with half exchanges.
 *
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java BinaryInsertion < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *
 *  % java BinaryInsertion < words3.txt
 *  all bad bed bug dad ... yes yet zoo   [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BinaryInsertion} class provides a static method for sorting an
 *  array using an optimized binary insertion sort with half exchanges.
 *  <p>
 *  In the worst case, this implementation makes
 *  ~ <em>n</em> log<sub>2</sub><em>n</em> compares to sort an array of length
 *  <em>n</em>. However, in the worst case, the running time is
 *  &Theta;(<em>n</em><sup>2</sup>) because the number of array accesses
 *  can be quadratic.
 *  As such, it is not suitable for sorting large arrays
 *  (unless the number of inversions is small).
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(1) extra memory (not including the input array).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Ivan Pesin
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BinaryInsertion   {

     // This class should not be instantiated.
     private   BinaryInsertion ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   1 ;  i  <  n ;  i ++ )   {

             // binary search to determine index j at which to insert a[i]
             Comparable  v  =  a [ i ];
             int  lo  =   0 ,  hi  =  i ;
             while   ( lo  <  hi )   {
                 int  mid  =  lo  +   ( hi  -  lo )   /   2 ;  
                 if   ( less ( v ,  a [ mid ]))  hi  =  mid ;
                 else                  lo  =  mid  +   1 ;
             }

             // insetion sort with "half exchanges"
             // (insert a[i] at index j and shift a[j], ..., a[i-1] to right)
             for   ( int  j  =  i ;  j  >  lo ;   -- j )
                a [ j ]   =  a [ j - 1 ];
            a [ lo ]   =  v ;
         }
         assert  isSorted ( a );
     }



    /***************************************************************************
    *  Helper sorting function.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }

    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }

     // is the array sorted from a[lo] to a[hi]
     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo + 1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; insertion sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         BinaryInsertion . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryOut.java

edu/princeton/cs/algs4/BinaryOut.java

/******************************************************************************
 *  Compilation:  javac BinaryOut.java
 *  Execution:    java BinaryOut
 *  Dependencies: none
 *
 *  Write binary data to an output stream, either one 1-bit boolean,
 *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,
 *  or one 64-bit long at a time. The output stream can be standard
 *  output, a file, an OutputStream or a Socket.
 *
 *  The bytes written are not aligned.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . BufferedOutputStream ;
import  java . io . FileOutputStream ;
import  java . io . IOException ;
import  java . io . OutputStream ;
import  java . net . Socket ;

/**
 *  <i>Binary output</i>. This class provides methods for converting
 *  primtive type variables ({ @code  boolean}, { @code  byte}, { @code  char},
 *  { @code  int}, { @code  long}, { @code  float}, and { @code  double})
 *  to sequences of bits and writing them to an output stream.
 *  The output stream can be standard output, a file, an OutputStream or a Socket.
 *  Uses big-endian (most-significant byte first).
 *  <p>
 *  The client must { @code  flush()} the output stream when finished writing bits.
 *  <p>
 *  The client should not intermix calls to { @code  BinaryOut} with calls
 *  to { @code  Out}; otherwise unexpected behavior will result.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   BinaryOut   {

     private   BufferedOutputStream  out ;    // the output stream
     private   int  buffer ;                  // 8-bit buffer of bits to write out
     private   int  n ;                       // number of bits remaining in buffer


    /**
     * Initializes a binary output stream from standard output.
     */
     public   BinaryOut ()   {
        out  =   new   BufferedOutputStream ( System . out );
     }

    /**
     * Initializes a binary output stream from an { @code  OutputStream}.
     *  @param  os the { @code  OutputStream}
     */
     public   BinaryOut ( OutputStream  os )   {
        out  =   new   BufferedOutputStream ( os );
     }

    /**
     * Initializes a binary output stream from a file.
     *  @param  filename the name of the file
     */
     public   BinaryOut ( String  filename )   {
         try   {
             OutputStream  os  =   new   FileOutputStream ( filename );
            out  =   new   BufferedOutputStream ( os );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Initializes a binary output stream from a socket.
     *  @param  socket the socket
     */
     public   BinaryOut ( Socket  socket )   {
         try   {
             OutputStream  os  =  socket . getOutputStream ();
            out  =   new   BufferedOutputStream ( os );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }


    /**
     * Writes the specified bit to the binary output stream.
     *  @param  x the bit
     */
     private   void  writeBit ( boolean  x )   {
         // add bit to buffer
        buffer  <<=   1 ;
         if   ( x )  buffer  |=   1 ;

         // if buffer is full (8 bits), write out as a single byte
        n ++ ;
         if   ( ==   8 )  clearBuffer ();
     }  

    /**
     * Writes the 8-bit byte to the binary output stream.
     *  @param  x the byte
     */
     private   void  writeByte ( int  x )   {
         assert  x  >=   0   &&  x  <   256 ;

         // optimized if byte-aligned
         if   ( ==   0 )   {
             try   {
                out . write ( x );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
             return ;
         }

         // otherwise write one bit at a time
         for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {
             boolean  bit  =   (( >>>   ( 8   -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }

     // write out any remaining bits in buffer to the binary output stream, padding with 0s
     private   void  clearBuffer ()   {
         if   ( ==   0 )   return ;
         if   ( >   0 )  buffer  <<=   ( 8   -  n );
         try   {
            out . write ( buffer );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
        n  =   0 ;
        buffer  =   0 ;
     }

    /**
     * Flushes the binary output stream, padding 0s if number of bits written so far
     * is not a multiple of 8.
     */
     public   void  flush ()   {
        clearBuffer ();
         try   {
            out . flush ();
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Flushes and closes the binary output stream.
     * Once it is closed, bits can no longer be written.
     */
     public   void  close ()   {
        flush ();
         try   {
            out . close ();
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }


    /**
     * Writes the specified bit to the binary output stream.
     *  @param  x the { @code  boolean} to write
     */
     public   void  write ( boolean  x )   {
        writeBit ( x );
     }  

    /**
     * Writes the 8-bit byte to the binary output stream.
     *  @param  x the { @code  byte} to write.
     */
     public   void  write ( byte  x )   {
        writeByte ( &   0xff );
     }

    /**
     * Writes the 32-bit int to the binary output stream.
     *  @param  x the { @code  int} to write
     */
     public   void  write ( int  x )   {
        writeByte (( >>>   24 )   &   0xff );
        writeByte (( >>>   16 )   &   0xff );
        writeByte (( >>>    8 )   &   0xff );
        writeByte (( >>>    0 )   &   0xff );
     }

    /**
     * Writes the r-bit int to the binary output stream.
     *
     *  @param   x the { @code  int} to write
     *  @param   r the number of relevant bits in the char
     *  @throws  IllegalArgumentException unless { @code  r} is between 1 and 32
     *  @throws  IllegalArgumentException unless { @code  x} is between 0 and 2<sup>r</sup> - 1
     */
     public   void  write ( int  x ,   int  r )   {
         if   ( ==   32 )   {
            write ( x );
             return ;
         }
         if   ( <   1   ||  r  >   32 )   throw   new   IllegalArgumentException ( "Illegal value for r = "   +  r );
         if   ( >=   ( 1   <<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
             boolean  bit  =   (( >>>   ( -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }


    /**
     * Writes the 64-bit double to the binary output stream.
     *  @param  x the { @code  double} to write
     */
     public   void  write ( double  x )   {
        write ( Double . doubleToRawLongBits ( x ));
     }

    /**
     * Writes the 64-bit long to the binary output stream.
     *  @param  x the { @code  long} to write
     */
     public   void  write ( long  x )   {
        writeByte (( int )   (( >>>   56 )   &   0xff ));
        writeByte (( int )   (( >>>   48 )   &   0xff ));
        writeByte (( int )   (( >>>   40 )   &   0xff ));
        writeByte (( int )   (( >>>   32 )   &   0xff ));
        writeByte (( int )   (( >>>   24 )   &   0xff ));
        writeByte (( int )   (( >>>   16 )   &   0xff ));
        writeByte (( int )   (( >>>    8 )   &   0xff ));
        writeByte (( int )   (( >>>    0 )   &   0xff ));
     }

    /**
     * Writes the 32-bit float to the binary output stream.
     *  @param  x the { @code  float} to write
     */
     public   void  write ( float  x )   {
        write ( Float . floatToRawIntBits ( x ));
     }

    /**
     * Write the 16-bit int to the binary output stream.
     *  @param  x the { @code  short} to write.
     */
     public   void  write ( short  x )   {
        writeByte (( >>>    8 )   &   0xff );
        writeByte (( >>>    0 )   &   0xff );
     }

    /**
     * Writes the 8-bit char to the binary output stream.
     *
     *  @param   x the { @code  char} to write
     *  @throws  IllegalArgumentException unless { @code  x} is betwen 0 and 255
     */
     public   void  write ( char  x )   {
         if   ( <   0   ||  x  >=   256 )   throw   new   IllegalArgumentException ( "Illegal 8-bit char = "   +  x );
        writeByte ( x );
     }

    /**
     * Writes the r-bit char to the binary output stream.
     *
     *  @param   x the { @code  char} to write
     *  @param   r the number of relevant bits in the char
     *  @throws  IllegalArgumentException unless { @code  r} is between 1 and 16
     *  @throws  IllegalArgumentException unless { @code  x} is between 0 and 2<sup>r</sup> - 1
     */
     public   void  write ( char  x ,   int  r )   {
         if   ( ==   8 )   {
            write ( x );
             return ;
         }
         if   ( <   1   ||  r  >   16 )   throw   new   IllegalArgumentException ( "Illegal value for r = "   +  r );
         if   ( >=   ( 1   <<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
             boolean  bit  =   (( >>>   ( -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }

    /**
     * Writes the string of 8-bit characters to the binary output stream.
     *
     *  @param   s the { @code  String} to write
     *  @throws  IllegalArgumentException if any character in the string is not
     *         between 0 and 255
     */
     public   void  write ( String  s )   {
         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )
            write ( s . charAt ( i ));
     }


    /**
     * Writes the string of r-bit characters to the binary output stream.
     *  @param   s the { @code  String} to write
     *  @param   r the number of relevants bits in each character
     *  @throws  IllegalArgumentException unless r is between 1 and 16
     *  @throws  IllegalArgumentException if any character in the string is not
     *         between 0 and 2<sup>r</sup> - 1
     */
     public   void  write ( String  s ,   int  r )   {
         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )
            write ( s . charAt ( i ),  r );
     }


    /**
     * Test client. Read bits from standard input and write to the file
     * specified on command line.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create binary output stream to write to file
         String  filename  =  args [ 0 ];
         BinaryOut  out  =   new   BinaryOut ( filename );
         BinaryIn   in   =   new   BinaryIn ();

         // read from standard input and write to file
         while   ( ! in . isEmpty ())   {
             char  c  =  in . readChar ();
            out . write ( c );
         }
        out . flush ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinarySearch.java

edu/princeton/cs/algs4/BinarySearch.java

/******************************************************************************
 *  Compilation:  javac BinarySearch.java
 *  Execution:    java BinarySearch whitelist.txt < input.txt
 *  Dependencies: In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/11model/tinyW.txt
 *                https://algs4.cs.princeton.edu/11model/tinyT.txt
 *                https://algs4.cs.princeton.edu/11model/largeW.txt
 *                https://algs4.cs.princeton.edu/11model/largeT.txt
 *
 *  % java BinarySearch tinyW.txt < tinyT.txt
 *  50
 *  99
 *  13
 *
 *  % java BinarySearch largeW.txt < largeT.txt | more
 *  499569
 *  984875
 *  295754
 *  207807
 *  140925
 *  161828
 *  [367,966 total values]
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 *  The { @code  BinarySearch} class provides a static method for binary
 *  searching for an integer in a sorted array of integers.
 *  <p>
 *  The <em>indexOf</em> operations takes logarithmic time in the worst case.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BinarySearch   {

     /**
     * This class should not be instantiated.
     */
     private   BinarySearch ()   {   }

     /**
     * Returns the index of the specified key in the specified array.
     *
     *  @param   a the array of integers, must be sorted in ascending order
     *  @param   key the search key
     *  @return  index of key in array { @code  a} if present; { @code  -1} otherwise
     */
     public   static   int  indexOf ( int []  a ,   int  key )   {
         int  lo  =   0 ;
         int  hi  =  a . length  -   1 ;
         while   ( lo  <=  hi )   {
             // Key is in a[lo..hi] or not present.
             int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
             if        ( key  <  a [ mid ])  hi  =  mid  -   1 ;
             else   if   ( key  >  a [ mid ])  lo  =  mid  +   1 ;
             else   return  mid ;
         }
         return   - 1 ;
     }

     /**
     * Returns the index of the specified key in the specified array.
     * This function is poorly named because it does not give the <em>rank</em>
     * if the array has duplicate keys or if the key is not in the array.
     *
     *  @param   key the search key
     *  @param   a the array of integers, must be sorted in ascending order
     *  @return  index of key in array { @code  a} if present; { @code  -1} otherwise
     *  @deprecated  Replaced by { @link  #indexOf(int[], int)}.
     */
    @ Deprecated
     public   static   int  rank ( int  key ,   int []  a )   {
         return  indexOf ( a ,  key );
     }

     /**
     * Reads in a sequence of integers from the whitelist file, specified as
     * a command-line argument; reads in integers from standard input;
     * prints to standard output those integers that do <em>not</em> appear in the file.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read the integers from a file
         In  in  =   new   In ( args [ 0 ]);
         int []  whitelist  =  in . readAllInts ();

         // sort the array
         Arrays . sort ( whitelist );

         // read integer key from standard input; print if not in whitelist
         while   ( ! StdIn . isEmpty ())   {
             int  key  =   StdIn . readInt ();
             if   ( BinarySearch . indexOf ( whitelist ,  key )   ==   - 1 )
                 StdOut . println ( key );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinarySearchST.java

edu/princeton/cs/algs4/BinarySearchST.java

/******************************************************************************
 *  Compilation:  javac BinarySearchST.java
 *  Execution:    java BinarySearchST
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyST.txt  
 *  
 *  Symbol table implementation with binary search in an ordered array.
 *
 *  % more tinyST.txt
 *  S E A R C H E X A M P L E
 *  
 *  % java BinarySearchST < tinyST.txt
 *  A 8
 *  C 4
 *  E 12
 *  H 5
 *  L 11
 *  M 9
 *  P 10
 *  R 3
 *  S 0
 *  X 7
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  BST} class represents an ordered symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, <em>select</em>, and <em>ceiling</em>.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  <p>
 *  This implementation uses a <em>sorted array</em>.
 *  The <em>put</em> and <em>remove</em> operations take &Theta;(<em>n</em>)
 *  time in the worst case.
 *  The <em>contains</em>, <em>ceiling</em>, <em>floor</em>,
 *  and <em>rank</em> operations take &Theta;(log <em>n</em>) time in the worst
 *  case.
 *  The <em>size</em>, <em>is-empty</em>, <em>minimum</em>, <em>maximum</em>,
 *  and <em>select</em> operations take &Theta;(1) time.
 *  Construction takes &Theta;(1) time.
 *  <p>
 *  For alternative implementations of the symbol table API,
 *  see { @link  ST}, { @link  BST}, { @link  SequentialSearchST}, { @link  RedBlackBST},
 *  { @link  SeparateChainingHashST}, and { @link  LinearProbingHashST},
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   BinarySearchST < Key   extends   Comparable < Key > ,   Value >   {
     private   static   final   int  INIT_CAPACITY  =   2 ;
     private   Key []  keys ;
     private   Value []  vals ;
     private   int  n  =   0 ;

     /**
     * Initializes an empty symbol table.
     */
     public   BinarySearchST ()   {
         this ( INIT_CAPACITY );
     }

     /**
     * Initializes an empty symbol table with the specified initial capacity.
     *  @param  capacity the maximum capacity
     */
     public   BinarySearchST ( int  capacity )   {  
        keys  =   ( Key [])   new   Comparable [ capacity ];  
        vals  =   ( Value [])   new   Object [ capacity ];  
     }    

     // resize the underlying arrays
     private   void  resize ( int  capacity )   {
         assert  capacity  >=  n ;
         Key []    tempk  =   ( Key [])     new   Comparable [ capacity ];
         Value []  tempv  =   ( Value [])   new   Object [ capacity ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            tempk [ i ]   =  keys [ i ];
            tempv [ i ]   =  vals [ i ];
         }
        vals  =  tempv ;
        keys  =  tempk ;
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns true if this symbol table is empty.
     *
     *  @return  { @code  true} if this symbol table is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }


     /**
     * Does this symbol table contain the given key?
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }

     /**
     * Returns the value associated with the given key in this symbol table.
     *
     *  @param   key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *         and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );  
         if   ( isEmpty ())   return   null ;
         int  i  =  rank ( key );  
         if   ( <  n  &&  keys [ i ]. compareTo ( key )   ==   0 )   return  vals [ i ];
         return   null ;
     }  

     /**
     * Returns the number of keys in this symbol table strictly less than { @code  key}.
     *
     *  @param   key the key
     *  @return  the number of keys in the symbol table strictly less than { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   int  rank ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );  

         int  lo  =   0 ,  hi  =  n - 1 ;  
         while   ( lo  <=  hi )   {  
             int  mid  =  lo  +   ( hi  -  lo )   /   2 ;  
             int  cmp  =  key . compareTo ( keys [ mid ]);
             if        ( cmp  <   0 )  hi  =  mid  -   1 ;  
             else   if   ( cmp  >   0 )  lo  =  mid  +   1 ;  
             else   return  mid ;  
         }  
         return  lo ;
     }  



     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )    {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );  

         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }

         int  i  =  rank ( key );

         // key is already in table
         if   ( <  n  &&  keys [ i ]. compareTo ( key )   ==   0 )   {
            vals [ i ]   =  val ;
             return ;
         }

         // insert new key-value pair
         if   ( ==  keys . length )  resize ( 2 * keys . length );

         for   ( int  j  =  n ;  j  >  i ;  j -- )    {
            keys [ j ]   =  keys [ j - 1 ];
            vals [ j ]   =  vals [ j - 1 ];
         }
        keys [ i ]   =  key ;
        vals [ i ]   =  val ;
        n ++ ;

         assert  check ();
     }  

     /**
     * Removes the specified key and associated value from this symbol table
     * (if the key is in the symbol table).
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );  
         if   ( isEmpty ())   return ;

         // compute rank
         int  i  =  rank ( key );

         // key not in table
         if   ( ==  n  ||  keys [ i ]. compareTo ( key )   !=   0 )   {
             return ;
         }

         for   ( int  j  =  i ;  j  <  n - 1 ;  j ++ )    {
            keys [ j ]   =  keys [ j + 1 ];
            vals [ j ]   =  vals [ j + 1 ];
         }

        n -- ;
        keys [ n ]   =   null ;    // to avoid loitering
        vals [ n ]   =   null ;

         // resize if 1/4 full
         if   ( >   0   &&  n  ==  keys . length / 4 )  resize ( keys . length / 2 );

         assert  check ();
     }  

     /**
     * Removes the smallest key and associated value from this symbol table.
     *
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Symbol table underflow error" );
        delete ( min ());
     }

     /**
     * Removes the largest key and associated value from this symbol table.
     *
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMax ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Symbol table underflow error" );
        delete ( max ());
     }


    /***************************************************************************
    *  Ordered symbol table methods.
    ***************************************************************************/

    /**
     * Returns the smallest key in this symbol table.
     *
     *  @return  the smallest key in this symbol table
     *  @throws  NoSuchElementException if this symbol table is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called min() with empty symbol table" );
         return  keys [ 0 ];  
     }

     /**
     * Returns the largest key in this symbol table.
     *
     *  @return  the largest key in this symbol table
     *  @throws  NoSuchElementException if this symbol table is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called max() with empty symbol table" );
         return  keys [ n - 1 ];
     }

     /**
     * Return the kth smallest key in this symbol table.
     *
     *  @param   k the order statistic
     *  @return  the { @code  k}th smallest key in this symbol table
     *  @throws  IllegalArgumentException unless { @code  k} is between 0 and
     *        <em>n</em>–1
     */
     public   Key  select ( int  k )   {
         if   ( <   0   ||  k  >=  size ())   {
             throw   new   IllegalArgumentException ( "called select() with invalid argument: "   +  k );
         }
         return  keys [ k ];
     }

     /**
     * Returns the largest key in this symbol table less than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the largest key in this symbol table less than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );  
         int  i  =  rank ( key );
         if   ( <  n  &&  key . compareTo ( keys [ i ])   ==   0 )   return  keys [ i ];
         if   ( ==   0 )   return   null ;
         else   return  keys [ i - 1 ];
     }

     /**
     * Returns the smallest key in this symbol table greater than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the smallest key in this symbol table greater than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );  
         int  i  =  rank ( key );
         if   ( ==  n )   return   null ;  
         else   return  keys [ i ];
     }

     /**
     * Returns the number of keys in this symbol table in the specified range.
     *
     *  @param  lo minimum endpoint
     *  @param  hi maximum endpoint
     *  @return  the number of keys in this symbol table between { @code  lo} 
     *         (inclusive) and { @code  hi} (inclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *         is { @code  null}
     */
     public   int  size ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to size() is null" );  
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to size() is null" );  

         if   ( lo . compareTo ( hi )   >   0 )   return   0 ;
         if   ( contains ( hi ))   return  rank ( hi )   -  rank ( lo )   +   1 ;
         else                return  rank ( hi )   -  rank ( lo );
     }

     /**
     * Returns all keys in this symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *
     *  @return  all keys in this symbol table
     */
     public   Iterable < Key >  keys ()   {
         return  keys ( min (),  max ());
     }

     /**
     * Returns all keys in this symbol table in the given range,
     * as an { @code  Iterable}.
     *
     *  @param  lo minimum endpoint
     *  @param  hi maximum endpoint
     *  @return  all keys in this symbol table between { @code  lo} 
     *         (inclusive) and { @code  hi} (inclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *         is { @code  null}
     */
     public   Iterable < Key >  keys ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to keys() is null" );  
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to keys() is null" );  

         Queue < Key >  queue  =   new   Queue < Key > ();  
         if   ( lo . compareTo ( hi )   >   0 )   return  queue ;
         for   ( int  i  =  rank ( lo );  i  <  rank ( hi );  i ++ )  
            queue . enqueue ( keys [ i ]);
         if   ( contains ( hi ))  queue . enqueue ( keys [ rank ( hi )]);
         return  queue ;  
     }


    /***************************************************************************
    *  Check internal invariants.
    ***************************************************************************/

     private   boolean  check ()   {
         return  isSorted ()   &&  rankCheck ();
     }

     // are the items in the array in ascending order?
     private   boolean  isSorted ()   {
         for   ( int  i  =   1 ;  i  <  size ();  i ++ )
             if   ( keys [ i ]. compareTo ( keys [ i - 1 ])   <   0 )   return   false ;
         return   true ;
     }

     // check that rank(select(i)) = i
     private   boolean  rankCheck ()   {
         for   ( int  i  =   0 ;  i  <  size ();  i ++ )
             if   ( !=  rank ( select ( i )))   return   false ;
         for   ( int  i  =   0 ;  i  <  size ();  i ++ )
             if   ( keys [ i ]. compareTo ( select ( rank ( keys [ i ])))   !=   0 )   return   false ;
         return   true ;
     }


     /**
     * Unit tests the { @code  BinarySearchST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         BinarySearchST < String ,   Integer >  st  =   new   BinarySearchST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }
         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryStdIn.java

edu/princeton/cs/algs4/BinaryStdIn.java

/******************************************************************************
 *  Compilation:  javac BinaryStdIn.java
 *  Execution:    java BinaryStdIn < input > output
 *  Dependencies: none             
 *  
 *  Supports reading binary data from standard input.
 *
 *  % java BinaryStdIn < input.jpg > output.jpg
 *  % diff input.jpg output.jpg
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . BufferedInputStream ;
import  java . io . IOException ;
import  java . util . NoSuchElementException ;

/**
 *  <i>Binary standard input</i>. This class provides methods for reading
 *  in bits from standard input, either one bit at a time (as a { @code  boolean}),
 *  8 bits at a time (as a { @code  byte} or { @code  char}),
 *  16 bits at a time (as a { @code  short}), 32 bits at a time
 *  (as an { @code  int} or { @code  float}), or 64 bits at a time (as a
 *  { @code  double} or { @code  long}).
 *  <p>
 *  All primitive types are assumed to be represented using their 
 *  standard Java representations, in big-endian (most significant
 *  byte first) order.
 *  <p>
 *  The client should not intermix calls to { @code  BinaryStdIn} with calls
 *  to { @code  StdIn} or { @code  System.in};
 *  otherwise unexpected behavior will result.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   BinaryStdIn   {
     private   static   final   int  EOF  =   - 1 ;        // end of file

     private   static   BufferedInputStream  in ;    // input stream
     private   static   int  buffer ;                // one character buffer
     private   static   int  n ;                     // number of bits left in buffer
     private   static   boolean  isInitialized ;     // has BinaryStdIn been called for first time?

     // don't instantiate
     private   BinaryStdIn ()   {   }

     // fill buffer
     private   static   void  initialize ()   {
        in  =   new   BufferedInputStream ( System . in );
        buffer  =   0 ;
        n  =   0 ;
        fillBuffer ();
        isInitialized  =   true ;
     }

     private   static   void  fillBuffer ()   {
         try   {
            buffer  =  in . read ();
            n  =   8 ;
         }
         catch   ( IOException  e )   {
             System . out . println ( "EOF" );
            buffer  =  EOF ;
            n  =   - 1 ;
         }
     }

    /**
     * Close this input stream and release any associated system resources.
     */
     public   static   void  close ()   {
         if   ( ! isInitialized )  initialize ();
         try   {
            in . close ();
            isInitialized  =   false ;
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalStateException ( "Could not close BinaryStdIn" ,  ioe );
         }
     }

    /**
     * Returns true if standard input is empty.
     *  @return  true if and only if standard input is empty
     */
     public   static   boolean  isEmpty ()   {
         if   ( ! isInitialized )  initialize ();
         return  buffer  ==  EOF ;
     }

    /**
     * Reads the next bit of data from standard input and return as a boolean.
     *
     *  @return  the next bit of data from standard input as a { @code  boolean}
     *  @throws  NoSuchElementException if standard input is empty
     */
     public   static   boolean  readBoolean ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );
        n -- ;
         boolean  bit  =   (( buffer  >>  n )   &   1 )   ==   1 ;
         if   ( ==   0 )  fillBuffer ();
         return  bit ;
     }

    /**
     * Reads the next 8 bits from standard input and return as an 8-bit char.
     * Note that { @code  char} is a 16-bit type;
     * to read the next 16 bits as a char, use { @code  readChar(16)}.
     *
     *  @return  the next 8 bits of data from standard input as a { @code  char}
     *  @throws  NoSuchElementException if there are fewer than 8 bits available on standard input
     */
     public   static   char  readChar ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );

         // special case when aligned byte
         if   ( ==   8 )   {
             int  x  =  buffer ;
            fillBuffer ();
             return   ( char )   ( &   0xff );
         }

         // combine last n bits of current buffer with first 8-n bits of new buffer
         int  x  =  buffer ;
        x  <<=   ( 8   -  n );
         int  oldN  =  n ;
        fillBuffer ();
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );
        n  =  oldN ;
        x  |=   ( buffer  >>>  n );
         return   ( char )   ( &   0xff );
         // the above code doesn't quite work for the last character if n = 8
         // because buffer will be -1, so there is a special case for aligned byte
     }

    /**
     * Reads the next r bits from standard input and return as an r-bit character.
     *
     *  @param   r number of bits to read.
     *  @return  the next r bits of data from standard input as a { @code  char}
     *  @throws  NoSuchElementException if there are fewer than { @code  r} bits available on standard input
     *  @throws  IllegalArgumentException unless { @code  1 <= r <= 16}
     */
     public   static   char  readChar ( int  r )   {
         if   ( <   1   ||  r  >   16 )   throw   new   IllegalArgumentException ( "Illegal value of r = "   +  r );

         // optimize r = 8 case
         if   ( ==   8 )   return  readChar ();

         char  x  =   0 ;
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
            x  <<=   1 ;
             boolean  bit  =  readBoolean ();
             if   ( bit )  x  |=   1 ;
         }
         return  x ;
     }

    /**
     * Reads the remaining bytes of data from standard input and return as a string. 
     *
     *  @return  the remaining bytes of data from standard input as a { @code  String}
     *  @throws  NoSuchElementException if standard input is empty or if the number of bits
     *         available on standard input is not a multiple of 8 (byte-aligned)
     */
     public   static   String  readString ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Reading from empty input stream" );

         StringBuilder  sb  =   new   StringBuilder ();
         while   ( ! isEmpty ())   {
             char  c  =  readChar ();
            sb . append ( c );
         }
         return  sb . toString ();
     }


    /**
     * Reads the next 16 bits from standard input and return as a 16-bit short.
     *
     *  @return  the next 16 bits of data from standard input as a { @code  short}
     *  @throws  NoSuchElementException if there are fewer than 16 bits available on standard input
     */
     public   static   short  readShort ()   {
         short  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   2 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }

    /**
     * Reads the next 32 bits from standard input and return as a 32-bit int.
     *
     *  @return  the next 32 bits of data from standard input as a { @code  int}
     *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input
     */
     public   static   int  readInt ()   {
         int  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   4 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }

    /**
     * Reads the next r bits from standard input and return as an r-bit int.
     *
     *  @param   r number of bits to read.
     *  @return  the next r bits of data from standard input as a { @code  int}
     *  @throws  NoSuchElementException if there are fewer than { @code  r} bits available on standard input
     *  @throws  IllegalArgumentException unless { @code  1 <= r <= 32}
     */
     public   static   int  readInt ( int  r )   {
         if   ( <   1   ||  r  >   32 )   throw   new   IllegalArgumentException ( "Illegal value of r = "   +  r );

         // optimize r = 32 case
         if   ( ==   32 )   return  readInt ();

         int  x  =   0 ;
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
            x  <<=   1 ;
             boolean  bit  =  readBoolean ();
             if   ( bit )  x  |=   1 ;
         }
         return  x ;
     }

    /**
     * Reads the next 64 bits from standard input and return as a 64-bit long.
     *
     *  @return  the next 64 bits of data from standard input as a { @code  long}
     *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input
     */
     public   static   long  readLong ()   {
         long  x  =   0 ;
         for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {
             char  c  =  readChar ();
            x  <<=   8 ;
            x  |=  c ;
         }
         return  x ;
     }


    /**
     * Reads the next 64 bits from standard input and return as a 64-bit double.
     *
     *  @return  the next 64 bits of data from standard input as a { @code  double}
     *  @throws  NoSuchElementException if there are fewer than 64 bits available on standard input
     */
     public   static   double  readDouble ()   {
         return   Double . longBitsToDouble ( readLong ());
     }

    /**
     * Reads the next 32 bits from standard input and return as a 32-bit float.
     *
     *  @return  the next 32 bits of data from standard input as a { @code  float}
     *  @throws  NoSuchElementException if there are fewer than 32 bits available on standard input
     */
     public   static   float  readFloat ()   {
         return   Float . intBitsToFloat ( readInt ());
     }


    /**
     * Reads the next 8 bits from standard input and return as an 8-bit byte.
     *
     *  @return  the next 8 bits of data from standard input as a { @code  byte}
     *  @throws  NoSuchElementException if there are fewer than 8 bits available on standard input
     */
     public   static   byte  readByte ()   {
         char  c  =  readChar ();
         return   ( byte )   ( &   0xff );
     }
    
    /**
     * Test client. Reads in a binary input file from standard input and writes
     * it to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read one 8-bit char at a time
         while   ( ! BinaryStdIn . isEmpty ())   {
             char  c  =   BinaryStdIn . readChar ();
             BinaryStdOut . write ( c );
         }
         BinaryStdOut . flush ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinaryStdOut.java

edu/princeton/cs/algs4/BinaryStdOut.java

/******************************************************************************
 *  Compilation:  javac BinaryStdOut.java
 *  Execution:    java BinaryStdOut
 *  Dependencies: none
 *
 *  Write binary data to standard output, either one 1-bit boolean,
 *  one 8-bit char, one 32-bit int, one 64-bit double, one 32-bit float,
 *  or one 64-bit long at a time.
 *
 *  The bytes written are not aligned.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . BufferedOutputStream ;
import  java . io . IOException ;

/**
 *  <i>Binary standard output</i>. This class provides methods for converting
 *  primtive type variables ({ @code  boolean}, { @code  byte}, { @code  char},
 *  { @code  int}, { @code  long}, { @code  float}, and { @code  double})
 *  to sequences of bits and writing them to standard output.
 *  Uses big-endian (most-significant byte first).
 *  <p>
 *  The client must { @code  flush()} the output stream when finished writing bits.
 *  <p>
 *  The client should not intermix calls to { @code  BinaryStdOut} with calls
 *  to { @code  StdOut} or { @code  System.out}; otherwise unexpected behavior 
 *  will result.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   BinaryStdOut   {
     private   static   BufferedOutputStream  out ;    // output stream (standard output)
     private   static   int  buffer ;                  // 8-bit buffer of bits to write
     private   static   int  n ;                       // number of bits remaining in buffer
     private   static   boolean  isInitialized ;       // has BinaryStdOut been called for first time?

     // don't instantiate
     private   BinaryStdOut ()   {   }

     // initialize BinaryStdOut
     private   static   void  initialize ()   {
        out  =   new   BufferedOutputStream ( System . out );
        buffer  =   0 ;
        n  =   0 ;
        isInitialized  =   true ;
     }

    /**
     * Writes the specified bit to standard output.
     */
     private   static   void  writeBit ( boolean  bit )   {
         if   ( ! isInitialized )  initialize ();

         // add bit to buffer
        buffer  <<=   1 ;
         if   ( bit )  buffer  |=   1 ;

         // if buffer is full (8 bits), write out as a single byte
        n ++ ;
         if   ( ==   8 )  clearBuffer ();
     }  

    /**
     * Writes the 8-bit byte to standard output.
     */
     private   static   void  writeByte ( int  x )   {
         if   ( ! isInitialized )  initialize ();

         assert  x  >=   0   &&  x  <   256 ;

         // optimized if byte-aligned
         if   ( ==   0 )   {
             try   {
                out . write ( x );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
             return ;
         }

         // otherwise write one bit at a time
         for   ( int  i  =   0 ;  i  <   8 ;  i ++ )   {
             boolean  bit  =   (( >>>   ( 8   -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }

     // write out any remaining bits in buffer to standard output, padding with 0s
     private   static   void  clearBuffer ()   {
         if   ( ! isInitialized )  initialize ();

         if   ( ==   0 )   return ;
         if   ( >   0 )  buffer  <<=   ( 8   -  n );
         try   {
            out . write ( buffer );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
        n  =   0 ;
        buffer  =   0 ;
     }

    /**
     * Flushes standard output, padding 0s if number of bits written so far
     * is not a multiple of 8.
     */
     public   static   void  flush ()   {
        clearBuffer ();
         try   {
            out . flush ();
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Flushes and closes standard output. Once standard output is closed, you can no
     * longer write bits to it.
     */
     public   static   void  close ()   {
        flush ();
         try   {
            out . close ();
            isInitialized  =   false ;
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }


    /**
     * Writes the specified bit to standard output.
     *  @param  x the { @code  boolean} to write.
     */
     public   static   void  write ( boolean  x )   {
        writeBit ( x );
     }  

    /**
     * Writes the 8-bit byte to standard output.
     *  @param  x the { @code  byte} to write.
     */
     public   static   void  write ( byte  x )   {
        writeByte ( &   0xff );
     }

    /**
     * Writes the 32-bit int to standard output.
     *  @param  x the { @code  int} to write.
     */
     public   static   void  write ( int  x )   {
        writeByte (( >>>   24 )   &   0xff );
        writeByte (( >>>   16 )   &   0xff );
        writeByte (( >>>    8 )   &   0xff );
        writeByte (( >>>    0 )   &   0xff );
     }

    /**
     * Writes the r-bit int to standard output.
     *  @param  x the { @code  int} to write.
     *  @param  r the number of relevant bits in the char.
     *  @throws  IllegalArgumentException if { @code  r} is not between 1 and 32.
     *  @throws  IllegalArgumentException if { @code  x} is not between 0 and 2<sup>r</sup> - 1.
     */
     public   static   void  write ( int  x ,   int  r )   {
         if   ( ==   32 )   {
            write ( x );
             return ;
         }
         if   ( <   1   ||  r  >   32 )          throw   new   IllegalArgumentException ( "Illegal value for r = "   +  r );
         if   ( <   0   ||  x  >=   ( 1   <<  r ))   throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
             boolean  bit  =   (( >>>   ( -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }





    /**
     * Writes the 64-bit double to standard output.
     *  @param  x the { @code  double} to write.
     */
     public   static   void  write ( double  x )   {
        write ( Double . doubleToRawLongBits ( x ));
     }

    /**
     * Writes the 64-bit long to standard output.
     *  @param  x the { @code  long} to write.
     */
     public   static   void  write ( long  x )   {
        writeByte (( int )   (( >>>   56 )   &   0xff ));
        writeByte (( int )   (( >>>   48 )   &   0xff ));
        writeByte (( int )   (( >>>   40 )   &   0xff ));
        writeByte (( int )   (( >>>   32 )   &   0xff ));
        writeByte (( int )   (( >>>   24 )   &   0xff ));
        writeByte (( int )   (( >>>   16 )   &   0xff ));
        writeByte (( int )   (( >>>    8 )   &   0xff ));
        writeByte (( int )   (( >>>    0 )   &   0xff ));
     }

    /**
     * Writes the 32-bit float to standard output.
     *  @param  x the { @code  float} to write.
     */
     public   static   void  write ( float  x )   {
        write ( Float . floatToRawIntBits ( x ));
     }

    /**
     * Writes the 16-bit int to standard output.
     *  @param  x the { @code  short} to write.
     */
     public   static   void  write ( short  x )   {
        writeByte (( >>>    8 )   &   0xff );
        writeByte (( >>>    0 )   &   0xff );
     }

    /**
     * Writes the 8-bit char to standard output.
     *  @param  x the { @code  char} to write.
     *  @throws  IllegalArgumentException if { @code  x} is not betwen 0 and 255.
     */
     public   static   void  write ( char  x )   {
         if   ( <   0   ||  x  >=   256 )   throw   new   IllegalArgumentException ( "Illegal 8-bit char = "   +  x );
        writeByte ( x );
     }

    /**
     * Writes the r-bit char to standard output.
     *  @param  x the { @code  char} to write.
     *  @param  r the number of relevant bits in the char.
     *  @throws  IllegalArgumentException if { @code  r} is not between 1 and 16.
     *  @throws  IllegalArgumentException if { @code  x} is not between 0 and 2<sup>r</sup> - 1.
     */
     public   static   void  write ( char  x ,   int  r )   {
         if   ( ==   8 )   {
            write ( x );
             return ;
         }
         if   ( <   1   ||  r  >   16 )   throw   new   IllegalArgumentException ( "Illegal value for r = "   +  r );
         if   ( >=   ( 1   <<  r ))     throw   new   IllegalArgumentException ( "Illegal "   +  r  +   "-bit char = "   +  x );
         for   ( int  i  =   0 ;  i  <  r ;  i ++ )   {
             boolean  bit  =   (( >>>   ( -  i  -   1 ))   &   1 )   ==   1 ;
            writeBit ( bit );
         }
     }

    /**
     * Writes the string of 8-bit characters to standard output.
     *  @param  s the { @code  String} to write.
     *  @throws  IllegalArgumentException if any character in the string is not
     * between 0 and 255.
     */
     public   static   void  write ( String  s )   {
         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )
            write ( s . charAt ( i ));
     }

    /**
     * Writes the string of r-bit characters to standard output.
     *  @param  s the { @code  String} to write.
     *  @param  r the number of relevants bits in each character.
     *  @throws  IllegalArgumentException if r is not between 1 and 16.
     *  @throws  IllegalArgumentException if any character in the string is not
     * between 0 and 2<sup>r</sup> - 1.
     */
     public   static   void  write ( String  s ,   int  r )   {
         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )
            write ( s . charAt ( i ),  r );
     }

    /**
     * Tests the methods in this class.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  m  =   Integer . parseInt ( args [ 0 ]);

         // write n integers to binary standard output
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             BinaryStdOut . write ( i );
         }
         BinaryStdOut . flush ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BinomialMinPQ.java

edu/princeton/cs/algs4/BinomialMinPQ.java

/******************************************************************************
 *  Compilation: javac BinomialMinPQ.java
 *  Execution:
 *  
 *  A binomial heap.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . Comparator ;
import  java . util . NoSuchElementException ;

/**
 *  The BinomialMinPQ class represents a priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations, 
 *  along with the merging of two heaps together.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  It is possible to build the priority queue using a Comparator.
 *  If not, the natural order relation between the keys will be used.
 *  
 *  This implementation uses a binomial heap.
 *  The insert, delete-the-minimum, union, min-key
 *  and size operations take logarithmic time.
 *  The is-empty and constructor operations take constant time.
 * 
 *   @author  Tristan Claverie
 */
public   class   BinomialMinPQ < Key >   implements   Iterable < Key >   {
     private   Node  head ;                    //head of the list of roots
     private   final   Comparator < Key >  comp ;   //Comparator over the keys
    
     //Represents a Node of a Binomial Tree
     private   class   Node   {
         Key  key ;                          //Key contained by the Node
         int  order ;                        //The order of the Binomial Tree rooted by this Node
         Node  child ,  sibling ;              //child and sibling of this Node
     }
    
     /**
     * Initializes an empty priority queue
     * Worst case is O(1)
     */
     public   BinomialMinPQ ()   {
        comp  =   new   MyComparator ();
     }
    
     /**
     * Initializes an empty priority queue using the given Comparator
     * Worst case is O(1)
     *  @param  C a comparator over the keys
     */
     public   BinomialMinPQ ( Comparator < Key >  C )   {
        comp  =  C ;
     }
    
     /**
     * Initializes a priority queue with given keys
     * Worst case is O(n*log(n))
     *  @param  a an array of keys
     */
     public   BinomialMinPQ ( Key []  a )   {
        comp  =   new   MyComparator ();
         for   ( Key  k  :  a )  insert ( k );
     }
    
     /**
     * Initializes a priority queue with given keys using the given Comparator
     * Worst case is O(n*log(n))
     *  @param  C a comparator over the keys
     *  @param  a an array of keys
     */
     public   BinomialMinPQ ( Comparator < Key >  C ,   Key []  a )   {
        comp  =  C ;
         for   ( Key  k  :  a )  insert ( k );
     }

     /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
     public   boolean  isEmpty ()   {
         return  head  ==   null ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(log(n))
     *  @throws  java.lang.ArithmeticException if there are more than 2^63-1 elements in the queue
     *  @return  the number of elements on the priority queue
     */
     public   int  size ()   {
         int  result  =   0 ,  tmp ;
         for   ( Node  node  =  head ;  node  !=   null ;  node  =  node . sibling )   {
             if   ( node . order  >   30 )   {   throw   new   ArithmeticException ( "The number of elements cannot be evaluated, but the priority queue is still valid." );   }
            tmp  =   1   <<  node . order ;
            result  |=  tmp ;
         }
         return  result ;
     }

     /**
     * Puts a Key in the heap
     * Worst case is O(log(n))
     *  @param  key a Key
     */
     public   void  insert ( Key  key )   {
         Node  x  =   new   Node ();
        x . key  =  key ;
        x . order  =   0 ;
         BinomialMinPQ < Key >  H  =   new   BinomialMinPQ < Key > ();   //The Comparator oh the H heap is not used
        H . head  =  x ;
         this . head  =   this . union ( H ). head ;
     }

     /**
     * Get the minimum key currently in the queue
     * Worst case is O(log(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         Node  min  =  head ;
         Node  current  =  head ;
         while   ( current . sibling  !=   null )   {
            min  =   ( greater ( min . key ,  current . sibling . key ))   ?  current  :  min ;
            current  =  current . sibling ;
         }
         return  min . key ;
     }

     /**
     * Deletes the minimum key
     * Worst case is O(log(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key
     */
     public   Key  delMin ()   {
         if ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         Node  min  =  eraseMin ();
         Node  x  =   ( min . child  ==   null )   ?  min  :  min . child ;
         if   ( min . child  !=   null )   {
            min . child  =   null ;
             Node  prevx  =   null ,  nextx  =  x . sibling ;
             while   ( nextx  !=   null )   {
                x . sibling  =  prevx ;
                prevx  =  x ;
                x  =  nextx ; nextx  =  nextx . sibling ;
             }
            x . sibling  =  prevx ;
             BinomialMinPQ < Key >  H  =   new   BinomialMinPQ < Key > ();
            H . head  =  x ;
            head  =  union ( H ). head ;
         }
         return  min . key ;
     }
    
     /**
     * Merges two Binomial heaps together
     * This operation is destructive
     * Worst case is O(log(n))
     *  @param  heap a Binomial Heap to be merged with the current heap
     *  @throws  java.lang.IllegalArgumentException if the heap in parameter is null
     *  @return  the union of two heaps
     */
     public   BinomialMinPQ < Key >  union ( BinomialMinPQ < Key >  heap )   {
         if   ( heap  ==   null )   throw   new   IllegalArgumentException ( "Cannot merge a Binomial Heap with null" );
         this . head  =  merge ( new   Node (),   this . head ,  heap . head ). sibling ;
         Node  x  =   this . head ;
         Node  prevx  =   null ,  nextx  =  x . sibling ;
         while   ( nextx  !=   null )   {
             if   ( x . order  <  nextx . order  ||
                ( nextx . sibling  !=   null   &&  nextx . sibling . order  ==  x . order ))   {
                prevx  =  x ;  x  =  nextx ;
             }   else   if   ( greater ( nextx . key ,  x . key ))   {
                x . sibling  =  nextx . sibling ;
                link ( nextx ,  x );
             }   else   {
                 if   ( prevx  ==   null )   {   this . head  =  nextx ;   }
                 else   {  prevx . sibling  =  nextx ;   }
                link ( x ,  nextx );
                x  =  nextx ;
             }
            nextx  =  x . sibling ;
         }
         return   this ;
     }
    
     /*************************************************
     * General helper functions
     ************************************************/
    
     //Compares two keys
     private   boolean  greater ( Key  n ,   Key  m )   {
         if   ( ==   null )   return   false ;
         if   ( ==   null )   return   true ;
         return  comp . compare ( n ,  m )   >   0 ;
     }
    
     //Assuming root1 holds a greater key than root2, root2 becomes the new root
     private   void  link ( Node  root1 ,   Node  root2 )   {
        root1 . sibling  =  root2 . child ;
        root2 . child  =  root1 ;
        root2 . order ++ ;
     }
    
     //Deletes and return the node containing the minimum key
     private   Node  eraseMin ()   {
         Node  min  =  head ;
         Node  previous  =   null ;
         Node  current  =  head ;
         while   ( current . sibling  !=   null )   {
             if   ( greater ( min . key ,  current . sibling . key ))   {
                previous  =  current ;
                min  =  current . sibling ;
             }
            current  =  current . sibling ;
         }
        previous . sibling  =  min . sibling ;
         if   ( min  ==  head )  head  =  min . sibling ;
         return  min ;
     }
    
     /**************************************************
     * Functions for inserting a key in the heap
     *************************************************/
    
     //Merges two root lists into one, there can be up to 2 Binomial Trees of same order
         private   Node  merge ( Node  h ,   Node  x ,   Node  y )   {
             if   ( ==   null   &&  y  ==   null )   return  h ;
             else   if   ( ==   null )  h . sibling  =  merge ( y ,   null ,  y . sibling );
             else   if   ( ==   null )  h . sibling  =  merge ( x ,  x . sibling ,   null );
             else   if   ( x . order  <  y . order )  h . sibling  =  merge ( x ,  x . sibling ,  y );
             else                         h . sibling  =  merge ( y ,  x ,  y . sibling );
             return  h ;
     }
    
     /******************************************************************
     * Iterator
     *****************************************************************/
    
     /**
     * Gets an Iterator over the keys in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(log(n))
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the keys in the priority queue in ascending order
     */
     public   Iterator < Key >  iterator ()   {
         return   new   MyIterator ();
     }
    
     private   class   MyIterator   implements   Iterator < Key >   {
         BinomialMinPQ < Key >  data ;
        
         //Constructor clones recursively the elements in the queue
         //It takes linear time
         public   MyIterator ()   {
            data  =   new   BinomialMinPQ < Key > ( comp );
            data . head  =  clone ( head ,   null );
         }
        
         private   Node  clone ( Node  x ,   Node  parent )   {
             if   ( ==   null )   return   null ;
             Node  node  =   new   Node ();
            node . key  =  x . key ;
            node . sibling  =  clone ( x . sibling ,  parent );
            node . child  =  clone ( x . child ,  node );
             return  node ;
         }
        
         public   boolean  hasNext ()   {
             return   ! data . isEmpty ();
         }
        
         public   Key  next ()   {
                         if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  data . delMin ();
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
     }
    
     /***************************
     * Comparator
     **************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }
    
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Bipartite.java

edu/princeton/cs/algs4/Bipartite.java

/******************************************************************************
 *  Compilation:  javac Bipartite.java
 *  Execution:    java  Bipartite V E F
 *  Dependencies: Graph.java 
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt
 *
 *  Given a graph, find either (i) a bipartition or (ii) an odd-length cycle.
 *  Runs in O(E + V) time.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  Bipartite} class represents a data type for 
 *  determining whether an undirected graph is <em>bipartite</em> or whether
 *  it has an <em>odd-length cycle</em>.
 *  A graph is bipartite if and only if it has no odd-length cycle.
 *  The <em>isBipartite</em> operation determines whether the graph is
 *  bipartite. If so, the <em>color</em> operation determines a
 *  bipartition; if not, the <em>oddCycle</em> operation determines a
 *  cycle with an odd number of edges.
 *  <p>
 *  This implementation uses <em>depth-first search</em>.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in
 *  the worst case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  See { @link  BipartiteX} for a nonrecursive version that uses breadth-first
 *  search.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Bipartite   {
     private   boolean  isBipartite ;     // is the graph bipartite?
     private   boolean []  color ;         // color[v] gives vertices on one side of bipartition
     private   boolean []  marked ;        // marked[v] = true iff v has been visited in DFS
     private   int []  edgeTo ;            // edgeTo[v] = last edge on path to v
     private   Stack < Integer >  cycle ;    // odd-length cycle

     /**
     * Determines whether an undirected graph is bipartite and finds either a
     * bipartition or an odd-length cycle.
     *
     *  @param   G the graph
     */
     public   Bipartite ( Graph  G )   {
        isBipartite  =   true ;
        color   =   new   boolean [ G . V ()];
        marked  =   new   boolean [ G . V ()];
        edgeTo  =   new   int [ G . V ()];

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ! marked [ v ])   {
                dfs ( G ,  v );
             }
         }
         assert  check ( G );
     }

     private   void  dfs ( Graph  G ,   int  v )   {  
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {

             // short circuit if odd-length cycle found
             if   ( cycle  !=   null )   return ;

             // found uncolored vertex, so recur
             if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  v ;
                color [ w ]   =   ! color [ v ];
                dfs ( G ,  w );
             }  

             // if v-w create an odd-length cycle, find it
             else   if   ( color [ w ]   ==  color [ v ])   {
                isBipartite  =   false ;
                cycle  =   new   Stack < Integer > ();
                cycle . push ( w );    // don't need this unless you want to include start vertex twice
                 for   ( int  x  =  v ;  x  !=  w ;  x  =  edgeTo [ x ])   {
                    cycle . push ( x );
                 }
                cycle . push ( w );
             }
         }
     }

     /**
     * Returns true if the graph is bipartite.
     *
     *  @return  { @code  true} if the graph is bipartite; { @code  false} otherwise
     */
     public   boolean  isBipartite ()   {
         return  isBipartite ;
     }
 
     /**
     * Returns the side of the bipartite that vertex { @code  v} is on.
     *
     *  @param   v the vertex
     *  @return  the side of the bipartition that vertex { @code  v} is on; two vertices
     *         are in the same side of the bipartition if and only if they have the
     *         same color
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V} 
     *  @throws  UnsupportedOperationException if this method is called when the graph
     *         is not bipartite
     */
     public   boolean  color ( int  v )   {
        validateVertex ( v );
         if   ( ! isBipartite )
             throw   new   UnsupportedOperationException ( "graph is not bipartite" );
         return  color [ v ];
     }

     /**
     * Returns an odd-length cycle if the graph is not bipartite, and
     * { @code  null} otherwise.
     *
     *  @return  an odd-length cycle if the graph is not bipartite
     *         (and hence has an odd-length cycle), and { @code  null}
     *         otherwise
     */
     public   Iterable < Integer >  oddCycle ()   {
         return  cycle ;  
     }

     private   boolean  check ( Graph  G )   {
         // graph is bipartite
         if   ( isBipartite )   {
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( int  w  :  G . adj ( v ))   {
                     if   ( color [ v ]   ==  color [ w ])   {
                         System . err . printf ( "edge %d-%d with %d and %d in same side of bipartition\n" ,  v ,  w ,  v ,  w );
                         return   false ;
                     }
                 }
             }
         }

         // graph has an odd-length cycle
         else   {
             // verify cycle
             int  first  =   - 1 ,  last  =   - 1 ;
             for   ( int  v  :  oddCycle ())   {
                 if   ( first  ==   - 1 )  first  =  v ;
                last  =  v ;
             }
             if   ( first  !=  last )   {
                 System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );
                 return   false ;
             }
         }

         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  Bipartite} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V1  =   Integer . parseInt ( args [ 0 ]);
         int  V2  =   Integer . parseInt ( args [ 1 ]);
         int  E   =   Integer . parseInt ( args [ 2 ]);
         int  F   =   Integer . parseInt ( args [ 3 ]);

         // create random bipartite graph with V1 vertices on left side,
         // V2 vertices on right side, and E edges; then add F random edges
         Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );
         for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V1  +  V2 );
             int  w  =   StdRandom . uniform ( V1  +  V2 );
            G . addEdge ( v ,  w );
         }

         StdOut . println ( G );


         Bipartite  b  =   new   Bipartite ( G );
         if   ( b . isBipartite ())   {
             StdOut . println ( "Graph is bipartite" );
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 StdOut . println ( +   ": "   +  b . color ( v ));
             }
         }
         else   {
             StdOut . print ( "Graph has an odd-length cycle: " );
             for   ( int  x  :  b . oddCycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BipartiteMatching.java

edu/princeton/cs/algs4/BipartiteMatching.java

/******************************************************************************
 *  Compilation:  javac BipartiteMatching.java
 *  Execution:    java BipartiteMatching V1 V2 E
 *  Dependencies: BipartiteX.java
 *
 *  Find a maximum cardinality matching (and minimum cardinality vertex cover)
 *  in a bipartite graph using the alternating path algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BipartiteMatching} class represents a data type for computing a
 *  <em>maximum (cardinality) matching</em> and a
 *  <em>minimum (cardinality) vertex cover</em> in a bipartite graph.
 *  A <em>bipartite graph</em> in a graph whose vertices can be partitioned
 *  into two disjoint sets such that every edge has one endpoint in either set.
 *  A <em>matching</em> in a graph is a subset of its edges with no common
 *  vertices. A <em>maximum matching</em> is a matching with the maximum number
 *  of edges.
 *  A <em>perfect matching</em> is a matching which matches all vertices in the graph.
 *  A <em>vertex cover</em> in a graph is a subset of its vertices such that
 *  every edge is incident to at least one vertex. A <em>minimum vertex cover</em>
 *  is a vertex cover with the minimum number of vertices.
 *  By Konig's theorem, in any biparite
 *  graph, the maximum number of edges in matching equals the minimum number
 *  of vertices in a vertex cover.
 *  The maximum matching problem in <em>nonbipartite</em> graphs is
 *  also important, but all known algorithms for this more general problem
 *  are substantially more complicated.
 *  <p>
 *  This implementation uses the <em>alternating-path algorithm</em>.
 *  It is equivalent to reducing to the maximum-flow problem and running
 *  the augmenting-path algorithm on the resulting flow network, but it
 *  does so with less overhead.
 *  The constructor takes <em>O</em>((<em>E</em> + <em>V</em>) <em>V</em>)
 *  time, where <em>E</em> is the number of edges and <em>V</em> is the
 *  number of vertices in the graph.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  <p>
 *  See also { @link  HopcroftKarp}, which solves the problem in
 *  <em>O</em>(<em>E</em> sqrt(<em>V</em>)) using the Hopcroft-Karp
 *  algorithm and
 *  <a href = "https://algs4.cs.princeton.edu/65reductions/BipartiteMatchingToMaxflow.java.html">BipartiteMatchingToMaxflow</a>,
 *  which solves the problem in <em>O</em>((<em>E</em> + <em>V</em>) <em>V</em>)
 *  time via a reduction to maxflow.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/65reductions">Section 6.5</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BipartiteMatching   {
     private   static   final   int  UNMATCHED  =   - 1 ;

     private   final   int  V ;                   // number of vertices in the graph
     private   BipartiteX  bipartition ;        // the bipartition
     private   int  cardinality ;               // cardinality of current matching
     private   int []  mate ;                    // mate[v] =  w if v-w is an edge in current matching
                                          //         = -1 if v is not in current matching
     private   boolean []  inMinVertexCover ;    // inMinVertexCover[v] = true iff v is in min vertex cover
     private   boolean []  marked ;              // marked[v] = true iff v is reachable via alternating path
     private   int []  edgeTo ;                  // edgeTo[v] = last edge on alternating path to v

     /**
     * Determines a maximum matching (and a minimum vertex cover)
     * in a bipartite graph.
     *
     *  @param   G the bipartite graph
     *  @throws  IllegalArgumentException if { @code  G} is not bipartite
     */
     public   BipartiteMatching ( Graph  G )   {
        bipartition  =   new   BipartiteX ( G );
         if   ( ! bipartition . isBipartite ())   {
             throw   new   IllegalArgumentException ( "graph is not bipartite" );
         }

         this . =  G . V ();

         // initialize empty matching
        mate  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            mate [ v ]   =  UNMATCHED ;

         // alternating path algorithm
         while   ( hasAugmentingPath ( G ))   {

             // find one endpoint t in alternating path
             int  t  =   - 1 ;
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 if   ( ! isMatched ( v )   &&  edgeTo [ v ]   !=   - 1 )   {
                    t  =  v ;
                     break ;
                 }
             }

             // update the matching according to alternating path in edgeTo[] array
             for   ( int  v  =  t ;  v  !=   - 1 ;  v  =  edgeTo [ edgeTo [ v ]])   {
                 int  w  =  edgeTo [ v ];
                mate [ v ]   =  w ;
                mate [ w ]   =  v ;
             }
            cardinality ++ ;
         }

         // find min vertex cover from marked[] array
        inMinVertexCover  =   new   boolean [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( bipartition . color ( v )   &&   ! marked [ v ])  inMinVertexCover [ v ]   =   true ;
             if   ( ! bipartition . color ( v )   &&  marked [ v ])  inMinVertexCover [ v ]   =   true ;
         }

         assert  certifySolution ( G );
     }


     /*
     * is there an augmenting path?
     *   - if so, upon termination adj[] contains the level graph;
     *   - if not, upon termination marked[] specifies those vertices reachable via an alternating
     *     path from one side of the bipartition
     *
     * an alternating path is a path whose edges belong alternately to the matching and not
     * to the matching
     *
     * an augmenting path is an alternating path that starts and ends at unmatched vertices
     *
     * this implementation finds a shortest augmenting path (fewest number of edges), though there
     * is no particular advantage to do so here
     */
     private   boolean  hasAugmentingPath ( Graph  G )   {
        marked  =   new   boolean [ V ];

        edgeTo  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            edgeTo [ v ]   =   - 1 ;

         // breadth-first search (starting from all unmatched vertices on one side of bipartition)
         Queue < Integer >  queue  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( bipartition . color ( v )   &&   ! isMatched ( v ))   {
                queue . enqueue ( v );
                marked [ v ]   =   true ;
             }
         }

         // run BFS, stopping as soon as an alternating path is found
         while   ( ! queue . isEmpty ())   {
             int  v  =  queue . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {

                 // either (1) forward edge not in matching or (2) backward edge in matching
                 if   ( isResidualGraphEdge ( v ,  w )   &&   ! marked [ w ])   {
                    edgeTo [ w ]   =  v ;
                    marked [ w ]   =   true ;
                     if   ( ! isMatched ( w ))   return   true ;
                    queue . enqueue ( w );
                 }
             }
         }

         return   false ;
     }

     // is the edge v-w a forward edge not in the matching or a reverse edge in the matching?
     private   boolean  isResidualGraphEdge ( int  v ,   int  w )   {
         if   (( mate [ v ]   !=  w )   &&   bipartition . color ( v ))   return   true ;
         if   (( mate [ v ]   ==  w )   &&   ! bipartition . color ( v ))   return   true ;
         return   false ;
     }

     /**
     * Returns the vertex to which the specified vertex is matched in
     * the maximum matching computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  the vertex to which vertex { @code  v} is matched in the
     *         maximum matching; { @code  -1} if the vertex is not matched
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *
     */
     public   int  mate ( int  v )   {
        validate ( v );
         return  mate [ v ];
     }

     /**
     * Returns true if the specified vertex is matched in the maximum matching
     * computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  { @code  true} if vertex { @code  v} is matched in maximum matching;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *
     */
     public   boolean  isMatched ( int  v )   {
        validate ( v );
         return  mate [ v ]   !=  UNMATCHED ;
     }

     /**
     * Returns the number of edges in a maximum matching.
     *
     *  @return  the number of edges in a maximum matching
     */
     public   int  size ()   {
         return  cardinality ;
     }

     /**
     * Returns true if the graph contains a perfect matching.
     * That is, the number of edges in a maximum matching is equal to one half
     * of the number of vertices in the graph (so that every vertex is matched).
     *
     *  @return  { @code  true} if the graph contains a perfect matching;
     *         { @code  false} otherwise
     */
     public   boolean  isPerfect ()   {
         return  cardinality  *   2   ==  V ;
     }

     /**
     * Returns true if the specified vertex is in the minimum vertex cover
     * computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  { @code  true} if vertex { @code  v} is in the minimum vertex cover;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  inMinVertexCover ( int  v )   {
        validate ( v );
         return  inMinVertexCover [ v ];
     }

     private   void  validate ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // check that mate[] and inVertexCover[] define a max matching and min vertex cover, respectively
     private   boolean  certifySolution ( Graph  G )   {

         // check that mate(v) = w iff mate(w) = v
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   ==   - 1 )   continue ;
             if   ( mate ( mate ( v ))   !=  v )   return   false ;
         }

         // check that size() is consistent with mate()
         int  matchedVertices  =   0 ;
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   !=   - 1 )  matchedVertices ++ ;
         }
         if   ( 2 * size ()   !=  matchedVertices )   return   false ;

         // check that size() is consistent with minVertexCover()
         int  sizeOfMinVertexCover  =   0 ;
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             if   ( inMinVertexCover ( v ))  sizeOfMinVertexCover ++ ;
         if   ( size ()   !=  sizeOfMinVertexCover )   return   false ;

         // check that mate() uses each vertex at most once
         boolean []  isMatched  =   new   boolean [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             int  w  =  mate [ v ];
             if   ( ==   - 1 )   continue ;
             if   ( ==  w )   return   false ;
             if   ( >=  w )   continue ;
             if   ( isMatched [ v ]   ||  isMatched [ w ])   return   false ;
            isMatched [ v ]   =   true ;
            isMatched [ w ]   =   true ;
         }

         // check that mate() uses only edges that appear in the graph
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   ==   - 1 )   continue ;
             boolean  isEdge  =   false ;
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( mate ( v )   ==  w )  isEdge  =   true ;
             }
             if   ( ! isEdge )   return   false ;
         }

         // check that inMinVertexCover() is a vertex cover
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( int  w  :  G . adj ( v ))
                 if   ( ! inMinVertexCover ( v )   &&   ! inMinVertexCover ( w ))   return   false ;

         return   true ;
     }

     /**
     * Unit tests the { @code  HopcroftKarp} data type.
     * Takes three command-line arguments { @code  V1}, { @code  V2}, and { @code  E};
     * creates a random bipartite graph with { @code  V1} + { @code  V2} vertices
     * and { @code  E} edges; computes a maximum matching and minimum vertex cover;
     * and prints the results.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V1  =   Integer . parseInt ( args [ 0 ]);
         int  V2  =   Integer . parseInt ( args [ 1 ]);
         int  E   =   Integer . parseInt ( args [ 2 ]);
         Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );

         if   ( G . V ()   <   1000 )   StdOut . println ( G );

         BipartiteMatching  matching  =   new   BipartiteMatching ( G );
        
         // print maximum matching
         StdOut . printf ( "Number of edges in max matching        = %d\n" ,  matching . size ());
         StdOut . printf ( "Number of vertices in min vertex cover = %d\n" ,  matching . size ());
         StdOut . printf ( "Graph has a perfect matching           = %b\n" ,  matching . isPerfect ());
         StdOut . println ();

         if   ( G . V ()   >=   1000 )   return ;

         StdOut . print ( "Max matching: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             int  w  =  matching . mate ( v );
             if   ( matching . isMatched ( v )   &&  v  <  w )    // print each edge only once
                 StdOut . print ( +   "-"   +  w  +   " " );
         }
         StdOut . println ();

         // print minimum vertex cover
         StdOut . print ( "Min vertex cover: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( matching . inMinVertexCover ( v ))
                 StdOut . print ( +   " " );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BipartiteX.java

edu/princeton/cs/algs4/BipartiteX.java

/******************************************************************************
 *  Compilation:  javac BipartiteX.java
 *  Execution:    java  Bipartite V E F
 *  Dependencies: Graph.java 
 *
 *  Given a graph, find either (i) a bipartition or (ii) an odd-length cycle.
 *  Runs in O(E + V) time.
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  BipartiteX} class represents a data type for 
 *  determining whether an undirected graph is <em>bipartite</em> or whether
 *  it has an <em>odd-length cycle</em>.
 *  A graph is bipartite if and only if it has no odd-length cycle.
 *  The <em>isBipartite</em> operation determines whether the graph is
 *  bipartite. If so, the <em>color</em> operation determines a
 *  bipartition; if not, the <em>oddCycle</em> operation determines a
 *  cycle with an odd number of edges.
 *  <p>
 *  This implementation uses <em>breadth-first search</em> and is nonrecursive.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in
 *  in the worst case, where <em>V</em> is the number of vertices
 *  and <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  See { @link  Bipartite} for a recursive version that uses depth-first search.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BipartiteX   {
     private   static   final   boolean  WHITE  =   false ;
     private   static   final   boolean  BLACK  =   true ;

     private   boolean  isBipartite ;     // is the graph bipartite?
     private   boolean []  color ;         // color[v] gives vertices on one side of bipartition
     private   boolean []  marked ;        // marked[v] = true iff v has been visited in DFS
     private   int []  edgeTo ;            // edgeTo[v] = last edge on path to v
     private   Queue < Integer >  cycle ;    // odd-length cycle

     /**
     * Determines whether an undirected graph is bipartite and finds either a
     * bipartition or an odd-length cycle.
     *
     *  @param   G the graph
     */
     public   BipartiteX ( Graph  G )   {
        isBipartite  =   true ;
        color   =   new   boolean [ G . V ()];
        marked  =   new   boolean [ G . V ()];
        edgeTo  =   new   int [ G . V ()];

         for   ( int  v  =   0 ;  v  <  G . V ()   &&  isBipartite ;  v ++ )   {
             if   ( ! marked [ v ])   {
                bfs ( G ,  v );
             }
         }
         assert  check ( G );
     }

     private   void  bfs ( Graph  G ,   int  s )   {  
         Queue < Integer >  q  =   new   Queue < Integer > ();
        color [ s ]   =  WHITE ;
        marked [ s ]   =   true ;
        q . enqueue ( s );

         while   ( ! q . isEmpty ())   {
             int  v  =  q . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ! marked [ w ])   {
                    marked [ w ]   =   true ;
                    edgeTo [ w ]   =  v ;
                    color [ w ]   =   ! color [ v ];
                    q . enqueue ( w );
                 }
                 else   if   ( color [ w ]   ==  color [ v ])   {
                    isBipartite  =   false ;

                     // to form odd cycle, consider s-v path and s-w path
                     // and let x be closest node to v and w common to two paths
                     // then (w-x path) + (x-v path) + (edge v-w) is an odd-length cycle
                     // Note: distTo[v] == distTo[w];
                    cycle  =   new   Queue < Integer > ();
                     Stack < Integer >  stack  =   new   Stack < Integer > ();
                     int  x  =  v ,  y  =  w ;
                     while   ( !=  y )   {
                        stack . push ( x );
                        cycle . enqueue ( y );
                        x  =  edgeTo [ x ];
                        y  =  edgeTo [ y ];
                     }
                    stack . push ( x );
                     while   ( ! stack . isEmpty ())
                        cycle . enqueue ( stack . pop ());
                    cycle . enqueue ( w );
                     return ;
                 }
             }
         }
     }

     /**
     * Returns true if the graph is bipartite.
     *
     *  @return  { @code  true} if the graph is bipartite; { @code  false} otherwise
     */
     public   boolean  isBipartite ()   {
         return  isBipartite ;
     }
 
     /**
     * Returns the side of the bipartite that vertex { @code  v} is on.
     *
     *  @param   v the vertex
     *  @return  the side of the bipartition that vertex { @code  v} is on; two vertices
     *         are in the same side of the bipartition if and only if they have the
     *         same color
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V} 
     *  @throws  UnsupportedOperationException if this method is called when the graph
     *         is not bipartite
     */
     public   boolean  color ( int  v )   {
        validateVertex ( v );
         if   ( ! isBipartite )
             throw   new   UnsupportedOperationException ( "Graph is not bipartite" );
         return  color [ v ];
     }


     /**
     * Returns an odd-length cycle if the graph is not bipartite, and
     * { @code  null} otherwise.
     *
     *  @return  an odd-length cycle if the graph is not bipartite
     *         (and hence has an odd-length cycle), and { @code  null}
     *         otherwise
     */
     public   Iterable < Integer >  oddCycle ()   {
         return  cycle ;  
     }

     private   boolean  check ( Graph  G )   {
         // graph is bipartite
         if   ( isBipartite )   {
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( int  w  :  G . adj ( v ))   {
                     if   ( color [ v ]   ==  color [ w ])   {
                         System . err . printf ( "edge %d-%d with %d and %d in same side of bipartition\n" ,  v ,  w ,  v ,  w );
                         return   false ;
                     }
                 }
             }
         }

         // graph has an odd-length cycle
         else   {
             // verify cycle
             int  first  =   - 1 ,  last  =   - 1 ;
             for   ( int  v  :  oddCycle ())   {
                 if   ( first  ==   - 1 )  first  =  v ;
                last  =  v ;
             }
             if   ( first  !=  last )   {
                 System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );
                 return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  BipartiteX} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V1  =   Integer . parseInt ( args [ 0 ]);
         int  V2  =   Integer . parseInt ( args [ 1 ]);
         int  E   =   Integer . parseInt ( args [ 2 ]);
         int  F   =   Integer . parseInt ( args [ 3 ]);

         // create random bipartite graph with V1 vertices on left side,
         // V2 vertices on right side, and E edges; then add F random edges
         Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );
         for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V1  +  V2 );
             int  w  =   StdRandom . uniform ( V1  +  V2 );
            G . addEdge ( v ,  w );
         }

         StdOut . println ( G );


         BipartiteX  b  =   new   BipartiteX ( G );
         if   ( b . isBipartite ())   {
             StdOut . println ( "Graph is bipartite" );
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 StdOut . println ( +   ": "   +  b . color ( v ));
             }
         }
         else   {
             StdOut . print ( "Graph has an odd-length cycle: " );
             for   ( int  x  :  b . oddCycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BlackFilter.java

edu/princeton/cs/algs4/BlackFilter.java

/******************************************************************************
 *  Compilation:  javac BlackFilter.java
 *  Execution:    java BlackFilter blacklist.txt < input.txt
 *  Dependencies: SET In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt
 *                https://algs4.cs.princeton.edu/35applications/list.txt
 *
 *  Read in a blacklist of words from a file. Then read in a list of
 *  words from standard input and print out all those words that
 *  are not in the first file.
 * 
 *  % more tinyTale.txt 
 *  it was the best of times it was the worst of times 
 *  it was the age of wisdom it was the age of foolishness 
 *  it was the epoch of belief it was the epoch of incredulity 
 *  it was the season of light it was the season of darkness 
 *  it was the spring of hope it was the winter of despair
 *
 *  % more list.txt 
 *  was it the of 
 * 
 *  % java BlackFilter list.txt < tinyTale.txt 
 *  best times worst times 
 *  age wisdom age foolishness 
 *  epoch belief epoch incredulity 
 *  season light season darkness 
 *  spring hope winter despair 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BlackFilter} class provides a client for reading in a <em>blacklist</em>
 *  of words from a file; then, reading in a sequence of words from standard input, 
 *  printing out each word that <em>does not</em> appear in the file. 
 *  It is useful as a test client for various symbol table implementations.   
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BlackFilter   {   

     // Do not instantiate.
     private   BlackFilter ()   {   }

     public   static   void  main ( String []  args )   {
        SET < String >  set  =   new  SET < String > ();

         // read in strings and add to set
         In  in  =   new   In ( args [ 0 ]);
         while   ( ! in . isEmpty ())   {
             String  word  =  in . readString ();
            set . add ( word );
         }

         // read in string from standard input, printing out all exceptions
         while   ( ! StdIn . isEmpty ())   {
             String  word  =   StdIn . readString ();
             if   ( ! set . contains ( word ))
                 StdOut . println ( word );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BoruvkaMST.java

edu/princeton/cs/algs4/BoruvkaMST.java

/******************************************************************************
 *  Compilation:  javac BoruvkaMST.java
 *  Execution:    java BoruvkaMST filename.txt
 *  Dependencies: EdgeWeightedGraph.java Edge.java Bag.java
 *                UF.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  Compute a minimum spanning forest using Boruvka's algorithm.
 *
 *  % java BoruvkaMST tinyEWG.txt 
 *  0-2 0.26000
 *  6-2 0.40000
 *  5-7 0.28000
 *  4-5 0.35000
 *  2-3 0.17000
 *  1-7 0.19000
 *  0-7 0.16000
 *  1.81000
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BoruvkaMST} class represents a data type for computing a
 *  <em>minimum spanning tree</em> in an edge-weighted graph.
 *  The edge weights can be positive, zero, or negative and need not
 *  be distinct. If the graph is not connected, it computes a <em>minimum
 *  spanning forest</em>, which is the union of minimum spanning trees
 *  in each connected component. The { @code  weight()} method returns the 
 *  weight of a minimum spanning tree and the { @code  edges()} method
 *  returns its edges.
 *  <p>
 *  This implementation uses <em>Boruvka's algorithm</em> and the union-find
 *  data type.
 *  The constructor takes &Theta;(<em>E</em> log <em>V</em>) time in
 *  the worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted graph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For alternate implementations, see { @link  LazyPrimMST}, { @link  PrimMST},
 *  and { @link  KruskalMST}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BoruvkaMST   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-12 ;

     private   Bag < Edge >  mst  =   new   Bag < Edge > ();      // edges in MST
     private   double  weight ;                        // weight of MST

     /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     *  @param  G the edge-weighted graph
     */
     public   BoruvkaMST ( EdgeWeightedGraph  G )   {
        UF uf  =   new  UF ( G . V ());

         // repeat at most log V times or until we have V-1 edges
         for   ( int  t  =   1 ;  t  <  G . V ()   &&  mst . size ()   <  G . V ()   -   1 ;  t  =  t  +  t )   {

             // foreach tree in forest, find closest edge
             // if edge weights are equal, ties are broken in favor of first edge in G.edges()
             Edge []  closest  =   new   Edge [ G . V ()];
             for   ( Edge  e  :  G . edges ())   {
                 int  v  =  e . either (),  w  =  e . other ( v );
                 int  i  =  uf . find ( v ),  j  =  uf . find ( w );
                 if   ( ==  j )   continue ;     // same tree
                 if   ( closest [ i ]   ==   null   ||  less ( e ,  closest [ i ]))  closest [ i ]   =  e ;
                 if   ( closest [ j ]   ==   null   ||  less ( e ,  closest [ j ]))  closest [ j ]   =  e ;
             }

             // add newly discovered edges to MST
             for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                 Edge  e  =  closest [ i ];
                 if   ( !=   null )   {
                     int  v  =  e . either (),  w  =  e . other ( v );
                     // don't add the same edge twice
                     if   ( uf . find ( v )   !=  uf . find ( w ))   {
                        mst . add ( e );
                        weight  +=  e . weight ();
                        uf . union ( v ,  w );
                     }
                 }
             }
         }

         // check optimality conditions
         assert  check ( G );
     }

     /**
     * Returns the edges in a minimum spanning tree (or forest).
     *  @return  the edges in a minimum spanning tree (or forest) as
     *    an iterable of edges
     */
     public   Iterable < Edge >  edges ()   {
         return  mst ;
     }


     /**
     * Returns the sum of the edge weights in a minimum spanning tree (or forest).
     *  @return  the sum of the edge weights in a minimum spanning tree (or forest)
     */
     public   double  weight ()   {
         return  weight ;
     }

     // is the weight of edge e strictly less than that of edge f?
     private   static   boolean  less ( Edge  e ,   Edge  f )   {
         return  e . compareTo ( f )   <   0 ;
     }

     // check optimality conditions (takes time proportional to E V lg* V)
     private   boolean  check ( EdgeWeightedGraph  G )   {

         // check weight
         double  totalWeight  =   0.0 ;
         for   ( Edge  e  :  edges ())   {
            totalWeight  +=  e . weight ();
         }
         if   ( Math . abs ( totalWeight  -  weight ())   >  FLOATING_POINT_EPSILON )   {
             System . err . printf ( "Weight of edges does not equal weight(): %f vs. %f\n" ,  totalWeight ,  weight ());
             return   false ;
         }

         // check that it is acyclic
        UF uf  =   new  UF ( G . V ());
         for   ( Edge  e  :  edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   ==  uf . find ( w ))   {
                 System . err . println ( "Not a forest" );
                 return   false ;
             }
            uf . union ( v ,  w );
         }

         // check that it is a spanning forest
         for   ( Edge  e  :  G . edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   !=  uf . find ( w ))   {
                 System . err . println ( "Not a spanning forest" );
                 return   false ;
             }
         }

         // check that it is a minimal spanning forest (cut optimality conditions)
         for   ( Edge  e  :  edges ())   {

             // all edges in MST except e
            uf  =   new  UF ( G . V ());
             for   ( Edge  f  :  mst )   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( !=  e )  uf . union ( x ,  y );
             }

             // check that e is min weight edge in crossing cut
             for   ( Edge  f  :  G . edges ())   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( uf . find ( x )   !=  uf . find ( y ))   {
                     if   ( f . weight ()   <  e . weight ())   {
                         System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );
                         return   false ;
                     }
                 }
             }

         }

         return   true ;
     }

     /**
     * Unit tests the { @code  BoruvkaMST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         BoruvkaMST  mst  =   new   BoruvkaMST ( G );
         for   ( Edge  e  :  mst . edges ())   {
             StdOut . println ( e );
         }
         StdOut . printf ( "%.5f\n" ,  mst . weight ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BoyerMoore.java

edu/princeton/cs/algs4/BoyerMoore.java

/******************************************************************************
 *  Compilation:  javac BoyerMoore.java
 *  Execution:    java BoyerMoore pattern text
 *  Dependencies: StdOut.java
 *
 *  Reads in two strings, the pattern and the input text, and
 *  searches for the pattern in the input text using the
 *  bad-character rule part of the Boyer-Moore algorithm.
 *  (does not implement the strong good suffix rule)
 *
 *  % java BoyerMoore abracadabra abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:               abracadabra
 *
 *  % java BoyerMoore rab abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:         rab
 *
 *  % java BoyerMoore bcara abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:                                   bcara
 *
 *  % java BoyerMoore rabrabracad abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern:                        rabrabracad
 *
 *  % java BoyerMoore abacad abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern: abacad
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BoyerMoore} class finds the first occurrence of a pattern string
 *  in a text string.
 *  <p>
 *  This implementation uses the Boyer-Moore algorithm (with the bad-character
 *  rule, but not the strong good suffix rule).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/53substring">Section 5.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   BoyerMoore   {
     private   final   int  R ;       // the radix
     private   int []  right ;       // the bad-character skip array

     private   char []  pattern ;    // store the pattern as a character array
     private   String  pat ;        // or as a string

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pat the pattern string
     */
     public   BoyerMoore ( String  pat )   {
         this . =   256 ;
         this . pat  =  pat ;

         // position of rightmost occurrence of c in the pattern
        right  =   new   int [ R ];
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
            right [ c ]   =   - 1 ;
         for   ( int  j  =   0 ;  j  <  pat . length ();  j ++ )
            right [ pat . charAt ( j )]   =  j ;
     }

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pattern the pattern string
     *  @param  R the alphabet size
     */
     public   BoyerMoore ( char []  pattern ,   int  R )   {
         this . =  R ;
         this . pattern  =   new   char [ pattern . length ];
         for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )
             this . pattern [ j ]   =  pattern [ j ];

         // position of rightmost occurrence of c in the pattern
        right  =   new   int [ R ];
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
            right [ c ]   =   - 1 ;
         for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )
            right [ pattern [ j ]]   =  j ;
     }

     /**
     * Returns the index of the first occurrrence of the pattern string
     * in the text string.
     *
     *  @param   txt the text string
     *  @return  the index of the first occurrence of the pattern string
     *         in the text string; n if no such match
     */
     public   int  search ( String  txt )   {
         int  m  =  pat . length ();
         int  n  =  txt . length ();
         int  skip ;
         for   ( int  i  =   0 ;  i  <=  n  -  m ;  i  +=  skip )   {
            skip  =   0 ;
             for   ( int  j  =  m - 1 ;  j  >=   0 ;  j -- )   {
                 if   ( pat . charAt ( j )   !=  txt . charAt ( i + j ))   {
                    skip  =   Math . max ( 1 ,  j  -  right [ txt . charAt ( i + j )]);
                     break ;
                 }
             }
             if   ( skip  ==   0 )   return  i ;      // found
         }
         return  n ;                         // not found
     }


     /**
     * Returns the index of the first occurrrence of the pattern string
     * in the text string.
     *
     *  @param   text the text string
     *  @return  the index of the first occurrence of the pattern string
     *         in the text string; n if no such match
     */
     public   int  search ( char []  text )   {
         int  m  =  pattern . length ;
         int  n  =  text . length ;
         int  skip ;
         for   ( int  i  =   0 ;  i  <=  n  -  m ;  i  +=  skip )   {
            skip  =   0 ;
             for   ( int  j  =  m - 1 ;  j  >=   0 ;  j -- )   {
                 if   ( pattern [ j ]   !=  text [ i + j ])   {
                    skip  =   Math . max ( 1 ,  j  -  right [ text [ i + j ]]);
                     break ;
                 }
             }
             if   ( skip  ==   0 )   return  i ;      // found
         }
         return  n ;                         // not found
     }


     /**
     * Takes a pattern string and an input string as command-line arguments;
     * searches for the pattern string in the text string; and prints
     * the first occurrence of the pattern string in the text string.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  pat  =  args [ 0 ];
         String  txt  =  args [ 1 ];
         char []  pattern  =  pat . toCharArray ();
         char []  text     =  txt . toCharArray ();

         BoyerMoore  boyermoore1  =   new   BoyerMoore ( pat );
         BoyerMoore  boyermoore2  =   new   BoyerMoore ( pattern ,   256 );
         int  offset1  =  boyermoore1 . search ( txt );
         int  offset2  =  boyermoore2 . search ( text );

         // print results
         StdOut . println ( "text:    "   +  txt );

         StdOut . print ( "pattern: " );
         for   ( int  i  =   0 ;  i  <  offset1 ;  i ++ )
             StdOut . print ( " " );
         StdOut . println ( pat );

         StdOut . print ( "pattern: " );
         for   ( int  i  =   0 ;  i  <  offset2 ;  i ++ )
             StdOut . print ( " " );
         StdOut . println ( pat );
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BreadthFirstDirectedPaths.java

edu/princeton/cs/algs4/BreadthFirstDirectedPaths.java

/******************************************************************************
 *  Compilation:  javac BreadthFirstDirectedPaths.java
 *  Execution:    java BreadthFirstDirectedPaths digraph.txt s
 *  Dependencies: Digraph.java Queue.java Stack.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Run breadth-first search on a digraph.
 *  Runs in O(E + V) time.
 *
 *  % java BreadthFirstDirectedPaths tinyDG.txt 3
 *  3 to 0 (2):  3->2->0
 *  3 to 1 (3):  3->2->0->1
 *  3 to 2 (1):  3->2
 *  3 to 3 (0):  3
 *  3 to 4 (2):  3->5->4
 *  3 to 5 (1):  3->5
 *  3 to 6 (-):  not connected
 *  3 to 7 (-):  not connected
 *  3 to 8 (-):  not connected
 *  3 to 9 (-):  not connected
 *  3 to 10 (-):  not connected
 *  3 to 11 (-):  not connected
 *  3 to 12 (-):  not connected
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BreadthDirectedFirstPaths} class represents a data type for
 *  finding shortest paths (number of edges) from a source vertex <em>s</em>
 *  (or set of source vertices) to every other vertex in the digraph.
 *  <p>
 *  This implementation uses breadth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and <em>E</em> is
 *  the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BreadthFirstDirectedPaths   {
     private   static   final   int  INFINITY  =   Integer . MAX_VALUE ;
     private   boolean []  marked ;    // marked[v] = is there an s->v path?
     private   int []  edgeTo ;        // edgeTo[v] = last edge on shortest s->v path
     private   int []  distTo ;        // distTo[v] = length of shortest s->v path

     /**
     * Computes the shortest path from { @code  s} and every other vertex in graph { @code  G}.
     *  @param  G the digraph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   BreadthFirstDirectedPaths ( Digraph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        distTo  =   new   int [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =  INFINITY ;
        validateVertex ( s );
        bfs ( G ,  s );
     }

     /**
     * Computes the shortest path from any one of the source vertices in { @code  sources}
     * to every other vertex in graph { @code  G}.
     *  @param  G the digraph
     *  @param  sources the source vertices
     *  @throws  IllegalArgumentException unless each vertex { @code  v} in
     *         { @code  sources} satisfies { @code  0 <= v < V}
     */
     public   BreadthFirstDirectedPaths ( Digraph  G ,   Iterable < Integer >  sources )   {
        marked  =   new   boolean [ G . V ()];
        distTo  =   new   int [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =  INFINITY ;
        validateVertices ( sources );
        bfs ( G ,  sources );
     }

     // BFS from single source
     private   void  bfs ( Digraph  G ,   int  s )   {
         Queue < Integer >  q  =   new   Queue < Integer > ();
        marked [ s ]   =   true ;
        distTo [ s ]   =   0 ;
        q . enqueue ( s );
         while   ( ! q . isEmpty ())   {
             int  v  =  q . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ! marked [ w ])   {
                    edgeTo [ w ]   =  v ;
                    distTo [ w ]   =  distTo [ v ]   +   1 ;
                    marked [ w ]   =   true ;
                    q . enqueue ( w );
                 }
             }
         }
     }

     // BFS from multiple sources
     private   void  bfs ( Digraph  G ,   Iterable < Integer >  sources )   {
         Queue < Integer >  q  =   new   Queue < Integer > ();
         for   ( int  s  :  sources )   {
            marked [ s ]   =   true ;
            distTo [ s ]   =   0 ;
            q . enqueue ( s );
         }
         while   ( ! q . isEmpty ())   {
             int  v  =  q . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ! marked [ w ])   {
                    edgeTo [ w ]   =  v ;
                    distTo [ w ]   =  distTo [ v ]   +   1 ;
                    marked [ w ]   =   true ;
                    q . enqueue ( w );
                 }
             }
         }
     }

     /**
     * Is there a directed path from the source { @code  s} (or sources) to vertex { @code  v}?
     *  @param  v the vertex
     *  @return  { @code  true} if there is a directed path, { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     /**
     * Returns the number of edges in a shortest path from the source { @code  s}
     * (or sources) to vertex { @code  v}?
     *  @param  v the vertex
     *  @return  the number of edges in a shortest path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Returns a shortest path from { @code  s} (or sources) to { @code  v}, or
     * { @code  null} if no such path.
     *  @param  v the vertex
     *  @return  the sequence of vertices on a shortest path, as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  pathTo ( int  v )   {
        validateVertex ( v );

         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < Integer >  path  =   new   Stack < Integer > ();
         int  x ;
         for   ( =  v ;  distTo [ x ]   !=   0 ;  x  =  edgeTo [ x ])
            path . push ( x );
        path . push ( x );
         return  path ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertices ( Iterable < Integer >  vertices )   {
         if   ( vertices  ==   null )   {
             throw   new   IllegalArgumentException ( "argument is null" );
         }
         int  V  =  marked . length ;
         for   ( int  v  :  vertices )   {
             if   ( <   0   ||  v  >=  V )   {
                 throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
             }
         }
     }


     /**
     * Unit tests the { @code  BreadthFirstDirectedPaths} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         // StdOut.println(G);

         int  s  =   Integer . parseInt ( args [ 1 ]);
         BreadthFirstDirectedPaths  bfs  =   new   BreadthFirstDirectedPaths ( G ,  s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( bfs . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d (%d):  " ,  s ,  v ,  bfs . distTo ( v ));
                 for   ( int  x  :  bfs . pathTo ( v ))   {
                     if   ( ==  s )   StdOut . print ( x );
                     else          StdOut . print ( "->"   +  x );
                 }
                 StdOut . println ();
             }

             else   {
                 StdOut . printf ( "%d to %d (-):  not connected\n" ,  s ,  v );
             }

         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BreadthFirstPaths.java

edu/princeton/cs/algs4/BreadthFirstPaths.java

/******************************************************************************
 *  Compilation:  javac BreadthFirstPaths.java
 *  Execution:    java BreadthFirstPaths G s
 *  Dependencies: Graph.java Queue.java Stack.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt
 *                https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt
 *
 *  Run breadth first search on an undirected graph.
 *  Runs in O(E + V) time.
 *
 *  %  java Graph tinyCG.txt
 *  6 8
 *  0: 2 1 5 
 *  1: 0 2 
 *  2: 0 1 3 4 
 *  3: 5 4 2 
 *  4: 3 2 
 *  5: 3 0 
 *
 *  %  java BreadthFirstPaths tinyCG.txt 0
 *  0 to 0 (0):  0
 *  0 to 1 (1):  0-1
 *  0 to 2 (1):  0-2
 *  0 to 3 (2):  0-2-3
 *  0 to 4 (2):  0-2-4
 *  0 to 5 (1):  0-5
 *
 *  %  java BreadthFirstPaths largeG.txt 0
 *  0 to 0 (0):  0
 *  0 to 1 (418):  0-932942-474885-82707-879889-971961-...
 *  0 to 2 (323):  0-460790-53370-594358-780059-287921-...
 *  0 to 3 (168):  0-713461-75230-953125-568284-350405-...
 *  0 to 4 (144):  0-460790-53370-310931-440226-380102-...
 *  0 to 5 (566):  0-932942-474885-82707-879889-971961-...
 *  0 to 6 (349):  0-932942-474885-82707-879889-971961-...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  BreadthFirstPaths} class represents a data type for finding
 *  shortest paths (number of edges) from a source vertex <em>s</em>
 *  (or a set of source vertices)
 *  to every other vertex in an undirected graph.
 *  <p>
 *  This implementation uses breadth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   BreadthFirstPaths   {
     private   static   final   int  INFINITY  =   Integer . MAX_VALUE ;
     private   boolean []  marked ;    // marked[v] = is there an s-v path
     private   int []  edgeTo ;        // edgeTo[v] = previous edge on shortest s-v path
     private   int []  distTo ;        // distTo[v] = number of edges shortest s-v path

     /**
     * Computes the shortest path between the source vertex { @code  s}
     * and every other vertex in the graph { @code  G}.
     *  @param  G the graph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   BreadthFirstPaths ( Graph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        distTo  =   new   int [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
        validateVertex ( s );
        bfs ( G ,  s );

         assert  check ( G ,  s );
     }

     /**
     * Computes the shortest path between any one of the source vertices in { @code  sources}
     * and every other vertex in graph { @code  G}.
     *  @param  G the graph
     *  @param  sources the source vertices
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V} for each vertex
     *         { @code  s} in { @code  sources}
     */
     public   BreadthFirstPaths ( Graph  G ,   Iterable < Integer >  sources )   {
        marked  =   new   boolean [ G . V ()];
        distTo  =   new   int [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =  INFINITY ;
        validateVertices ( sources );
        bfs ( G ,  sources );
     }


     // breadth-first search from a single source
     private   void  bfs ( Graph  G ,   int  s )   {
         Queue < Integer >  q  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =  INFINITY ;
        distTo [ s ]   =   0 ;
        marked [ s ]   =   true ;
        q . enqueue ( s );

         while   ( ! q . isEmpty ())   {
             int  v  =  q . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ! marked [ w ])   {
                    edgeTo [ w ]   =  v ;
                    distTo [ w ]   =  distTo [ v ]   +   1 ;
                    marked [ w ]   =   true ;
                    q . enqueue ( w );
                 }
             }
         }
     }

     // breadth-first search from multiple sources
     private   void  bfs ( Graph  G ,   Iterable < Integer >  sources )   {
         Queue < Integer >  q  =   new   Queue < Integer > ();
         for   ( int  s  :  sources )   {
            marked [ s ]   =   true ;
            distTo [ s ]   =   0 ;
            q . enqueue ( s );
         }
         while   ( ! q . isEmpty ())   {
             int  v  =  q . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ! marked [ w ])   {
                    edgeTo [ w ]   =  v ;
                    distTo [ w ]   =  distTo [ v ]   +   1 ;
                    marked [ w ]   =   true ;
                    q . enqueue ( w );
                 }
             }
         }
     }

     /**
     * Is there a path between the source vertex { @code  s} (or sources) and vertex { @code  v}?
     *  @param  v the vertex
     *  @return  { @code  true} if there is a path, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     /**
     * Returns the number of edges in a shortest path between the source vertex { @code  s}
     * (or sources) and vertex { @code  v}?
     *  @param  v the vertex
     *  @return  the number of edges in a shortest path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Returns a shortest path between the source vertex { @code  s} (or sources)
     * and { @code  v}, or { @code  null} if no such path.
     *  @param   v the vertex
     *  @return  the sequence of vertices on a shortest path, as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < Integer >  path  =   new   Stack < Integer > ();
         int  x ;
         for   ( =  v ;  distTo [ x ]   !=   0 ;  x  =  edgeTo [ x ])
            path . push ( x );
        path . push ( x );
         return  path ;
     }


     // check optimality conditions for single source
     private   boolean  check ( Graph  G ,   int  s )   {

         // check that the distance of s = 0
         if   ( distTo [ s ]   !=   0 )   {
             StdOut . println ( "distance of source "   +  s  +   " to itself = "   +  distTo [ s ]);
             return   false ;
         }

         // check that for each edge v-w dist[w] <= dist[v] + 1
         // provided v is reachable from s
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( hasPathTo ( v )   !=  hasPathTo ( w ))   {
                     StdOut . println ( "edge "   +  v  +   "-"   +  w );
                     StdOut . println ( "hasPathTo("   +  v  +   ") = "   +  hasPathTo ( v ));
                     StdOut . println ( "hasPathTo("   +  w  +   ") = "   +  hasPathTo ( w ));
                     return   false ;
                 }
                 if   ( hasPathTo ( v )   &&   ( distTo [ w ]   >  distTo [ v ]   +   1 ))   {
                     StdOut . println ( "edge "   +  v  +   "-"   +  w );
                     StdOut . println ( "distTo["   +  v  +   "] = "   +  distTo [ v ]);
                     StdOut . println ( "distTo["   +  w  +   "] = "   +  distTo [ w ]);
                     return   false ;
                 }
             }
         }

         // check that v = edgeTo[w] satisfies distTo[w] = distTo[v] + 1
         // provided v is reachable from s
         for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
             if   ( ! hasPathTo ( w )   ||  w  ==  s )   continue ;
             int  v  =  edgeTo [ w ];
             if   ( distTo [ w ]   !=  distTo [ v ]   +   1 )   {
                 StdOut . println ( "shortest path edge "   +  v  +   "-"   +  w );
                 StdOut . println ( "distTo["   +  v  +   "] = "   +  distTo [ v ]);
                 StdOut . println ( "distTo["   +  w  +   "] = "   +  distTo [ w ]);
                 return   false ;
             }
         }

         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertices ( Iterable < Integer >  vertices )   {
         if   ( vertices  ==   null )   {
             throw   new   IllegalArgumentException ( "argument is null" );
         }
         int  V  =  marked . length ;
         for   ( int  v  :  vertices )   {
             if   ( <   0   ||  v  >=  V )   {
                 throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
             }
         }
     }

     /**
     * Unit tests the { @code  BreadthFirstPaths} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         // StdOut.println(G);

         int  s  =   Integer . parseInt ( args [ 1 ]);
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( G ,  s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( bfs . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d (%d):  " ,  s ,  v ,  bfs . distTo ( v ));
                 for   ( int  x  :  bfs . pathTo ( v ))   {
                     if   ( ==  s )   StdOut . print ( x );
                     else          StdOut . print ( "-"   +  x );
                 }
                 StdOut . println ();
             }

             else   {
                 StdOut . printf ( "%d to %d (-):  not connected\n" ,  s ,  v );
             }

         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BST.java

edu/princeton/cs/algs4/BST.java

/******************************************************************************
 *  Compilation:  javac BST.java
 *  Execution:    java BST
 *  Dependencies: StdIn.java StdOut.java Queue.java
 *  Data files:   https://algs4.cs.princeton.edu/32bst/tinyST.txt  
 *
 *  A symbol table implemented with a binary search tree.
 * 
 *  % more tinyST.txt
 *  S E A R C H E X A M P L E
 *  
 *  % java BST < tinyST.txt
 *  A 8
 *  C 4
 *  E 12
 *  H 5
 *  L 11
 *  M 9
 *  P 10
 *  R 3
 *  S 0
 *  X 7
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  BST} class represents an ordered symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, <em>select</em>, <em>ceiling</em>.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  <p>
 *  This implementation uses an (unbalanced) <em>binary search tree</em>.
 *  The <em>put</em>, <em>contains</em>, <em>remove</em>, <em>minimum</em>,
 *  <em>maximum</em>, <em>ceiling</em>, <em>floor</em>, <em>select</em>, and
 *  <em>rank</em>  operations each take &Theta;(<em>n</em>) time in the worst
 *  case, where <em>n</em> is the number of key-value pairs.
 *  The <em>size</em> and <em>is-empty</em> operations take &Theta;(1) time.
 *  The keys method takes &Theta;(<em>n</em>) time in the worst case.
 *  Construction takes &Theta;(1) time.
 *  <p>
 *  For alternative implementations of the symbol table API, see { @link  ST},
 *  { @link  BinarySearchST}, { @link  SequentialSearchST}, { @link  RedBlackBST},
 *  { @link  SeparateChainingHashST}, and { @link  LinearProbingHashST},
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/32bst">Section 3.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  BST < Key   extends   Comparable < Key > ,   Value >   {
     private   Node  root ;               // root of BST

     private   class   Node   {
         private   Key  key ;             // sorted by key
         private   Value  val ;           // associated data
         private   Node  left ,  right ;    // left and right subtrees
         private   int  size ;            // number of nodes in subtree

         public   Node ( Key  key ,   Value  val ,   int  size )   {
             this . key  =  key ;
             this . val  =  val ;
             this . size  =  size ;
         }
     }

     /**
     * Initializes an empty symbol table.
     */
     public  BST ()   {
     }

     /**
     * Returns true if this symbol table is empty.
     *  @return  { @code  true} if this symbol table is empty; { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  size ( root );
     }

     // return number of key-value pairs in BST rooted at x
     private   int  size ( Node  x )   {
         if   ( ==   null )   return   0 ;
         else   return  x . size ;
     }

     /**
     * Does this symbol table contain the given key?
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }

     /**
     * Returns the value associated with the given key.
     *
     *  @param   key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *         and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         return  get ( root ,  key );
     }

     private   Value  get ( Node  x ,   Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls get() with a null key" );
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if        ( cmp  <   0 )   return  get ( x . left ,  key );
         else   if   ( cmp  >   0 )   return  get ( x . right ,  key );
         else                return  x . val ;
     }

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls put() with a null key" );
         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }
        root  =  put ( root ,  key ,  val );
         assert  check ();
     }

     private   Node  put ( Node  x ,   Key  key ,   Value  val )   {
         if   ( ==   null )   return   new   Node ( key ,  val ,   1 );
         int  cmp  =  key . compareTo ( x . key );
         if        ( cmp  <   0 )  x . left   =  put ( x . left ,   key ,  val );
         else   if   ( cmp  >   0 )  x . right  =  put ( x . right ,  key ,  val );
         else               x . val    =  val ;
        x . size  =   1   +  size ( x . left )   +  size ( x . right );
         return  x ;
     }


     /**
     * Removes the smallest key and associated value from the symbol table.
     *
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Symbol table underflow" );
        root  =  deleteMin ( root );
         assert  check ();
     }

     private   Node  deleteMin ( Node  x )   {
         if   ( x . left  ==   null )   return  x . right ;
        x . left  =  deleteMin ( x . left );
        x . size  =  size ( x . left )   +  size ( x . right )   +   1 ;
         return  x ;
     }

     /**
     * Removes the largest key and associated value from the symbol table.
     *
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMax ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Symbol table underflow" );
        root  =  deleteMax ( root );
         assert  check ();
     }

     private   Node  deleteMax ( Node  x )   {
         if   ( x . right  ==   null )   return  x . left ;
        x . right  =  deleteMax ( x . right );
        x . size  =  size ( x . left )   +  size ( x . right )   +   1 ;
         return  x ;
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).    
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls delete() with a null key" );
        root  =  delete ( root ,  key );
         assert  check ();
     }

     private   Node  delete ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;

         int  cmp  =  key . compareTo ( x . key );
         if        ( cmp  <   0 )  x . left   =  delete ( x . left ,   key );
         else   if   ( cmp  >   0 )  x . right  =  delete ( x . right ,  key );
         else   {  
             if   ( x . right  ==   null )   return  x . left ;
             if   ( x . left   ==   null )   return  x . right ;
             Node  t  =  x ;
            x  =  min ( t . right );
            x . right  =  deleteMin ( t . right );
            x . left  =  t . left ;
         }  
        x . size  =  size ( x . left )   +  size ( x . right )   +   1 ;
         return  x ;
     }  


     /**
     * Returns the smallest key in the symbol table.
     *
     *  @return  the smallest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls min() with empty symbol table" );
         return  min ( root ). key ;
     }  

     private   Node  min ( Node  x )   {  
         if   ( x . left  ==   null )   return  x ;  
         else                  return  min ( x . left );  
     }  

     /**
     * Returns the largest key in the symbol table.
     *
     *  @return  the largest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls max() with empty symbol table" );
         return  max ( root ). key ;
     }  

     private   Node  max ( Node  x )   {
         if   ( x . right  ==   null )   return  x ;  
         else                   return  max ( x . right );  
     }  

     /**
     * Returns the largest key in the symbol table less than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the largest key in the symbol table less than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls floor() with empty symbol table" );
         Node  x  =  floor ( root ,  key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );
         else   return  x . key ;
     }  

     private   Node  floor ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  <    0 )   return  floor ( x . left ,  key );
         Node  t  =  floor ( x . right ,  key );  
         if   ( !=   null )   return  t ;
         else   return  x ;  
     }  

     public   Key  floor2 ( Key  key )   {
         Key  x  =  floor2 ( root ,  key ,   null );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );
         else   return  x ;

     }

     private   Key  floor2 ( Node  x ,   Key  key ,   Key  best )   {
         if   ( ==   null )   return  best ;
         int  cmp  =  key . compareTo ( x . key );
         if        ( cmp   <   0 )   return  floor2 ( x . left ,  key ,  best );
         else   if   ( cmp   >   0 )   return  floor2 ( x . right ,  key ,  x . key );
         else                 return  x . key ;
     }  

     /**
     * Returns the smallest key in the symbol table greater than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the smallest key in the symbol table greater than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls ceiling() with empty symbol table" );
         Node  x  =  ceiling ( root ,  key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too large" );
         else   return  x . key ;
     }

     private   Node  ceiling ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  <   0 )   {  
             Node  t  =  ceiling ( x . left ,  key );  
             if   ( !=   null )   return  t ;
             else   return  x ;  
         }  
         return  ceiling ( x . right ,  key );  
     }  

     /**
     * Return the key in the symbol table whose rank is { @code  k}.
     * This is the (k+1)st smallest key in the symbol table.
     *
     *  @param   k the order statistic
     *  @return  the key in the symbol table of rank { @code  k}
     *  @throws  IllegalArgumentException unless { @code  k} is between 0 and
     *        <em>n</em>–1
     */
     public   Key  select ( int  k )   {
         if   ( <   0   ||  k  >=  size ())   {
             throw   new   IllegalArgumentException ( "argument to select() is invalid: "   +  k );
         }
         Node  x  =  select ( root ,  k );
         return  x . key ;
     }

     // Return key of rank k. 
     private   Node  select ( Node  x ,   int  k )   {
         if   ( ==   null )   return   null ;  
         int  t  =  size ( x . left );  
         if        ( >  k )   return  select ( x . left ,   k );  
         else   if   ( <  k )   return  select ( x . right ,  k - t - 1 );  
         else              return  x ;  
     }  

     /**
     * Return the number of keys in the symbol table strictly less than { @code  key}.
     *
     *  @param   key the key
     *  @return  the number of keys in the symbol table strictly less than { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   int  rank ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );
         return  rank ( key ,  root );
     }  

     // Number of keys in the subtree less than key.
     private   int  rank ( Key  key ,   Node  x )   {
         if   ( ==   null )   return   0 ;  
         int  cmp  =  key . compareTo ( x . key );  
         if        ( cmp  <   0 )   return  rank ( key ,  x . left );  
         else   if   ( cmp  >   0 )   return   1   +  size ( x . left )   +  rank ( key ,  x . right );  
         else                return  size ( x . left );  
     }  

     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *
     *  @return  all keys in the symbol table
     */
     public   Iterable < Key >  keys ()   {
         if   ( isEmpty ())   return   new   Queue < Key > ();
         return  keys ( min (),  max ());
     }

     /**
     * Returns all keys in the symbol table in the given range,
     * as an { @code  Iterable}.
     *
     *  @param   lo minimum endpoint
     *  @param   hi maximum endpoint
     *  @return  all keys in the symbol table between { @code  lo} 
     *         (inclusive) and { @code  hi} (inclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *         is { @code  null}
     */
     public   Iterable < Key >  keys ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to keys() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to keys() is null" );

         Queue < Key >  queue  =   new   Queue < Key > ();
        keys ( root ,  queue ,  lo ,  hi );
         return  queue ;
     }  

     private   void  keys ( Node  x ,   Queue < Key >  queue ,   Key  lo ,   Key  hi )   {  
         if   ( ==   null )   return ;  
         int  cmplo  =  lo . compareTo ( x . key );  
         int  cmphi  =  hi . compareTo ( x . key );  
         if   ( cmplo  <   0 )  keys ( x . left ,  queue ,  lo ,  hi );  
         if   ( cmplo  <=   0   &&  cmphi  >=   0 )  queue . enqueue ( x . key );  
         if   ( cmphi  >   0 )  keys ( x . right ,  queue ,  lo ,  hi );  
     }  

     /**
     * Returns the number of keys in the symbol table in the given range.
     *
     *  @param   lo minimum endpoint
     *  @param   hi maximum endpoint
     *  @return  the number of keys in the symbol table between { @code  lo} 
     *         (inclusive) and { @code  hi} (inclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *         is { @code  null}
     */
     public   int  size ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to size() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to size() is null" );

         if   ( lo . compareTo ( hi )   >   0 )   return   0 ;
         if   ( contains ( hi ))   return  rank ( hi )   -  rank ( lo )   +   1 ;
         else                return  rank ( hi )   -  rank ( lo );
     }

     /**
     * Returns the height of the BST (for debugging).
     *
     *  @return  the height of the BST (a 1-node tree has height 0)
     */
     public   int  height ()   {
         return  height ( root );
     }
     private   int  height ( Node  x )   {
         if   ( ==   null )   return   - 1 ;
         return   1   +   Math . max ( height ( x . left ),  height ( x . right ));
     }

     /**
     * Returns the keys in the BST in level order (for debugging).
     *
     *  @return  the keys in the BST in level order traversal
     */
     public   Iterable < Key >  levelOrder ()   {
         Queue < Key >  keys  =   new   Queue < Key > ();
         Queue < Node >  queue  =   new   Queue < Node > ();
        queue . enqueue ( root );
         while   ( ! queue . isEmpty ())   {
             Node  x  =  queue . dequeue ();
             if   ( ==   null )   continue ;
            keys . enqueue ( x . key );
            queue . enqueue ( x . left );
            queue . enqueue ( x . right );
         }
         return  keys ;
     }

   /*************************************************************************
    *  Check integrity of BST data structure.
    ***************************************************************************/
     private   boolean  check ()   {
         if   ( ! isBST ())              StdOut . println ( "Not in symmetric order" );
         if   ( ! isSizeConsistent ())   StdOut . println ( "Subtree counts not consistent" );
         if   ( ! isRankConsistent ())   StdOut . println ( "Ranks not consistent" );
         return  isBST ()   &&  isSizeConsistent ()   &&  isRankConsistent ();
     }

     // does this binary tree satisfy symmetric order?
     // Note: this test also ensures that data structure is a binary tree since order is strict
     private   boolean  isBST ()   {
         return  isBST ( root ,   null ,   null );
     }

     // is the tree rooted at x a BST with all keys strictly between min and max
     // (if min or max is null, treat as empty constraint)
     // Credit: Bob Dondero's elegant solution
     private   boolean  isBST ( Node  x ,   Key  min ,   Key  max )   {
         if   ( ==   null )   return   true ;
         if   ( min  !=   null   &&  x . key . compareTo ( min )   <=   0 )   return   false ;
         if   ( max  !=   null   &&  x . key . compareTo ( max )   >=   0 )   return   false ;
         return  isBST ( x . left ,  min ,  x . key )   &&  isBST ( x . right ,  x . key ,  max );
     }  

     // are the size fields correct?
     private   boolean  isSizeConsistent ()   {   return  isSizeConsistent ( root );   }
     private   boolean  isSizeConsistent ( Node  x )   {
         if   ( ==   null )   return   true ;
         if   ( x . size  !=  size ( x . left )   +  size ( x . right )   +   1 )   return   false ;
         return  isSizeConsistent ( x . left )   &&  isSizeConsistent ( x . right );
     }  

     // check that ranks are consistent
     private   boolean  isRankConsistent ()   {
         for   ( int  i  =   0 ;  i  <  size ();  i ++ )
             if   ( !=  rank ( select ( i )))   return   false ;
         for   ( Key  key  :  keys ())
             if   ( key . compareTo ( select ( rank ( key )))   !=   0 )   return   false ;
         return   true ;
     }


     /**
     * Unit tests the { @code  BST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
        BST < String ,   Integer >  st  =   new  BST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }

         for   ( String  s  :  st . levelOrder ())
             StdOut . println ( +   " "   +  st . get ( s ));

         StdOut . println ();

         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/BTree.java

edu/princeton/cs/algs4/BTree.java

/******************************************************************************
 *  Compilation:  javac BTree.java
 *  Execution:    java BTree
 *  Dependencies: StdOut.java
 *
 *  B-tree.
 *
 *  Limitations
 *  -----------
 *   -  Assumes M is even and M >= 4
 *   -  should b be an array of children or list (it would help with
 *      casting to make it a list)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  BTree} class represents an ordered symbol table of generic
 *  key-value pairs.
 *  It supports the <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>size</em>, and <em>is-empty</em> methods.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This implementation uses a B-tree. It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  The <em>get</em>, <em>put</em>, and <em>contains</em> operations
 *  each make log<sub><em>m</em></sub>(<em>n</em>) probes in the worst case,
 *  where <em>n</em> is the number of key-value pairs
 *  and <em>m</em> is the branching factor.
 *  The <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction takes constant time.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/62btree">Section 6.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   BTree < Key   extends   Comparable < Key > ,   Value >    {
     // max children per B-tree node = M-1
     // (must be even and greater than 2)
     private   static   final   int  M  =   4 ;

     private   Node  root ;         // root of the B-tree
     private   int  height ;        // height of the B-tree
     private   int  n ;             // number of key-value pairs in the B-tree

     // helper B-tree node data type
     private   static   final   class   Node   {
         private   int  m ;                               // number of children
         private   Entry []  children  =   new   Entry [ M ];     // the array of children

         // create a node with k children
         private   Node ( int  k )   {
            m  =  k ;
         }
     }

     // internal nodes: only use key and next
     // external nodes: only use key and value
     private   static   class   Entry   {
         private   Comparable  key ;
         private   final   Object  val ;
         private   Node  next ;       // helper field to iterate over array entries
         public   Entry ( Comparable  key ,   Object  val ,   Node  next )   {
             this . key   =  key ;
             this . val   =  val ;
             this . next  =  next ;
         }
     }

     /**
     * Initializes an empty B-tree.
     */
     public   BTree ()   {
        root  =   new   Node ( 0 );
     }
 
     /**
     * Returns true if this symbol table is empty.
     *  @return  { @code  true} if this symbol table is empty; { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns the height of this B-tree (for debugging).
     *
     *  @return  the height of this B-tree
     */
     public   int  height ()   {
         return  height ;
     }


     /**
     * Returns the value associated with the given key.
     *
     *  @param   key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *         and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         return  search ( root ,  key ,  height );
     }

     private   Value  search ( Node  x ,   Key  key ,   int  ht )   {
         Entry []  children  =  x . children ;

         // external node
         if   ( ht  ==   0 )   {
             for   ( int  j  =   0 ;  j  <  x . m ;  j ++ )   {
                 if   ( eq ( key ,  children [ j ]. key ))   return   ( Value )  children [ j ]. val ;
             }
         }

         // internal node
         else   {
             for   ( int  j  =   0 ;  j  <  x . m ;  j ++ )   {
                 if   ( j + 1   ==  x . ||  less ( key ,  children [ j + 1 ]. key ))
                     return  search ( children [ j ]. next ,  key ,  ht - 1 );
             }
         }
         return   null ;
     }


     /**
     * Inserts the key-value pair into the symbol table, overwriting the old value
     * with the new value if the key is already in the symbol table.
     * If the value is { @code  null}, this effectively deletes the key from the symbol table.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument key to put() is null" );
         Node  u  =  insert ( root ,  key ,  val ,  height );  
        n ++ ;
         if   ( ==   null )   return ;

         // need to split root
         Node  t  =   new   Node ( 2 );
        t . children [ 0 ]   =   new   Entry ( root . children [ 0 ]. key ,   null ,  root );
        t . children [ 1 ]   =   new   Entry ( u . children [ 0 ]. key ,   null ,  u );
        root  =  t ;
        height ++ ;
     }

     private   Node  insert ( Node  h ,   Key  key ,   Value  val ,   int  ht )   {
         int  j ;
         Entry  t  =   new   Entry ( key ,  val ,   null );

         // external node
         if   ( ht  ==   0 )   {
             for   ( =   0 ;  j  <  h . m ;  j ++ )   {
                 if   ( less ( key ,  h . children [ j ]. key ))   break ;
             }
         }

         // internal node
         else   {
             for   ( =   0 ;  j  <  h . m ;  j ++ )   {
                 if   (( j + 1   ==  h . m )   ||  less ( key ,  h . children [ j + 1 ]. key ))   {
                     Node  u  =  insert ( h . children [ j ++ ]. next ,  key ,  val ,  ht - 1 );
                     if   ( ==   null )   return   null ;
                    t . key  =  u . children [ 0 ]. key ;
                    t . next  =  u ;
                     break ;
                 }
             }
         }

         for   ( int  i  =  h . m ;  i  >  j ;  i -- )
            h . children [ i ]   =  h . children [ i - 1 ];
        h . children [ j ]   =  t ;
        h . m ++ ;
         if   ( h . <  M )   return   null ;
         else           return  split ( h );
     }

     // split node in half
     private   Node  split ( Node  h )   {
         Node  t  =   new   Node ( M / 2 );
        h . =  M / 2 ;
         for   ( int  j  =   0 ;  j  <  M / 2 ;  j ++ )
            t . children [ j ]   =  h . children [ M / 2 + j ];  
         return  t ;     
     }

     /**
     * Returns a string representation of this B-tree (for debugging).
     *
     *  @return  a string representation of this B-tree.
     */
     public   String  toString ()   {
         return  toString ( root ,  height ,   "" )   +   "\n" ;
     }

     private   String  toString ( Node  h ,   int  ht ,   String  indent )   {
         StringBuilder  s  =   new   StringBuilder ();
         Entry []  children  =  h . children ;

         if   ( ht  ==   0 )   {
             for   ( int  j  =   0 ;  j  <  h . m ;  j ++ )   {
                s . append ( indent  +  children [ j ]. key  +   " "   +  children [ j ]. val  +   "\n" );
             }
         }
         else   {
             for   ( int  j  =   0 ;  j  <  h . m ;  j ++ )   {
                 if   ( >   0 )  s . append ( indent  +   "("   +  children [ j ]. key  +   ")\n" );
                s . append ( toString ( children [ j ]. next ,  ht - 1 ,  indent  +   "     " ));
             }
         }
         return  s . toString ();
     }


     // comparison functions - make Comparable instead of Key to avoid casts
     private   boolean  less ( Comparable  k1 ,   Comparable  k2 )   {
         return  k1 . compareTo ( k2 )   <   0 ;
     }

     private   boolean  eq ( Comparable  k1 ,   Comparable  k2 )   {
         return  k1 . compareTo ( k2 )   ==   0 ;
     }


     /**
     * Unit tests the { @code  BTree} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         BTree < String ,   String >  st  =   new   BTree < String ,   String > ();

        st . put ( "www.cs.princeton.edu" ,   "128.112.136.12" );
        st . put ( "www.cs.princeton.edu" ,   "128.112.136.11" );
        st . put ( "www.princeton.edu" ,      "128.112.128.15" );
        st . put ( "www.yale.edu" ,           "130.132.143.21" );
        st . put ( "www.simpsons.com" ,       "209.052.165.60" );
        st . put ( "www.apple.com" ,          "17.112.152.32" );
        st . put ( "www.amazon.com" ,         "207.171.182.16" );
        st . put ( "www.ebay.com" ,           "66.135.192.87" );
        st . put ( "www.cnn.com" ,            "64.236.16.20" );
        st . put ( "www.google.com" ,         "216.239.41.99" );
        st . put ( "www.nytimes.com" ,        "199.239.136.200" );
        st . put ( "www.microsoft.com" ,      "207.126.99.140" );
        st . put ( "www.dell.com" ,           "143.166.224.230" );
        st . put ( "www.slashdot.org" ,       "66.35.250.151" );
        st . put ( "www.espn.com" ,           "199.181.135.201" );
        st . put ( "www.weather.com" ,        "63.111.66.11" );
        st . put ( "www.yahoo.com" ,          "216.109.118.65" );


         StdOut . println ( "cs.princeton.edu:  "   +  st . get ( "www.cs.princeton.edu" ));
         StdOut . println ( "hardvardsucks.com: "   +  st . get ( "www.harvardsucks.com" ));
         StdOut . println ( "simpsons.com:      "   +  st . get ( "www.simpsons.com" ));
         StdOut . println ( "apple.com:         "   +  st . get ( "www.apple.com" ));
         StdOut . println ( "ebay.com:          "   +  st . get ( "www.ebay.com" ));
         StdOut . println ( "dell.com:          "   +  st . get ( "www.dell.com" ));
         StdOut . println ();

         StdOut . println ( "size:    "   +  st . size ());
         StdOut . println ( "height:  "   +  st . height ());
         StdOut . println ( st );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Cat.java

edu/princeton/cs/algs4/Cat.java

/******************************************************************************
 *  Compilation:  javac Cat.java
 *  Execution:    java Cat input0.txt input1.txt ... output.txt
 *  Dependencies: In.java Out.java
 *  Data files:   https://algs4.cs.princeton.edu/11model/in1.txt
 *                https://algs4.cs.princeton.edu/11model/in2.txt
 *
 *  Reads in text files specified as the first command-line 
 *  arguments, concatenates them, and writes the result to
 *  filename specified as the last command-line arguments.
 *
 *  % more in1.txt
 *  This is
 *
 *  % more in2.txt 
 *  a tiny
 *  test.
 * 
 *  % java Cat in1.txt in2.txt out.txt
 *
 *  % more out.txt
 *  This is
 *  a tiny
 *  test.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Cat} class provides a client for concatenating the results
 *  of several text files.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Cat   {  

     // this class should not be instantiated
     private   Cat ()   {   }

     /**
     * Reads in a sequence of text files specified as the first command-line
     * arguments, concatenates them, and writes the results to the file
     * specified as the last command-line argument.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         Out  out  =   new   Out ( args [ args . length  -   1 ]);
         for   ( int  i  =   0 ;  i  <  args . length  -   1 ;  i ++ )   {
             In  in  =   new   In ( args [ i ]);
             String  s  =  in . readAll ();
            out . println ( s );
            in . close ();
         }
        out . close ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/CC.java

edu/princeton/cs/algs4/CC.java

/******************************************************************************
 *  Compilation:  javac CC.java
 *  Execution:    java CC filename.txt
 *  Dependencies: Graph.java StdOut.java Queue.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt
 *
 *  Compute connected components using depth first search.
 *  Runs in O(E + V) time.
 *
 *  % java CC tinyG.txt
 *  3 components
 *  0 1 2 3 4 5 6
 *  7 8 
 *  9 10 11 12
 *
 *  % java CC mediumG.txt 
 *  1 components
 *  0 1 2 3 4 5 6 7 8 9 10 ...
 *
 *  % java -Xss50m CC largeG.txt 
 *  1 components
 *  0 1 2 3 4 5 6 7 8 9 10 ...
 *
 *  Note: This implementation uses a recursive DFS. To avoid needing
 *        a potentially very large stack size, replace with a non-recurisve
 *        DFS ala NonrecursiveDFS.java.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  CC} class represents a data type for 
 *  determining the connected components in an undirected graph.
 *  The <em>id</em> operation determines in which connected component
 *  a given vertex lies; the <em>connected</em> operation
 *  determines whether two vertices are in the same connected component;
 *  the <em>count</em> operation determines the number of connected
 *  components; and the <em>size</em> operation determines the number
 *  of vertices in the connect component containing a given vertex.

 *  The <em>component identifier</em> of a connected component is one of the
 *  vertices in the connected component: two vertices have the same component
 *  identifier if and only if they are in the same connected component.

 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  <p>
 *  For additional documentation, see 
 *  <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <em>Algorithms, 4th Edition</em> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  CC  {
     private   boolean []  marked ;     // marked[v] = has vertex v been marked?
     private   int []  id ;             // id[v] = id of connected component containing v
     private   int []  size ;           // size[id] = number of vertices in given component
     private   int  count ;            // number of connected components

     /**
     * Computes the connected components of the undirected graph { @code  G}.
     *
     *  @param  G the undirected graph
     */
     public  CC ( Graph  G )   {
        marked  =   new   boolean [ G . V ()];
        id  =   new   int [ G . V ()];
        size  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ! marked [ v ])   {
                dfs ( G ,  v );
                count ++ ;
             }
         }
     }

     /**
     * Computes the connected components of the edge-weighted graph { @code  G}.
     *
     *  @param  G the edge-weighted graph
     */
     public  CC ( EdgeWeightedGraph  G )   {
        marked  =   new   boolean [ G . V ()];
        id  =   new   int [ G . V ()];
        size  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ! marked [ v ])   {
                dfs ( G ,  v );
                count ++ ;
             }
         }
     }

     // depth-first search for a Graph
     private   void  dfs ( Graph  G ,   int  v )   {
        marked [ v ]   =   true ;
        id [ v ]   =  count ;
        size [ count ] ++ ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])   {
                dfs ( G ,  w );
             }
         }
     }

     // depth-first search for an EdgeWeightedGraph
     private   void  dfs ( EdgeWeightedGraph  G ,   int  v )   {
        marked [ v ]   =   true ;
        id [ v ]   =  count ;
        size [ count ] ++ ;
         for   ( Edge  e  :  G . adj ( v ))   {
             int  w  =  e . other ( v );
             if   ( ! marked [ w ])   {
                dfs ( G ,  w );
             }
         }
     }


     /**
     * Returns the component id of the connected component containing vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the component id of the connected component containing vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  id ( int  v )   {
        validateVertex ( v );
         return  id [ v ];
     }

     /**
     * Returns the number of vertices in the connected component containing vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the number of vertices in the connected component containing vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  size ( int  v )   {
        validateVertex ( v );
         return  size [ id [ v ]];
     }

     /**
     * Returns the number of connected components in the graph { @code  G}.
     *
     *  @return  the number of connected components in the graph { @code  G}
     */
     public   int  count ()   {
         return  count ;
     }

     /**
     * Returns true if vertices { @code  v} and { @code  w} are in the same
     * connected component.
     *
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same
     *         connected component; { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     */
     public   boolean  connected ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  id ( v )   ==  id ( w );
     }

     /**
     * Returns true if vertices { @code  v} and { @code  w} are in the same
     * connected component.
     *
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same
     *         connected component; { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     *  @deprecated  Replaced by { @link  #connected(int, int)}.
     */
    @ Deprecated
     public   boolean  areConnected ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  id ( v )   ==  id ( w );
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  CC} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
        CC cc  =   new  CC ( G );

         // number of connected components
         int  m  =  cc . count ();
         StdOut . println ( +   " components" );

         // compute list of vertices in each connected component
         Queue < Integer > []  components  =   ( Queue < Integer > [])   new   Queue [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
            components [ i ]   =   new   Queue < Integer > ();
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            components [ cc . id ( v )]. enqueue ( v );
         }

         // print results
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  v  :  components [ i ])   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ClosestPair.java

edu/princeton/cs/algs4/ClosestPair.java

/******************************************************************************
 *  Compilation:  javac ClosestPair.java
 *  Execution:    java ClosestPair < input.txt
 *  Dependencies: Point2D.java
 *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt
 *                https://algs4.cs.princeton.edu/99hull/kw1260.txt
 *  
 *  Given n points in the plane, find the closest pair in n log n time.
 *
 *  Note: could speed it up by comparing square of Euclidean distances
 *  instead of Euclidean distances.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 *  The { @code  ClosestPair} data type computes a closest pair of points
 *  in a set of <em>n</em> points in the plane and provides accessor methods 
 *  for getting the closest pair of points and the distance between them.
 *  The distance between two points is their Euclidean distance.
 *  <p>
 *  This implementation uses a divide-and-conquer algorithm. 
 *  It runs in O(<em>n</em> log <em>n</em>) time in the worst case and uses
 *  O(<em>n</em>) extra space.
 *  <p>
 *  See also { @link  FarthestPair}.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/99hull">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ClosestPair   {

     // closest pair of points and their Euclidean distance
     private   Point2D  best1 ,  best2 ;
     private   double  bestDistance  =   Double . POSITIVE_INFINITY ;

     /**
     * Computes the closest pair of points in the specified array of points.
     *
     *  @param   points the array of points
     *  @throws  IllegalArgumentException if { @code  points} is { @code  null} or if any
     *         entry in { @code  points[]} is { @code  null}
     */
     public   ClosestPair ( Point2D []  points )   {
         if   ( points  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );
         for   ( int  i  =   0 ;  i  <  points . length ;  i ++ )   {
             if   ( points [ i ]   ==   null )   throw   new   IllegalArgumentException ( "array element "   +  i  +   " is null" );
         }

         int  n  =  points . length ;
         if   ( <=   1 )   return ;

         // sort by x-coordinate (breaking ties by y-coordinate)
         Point2D []  pointsByX  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            pointsByX [ i ]   =  points [ i ];
         Arrays . sort ( pointsByX ,   Point2D . X_ORDER );

         // check for coincident points
         for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )   {
             if   ( pointsByX [ i ]. equals ( pointsByX [ i + 1 ]))   {
                bestDistance  =   0.0 ;
                best1  =  pointsByX [ i ];
                best2  =  pointsByX [ i + 1 ];
                 return ;
             }
         }

         // sort by y-coordinate (but not yet sorted) 
         Point2D []  pointsByY  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            pointsByY [ i ]   =  pointsByX [ i ];

         // auxiliary array
         Point2D []  aux  =   new   Point2D [ n ];

        closest ( pointsByX ,  pointsByY ,  aux ,   0 ,  n - 1 );
     }

     // find closest pair of points in pointsByX[lo..hi]
     // precondition:  pointsByX[lo..hi] and pointsByY[lo..hi] are the same sequence of points
     // precondition:  pointsByX[lo..hi] sorted by x-coordinate
     // postcondition: pointsByY[lo..hi] sorted by y-coordinate
     private   double  closest ( Point2D []  pointsByX ,   Point2D []  pointsByY ,   Point2D []  aux ,   int  lo ,   int  hi )   {
         if   ( hi  <=  lo )   return   Double . POSITIVE_INFINITY ;

         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
         Point2D  median  =  pointsByX [ mid ];

         // compute closest pair with both endpoints in left subarray or both in right subarray
         double  delta1  =  closest ( pointsByX ,  pointsByY ,  aux ,  lo ,  mid );
         double  delta2  =  closest ( pointsByX ,  pointsByY ,  aux ,  mid + 1 ,  hi );
         double  delta  =   Math . min ( delta1 ,  delta2 );

         // merge back so that pointsByY[lo..hi] are sorted by y-coordinate
        merge ( pointsByY ,  aux ,  lo ,  mid ,  hi );

         // aux[0..m-1] = sequence of points closer than delta, sorted by y-coordinate
         int  m  =   0 ;
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             if   ( Math . abs ( pointsByY [ i ]. x ()   -  median . x ())   <  delta )
                aux [ m ++ ]   =  pointsByY [ i ];
         }

         // compare each point to its neighbors with y-coordinate closer than delta
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             // a geometric packing argument shows that this loop iterates at most 7 times
             for   ( int  j  =  i + 1 ;   ( <  m )   &&   ( aux [ j ]. y ()   -  aux [ i ]. y ()   <  delta );  j ++ )   {
                 double  distance  =  aux [ i ]. distanceTo ( aux [ j ]);
                 if   ( distance  <  delta )   {
                    delta  =  distance ;
                     if   ( distance  <  bestDistance )   {
                        bestDistance  =  delta ;
                        best1  =  aux [ i ];
                        best2  =  aux [ j ];
                         // StdOut.println("better distance = " + delta + " from " + best1 + " to " + best2);
                     }
                 }
             }
         }
         return  delta ;
     }

     /**
     * Returns one of the points in the closest pair of points.
     *
     *  @return  one of the two points in the closest pair of points;
     *         { @code  null} if no such point (because there are fewer than 2 points)
     */
     public   Point2D  either ()   {
         return  best1 ;
     }

     /**
     * Returns the other point in the closest pair of points.
     *
     *  @return  the other point in the closest pair of points
     *         { @code  null} if no such point (because there are fewer than 2 points)
     */
     public   Point2D  other ()   {
         return  best2 ;
     }

     /**
     * Returns the Eucliden distance between the closest pair of points.
     *
     *  @return  the Euclidean distance between the closest pair of points
     *         { @code  Double.POSITIVE_INFINITY} if no such pair of points
     *         exist (because there are fewer than 2 points)
     */
     public   double  distance ()   {
         return  bestDistance ;
     }

     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }

     // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
     // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
     private   static   void  merge ( Comparable []  a ,   Comparable []  aux ,   int  lo ,   int  mid ,   int  hi )   {
         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  a [ k ];
         }
    
         // merge back to a[] 
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )               a [ k ]   =  aux [ j ++ ];
             else   if   ( >  hi )                a [ k ]   =  aux [ i ++ ];
             else   if   ( less ( aux [ j ],  aux [ i ]))  a [ k ]   =  aux [ j ++ ];
             else                            a [ k ]   =  aux [ i ++ ];
         }
     }



    /**
     * Unit tests the { @code  ClosestPair} data type.
     * Reads in an integer { @code  n} and { @code  n} points (specified by
     * their <em>x</em>- and <em>y</em>-coordinates) from standard input;
     * computes a closest pair of points; and prints the pair to standard
     * output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         Point2D []  points  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             double  x  =   StdIn . readDouble ();
             double  y  =   StdIn . readDouble ();
            points [ i ]   =   new   Point2D ( x ,  y );
         }
         ClosestPair  closest  =   new   ClosestPair ( points );
         StdOut . println ( closest . distance ()   +   " from "   +  closest . either ()   +   " to "   +  closest . other ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/CollisionSystem.java

edu/princeton/cs/algs4/CollisionSystem.java

/******************************************************************************
 *  Compilation:  javac CollisionSystem.java
 *  Execution:    java CollisionSystem n               (n random particles)
 *                java CollisionSystem < input.txt     (from a file) 
 *  Dependencies: StdDraw.java Particle.java MinPQ.java
 *  Data files:   https://algs4.cs.princeton.edu/61event/diffusion.txt
 *                https://algs4.cs.princeton.edu/61event/diffusion2.txt
 *                https://algs4.cs.princeton.edu/61event/diffusion3.txt
 *                https://algs4.cs.princeton.edu/61event/brownian.txt
 *                https://algs4.cs.princeton.edu/61event/brownian2.txt
 *                https://algs4.cs.princeton.edu/61event/billiards5.txt
 *                https://algs4.cs.princeton.edu/61event/pendulum.txt
 *  
 *  Creates n random particles and simulates their motion according
 *  to the laws of elastic collisions.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . Color ;

/**
 *  The { @code  CollisionSystem} class represents a collection of particles
 *  moving in the unit box, according to the laws of elastic collision.
 *  This event-based simulation relies on a priority queue.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/61event">Section 6.1</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   CollisionSystem   {
     private   static   final   double  HZ  =   0.5 ;      // number of redraw events per clock tick

     private   MinPQ < Event >  pq ;            // the priority queue
     private   double  t   =   0.0 ;            // simulation clock time
     private   Particle []  particles ;       // the array of particles

     /**
     * Initializes a system with the specified collection of particles.
     * The individual particles will be mutated during the simulation.
     *
     *  @param   particles the array of particles
     */
     public   CollisionSystem ( Particle []  particles )   {
         this . particles  =  particles . clone ();     // defensive copy
     }

     // updates priority queue with all new events for particle a
     private   void  predict ( Particle  a ,   double  limit )   {
         if   ( ==   null )   return ;

         // particle-particle collisions
         for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )   {
             double  dt  =  a . timeToHit ( particles [ i ]);
             if   ( +  dt  <=  limit )
                pq . insert ( new   Event ( +  dt ,  a ,  particles [ i ]));
         }

         // particle-wall collisions
         double  dtX  =  a . timeToHitVerticalWall ();
         double  dtY  =  a . timeToHitHorizontalWall ();
         if   ( +  dtX  <=  limit )  pq . insert ( new   Event ( +  dtX ,  a ,   null ));
         if   ( +  dtY  <=  limit )  pq . insert ( new   Event ( +  dtY ,   null ,  a ));
     }

     // redraw all particles
     private   void  redraw ( double  limit )   {
         StdDraw . clear ();
         for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )   {
            particles [ i ]. draw ();
         }
         StdDraw . show ();
         StdDraw . pause ( 20 );
         if   ( <  limit )   {
            pq . insert ( new   Event ( +   1.0   /  HZ ,   null ,   null ));
         }
     }

      
     /**
     * Simulates the system of particles for the specified amount of time.
     *
     *  @param   limit the amount of time
     */
     public   void  simulate ( double  limit )   {
        
         // initialize PQ with collision events and redraw event
        pq  =   new   MinPQ < Event > ();
         for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )   {
            predict ( particles [ i ],  limit );
         }
        pq . insert ( new   Event ( 0 ,   null ,   null ));          // redraw event


         // the main event-driven simulation loop
         while   ( ! pq . isEmpty ())   {  

             // get impending event, discard if invalidated
             Event  e  =  pq . delMin ();
             if   ( ! e . isValid ())   continue ;
             Particle  a  =  e . a ;
             Particle  b  =  e . b ;

             // physical collision, so update positions, and then simulation clock
             for   ( int  i  =   0 ;  i  <  particles . length ;  i ++ )
                particles [ i ]. move ( e . time  -  t );
            t  =  e . time ;

             // process event
             if        ( !=   null   &&  b  !=   null )  a . bounceOff ( b );                // particle-particle collision
             else   if   ( !=   null   &&  b  ==   null )  a . bounceOffVerticalWall ();     // particle-wall collision
             else   if   ( ==   null   &&  b  !=   null )  b . bounceOffHorizontalWall ();   // particle-wall collision
             else   if   ( ==   null   &&  b  ==   null )  redraw ( limit );                 // redraw event

             // update the priority queue with new collisions involving a or b
            predict ( a ,  limit );
            predict ( b ,  limit );
         }
     }


    /***************************************************************************
    *  An event during a particle collision simulation. Each event contains
    *  the time at which it will occur (assuming no supervening actions)
    *  and the particles a and b involved.
    *
    *    -  a and b both null:      redraw event
    *    -  a null, b not null:     collision with vertical wall
    *    -  a not null, b null:     collision with horizontal wall
    *    -  a and b both not null:  binary collision between a and b
    *
    ***************************************************************************/
     private   static   class   Event   implements   Comparable < Event >   {
         private   final   double  time ;           // time that event is scheduled to occur
         private   final   Particle  a ,  b ;         // particles involved in event, possibly null
         private   final   int  countA ,  countB ;    // collision counts at event creation
                
        
         // create a new event to occur at time t involving a and b
         public   Event ( double  t ,   Particle  a ,   Particle  b )   {
             this . time  =  t ;
             this . a     =  a ;
             this . b     =  b ;
             if   ( !=   null )  countA  =  a . count ();
             else            countA  =   - 1 ;
             if   ( !=   null )  countB  =  b . count ();
             else            countB  =   - 1 ;
         }

         // compare times when two events will occur
         public   int  compareTo ( Event  that )   {
             return   Double . compare ( this . time ,  that . time );
         }
        
         // has any collision occurred between when event was created and now?
         public   boolean  isValid ()   {
             if   ( !=   null   &&  a . count ()   !=  countA )   return   false ;
             if   ( !=   null   &&  b . count ()   !=  countB )   return   false ;
             return   true ;
         }
   
     }


     /**
     * Unit tests the { @code  CollisionSystem} data type.
     * Reads in the particle collision system from a standard input
     * (or generates { @code  N} random particles if a command-line integer
     * is specified); simulates the system.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         StdDraw . setCanvasSize ( 600 ,   600 );

         // enable double buffering
         StdDraw . enableDoubleBuffering ();

         // the array of particles
         Particle []  particles ;

         // create n random particles
         if   ( args . length  ==   1 )   {
             int  n  =   Integer . parseInt ( args [ 0 ]);
            particles  =   new   Particle [ n ];
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )
                particles [ i ]   =   new   Particle ();
         }

         // or read from standard input
         else   {
             int  n  =   StdIn . readInt ();
            particles  =   new   Particle [ n ];
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 double  rx      =   StdIn . readDouble ();
                 double  ry      =   StdIn . readDouble ();
                 double  vx      =   StdIn . readDouble ();
                 double  vy      =   StdIn . readDouble ();
                 double  radius  =   StdIn . readDouble ();
                 double  mass    =   StdIn . readDouble ();
                 int  r          =   StdIn . readInt ();
                 int  g          =   StdIn . readInt ();
                 int  b          =   StdIn . readInt ();
                 Color  color    =   new   Color ( r ,  g ,  b );
                particles [ i ]   =   new   Particle ( rx ,  ry ,  vx ,  vy ,  radius ,  mass ,  color );
             }
         }

         // create collision system and simulate
         CollisionSystem  system  =   new   CollisionSystem ( particles );
        system . simulate ( 10000 );
     }
      
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Complex.java

edu/princeton/cs/algs4/Complex.java

/******************************************************************************
 *  Compilation:  javac Complex.java
 *  Execution:    java Complex
 *  Dependencies: StdOut.java
 *
 *  Data type for complex numbers.
 *
 *  The data type is "immutable" so once you create and initialize
 *  a Complex object, you cannot change it. The "final" keyword
 *  when declaring re and im enforces this rule, making it a
 *  compile-time error to change the .re or .im fields after
 *  they've been initialized.
 *
 *  % java Complex
 *  a            = 5.0 + 6.0i
 *  b            = -3.0 + 4.0i
 *  Re(a)        = 5.0
 *  Im(a)        = 6.0
 *  b + a        = 2.0 + 10.0i
 *  a - b        = 8.0 + 2.0i
 *  a * b        = -39.0 + 2.0i
 *  b * a        = -39.0 + 2.0i
 *  a / b        = 0.36 - 1.52i
 *  (a / b) * b  = 5.0 + 6.0i
 *  conj(a)      = 5.0 - 6.0i
 *  |a|          = 7.810249675906654
 *  tan(a)       = -6.685231390246571E-6 + 1.0000103108981198i
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Complex} class represents a complex number.
 *  Complex numbers are immutable: their values cannot be changed after they
 *  are created.
 *  It includes methods for addition, subtraction, multiplication, division,
 *  conjugation, and other common functions on complex numbers.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Complex   {
     private   final   double  re ;     // the real part
     private   final   double  im ;     // the imaginary part

     /**
     * Initializes a complex number from the specified real and imaginary parts.
     *
     *  @param  real the real part
     *  @param  imag the imaginary part
     */
     public   Complex ( double  real ,   double  imag )   {
        re  =  real ;
        im  =  imag ;
     }

     /**
     * Returns a string representation of this complex number.
     *
     *  @return  a string representation of this complex number,
     *         of the form 34 - 56i.
     */
     public   String  toString ()   {
         if   ( im  ==   0 )   return  re  +   "" ;
         if   ( re  ==   0 )   return  im  +   "i" ;
         if   ( im  <    0 )   return  re  +   " - "   +   ( - im )   +   "i" ;
         return  re  +   " + "   +  im  +   "i" ;
     }

     /**
     * Returns the absolute value of this complex number.
     * This quantity is also known as the <em>modulus</em> or <em>magnitude</em>.
     *
     *  @return  the absolute value of this complex number
     */
     public   double  abs ()   {
         return   Math . hypot ( re ,  im );
     }

     /**
     * Returns the phase of this complex number.
     * This quantity is also known as the <em>angle</em> or <em>argument</em>.
     *
     *  @return  the phase of this complex number, a real number between -pi and pi
     */
     public   double  phase ()   {
         return   Math . atan2 ( im ,  re );
     }

     /**
     * Returns the sum of this complex number and the specified complex number.
     *
     *  @param   that the other complex number
     *  @return  the complex number whose value is { @code  (this + that)}
     */
     public   Complex  plus ( Complex  that )   {
         double  real  =   this . re  +  that . re ;
         double  imag  =   this . im  +  that . im ;
         return   new   Complex ( real ,  imag );
     }

     /**
     * Returns the result of subtracting the specified complex number from
     * this complex number.
     *
     *  @param   that the other complex number
     *  @return  the complex number whose value is { @code  (this - that)}
     */
     public   Complex  minus ( Complex  that )   {
         double  real  =   this . re  -  that . re ;
         double  imag  =   this . im  -  that . im ;
         return   new   Complex ( real ,  imag );
     }

     /**
     * Returns the product of this complex number and the specified complex number.
     *
     *  @param   that the other complex number
     *  @return  the complex number whose value is { @code  (this * that)}
     */
     public   Complex  times ( Complex  that )   {
         double  real  =   this . re  *  that . re  -   this . im  *  that . im ;
         double  imag  =   this . re  *  that . im  +   this . im  *  that . re ;
         return   new   Complex ( real ,  imag );
     }

     /**
     * Returns the product of this complex number and the specified scalar.
     *
     *  @param   alpha the scalar
     *  @return  the complex number whose value is { @code  (alpha * this)}
     */
     public   Complex  scale ( double  alpha )   {
         return   new   Complex ( alpha  *  re ,  alpha  *  im );
     }

     /**
     * Returns the product of this complex number and the specified scalar.
     *
     *  @param   alpha the scalar
     *  @return  the complex number whose value is { @code  (alpha * this)}
     *  @deprecated  Replaced by { @link  #scale(double)}.
     */
    @ Deprecated
     public   Complex  times ( double  alpha )   {
         return   new   Complex ( alpha  *  re ,  alpha  *  im );
     }

     /**
     * Returns the complex conjugate of this complex number.
     *
     *  @return  the complex conjugate of this complex number
     */
     public   Complex  conjugate ()   {
         return   new   Complex ( re ,   - im );
     }

     /**
     * Returns the reciprocal of this complex number.
     *
     *  @return  the complex number whose value is { @code  (1 / this)}
     */
     public   Complex  reciprocal ()   {
         double  scale  =  re * re  +  im * im ;
         return   new   Complex ( re  /  scale ,   - im  /  scale );
     }

     /**
     * Returns the real part of this complex number.
     *
     *  @return  the real part of this complex number
     */
     public   double  re ()   {
         return  re ;
     }

     /**
     * Returns the imaginary part of this complex number.
     *
     *  @return  the imaginary part of this complex number
     */
     public   double  im ()   {
         return  im ;
     }

     /**
     * Returns the result of dividing the specified complex number into
     * this complex number.
     *
     *  @param   that the other complex number
     *  @return  the complex number whose value is { @code  (this / that)}
     */
     public   Complex  divides ( Complex  that )   {
         return   this . times ( that . reciprocal ());
     }

     /**
     * Returns the complex exponential of this complex number.
     *
     *  @return  the complex exponential of this complex number
     */
     public   Complex  exp ()   {
         return   new   Complex ( Math . exp ( re )   *   Math . cos ( im ),   Math . exp ( re )   *   Math . sin ( im ));
     }

     /**
     * Returns the complex sine of this complex number.
     *
     *  @return  the complex sine of this complex number
     */
     public   Complex  sin ()   {
         return   new   Complex ( Math . sin ( re )   *   Math . cosh ( im ),   Math . cos ( re )   *   Math . sinh ( im ));
     }

     /**
     * Returns the complex cosine of this complex number.
     *
     *  @return  the complex cosine of this complex number
     */
     public   Complex  cos ()   {
         return   new   Complex ( Math . cos ( re )   *   Math . cosh ( im ),   - Math . sin ( re )   *   Math . sinh ( im ));
     }

     /**
     * Returns the complex tangent of this complex number.
     *
     *  @return  the complex tangent of this complex number
     */
     public   Complex  tan ()   {
         return  sin (). divides ( cos ());
     }
    

     /**
     * Unit tests the { @code  Complex} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Complex  a  =   new   Complex ( 5.0 ,   6.0 );
         Complex  b  =   new   Complex ( - 3.0 ,   4.0 );

         StdOut . println ( "a            = "   +  a );
         StdOut . println ( "b            = "   +  b );
         StdOut . println ( "Re(a)        = "   +  a . re ());
         StdOut . println ( "Im(a)        = "   +  a . im ());
         StdOut . println ( "b + a        = "   +  b . plus ( a ));
         StdOut . println ( "a - b        = "   +  a . minus ( b ));
         StdOut . println ( "a * b        = "   +  a . times ( b ));
         StdOut . println ( "b * a        = "   +  b . times ( a ));
         StdOut . println ( "a / b        = "   +  a . divides ( b ));
         StdOut . println ( "(a / b) * b  = "   +  a . divides ( b ). times ( b ));
         StdOut . println ( "conj(a)      = "   +  a . conjugate ());
         StdOut . println ( "|a|          = "   +  a . abs ());
         StdOut . println ( "tan(a)       = "   +  a . tan ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Counter.java

edu/princeton/cs/algs4/Counter.java

/******************************************************************************
 *  Compilation:  javac Counter.java
 *  Execution:    java Counter n trials
 *  Dependencies: StdRandom.java StdOut.java
 *
 *  A mutable data type for an integer counter.
 *
 *  The test clients create n counters and performs trials increment
 *  operations on random counters.
 *
 * java Counter 6 600000
 *  100140 counter0
 *  100273 counter1
 *  99848 counter2
 *  100129 counter3
 *  99973 counter4
 *  99637 counter5
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Counter} class is a mutable data type to encapsulate a counter.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Counter   implements   Comparable < Counter >   {

     private   final   String  name ;       // counter name
     private   int  count  =   0 ;           // current value

     /**
     * Initializes a new counter starting at 0, with the given id.
     *
     *  @param  id the name of the counter
     */
     public   Counter ( String  id )   {
        name  =  id ;
     }  

     /**
     * Increments the counter by 1.
     */
     public   void  increment ()   {
        count ++ ;
     }  

     /**
     * Returns the current value of this counter.
     *
     *  @return  the current value of this counter
     */
     public   int  tally ()   {
         return  count ;
     }  

     /**
     * Returns a string representation of this counter.
     *
     *  @return  a string representation of this counter
     */
     public   String  toString ()   {
         return  count  +   " "   +  name ;
     }  

     /**
     * Compares this counter to the specified counter.
     *
     *  @param   that the other counter
     *  @return  { @code  0} if the value of this counter equals
     *         the value of that counter; a negative integer if
     *         the value of this counter is less than the value of
     *         that counter; and a positive integer if the value
     *         of this counter is greater than the value of that
     *         counter
     */
    @ Override
     public   int  compareTo ( Counter  that )   {
         if        ( this . count  <  that . count )   return   - 1 ;
         else   if   ( this . count  >  that . count )   return   + 1 ;
         else                                return    0 ;
     }


     /**
     * Reads two command-line integers n and trials; creates n counters;
     * increments trials counters at random; and prints results.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         int  n  =   Integer . parseInt ( args [ 0 ]);
         int  trials  =   Integer . parseInt ( args [ 1 ]);

         // create n counters
         Counter []  hits  =   new   Counter [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            hits [ i ]   =   new   Counter ( "counter"   +  i );
         }

         // increment trials counters at random
         for   ( int  t  =   0 ;  t  <  trials ;  t ++ )   {
            hits [ StdRandom . uniform ( n )]. increment ();
         }

         // print results
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdOut . println ( hits [ i ]);
         }
     }  
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Count.java

edu/princeton/cs/algs4/Count.java

/******************************************************************************
 *  Compilation:  javac Count.java
 *  Execution:    java Count alpha < input.txt
 *  Dependencies: Alphabet.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/50strings/abra.txt
 *                https://algs4.cs.princeton.edu/50strings/pi.txt
 *
 *  Create an alphabet specified on the command line, read in a 
 *  sequence of characters over that alphabet (ignoring characters
 *  not in the alphabet), computes the frequency of occurrence of
 *  each character, and print out the results.
 *
 *  %  java Count ABCDR < abra.txt 
 *  A 5
 *  B 2
 *  C 1
 *  D 1
 *  R 2
 *
 *  % java Count 0123456789 < pi.txt
 *  0 99959
 *  1 99757
 *  2 100026
 *  3 100230
 *  4 100230
 *  5 100359
 *  6 99548
 *  7 99800
 *  8 99985
 *  9 100106
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  Count} class provides an { @link  Alphabet} client for reading
 *  in a piece of text and computing the frequency of occurrence of each
 *  character over a given alphabet.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compress">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Count   {

     // Do not instantiate.
     private   Count ()   {   }

     /**
     * Reads in text from standard input; calculates the frequency of
     * occurrence of each character over the alphabet specified as a
     * commmand-line argument; and prints the frequencies to standard
     * output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Alphabet  alphabet  =   new   Alphabet ( args [ 0 ]);
         final   int  R  =  alphabet . radix ();
         int []  count  =   new   int [ R ];
         while   ( StdIn . hasNextChar ())   {
             char  c  =   StdIn . readChar ();
             if   ( alphabet . contains ( c ))
                count [ alphabet . toIndex ( c )] ++ ;
         }
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
             StdOut . println ( alphabet . toChar ( c )   +   " "   +  count [ c ]);
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/CPM.java

edu/princeton/cs/algs4/CPM.java

/******************************************************************************
 *  Compilation:  javac CPM.java
 *  Execution:    java CPM < input.txt
 *  Dependencies: EdgeWeightedDigraph.java AcyclicDigraphLP.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/jobsPC.txt
 *
 *  Critical path method.
 *
 *  % java CPM < jobsPC.txt
 *   job   start  finish
 *  --------------------
 *     0     0.0    41.0
 *     1    41.0    92.0
 *     2   123.0   173.0
 *     3    91.0   127.0
 *     4    70.0   108.0
 *     5     0.0    45.0
 *     6    70.0    91.0
 *     7    41.0    73.0
 *     8    91.0   123.0
 *     9    41.0    70.0
 *  Finish time:   173.0
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  CPM} class provides a client that solves the
 *  parallel precedence-constrained job scheduling problem
 *  via the <em>critical path method</em>. It reduces the problem
 *  to the longest-paths problem in edge-weighted DAGs.
 *  It builds an edge-weighted digraph (which must be a DAG)
 *  from the job-scheduling problem specification,
 *  finds the longest-paths tree, and computes the longest-paths
 *  lengths (which are precisely the start times for each job).
 *  <p>
 *  This implementation uses { @link  AcyclicLP} to find a longest
 *  path in a DAG.
 *  The program takes &Theta;(<em>V</em> + <em>E</em>) time in
 *  the worst case, where <em>V</em> is the number of jobs and
 *  <em>E</em> is the number of precedence constraints.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  CPM  {

     // this class cannot be instantiated
     private  CPM ()   {   }

     /**
     *  Reads the precedence constraints from standard input
     *  and prints a feasible schedule to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // number of jobs
         int  n  =   StdIn . readInt ();

         // source and sink
         int  source  =   2 * n ;
         int  sink    =   2 * +   1 ;

         // build network
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( 2 * +   2 );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             double  duration  =   StdIn . readDouble ();
            G . addEdge ( new   DirectedEdge ( source ,  i ,   0.0 ));
            G . addEdge ( new   DirectedEdge ( i + n ,  sink ,   0.0 ));
            G . addEdge ( new   DirectedEdge ( i ,  i + n ,     duration ));

             // precedence constraints
             int  m  =   StdIn . readInt ();
             for   ( int  j  =   0 ;  j  <  m ;  j ++ )   {
                 int  precedent  =   StdIn . readInt ();
                G . addEdge ( new   DirectedEdge ( n + i ,  precedent ,   0.0 ));
             }
         }

         // compute longest path
         AcyclicLP  lp  =   new   AcyclicLP ( G ,  source );

         // print results
         StdOut . println ( " job   start  finish" );
         StdOut . println ( "--------------------" );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdOut . printf ( "%4d %7.1f %7.1f\n" ,  i ,  lp . distTo ( i ),  lp . distTo ( i + n ));
         }
         StdOut . printf ( "Finish time: %7.1f\n" ,  lp . distTo ( sink ));
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Cycle.java

edu/princeton/cs/algs4/Cycle.java

/******************************************************************************
 *  Compilation:  javac Cycle.java
 *  Execution:    java  Cycle filename.txt
 *  Dependencies: Graph.java Stack.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt  
 *
 *  Identifies a cycle.
 *  Runs in O(E + V) time.
 *
 *  % java Cycle tinyG.txt
 *  3 4 5 3 
 * 
 *  % java Cycle mediumG.txt 
 *  15 0 225 15 
 * 
 *  % java Cycle largeG.txt 
 *  996673 762 840164 4619 785187 194717 996673 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Cycle} class represents a data type for 
 *  determining whether an undirected graph has a simple cycle.
 *  The <em>hasCycle</em> operation determines whether the graph has
 *  a cycle and, if so, the <em>cycle</em> operation returns one.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  (The depth-first search part takes only <em>O</em>(<em>V</em>) time;
 *  however, checking for self-loops and parallel edges takes
 *  &Theta;(<em>V</em> + <em>E</em>) time in the worst case.)
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Cycle   {
     private   boolean []  marked ;
     private   int []  edgeTo ;
     private   Stack < Integer >  cycle ;

     /**
     * Determines whether the undirected graph { @code  G} has a cycle and,
     * if so, finds such a cycle.
     *
     *  @param  G the undirected graph
     */
     public   Cycle ( Graph  G )   {
         if   ( hasSelfLoop ( G ))   return ;
         if   ( hasParallelEdges ( G ))   return ;
        marked  =   new   boolean [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( ! marked [ v ])
                dfs ( G ,   - 1 ,  v );
     }


     // does this graph have a self loop?
     // side effect: initialize cycle to be self loop
     private   boolean  hasSelfLoop ( Graph  G )   {
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( ==  w )   {
                    cycle  =   new   Stack < Integer > ();
                    cycle . push ( v );
                    cycle . push ( v );
                     return   true ;
                 }
             }
         }
         return   false ;
     }

     // does this graph have two parallel edges?
     // side effect: initialize cycle to be two parallel edges
     private   boolean  hasParallelEdges ( Graph  G )   {
        marked  =   new   boolean [ G . V ()];

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {

             // check for parallel edges incident to v
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( marked [ w ])   {
                    cycle  =   new   Stack < Integer > ();
                    cycle . push ( v );
                    cycle . push ( w );
                    cycle . push ( v );
                     return   true ;
                 }
                marked [ w ]   =   true ;
             }

             // reset so marked[v] = false for all v
             for   ( int  w  :  G . adj ( v ))   {
                marked [ w ]   =   false ;
             }
         }
         return   false ;
     }

     /**
     * Returns true if the graph { @code  G} has a cycle.
     *
     *  @return  { @code  true} if the graph has a cycle; { @code  false} otherwise
     */
     public   boolean  hasCycle ()   {
         return  cycle  !=   null ;
     }

      /**
     * Returns a cycle in the graph { @code  G}.
     *  @return  a cycle if the graph { @code  G} has a cycle,
     *         and { @code  null} otherwise
     */
     public   Iterable < Integer >  cycle ()   {
         return  cycle ;
     }

     private   void  dfs ( Graph  G ,   int  u ,   int  v )   {
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {

             // short circuit if cycle already found
             if   ( cycle  !=   null )   return ;

             if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  v ;
                dfs ( G ,  v ,  w );
             }

             // check for cycle (but disregard reverse of edge leading to v)
             else   if   ( !=  u )   {
                cycle  =   new   Stack < Integer > ();
                 for   ( int  x  =  v ;  x  !=  w ;  x  =  edgeTo [ x ])   {
                    cycle . push ( x );
                 }
                cycle . push ( w );
                cycle . push ( v );
             }
         }
     }

     /**
     * Unit tests the { @code  Cycle} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         Cycle  finder  =   new   Cycle ( G );
         if   ( finder . hasCycle ())   {
             for   ( int  v  :  finder . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
         else   {
             StdOut . println ( "Graph is acyclic" );
         }
     }


}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Date.java

edu/princeton/cs/algs4/Date.java

/******************************************************************************
 *  Compilation:  javac Date.java
 *  Execution:    java Date
 *  Dependencies: StdOut.java
 *
 *  An immutable data type for dates.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Date} class is an immutable data type to encapsulate a
 *  date (day, month, and year).
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Date   implements   Comparable < Date >   {
     private   static   final   int []  DAYS  =   {   0 ,   31 ,   29 ,   31 ,   30 ,   31 ,   30 ,   31 ,   31 ,   30 ,   31 ,   30 ,   31   };

     private   final   int  month ;     // month (between 1 and 12)
     private   final   int  day ;       // day   (between 1 and DAYS[month]
     private   final   int  year ;      // year

    /**
     * Initializes a new date from the month, day, and year.
     *  @param  month the month (between 1 and 12)
     *  @param  day the day (between 1 and 28-31, depending on the month)
     *  @param  year the year
     *  @throws  IllegalArgumentException if this date is invalid
     */
     public   Date ( int  month ,   int  day ,   int  year )   {
         if   ( ! isValid ( month ,  day ,  year ))   throw   new   IllegalArgumentException ( "Invalid date" );
         this . month  =  month ;
         this . day    =  day ;
         this . year   =  year ;
     }

     /**
     * Initializes new date specified as a string in form MM/DD/YYYY.
     *  @param  date the string representation of this date
     *  @throws  IllegalArgumentException if this date is invalid
     */
     public   Date ( String  date )   {
         String []  fields  =  date . split ( "/" );
         if   ( fields . length  !=   3 )   {
             throw   new   IllegalArgumentException ( "Invalid date" );
         }
        month  =   Integer . parseInt ( fields [ 0 ]);
        day    =   Integer . parseInt ( fields [ 1 ]);
        year   =   Integer . parseInt ( fields [ 2 ]);
         if   ( ! isValid ( month ,  day ,  year ))   throw   new   IllegalArgumentException ( "Invalid date" );
     }

     /**
     * Return the month.
     *  @return  the month (an integer between 1 and 12)
     */
     public   int  month ()   {
         return  month ;
     }

     /**
     * Returns the day.
     *  @return  the day (an integer between 1 and 31)
     */
     public   int  day ()   {
         return  day ;
     }

     /**
     * Returns the year.
     *  @return  the year
     */
     public   int  year ()   {
         return  year ;
     }


     // is the given date valid?
     private   static   boolean  isValid ( int  m ,   int  d ,   int  y )   {
         if   ( <   1   ||  m  >   12 )        return   false ;
         if   ( <   1   ||  d  >  DAYS [ m ])   return   false ;
         if   ( ==   2   &&  d  ==   29   &&   ! isLeapYear ( y ))   return   false ;
         return   true ;
     }

     // is y a leap year?
     private   static   boolean  isLeapYear ( int  y )   {
         if   ( %   400   ==   0 )   return   true ;
         if   ( %   100   ==   0 )   return   false ;
         return  y  %   4   ==   0 ;
     }

     /**
     * Returns the next date in the calendar.
     *
     *  @return  a date that represents the next day after this day
     */
     public   Date  next ()   {
         if   ( isValid ( month ,  day  +   1 ,  year ))      return   new   Date ( month ,  day  +   1 ,  year );
         else   if   ( isValid ( month  +   1 ,   1 ,  year ))   return   new   Date ( month  +   1 ,   1 ,  year );
         else                                    return   new   Date ( 1 ,   1 ,  year  +   1 );
     }

     /**
     * Compares two dates chronologically.
     *
     *  @param   that the other date
     *  @return  { @code  true} if this date is after that date; { @code  false} otherwise
     */
     public   boolean  isAfter ( Date  that )   {
         return  compareTo ( that )   >   0 ;
     }

     /**
     * Compares two dates chronologically.
     *
     *  @param   that the other date
     *  @return  { @code  true} if this date is before that date; { @code  false} otherwise
     */
     public   boolean  isBefore ( Date  that )   {
         return  compareTo ( that )   <   0 ;
     }

     /**
     * Compares two dates chronologically.
     *
     *  @return  the value { @code  0} if the argument date is equal to this date;
     *         a negative integer if this date is chronologically less than
     *         the argument date; and a positive ineger if this date is chronologically
     *         after the argument date
     */
    @ Override
     public   int  compareTo ( Date  that )   {
         if   ( this . year   <  that . year )    return   - 1 ;
         if   ( this . year   >  that . year )    return   + 1 ;
         if   ( this . month  <  that . month )   return   - 1 ;
         if   ( this . month  >  that . month )   return   + 1 ;
         if   ( this . day    <  that . day )     return   - 1 ;
         if   ( this . day    >  that . day )     return   + 1 ;
         return   0 ;
     }

     /**
     * Returns a string representation of this date.
     *
     *  @return  the string representation in the format MM/DD/YYYY
     */
    @ Override
     public   String  toString ()   {
         return  month  +   "/"   +  day  +   "/"   +  year ;
     }

     /**
     * Compares this date to the specified date.
     *
     *  @param   other the other date
     *  @return  { @code  true} if this date equals { @code  other}; { @code  false} otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Date  that  =   ( Date )  other ;
         return   ( this . month  ==  that . month )   &&   ( this . day  ==  that . day )   &&   ( this . year  ==  that . year );
     }

     /**
     * Returns an integer hash code for this date.
     *
     *  @return  an integer hash code for this date
     */
    @ Override
     public   int  hashCode ()   {
         return  day  +   31 * month  +   31 * 12 * year ;
     }

     /**
     * Unit tests the { @code  Date} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Date  today  =   new   Date ( 2 ,   25 ,   2004 );
         StdOut . println ( today );
         for   ( int  i  =   0 ;  i  <   10 ;  i ++ )   {
            today  =  today . next ();
             StdOut . println ( today );
         }

         StdOut . println ( today . isAfter ( today . next ()));
         StdOut . println ( today . isAfter ( today ));
         StdOut . println ( today . next (). isAfter ( today ));


         Date  birthday  =   new   Date ( 10 ,   16 ,   1971 );
         StdOut . println ( birthday );
         for   ( int  i  =   0 ;  i  <   10 ;  i ++ )   {
            birthday  =  birthday . next ();
             StdOut . println ( birthday );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DeDup.java

edu/princeton/cs/algs4/DeDup.java

/******************************************************************************
 *  Compilation:  javac DeDup.java
 *  Execution:    java DeDup < input.txt
 *  Dependencies: SET StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt
 *
 *  Read in a list of words from standard input and print out
 *  each word, removing any duplicates.
 *
 *  % more tinyTale.txt 
 *  it was the best of times it was the worst of times 
 *  it was the age of wisdom it was the age of foolishness 
 *  it was the epoch of belief it was the epoch of incredulity 
 *  it was the season of light it was the season of darkness 
 *  it was the spring of hope it was the winter of despair
 *
 *  % java DeDup < tinyTale.txt 
 *  it
 *  was
 *  the
 *  best
 *  of
 *  times
 *  worst
 *  age
 *  wisdom
 *  ...
 *  winter
 *  despair
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DeDup} class provides a client for reading in a sequence of
 *  words from standard input and printing each word, removing any duplicates.
 *  It is useful as a test client for various symbol table implementations.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DeDup   {   

     // Do not instantiate.
     private   DeDup ()   {   }

     public   static   void  main ( String []  args )   {
        SET < String >  set  =   new  SET < String > ();

         // read in strings and add to set
         while   ( ! StdIn . isEmpty ())   {
             String  key  =   StdIn . readString ();
             if   ( ! set . contains ( key ))   {
                set . add ( key );
                 StdOut . println ( key );
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DegreesOfSeparation.java

edu/princeton/cs/algs4/DegreesOfSeparation.java

/******************************************************************************
 *  Compilation:  javac DegreesOfSeparation.java
 *  Execution:    java DegreesOfSeparation filename delimiter source
 *  Dependencies: SymbolGraph.java Graph.java BreadthFirstPaths.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/routes.txt
 *                https://algs4.cs.princeton.edu/41graph/movies.txt
 *  
 *  
 *  %  java DegreesOfSeparation routes.txt " " "JFK"
 *  LAS
 *     JFK
 *     ORD
 *     DEN
 *     LAS
 *  DFW
 *     JFK
 *     ORD
 *     DFW
 *  EWR
 *     Not in database.
 *
 *  % java DegreesOfSeparation movies.txt "/" "Bacon, Kevin"
 *  Kidman, Nicole
 *     Bacon, Kevin
 *     Woodsman, The (2004)
 *     Grier, David Alan
 *     Bewitched (2005)
 *     Kidman, Nicole
 *  Grant, Cary
 *     Bacon, Kevin
 *     Planes, Trains & Automobiles (1987)
 *     Martin, Steve (I)
 *     Dead Men Don't Wear Plaid (1982)
 *     Grant, Cary
 *
 *  % java DegreesOfSeparation movies.txt "/" "Animal House (1978)"
 *  Titanic (1997)
 *     Animal House (1978)
 *     Allen, Karen (I)
 *     Raiders of the Lost Ark (1981)
 *     Taylor, Rocky (I)
 *     Titanic (1997)
 *  To Catch a Thief (1955)
 *     Animal House (1978)
 *     Vernon, John (I)
 *     Topaz (1969)
 *     Hitchcock, Alfred (I)
 *     To Catch a Thief (1955)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DegreesOfSeparation} class provides a client for finding
 *  the degree of separation between one distinguished individual and
 *  every other individual in a social network.
 *  As an example, if the social network consists of actors in which
 *  two actors are connected by a link if they appeared in the same movie,
 *  and Kevin Bacon is the distinguished individual, then the client
 *  computes the Kevin Bacon number of every actor in the network.
 *  <p>
 *  The running time is proportional to the number of individuals and
 *  connections in the network. If the connections are given implicitly,
 *  as in the movie network example (where every two actors are connected
 *  if they appear in the same movie), the efficiency of the algorithm
 *  is improved by allowing both movie and actor vertices and connecting
 *  each movie to all of the actors that appear in that movie.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DegreesOfSeparation   {

     // this class cannot be instantiated
     private   DegreesOfSeparation ()   {   }

     /**
     *  Reads in a social network from a file, and then repeatedly reads in
     *  individuals from standard input and prints out their degrees of
     *  separation.
     *  Takes three command-line arguments: the name of a file,
     *  a delimiter, and the name of the distinguished individual.
     *  Each line in the file contains the name of a vertex, followed by a
     *  list of the names of the vertices adjacent to that vertex,
     *  separated by the delimiter.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  filename   =  args [ 0 ];
         String  delimiter  =  args [ 1 ];
         String  source     =  args [ 2 ];

         // StdOut.println("Source: " + source);

         SymbolGraph  sg  =   new   SymbolGraph ( filename ,  delimiter );
         Graph  G  =  sg . graph ();
         if   ( ! sg . contains ( source ))   {
             StdOut . println ( source  +   " not in database." );
             return ;
         }

         int  s  =  sg . indexOf ( source );
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( G ,  s );

         while   ( ! StdIn . isEmpty ())   {
             String  sink  =   StdIn . readLine ();
             if   ( sg . contains ( sink ))   {
                 int  t  =  sg . indexOf ( sink );
                 if   ( bfs . hasPathTo ( t ))   {
                     for   ( int  v  :  bfs . pathTo ( t ))   {
                         StdOut . println ( "   "   +  sg . nameOf ( v ));
                     }
                 }
                 else   {
                     StdOut . println ( "Not connected" );
                 }
             }
             else   {
                 StdOut . println ( "   Not in database." );
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DepthFirstDirectedPaths.java

edu/princeton/cs/algs4/DepthFirstDirectedPaths.java

/******************************************************************************
 *  Compilation:  javac DepthFirstDirectedPaths.java
 *  Execution:    java DepthFirstDirectedPaths digraph.txt s
 *  Dependencies: Digraph.java Stack.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Determine reachability in a digraph from a given vertex using
 *  depth-first search.
 *  Runs in O(E + V) time.
 *
 *  % java DepthFirstDirectedPaths tinyDG.txt 3
 *  3 to 0:  3-5-4-2-0
 *  3 to 1:  3-5-4-2-0-1
 *  3 to 2:  3-5-4-2
 *  3 to 3:  3
 *  3 to 4:  3-5-4
 *  3 to 5:  3-5
 *  3 to 6:  not connected
 *  3 to 7:  not connected
 *  3 to 8:  not connected
 *  3 to 9:  not connected
 *  3 to 10:  not connected
 *  3 to 11:  not connected
 *  3 to 12:  not connected
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DepthFirstDirectedPaths} class represents a data type for
 *  finding directed paths from a source vertex <em>s</em> to every
 *  other vertex in the digraph.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  See { @link  DepthFirstDirectedPaths} for a nonrecursive implementation.
 *  For additional documentation,  
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of  
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DepthFirstDirectedPaths   {
     private   boolean []  marked ;    // marked[v] = true iff v is reachable from s
     private   int []  edgeTo ;        // edgeTo[v] = last edge on path from s to v
     private   final   int  s ;         // source vertex

     /**
     * Computes a directed path from { @code  s} to every other vertex in digraph { @code  G}.
     *  @param   G the digraph
     *  @param   s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DepthFirstDirectedPaths ( Digraph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        edgeTo  =   new   int [ G . V ()];
         this . =  s ;
        validateVertex ( s );
        dfs ( G ,  s );
     }

     private   void  dfs ( Digraph  G ,   int  v )   {  
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  v ;
                dfs ( G ,  w );
             }
         }
     }

     /**
     * Is there a directed path from the source vertex { @code  s} to vertex { @code  v}?
     *  @param   v the vertex
     *  @return  { @code  true} if there is a directed path from the source
     *         vertex { @code  s} to vertex { @code  v}, { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

    
     /**
     * Returns a directed path from the source vertex { @code  s} to vertex { @code  v}, or
     * { @code  null} if no such path.
     *  @param   v the vertex
     *  @return  the sequence of vertices on a directed path from the source vertex
     *         { @code  s} to vertex { @code  v}, as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < Integer >  path  =   new   Stack < Integer > ();
         for   ( int  x  =  v ;  x  !=  s ;  x  =  edgeTo [ x ])
            path . push ( x );
        path . push ( s );
         return  path ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DepthFirstDirectedPaths} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         // StdOut.println(G);

         int  s  =   Integer . parseInt ( args [ 1 ]);
         DepthFirstDirectedPaths  dfs  =   new   DepthFirstDirectedPaths ( G ,  s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( dfs . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d:  " ,  s ,  v );
                 for   ( int  x  :  dfs . pathTo ( v ))   {
                     if   ( ==  s )   StdOut . print ( x );
                     else          StdOut . print ( "-"   +  x );
                 }
                 StdOut . println ();
             }

             else   {
                 StdOut . printf ( "%d to %d:  not connected\n" ,  s ,  v );
             }

         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DepthFirstOrder.java

edu/princeton/cs/algs4/DepthFirstOrder.java

/******************************************************************************
 *  Compilation:  javac DepthFirstOrder.java
 *  Execution:    java DepthFirstOrder digraph.txt
 *  Dependencies: Digraph.java Queue.java Stack.java StdOut.java
 *                EdgeWeightedDigraph.java DirectedEdge.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt
 *                https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *
 *  Compute preorder and postorder for a digraph or edge-weighted digraph.
 *  Runs in O(E + V) time.
 *
 *  % java DepthFirstOrder tinyDAG.txt
 *     v  pre post
 *  --------------
 *     0    0    8
 *     1    3    2
 *     2    9   10
 *     3   10    9
 *     4    2    0
 *     5    1    1
 *     6    4    7
 *     7   11   11
 *     8   12   12
 *     9    5    6
 *    10    8    5
 *    11    6    4
 *    12    7    3
 *  Preorder:  0 5 4 1 6 9 11 12 10 2 3 7 8 
 *  Postorder: 4 5 1 12 11 10 9 6 0 3 2 7 8 
 *  Reverse postorder: 8 7 2 3 0 6 9 10 11 12 1 5 4 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DepthFirstOrder} class represents a data type for 
 *  determining depth-first search ordering of the vertices in a digraph
 *  or edge-weighted digraph, including preorder, postorder, and reverse postorder.
 *  <p>
 *  This implementation uses depth-first search.
 *  Each constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DepthFirstOrder   {
     private   boolean []  marked ;            // marked[v] = has v been marked in dfs?
     private   int []  pre ;                   // pre[v]    = preorder  number of v
     private   int []  post ;                  // post[v]   = postorder number of v
     private   Queue < Integer >  preorder ;     // vertices in preorder
     private   Queue < Integer >  postorder ;    // vertices in postorder
     private   int  preCounter ;              // counter or preorder numbering
     private   int  postCounter ;             // counter for postorder numbering

     /**
     * Determines a depth-first order for the digraph { @code  G}.
     *  @param  G the digraph
     */
     public   DepthFirstOrder ( Digraph  G )   {
        pre     =   new   int [ G . V ()];
        post    =   new   int [ G . V ()];
        postorder  =   new   Queue < Integer > ();
        preorder   =   new   Queue < Integer > ();
        marked     =   new   boolean [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( ! marked [ v ])  dfs ( G ,  v );

         assert  check ();
     }

     /**
     * Determines a depth-first order for the edge-weighted digraph { @code  G}.
     *  @param  G the edge-weighted digraph
     */
     public   DepthFirstOrder ( EdgeWeightedDigraph  G )   {
        pre     =   new   int [ G . V ()];
        post    =   new   int [ G . V ()];
        postorder  =   new   Queue < Integer > ();
        preorder   =   new   Queue < Integer > ();
        marked     =   new   boolean [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( ! marked [ v ])  dfs ( G ,  v );
     }

     // run DFS in digraph G from vertex v and compute preorder/postorder
     private   void  dfs ( Digraph  G ,   int  v )   {
        marked [ v ]   =   true ;
        pre [ v ]   =  preCounter ++ ;
        preorder . enqueue ( v );
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])   {
                dfs ( G ,  w );
             }
         }
        postorder . enqueue ( v );
        post [ v ]   =  postCounter ++ ;
     }

     // run DFS in edge-weighted digraph G from vertex v and compute preorder/postorder
     private   void  dfs ( EdgeWeightedDigraph  G ,   int  v )   {
        marked [ v ]   =   true ;
        pre [ v ]   =  preCounter ++ ;
        preorder . enqueue ( v );
         for   ( DirectedEdge  e  :  G . adj ( v ))   {
             int  w  =  e . to ();
             if   ( ! marked [ w ])   {
                dfs ( G ,  w );
             }
         }
        postorder . enqueue ( v );
        post [ v ]   =  postCounter ++ ;
     }

     /**
     * Returns the preorder number of vertex { @code  v}.
     *  @param   v the vertex
     *  @return  the preorder number of vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  pre ( int  v )   {
        validateVertex ( v );
         return  pre [ v ];
     }

     /**
     * Returns the postorder number of vertex { @code  v}.
     *  @param   v the vertex
     *  @return  the postorder number of vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  post ( int  v )   {
        validateVertex ( v );
         return  post [ v ];
     }

     /**
     * Returns the vertices in postorder.
     *  @return  the vertices in postorder, as an iterable of vertices
     */
     public   Iterable < Integer >  post ()   {
         return  postorder ;
     }

     /**
     * Returns the vertices in preorder.
     *  @return  the vertices in preorder, as an iterable of vertices
     */
     public   Iterable < Integer >  pre ()   {
         return  preorder ;
     }

     /**
     * Returns the vertices in reverse postorder.
     *  @return  the vertices in reverse postorder, as an iterable of vertices
     */
     public   Iterable < Integer >  reversePost ()   {
         Stack < Integer >  reverse  =   new   Stack < Integer > ();
         for   ( int  v  :  postorder )
            reverse . push ( v );
         return  reverse ;
     }


     // check that pre() and post() are consistent with pre(v) and post(v)
     private   boolean  check ()   {

         // check that post(v) is consistent with post()
         int  r  =   0 ;
         for   ( int  v  :  post ())   {
             if   ( post ( v )   !=  r )   {
                 StdOut . println ( "post(v) and post() inconsistent" );
                 return   false ;
             }
            r ++ ;
         }

         // check that pre(v) is consistent with pre()
        r  =   0 ;
         for   ( int  v  :  pre ())   {
             if   ( pre ( v )   !=  r )   {
                 StdOut . println ( "pre(v) and pre() inconsistent" );
                 return   false ;
             }
            r ++ ;
         }

         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DepthFirstOrder} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );

         DepthFirstOrder  dfs  =   new   DepthFirstOrder ( G );
         StdOut . println ( "   v  pre post" );
         StdOut . println ( "--------------" );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%4d %4d %4d\n" ,  v ,  dfs . pre ( v ),  dfs . post ( v ));
         }

         StdOut . print ( "Preorder:  " );
         for   ( int  v  :  dfs . pre ())   {
             StdOut . print ( +   " " );
         }
         StdOut . println ();

         StdOut . print ( "Postorder: " );
         for   ( int  v  :  dfs . post ())   {
             StdOut . print ( +   " " );
         }
         StdOut . println ();

         StdOut . print ( "Reverse postorder: " );
         for   ( int  v  :  dfs . reversePost ())   {
             StdOut . print ( +   " " );
         }
         StdOut . println ();


     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DepthFirstPaths.java

edu/princeton/cs/algs4/DepthFirstPaths.java

/******************************************************************************
 *  Compilation:  javac DepthFirstPaths.java
 *  Execution:    java DepthFirstPaths G s
 *  Dependencies: Graph.java Stack.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt
 *                https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt
 *
 *  Run depth-first search on an undirected graph.
 *
 *  %  java Graph tinyCG.txt
 *  6 8
 *  0: 2 1 5 
 *  1: 0 2 
 *  2: 0 1 3 4 
 *  3: 5 4 2 
 *  4: 3 2 
 *  5: 3 0 
 *
 *  % java DepthFirstPaths tinyCG.txt 0
 *  0 to 0:  0
 *  0 to 1:  0-2-1
 *  0 to 2:  0-2
 *  0 to 3:  0-2-3
 *  0 to 4:  0-2-3-4
 *  0 to 5:  0-2-3-5
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DepthFirstPaths} class represents a data type for finding
 *  paths from a source vertex <em>s</em> to every other vertex
 *  in an undirected graph.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DepthFirstPaths   {
     private   boolean []  marked ;      // marked[v] = is there an s-v path?
     private   int []  edgeTo ;          // edgeTo[v] = last edge on s-v path
     private   final   int  s ;           // source vertex

     /**
     * Computes a path between { @code  s} and every other vertex in graph { @code  G}.
     *  @param  G the graph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DepthFirstPaths ( Graph  G ,   int  s )   {
         this . =  s ;
        edgeTo  =   new   int [ G . V ()];
        marked  =   new   boolean [ G . V ()];
        validateVertex ( s );
        dfs ( G ,  s );
     }

     // depth first search from v
     private   void  dfs ( Graph  G ,   int  v )   {
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  v ;
                dfs ( G ,  w );
             }
         }
     }

     /**
     * Is there a path between the source vertex { @code  s} and vertex { @code  v}?
     *  @param  v the vertex
     *  @return  { @code  true} if there is a path, { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     /**
     * Returns a path between the source vertex { @code  s} and vertex { @code  v}, or
     * { @code  null} if no such path.
     *  @param   v the vertex
     *  @return  the sequence of vertices on a path between the source vertex
     *         { @code  s} and vertex { @code  v}, as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < Integer >  path  =   new   Stack < Integer > ();
         for   ( int  x  =  v ;  x  !=  s ;  x  =  edgeTo [ x ])
            path . push ( x );
        path . push ( s );
         return  path ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DepthFirstPaths} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);
         DepthFirstPaths  dfs  =   new   DepthFirstPaths ( G ,  s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( dfs . hasPathTo ( v ))   {
                 StdOut . printf ( "%d to %d:  " ,  s ,  v );
                 for   ( int  x  :  dfs . pathTo ( v ))   {
                     if   ( ==  s )   StdOut . print ( x );
                     else          StdOut . print ( "-"   +  x );
                 }
                 StdOut . println ();
             }

             else   {
                 StdOut . printf ( "%d to %d:  not connected\n" ,  s ,  v );
             }

         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DepthFirstSearch.java

edu/princeton/cs/algs4/DepthFirstSearch.java

/******************************************************************************
 *  Compilation:  javac DepthFirstSearch.java
 *  Execution:    java DepthFirstSearch filename.txt s
 *  Dependencies: Graph.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *
 *  Run depth first search on an undirected graph.
 *  Runs in O(E + V) time.
 *
 *  % java DepthFirstSearch tinyG.txt 0
 *  0 1 2 3 4 5 6 
 *  NOT connected
 *
 *  % java DepthFirstSearch tinyG.txt 9
 *  9 10 11 12 
 *  NOT connected
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DepthFirstSearch} class represents a data type for 
 *  determining the vertices connected to a given source vertex <em>s</em>
 *  in an undirected graph. For versions that find the paths, see
 *  { @link  DepthFirstPaths} and { @link  BreadthFirstPaths}.
 *  <p>
 *  This implementation uses depth-first search.
 *  See { @link  NonrecursiveDFS} for a non-recursive version.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the worst
 *  case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph). 
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DepthFirstSearch   {
     private   boolean []  marked ;      // marked[v] = is there an s-v path?
     private   int  count ;             // number of vertices connected to s

     /**
     * Computes the vertices in graph { @code  G} that are
     * connected to the source vertex { @code  s}.
     *  @param  G the graph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DepthFirstSearch ( Graph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        validateVertex ( s );
        dfs ( G ,  s );
     }

     // depth first search from v
     private   void  dfs ( Graph  G ,   int  v )   {
        count ++ ;
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])   {
                dfs ( G ,  w );
             }
         }
     }

     /**
     * Is there a path between the source vertex { @code  s} and vertex { @code  v}?
     *  @param  v the vertex
     *  @return  { @code  true} if there is a path, { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  marked ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     /**
     * Returns the number of vertices connected to the source vertex { @code  s}.
     *  @return  the number of vertices connected to the source vertex { @code  s}
     */
     public   int  count ()   {
         return  count ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DepthFirstSearch} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);
         DepthFirstSearch  search  =   new   DepthFirstSearch ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( search . marked ( v ))
                 StdOut . print ( +   " " );
         }

         StdOut . println ();
         if   ( search . count ()   !=  G . V ())   StdOut . println ( "NOT connected" );
         else                           StdOut . println ( "connected" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DigraphGenerator.java

edu/princeton/cs/algs4/DigraphGenerator.java

/******************************************************************************
 *  Compilation:  javac DigraphGenerator.java
 *  Execution:    java DigraphGenerator V E
 *  Dependencies: Digraph.java
 *
 *  A digraph generator.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DigraphGenerator} class provides static methods for creating
 *  various digraphs, including Erdos-Renyi random digraphs, random DAGs,
 *  random rooted trees, random rooted DAGs, random tournaments, path digraphs,
 *  cycle digraphs, and the complete digraph.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DigraphGenerator   {
     private   static   final   class   Edge   implements   Comparable < Edge >   {
         private   final   int  v ;
         private   final   int  w ;

         private   Edge ( int  v ,   int  w )   {
             this . =  v ;
             this . =  w ;
         }

         public   int  compareTo ( Edge  that )   {
             if   ( this . <  that . v )   return   - 1 ;
             if   ( this . >  that . v )   return   + 1 ;
             if   ( this . <  that . w )   return   - 1 ;
             if   ( this . >  that . w )   return   + 1 ;
             return   0 ;
         }
     }

     // this class cannot be instantiated
     private   DigraphGenerator ()   {   }

     /**
     * Returns a random simple digraph containing { @code  V} vertices and { @code  E} edges.
     *  @param  V the number of vertices
     *  @param  E the number of vertices
     *  @return  a random simple digraph on { @code  V} vertices, containing a total
     *     of { @code  E} edges
     *  @throws  IllegalArgumentException if no such simple digraph exists
     */
     public   static   Digraph  simple ( int  V ,   int  E )   {
         if   ( >   ( long )  V * ( V - 1 ))   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <   0 )                throw   new   IllegalArgumentException ( "Too few edges" );
         Digraph  G  =   new   Digraph ( V );
        SET < Edge >  set  =   new  SET < Edge > ();
         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( v ,  w );
             if   (( !=  w )   &&   ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( v ,  w );
             }
         }
         return  G ;
     }

    /**
     * Returns a random simple digraph on { @code  V} vertices, with an 
     * edge between any two vertices with probability { @code  p}. This is sometimes
     * referred to as the Erdos-Renyi random digraph model.
     * This implementations takes time propotional to V^2 (even if { @code  p} is small).
     *  @param  V the number of vertices
     *  @param  p the probability of choosing an edge
     *  @return  a random simple digraph on { @code  V} vertices, with an edge between
     *     any two vertices with probability { @code  p}
     *  @throws  IllegalArgumentException if probability is not between 0 and 1
     */
     public   static   Digraph  simple ( int  V ,   double  p )   {
         if   ( <   0.0   ||  p  >   1.0 )
             throw   new   IllegalArgumentException ( "Probability must be between 0 and 1" );
         Digraph  G  =   new   Digraph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( int  w  =   0 ;  w  <  V ;  w ++ )
                 if   ( !=  w )
                     if   ( StdRandom . bernoulli ( p ))
                        G . addEdge ( v ,  w );
         return  G ;
     }

     /**
     * Returns the complete digraph on { @code  V} vertices.
     * In a complete digraph, every pair of distinct vertices is connected
     * by two antiparallel edges. There are { @code  V*(V-1)} edges.
     *  @param  V the number of vertices
     *  @return  the complete digraph on { @code  V} vertices
     */
     public   static   Digraph  complete ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( int  w  =   0 ;  w  <  V ;  w ++ )
                     if   ( !=  w )  G . addEdge ( v ,  w );
         return  G ;
     }

     /**
     * Returns a random simple DAG containing { @code  V} vertices and { @code  E} edges.
     * Note: it is not uniformly selected at random among all such DAGs.
     *  @param  V the number of vertices
     *  @param  E the number of vertices
     *  @return  a random simple DAG on { @code  V} vertices, containing a total
     *     of { @code  E} edges
     *  @throws  IllegalArgumentException if no such simple DAG exists
     */
     public   static   Digraph  dag ( int  V ,   int  E )   {
         if   ( >   ( long )  V * ( V - 1 )   /   2 )   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <   0 )                    throw   new   IllegalArgumentException ( "Too few edges" );
         Digraph  G  =   new   Digraph ( V );
        SET < Edge >  set  =   new  SET < Edge > ();
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( v ,  w );
             if   (( <  w )   &&   ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( vertices [ v ],  vertices [ w ]);
             }
         }
         return  G ;
     }

     /**
     * Returns a random tournament digraph on { @code  V} vertices. A tournament digraph
     * is a digraph in which, for every pair of vertices, there is one and only one
     * directed edge connecting them. A tournament is an oriented complete graph.
     *  @param  V the number of vertices
     *  @return  a random tournament digraph on { @code  V} vertices
     */
     public   static   Digraph  tournament ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  =  v + 1 ;  w  <  G . V ();  w ++ )   {
                 if   ( StdRandom . bernoulli ( 0.5 ))  G . addEdge ( v ,  w );
                 else                           G . addEdge ( w ,  v );
             }
         }
         return  G ;
     }

     /**
     * Returns a complete rooted-in DAG on { @code  V} vertices.
     * A rooted in-tree is a DAG in which there is a single vertex
     * reachable from every other vertex. A complete rooted in-DAG
     * has V*(V-1)/2 edges.
     *  @param  V the number of vertices
     *  @return  a complete rooted-in DAG on { @code  V} vertices
     */
     public   static   Digraph  completeRootedInDAG ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
             for   ( int  j  =  i + 1 ;  j  <  V ;  j ++ )
                 G . addEdge ( vertices [ i ],  vertices [ j ]);

         return  G ;
     }

     /**
     * Returns a random rooted-in DAG on { @code  V} vertices and { @code  E} edges.
     * A rooted in-tree is a DAG in which there is a single vertex
     * reachable from every other vertex.
     * The DAG returned is not chosen uniformly at random among all such DAGs.
     *  @param  V the number of vertices
     *  @param  E the number of edges
     *  @return  a random rooted-in DAG on { @code  V} vertices and { @code  E} edges
     */
     public   static   Digraph  rootedInDAG ( int  V ,   int  E )   {
         if   ( >   ( long )  V * ( V - 1 )   /   2 )   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <  V - 1 )                  throw   new   IllegalArgumentException ( "Too few edges" );
         Digraph  G  =   new   Digraph ( V );
        SET < Edge >  set  =   new  SET < Edge > ();

         // fix a topological order
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );

         // one edge pointing from each vertex, other than the root = vertices[V-1]
         for   ( int  v  =   0 ;  v  <  V - 1 ;  v ++ )   {
             int  w  =   StdRandom . uniform ( v + 1 ,  V );
             Edge  e  =   new   Edge ( v ,  w );
            set . add ( e );
            G . addEdge ( vertices [ v ],  vertices [ w ]);
         }

         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( v ,  w );
             if   (( <  w )   &&   ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( vertices [ v ],  vertices [ w ]);
             }
         }
         return  G ;
     }

     /**
     * Returns a complete rooted-out DAG on { @code  V} vertices.
     * A rooted out-tree is a DAG in which every vertex is reachable
     * from a single vertex. A complete rooted in-DAG has V*(V-1)/2 edges.
     *  @param  V the number of vertices
     *  @return  a complete rooted-out DAG on { @code  V} vertices
     */
     public   static   Digraph  completeRootedOutDAG ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
             for   ( int  j  =  i + 1 ;  j  <  V ;  j ++ )
                 G . addEdge ( vertices [ j ],  vertices [ i ]);

         return  G ;
     }

     /**
     * Returns a random rooted-out DAG on { @code  V} vertices and { @code  E} edges.
     * A rooted out-tree is a DAG in which every vertex is reachable from a
     * single vertex.
     * The DAG returned is not chosen uniformly at random among all such DAGs.
     *  @param  V the number of vertices
     *  @param  E the number of edges
     *  @return  a random rooted-out DAG on { @code  V} vertices and { @code  E} edges
     */
     public   static   Digraph  rootedOutDAG ( int  V ,   int  E )   {
         if   ( >   ( long )  V * ( V - 1 )   /   2 )   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <  V - 1 )                  throw   new   IllegalArgumentException ( "Too few edges" );
         Digraph  G  =   new   Digraph ( V );
        SET < Edge >  set  =   new  SET < Edge > ();

         // fix a topological order
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );

         // one edge pointing from each vertex, other than the root = vertices[V-1]
         for   ( int  v  =   0 ;  v  <  V - 1 ;  v ++ )   {
             int  w  =   StdRandom . uniform ( v + 1 ,  V );
             Edge  e  =   new   Edge ( w ,  v );
            set . add ( e );
            G . addEdge ( vertices [ w ],  vertices [ v ]);
         }

         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( w ,  v );
             if   (( <  w )   &&   ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( vertices [ w ],  vertices [ v ]);
             }
         }
         return  G ;
     }

     /**
     * Returns a random rooted-in tree on { @code  V} vertices.
     * A rooted in-tree is an oriented tree in which there is a single vertex
     * reachable from every other vertex.
     * The tree returned is not chosen uniformly at random among all such trees.
     *  @param  V the number of vertices
     *  @return  a random rooted-in tree on { @code  V} vertices
     */
     public   static   Digraph  rootedInTree ( int  V )   {
         return  rootedInDAG ( V ,  V - 1 );
     }

     /**
     * Returns a random rooted-out tree on { @code  V} vertices. A rooted out-tree
     * is an oriented tree in which each vertex is reachable from a single vertex.
     * It is also known as a <em>arborescence</em> or <em>branching</em>.
     * The tree returned is not chosen uniformly at random among all such trees.
     *  @param  V the number of vertices
     *  @return  a random rooted-out tree on { @code  V} vertices
     */
     public   static   Digraph  rootedOutTree ( int  V )   {
         return  rootedOutDAG ( V ,  V - 1 );
     }

     /**
     * Returns a path digraph on { @code  V} vertices.
     *  @param  V the number of vertices in the path
     *  @return  a digraph that is a directed path on { @code  V} vertices
     */
     public   static   Digraph  path ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
         return  G ;
     }

     /**
     * Returns a complete binary tree digraph on { @code  V} vertices.
     *  @param  V the number of vertices in the binary tree
     *  @return  a digraph that is a complete binary tree on { @code  V} vertices
     */
     public   static   Digraph  binaryTree ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [( i - 1 ) / 2 ]);
         }
         return  G ;
     }

     /**
     * Returns a cycle digraph on { @code  V} vertices.
     *  @param  V the number of vertices in the cycle
     *  @return  a digraph that is a directed cycle on { @code  V} vertices
     */
     public   static   Digraph  cycle ( int  V )   {
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
        G . addEdge ( vertices [ V - 1 ],  vertices [ 0 ]);
         return  G ;
     }

     /**
     * Returns an Eulerian cycle digraph on { @code  V} vertices.
     *
     *  @param   V the number of vertices in the cycle
     *  @param   E the number of edges in the cycle
     *  @return  a digraph that is a directed Eulerian cycle on { @code  V} vertices
     *         and { @code  E} edges
     *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E <= 0}
     */
     public   static   Digraph  eulerianCycle ( int  V ,   int  E )   {
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one edge" );
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one vertex" );
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ E ];
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )
            vertices [ i ]   =   StdRandom . uniform ( V );
         for   ( int  i  =   0 ;  i  <  E - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
        G . addEdge ( vertices [ E - 1 ],  vertices [ 0 ]);
         return  G ;
     }

     /**
     * Returns an Eulerian path digraph on { @code  V} vertices.
     *
     *  @param   V the number of vertices in the path
     *  @param   E the number of edges in the path
     *  @return  a digraph that is a directed Eulerian path on { @code  V} vertices
     *         and { @code  E} edges
     *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E < 0}
     */
     public   static   Digraph  eulerianPath ( int  V ,   int  E )   {
         if   ( <   0 )
             throw   new   IllegalArgumentException ( "negative number of edges" );
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian path must have at least one vertex" );
         Digraph  G  =   new   Digraph ( V );
         int []  vertices  =   new   int [ E + 1 ];
         for   ( int  i  =   0 ;  i  <  E + 1 ;  i ++ )
            vertices [ i ]   =   StdRandom . uniform ( V );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
         return  G ;
     }

    /**
     * Returns a random simple digraph on { @code  V} vertices, { @code  E}
     * edges and (at least) { @code  c} strong components. The vertices are randomly
     * assigned integer labels between { @code  0} and { @code  c-1} (corresponding to 
     * strong components). Then, a strong component is creates among the vertices
     * with the same label. Next, random edges (either between two vertices with
     * the same labels or from a vetex with a smaller label to a vertex with a 
     * larger label). The number of components will be equal to the number of
     * distinct labels that are assigned to vertices.
     *
     *  @param  V the number of vertices
     *  @param  E the number of edges
     *  @param  c the (maximum) number of strong components
     *  @return  a random simple digraph on { @code  V} vertices and
               { @code  E} edges, with (at most) { @code  c} strong components
     *  @throws  IllegalArgumentException if { @code  c} is larger than { @code  V}
     */
     public   static   Digraph  strong ( int  V ,   int  E ,   int  c )   {
         if   ( >=  V  ||  c  <=   0 )
             throw   new   IllegalArgumentException ( "Number of components must be between 1 and V" );
         if   ( <=   2 * ( V - c ))
             throw   new   IllegalArgumentException ( "Number of edges must be at least 2(V-c)" );
         if   ( >   ( long )  V * ( V - 1 )   /   2 )
             throw   new   IllegalArgumentException ( "Too many edges" );

         // the digraph
         Digraph  G  =   new   Digraph ( V );

         // edges added to G (to avoid duplicate edges)
        SET < Edge >  set  =   new  SET < Edge > ();

         int []  label  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            label [ v ]   =   StdRandom . uniform ( c );

         // make all vertices with label c a strong component by
         // combining a rooted in-tree and a rooted out-tree
         for   ( int  i  =   0 ;  i  <  c ;  i ++ )   {
             // how many vertices in component c
             int  count  =   0 ;
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 if   ( label [ v ]   ==  i )  count ++ ;
             }

             // if (count == 0) System.err.println("less than desired number of strong components");

             int []  vertices  =   new   int [ count ];
             int  j  =   0 ;
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                 if   ( label [ v ]   ==  i )  vertices [ j ++ ]   =  v ;
             }
             StdRandom . shuffle ( vertices );

             // rooted-in tree with root = vertices[count-1]
             for   ( int  v  =   0 ;  v  <  count - 1 ;  v ++ )   {
                 int  w  =   StdRandom . uniform ( v + 1 ,  count );
                 Edge  e  =   new   Edge ( w ,  v );
                set . add ( e );
                G . addEdge ( vertices [ w ],  vertices [ v ]);
             }

             // rooted-out tree with root = vertices[count-1]
             for   ( int  v  =   0 ;  v  <  count - 1 ;  v ++ )   {
                 int  w  =   StdRandom . uniform ( v + 1 ,  count );
                 Edge  e  =   new   Edge ( v ,  w );
                set . add ( e );
                G . addEdge ( vertices [ v ],  vertices [ w ]);
             }
         }

         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( v ,  w );
             if   ( ! set . contains ( e )   &&  v  !=  w  &&  label [ v ]   <=  label [ w ])   {
                set . add ( e );
                G . addEdge ( v ,  w );
             }
         }

         return  G ;
     }

     /**
     * Unit tests the { @code  DigraphGenerator} library.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         StdOut . println ( "complete graph" );
         StdOut . println ( complete ( V ));
         StdOut . println ();

         StdOut . println ( "simple" );
         StdOut . println ( simple ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "path" );
         StdOut . println ( path ( V ));
         StdOut . println ();

         StdOut . println ( "cycle" );
         StdOut . println ( cycle ( V ));
         StdOut . println ();

         StdOut . println ( "Eulierian path" );
         StdOut . println ( eulerianPath ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "Eulierian cycle" );
         StdOut . println ( eulerianCycle ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "binary tree" );
         StdOut . println ( binaryTree ( V ));
         StdOut . println ();

         StdOut . println ( "tournament" );
         StdOut . println ( tournament ( V ));
         StdOut . println ();

         StdOut . println ( "DAG" );
         StdOut . println ( dag ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "rooted-in DAG" );
         StdOut . println ( rootedInDAG ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "rooted-out DAG" );
         StdOut . println ( rootedOutDAG ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "rooted-in tree" );
         StdOut . println ( rootedInTree ( V ));
         StdOut . println ();

         StdOut . println ( "rooted-out DAG" );
         StdOut . println ( rootedOutTree ( V ));
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Digraph.java

edu/princeton/cs/algs4/Digraph.java

/******************************************************************************
 *  Compilation:  javac Digraph.java
 *  Execution:    java Digraph filename.txt
 *  Dependencies: Bag.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt  
 *
 *  A graph, implemented using an array of lists.
 *  Parallel edges and self-loops are permitted.
 *
 *  % java Digraph tinyDG.txt
 *  13 vertices, 22 edges
 *  0: 5 1 
 *  1: 
 *  2: 0 3 
 *  3: 5 2 
 *  4: 3 2 
 *  5: 4 
 *  6: 9 4 8 0 
 *  7: 6 9
 *  8: 6 
 *  9: 11 10 
 *  10: 12 
 *  11: 4 12 
 *  12: 9 
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  Digraph} class represents a directed graph of vertices
 *  named 0 through <em>V</em> - 1.
 *  It supports the following two primary operations: add an edge to the digraph,
 *  iterate over all of the vertices adjacent from a given vertex.
 *  It also provides
 *  methods for returning the indegree or outdegree of a vertex, 
 *  the number of vertices <em>V</em> in the digraph, 
 *  the number of edges <em>E</em> in the digraph, and the reverse digraph.
 *  Parallel edges and self-loops are permitted.
 *  <p>
 *  This implementation uses an <em>adjacency-lists representation</em>, which
 *  is a vertex-indexed array of { @link  Bag} objects.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) space, where <em>E</em> is
 *  the number of edges and <em>V</em> is the number of vertices.
 *  All instance methods take &Theta;(1) time. (Though, iterating over
 *  the vertices returned by { @link  #adj(int)} takes time proportional
 *  to the outdegree of the vertex.)
 *  Constructing an empty digraph with <em>V</em> vertices takes
 *  &Theta;(<em>V</em>) time; constructing a digraph with <em>E</em> edges
 *  and <em>V</em> vertices takes &Theta;(<em>E</em> + <em>V</em>) time.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   Digraph   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;             // number of vertices in this digraph
     private   int  E ;                   // number of edges in this digraph
     private   Bag < Integer > []  adj ;      // adj[v] = adjacency list for vertex v
     private   int []  indegree ;          // indegree[v] = indegree of vertex v
    
     /**
     * Initializes an empty digraph with <em>V</em> vertices.
     *
     *  @param   V the number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   Digraph ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );
         this . =  V ;
         this . =   0 ;
        indegree  =   new   int [ V ];
        adj  =   ( Bag < Integer > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            adj [ v ]   =   new   Bag < Integer > ();
         }
     }

     /**  
     * Initializes a digraph from the specified input stream.
     * The format is the number of vertices <em>V</em>,
     * followed by the number of edges <em>E</em>,
     * followed by <em>E</em> pairs of vertices, with each entry separated by whitespace.
     *
     *  @param   in the input stream
     *  @throws  IllegalArgumentException if { @code  in} is { @code  null}
     *  @throws  IllegalArgumentException if the endpoints of any edge are not in prescribed range
     *  @throws  IllegalArgumentException if the number of vertices or edges is negative
     *  @throws  IllegalArgumentException if the input stream is in the wrong format
     */
     public   Digraph ( In  in )   {
         if   ( in  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );
         try   {
             this . =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Digraph must be nonnegative" );
            indegree  =   new   int [ V ];
            adj  =   ( Bag < Integer > [])   new   Bag [ V ];
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                adj [ v ]   =   new   Bag < Integer > ();
             }
             int  E  =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "number of edges in a Digraph must be nonnegative" );
             for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
                 int  v  =  in . readInt ();
                 int  w  =  in . readInt ();
                addEdge ( v ,  w );  
             }
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   IllegalArgumentException ( "invalid input format in Digraph constructor" ,  e );
         }
     }

     /**
     * Initializes a new digraph that is a deep copy of the specified digraph.
     *
     *  @param   G the digraph to copy
     *  @throws  IllegalArgumentException if { @code  G} is { @code  null}
     */
     public   Digraph ( Digraph  G )   {
         if   ( ==   null )   throw   new   IllegalArgumentException ( "argument is null" );

         this . =  G . V ();
         this . =  G . E ();
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );

         // update indegrees
        indegree  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             this . indegree [ v ]   =  G . indegree ( v );

         // update adjacency lists
        adj  =   ( Bag < Integer > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            adj [ v ]   =   new   Bag < Integer > ();
         }

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             // reverse so that adjacency list is in same order as original
             Stack < Integer >  reverse  =   new   Stack < Integer > ();
             for   ( int  w  :  G . adj [ v ])   {
                reverse . push ( w );
             }
             for   ( int  w  :  reverse )   {
                adj [ v ]. add ( w );
             }
         }
     }
        
     /**
     * Returns the number of vertices in this digraph.
     *
     *  @return  the number of vertices in this digraph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in this digraph.
     *
     *  @return  the number of edges in this digraph
     */
     public   int  E ()   {
         return  E ;
     }


     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Adds the directed edge v→w to this digraph.
     *
     *  @param   v the tail vertex
     *  @param   w the head vertex
     *  @throws  IllegalArgumentException unless both { @code  0 <= v < V} and { @code  0 <= w < V}
     */
     public   void  addEdge ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
        adj [ v ]. add ( w );
        indegree [ w ] ++ ;
        E ++ ;
     }

     /**
     * Returns the vertices adjacent from vertex { @code  v} in this digraph.
     *
     *  @param   v the vertex
     *  @return  the vertices adjacent from vertex { @code  v} in this digraph, as an iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  adj ( int  v )   {
        validateVertex ( v );
         return  adj [ v ];
     }

     /**
     * Returns the number of directed edges incident from vertex { @code  v}.
     * This is known as the <em>outdegree</em> of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the outdegree of vertex { @code  v}               
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  outdegree ( int  v )   {
        validateVertex ( v );
         return  adj [ v ]. size ();
     }

     /**
     * Returns the number of directed edges incident to vertex { @code  v}.
     * This is known as the <em>indegree</em> of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the indegree of vertex { @code  v}               
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  indegree ( int  v )   {
        validateVertex ( v );
         return  indegree [ v ];
     }

     /**
     * Returns the reverse of the digraph.
     *
     *  @return  the reverse of the digraph
     */
     public   Digraph  reverse ()   {
         Digraph  reverse  =   new   Digraph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             for   ( int  w  :  adj ( v ))   {
                reverse . addEdge ( w ,  v );
             }
         }
         return  reverse ;
     }

     /**
     * Returns a string representation of the graph.
     *
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,  
     *         followed by the <em>V</em> adjacency lists
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " vertices, "   +  E  +   " edges "   +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( String . format ( "%d: " ,  v ));
             for   ( int  w  :  adj [ v ])   {
                s . append ( String . format ( "%d " ,  w ));
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  Digraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DijkstraAllPairsSP.java

edu/princeton/cs/algs4/DijkstraAllPairsSP.java

/******************************************************************************
 *  Compilation:  javac DijkstraAllPairsSP.java
 *  Execution:    none
 *  Dependencies: EdgeWeightedDigraph.java Dijkstra.java
 *
 *  Dijkstra's algorithm run from each vertex. 
 *  Takes time proportional to E V log V and space proportional to EV.
 *
 *  % java DijkstraAllPairsSP tinyEWD.txt
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DijkstraAllPairsSP} class represents a data type for solving the
 *  all-pairs shortest paths problem in edge-weighted digraphs
 *  where the edge weights are nonnegative.
 *  <p>
 *  This implementation runs Dijkstra's algorithm from each vertex.
 *  The constructor takes &Theta;(<em>V</em> (<em>E</em> log <em>V</em>)) time
 *  in the worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em><sup>2</sup>) extra space (not including the
 *  edge-weighted digraph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DijkstraAllPairsSP   {
     private   DijkstraSP []  all ;

     /**
     * Computes a shortest paths tree from each vertex to to every other vertex in
     * the edge-weighted digraph { @code  G}.
     *  @param  G the edge-weighted digraph
     *  @throws  IllegalArgumentException if an edge weight is negative
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DijkstraAllPairsSP ( EdgeWeightedDigraph  G )   {
        all   =   new   DijkstraSP [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            all [ v ]   =   new   DijkstraSP ( G ,  v );
     }

     /**
     * Returns a shortest path from vertex { @code  s} to vertex { @code  t}.
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  a shortest path from vertex { @code  s} to vertex { @code  t}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= t < V}
     */
     public   Iterable < DirectedEdge >  path ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         return  all [ s ]. pathTo ( t );
     }

     /**
     * Is there a path from the vertex { @code  s} to vertex { @code  t}?
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  { @code  true} if there is a path from vertex { @code  s} 
     *         to vertex { @code  t}, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= t < V}
     */
     public   boolean  hasPath ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         return  dist ( s ,  t )   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns the length of a shortest path from vertex { @code  s} to vertex { @code  t}.
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  the length of a shortest path from vertex { @code  s} to vertex { @code  t};
     *         { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= t < V}
     */
     public   double  dist ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         return  all [ s ]. distTo ( t );
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  all . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }


     /**
     * Unit tests the { @code  DijkstraAllPairsSP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read edge-weighted digraph
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );

         // compute shortest paths between all pairs of vertices
         DijkstraAllPairsSP  spt  =   new   DijkstraAllPairsSP ( G );

         // print all-pairs shortest path distances
         StdOut . printf ( "  " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%6d " ,  v );
         }
         StdOut . println ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%3d: " ,  v );
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( spt . hasPath ( v ,  w ))   StdOut . printf ( "%6.2f " ,  spt . dist ( v ,  w ));
                 else   StdOut . printf ( "  Inf " );
             }
             StdOut . println ();
         }
         StdOut . println ();

         // print all-pairs shortest paths
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( spt . hasPath ( v ,  w ))   {
                     StdOut . printf ( "%d to %d (%5.2f)  " ,  v ,  w ,  spt . dist ( v ,  w ));
                     for   ( DirectedEdge  e  :  spt . path ( v ,  w ))
                         StdOut . print ( +   "  " );
                     StdOut . println ();
                 }
                 else   {
                     StdOut . printf ( "%d to %d no path\n" ,  v ,  w );
                 }
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DijkstraSP.java

edu/princeton/cs/algs4/DijkstraSP.java

/******************************************************************************
 *  Compilation:  javac DijkstraSP.java
 *  Execution:    java DijkstraSP input.txt s
 *  Dependencies: EdgeWeightedDigraph.java IndexMinPQ.java Stack.java DirectedEdge.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWD.txt
 *                https://algs4.cs.princeton.edu/44sp/mediumEWD.txt
 *                https://algs4.cs.princeton.edu/44sp/largeEWD.txt
 *
 *  Dijkstra's algorithm. Computes the shortest path tree.
 *  Assumes all weights are nonnegative.
 *
 *  % java DijkstraSP tinyEWD.txt 0
 *  0 to 0 (0.00)  
 *  0 to 1 (1.05)  0->4  0.38   4->5  0.35   5->1  0.32   
 *  0 to 2 (0.26)  0->2  0.26   
 *  0 to 3 (0.99)  0->2  0.26   2->7  0.34   7->3  0.39   
 *  0 to 4 (0.38)  0->4  0.38   
 *  0 to 5 (0.73)  0->4  0.38   4->5  0.35   
 *  0 to 6 (1.51)  0->2  0.26   2->7  0.34   7->3  0.39   3->6  0.52   
 *  0 to 7 (0.60)  0->2  0.26   2->7  0.34   
 *
 *  % java DijkstraSP mediumEWD.txt 0
 *  0 to 0 (0.00)  
 *  0 to 1 (0.71)  0->44  0.06   44->93  0.07   ...  107->1  0.07   
 *  0 to 2 (0.65)  0->44  0.06   44->231  0.10  ...  42->2  0.11   
 *  0 to 3 (0.46)  0->97  0.08   97->248  0.09  ...  45->3  0.12   
 *  0 to 4 (0.42)  0->44  0.06   44->93  0.07   ...  77->4  0.11   
 *  ...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  DijkstraSP} class represents a data type for solving the
 *  single-source shortest paths problem in edge-weighted digraphs
 *  where the edge weights are nonnegative.
 *  <p>
 *  This implementation uses <em>Dijkstra's algorithm</em> with a
 *  <em>binary heap</em>. The constructor takes
 *  &Theta;(<em>E</em> log <em>V</em>) time in the worst case,
 *  where <em>V</em> is the number of vertices and <em>E</em> is
 *  the number of edges. Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted digraph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DijkstraSP   {
     private   double []  distTo ;            // distTo[v] = distance  of shortest s->v path
     private   DirectedEdge []  edgeTo ;      // edgeTo[v] = last edge on shortest s->v path
     private   IndexMinPQ < Double >  pq ;      // priority queue of vertices

     /**
     * Computes a shortest-paths tree from the source vertex { @code  s} to every other
     * vertex in the edge-weighted digraph { @code  G}.
     *
     *  @param   G the edge-weighted digraph
     *  @param   s the source vertex
     *  @throws  IllegalArgumentException if an edge weight is negative
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DijkstraSP ( EdgeWeightedDigraph  G ,   int  s )   {
         for   ( DirectedEdge  e  :  G . edges ())   {
             if   ( e . weight ()   <   0 )
                 throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );
         }

        distTo  =   new   double [ G . V ()];
        edgeTo  =   new   DirectedEdge [ G . V ()];

        validateVertex ( s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . POSITIVE_INFINITY ;
        distTo [ s ]   =   0.0 ;

         // relax vertices in order of distance from s
        pq  =   new   IndexMinPQ < Double > ( G . V ());
        pq . insert ( s ,  distTo [ s ]);
         while   ( ! pq . isEmpty ())   {
             int  v  =  pq . delMin ();
             for   ( DirectedEdge  e  :  G . adj ( v ))
                relax ( e );
         }

         // check optimality conditions
         assert  check ( G ,  s );
     }

     // relax edge e and update pq if changed
     private   void  relax ( DirectedEdge  e )   {
         int  v  =  e . from (),  w  =  e . to ();
         if   ( distTo [ w ]   >  distTo [ v ]   +  e . weight ())   {
            distTo [ w ]   =  distTo [ v ]   +  e . weight ();
            edgeTo [ w ]   =  e ;
             if   ( pq . contains ( w ))  pq . decreaseKey ( w ,  distTo [ w ]);
             else                 pq . insert ( w ,  distTo [ w ]);
         }
     }

     /**
     * Returns the length of a shortest path from the source vertex { @code  s} to vertex { @code  v}.
     *  @param   v the destination vertex
     *  @return  the length of a shortest path from the source vertex { @code  s} to vertex { @code  v};
     *         { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Returns true if there is a path from the source vertex { @code  s} to vertex { @code  v}.
     *
     *  @param   v the destination vertex
     *  @return  { @code  true} if there is a path from the source vertex
     *         { @code  s} to vertex { @code  v}; { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns a shortest path from the source vertex { @code  s} to vertex { @code  v}.
     *
     *  @param   v the destination vertex
     *  @return  a shortest path from the source vertex { @code  s} to vertex { @code  v}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < DirectedEdge >  path  =   new   Stack < DirectedEdge > ();
         for   ( DirectedEdge  e  =  edgeTo [ v ];  e  !=   null ;  e  =  edgeTo [ e . from ()])   {
            path . push ( e );
         }
         return  path ;
     }


     // check optimality conditions:
     // (i) for all edges e:            distTo[e.to()] <= distTo[e.from()] + e.weight()
     // (ii) for all edge e on the SPT: distTo[e.to()] == distTo[e.from()] + e.weight()
     private   boolean  check ( EdgeWeightedDigraph  G ,   int  s )   {

         // check that edge weights are nonnegative
         for   ( DirectedEdge  e  :  G . edges ())   {
             if   ( e . weight ()   <   0 )   {
                 System . err . println ( "negative edge weight detected" );
                 return   false ;
             }
         }

         // check that distTo[v] and edgeTo[v] are consistent
         if   ( distTo [ s ]   !=   0.0   ||  edgeTo [ s ]   !=   null )   {
             System . err . println ( "distTo[s] and edgeTo[s] inconsistent" );
             return   false ;
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ==  s )   continue ;
             if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {
                 System . err . println ( "distTo[] and edgeTo[] inconsistent" );
                 return   false ;
             }
         }

         // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( DirectedEdge  e  :  G . adj ( v ))   {
                 int  w  =  e . to ();
                 if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {
                     System . err . println ( "edge "   +  e  +   " not relaxed" );
                     return   false ;
                 }
             }
         }

         // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
         for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
             if   ( edgeTo [ w ]   ==   null )   continue ;
             DirectedEdge  e  =  edgeTo [ w ];
             int  v  =  e . from ();
             if   ( !=  e . to ())   return   false ;
             if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {
                 System . err . println ( "edge "   +  e  +   " on shortest path not tight" );
                 return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DijkstraSP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);

         // compute shortest paths
         DijkstraSP  sp  =   new   DijkstraSP ( G ,  s );


         // print shortest path
         for   ( int  t  =   0 ;  t  <  G . V ();  t ++ )   {
             if   ( sp . hasPathTo ( t ))   {
                 StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  t ,  sp . distTo ( t ));
                 for   ( DirectedEdge  e  :  sp . pathTo ( t ))   {
                     StdOut . print ( +   "   " );
                 }
                 StdOut . println ();
             }
             else   {
                 StdOut . printf ( "%d to %d         no path\n" ,  s ,  t );
             }
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DijkstraUndirectedSP.java

edu/princeton/cs/algs4/DijkstraUndirectedSP.java

/******************************************************************************
 *  Compilation:  javac DijkstraUndirectedSP.java
 *  Execution:    java DijkstraUndirectedSP input.txt s
 *  Dependencies: EdgeWeightedGraph.java IndexMinPQ.java Stack.java Edge.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  Dijkstra's algorithm. Computes the shortest path tree.
 *  Assumes all weights are nonnegative.
 *
 *  % java DijkstraUndirectedSP tinyEWG.txt 6
 *  6 to 0 (0.58)  6-0 0.58000
 *  6 to 1 (0.76)  6-2 0.40000   1-2 0.36000
 *  6 to 2 (0.40)  6-2 0.40000
 *  6 to 3 (0.52)  3-6 0.52000
 *  6 to 4 (0.93)  6-4 0.93000
 *  6 to 5 (1.02)  6-2 0.40000   2-7 0.34000   5-7 0.28000
 *  6 to 6 (0.00)
 *  6 to 7 (0.74)  6-2 0.40000   2-7 0.34000
 *
 *  % java DijkstraUndirectedSP mediumEWG.txt 0
 *  0 to 0 (0.00)
 *  0 to 1 (0.71)  0-44 0.06471   44-93  0.06793  ...   1-107 0.07484
 *  0 to 2 (0.65)  0-44 0.06471   44-231 0.10384  ...   2-42  0.11456
 *  0 to 3 (0.46)  0-97 0.07705   97-248 0.08598  ...   3-45  0.11902
 *  ...
 *
 *  % java DijkstraUndirectedSP largeEWG.txt 0
 *  0 to 0 (0.00)  
 *  0 to 1 (0.78)  0-460790 0.00190  460790-696678 0.00173   ...   1-826350 0.00191
 *  0 to 2 (0.61)  0-15786  0.00130  15786-53370   0.00113   ...   2-793420 0.00040
 *  0 to 3 (0.31)  0-460790 0.00190  460790-752483 0.00194   ...   3-698373 0.00172
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  DijkstraUndirectedSP} class represents a data type for solving
 *  the single-source shortest paths problem in edge-weighted graphs
 *  where the edge weights are nonnegative.
 *  <p>
 *  This implementation uses Dijkstra's algorithm with a binary heap.
 *  The constructor takes &Theta;(<em>E</em> log <em>V</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the
 *  edge-weighted graph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *  See { @link  DijkstraSP} for a version on edge-weighted digraphs.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *   @author  Nate Liu
 */
public   class   DijkstraUndirectedSP   {
     private   double []  distTo ;            // distTo[v] = distance  of shortest s->v path
     private   Edge []  edgeTo ;              // edgeTo[v] = last edge on shortest s->v path
     private   IndexMinPQ < Double >  pq ;      // priority queue of vertices

     /**
     * Computes a shortest-paths tree from the source vertex { @code  s} to every
     * other vertex in the edge-weighted graph { @code  G}.
     *
     *  @param   G the edge-weighted digraph
     *  @param   s the source vertex
     *  @throws  IllegalArgumentException if an edge weight is negative
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DijkstraUndirectedSP ( EdgeWeightedGraph  G ,   int  s )   {
         for   ( Edge  e  :  G . edges ())   {
             if   ( e . weight ()   <   0 )
                 throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );
         }

        distTo  =   new   double [ G . V ()];
        edgeTo  =   new   Edge [ G . V ()];

        validateVertex ( s );

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . POSITIVE_INFINITY ;
        distTo [ s ]   =   0.0 ;

         // relax vertices in order of distance from s
        pq  =   new   IndexMinPQ < Double > ( G . V ());
        pq . insert ( s ,  distTo [ s ]);
         while   ( ! pq . isEmpty ())   {
             int  v  =  pq . delMin ();
             for   ( Edge  e  :  G . adj ( v ))
                relax ( e ,  v );
         }

         // check optimality conditions
         assert  check ( G ,  s );
     }

     // relax edge e and update pq if changed
     private   void  relax ( Edge  e ,   int  v )   {
         int  w  =  e . other ( v );
         if   ( distTo [ w ]   >  distTo [ v ]   +  e . weight ())   {
            distTo [ w ]   =  distTo [ v ]   +  e . weight ();
            edgeTo [ w ]   =  e ;
             if   ( pq . contains ( w ))  pq . decreaseKey ( w ,  distTo [ w ]);
             else                 pq . insert ( w ,  distTo [ w ]);
         }
     }

     /**
     * Returns the length of a shortest path between the source vertex { @code  s} and
     * vertex { @code  v}.
     *
     *  @param   v the destination vertex
     *  @return  the length of a shortest path between the source vertex { @code  s} and
     *         the vertex { @code  v}; { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  distTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ];
     }

     /**
     * Returns true if there is a path between the source vertex { @code  s} and
     * vertex { @code  v}.
     *
     *  @param   v the destination vertex
     *  @return  { @code  true} if there is a path between the source vertex
     *         { @code  s} to vertex { @code  v}; { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  hasPathTo ( int  v )   {
        validateVertex ( v );
         return  distTo [ v ]   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns a shortest path between the source vertex { @code  s} and vertex { @code  v}.
     *
     *  @param   v the destination vertex
     *  @return  a shortest path between the source vertex { @code  s} and vertex { @code  v};
     *         { @code  null} if no such path
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Edge >  pathTo ( int  v )   {
        validateVertex ( v );
         if   ( ! hasPathTo ( v ))   return   null ;
         Stack < Edge >  path  =   new   Stack < Edge > ();
         int  x  =  v ;
         for   ( Edge  e  =  edgeTo [ v ];  e  !=   null ;  e  =  edgeTo [ x ])   {
            path . push ( e );
            x  =  e . other ( x );
         }
         return  path ;
     }


     // check optimality conditions:
     // (i) for all edges e = v-w:            distTo[w] <= distTo[v] + e.weight()
     // (ii) for all edge e = v-w on the SPT: distTo[w] == distTo[v] + e.weight()
     private   boolean  check ( EdgeWeightedGraph  G ,   int  s )   {

         // check that edge weights are nonnegative
         for   ( Edge  e  :  G . edges ())   {
             if   ( e . weight ()   <   0 )   {
                 System . err . println ( "negative edge weight detected" );
                 return   false ;
             }
         }

         // check that distTo[v] and edgeTo[v] are consistent
         if   ( distTo [ s ]   !=   0.0   ||  edgeTo [ s ]   !=   null )   {
             System . err . println ( "distTo[s] and edgeTo[s] inconsistent" );
             return   false ;
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ==  s )   continue ;
             if   ( edgeTo [ v ]   ==   null   &&  distTo [ v ]   !=   Double . POSITIVE_INFINITY )   {
                 System . err . println ( "distTo[] and edgeTo[] inconsistent" );
                 return   false ;
             }
         }

         // check that all edges e = v-w satisfy distTo[w] <= distTo[v] + e.weight()
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( Edge  e  :  G . adj ( v ))   {
                 int  w  =  e . other ( v );
                 if   ( distTo [ v ]   +  e . weight ()   <  distTo [ w ])   {
                     System . err . println ( "edge "   +  e  +   " not relaxed" );
                     return   false ;
                 }
             }
         }

         // check that all edges e = v-w on SPT satisfy distTo[w] == distTo[v] + e.weight()
         for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
             if   ( edgeTo [ w ]   ==   null )   continue ;
             Edge  e  =  edgeTo [ w ];
             if   ( !=  e . either ()   &&  w  !=  e . other ( e . either ()))   return   false ;
             int  v  =  e . other ( w );
             if   ( distTo [ v ]   +  e . weight ()   !=  distTo [ w ])   {
                 System . err . println ( "edge "   +  e  +   " on shortest path not tight" );
                 return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  DijkstraUndirectedSP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);

         // compute shortest paths
         DijkstraUndirectedSP  sp  =   new   DijkstraUndirectedSP ( G ,  s );


         // print shortest path
         for   ( int  t  =   0 ;  t  <  G . V ();  t ++ )   {
             if   ( sp . hasPathTo ( t ))   {
                 StdOut . printf ( "%d to %d (%.2f)  " ,  s ,  t ,  sp . distTo ( t ));
                 for   ( Edge  e  :  sp . pathTo ( t ))   {
                     StdOut . print ( +   "   " );
                 }
                 StdOut . println ();
             }
             else   {
                 StdOut . printf ( "%d to %d         no path\n" ,  s ,  t );
             }
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedCycle.java

edu/princeton/cs/algs4/DirectedCycle.java

/******************************************************************************
 *  Compilation:  javac DirectedCycle.java
 *  Execution:    java DirectedCycle input.txt
 *  Dependencies: Digraph.java Stack.java StdOut.java In.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt
 *
 *  Finds a directed cycle in a digraph.
 *
 *  % java DirectedCycle tinyDG.txt 
 *  Directed cycle: 3 5 4 3 
 *
 *  %  java DirectedCycle tinyDAG.txt 
 *  No directed cycle
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DirectedCycle} class represents a data type for 
 *  determining whether a digraph has a directed cycle.
 *  The <em>hasCycle</em> operation determines whether the digraph has
 *  a simple directed cycle and, if so, the <em>cycle</em> operation
 *  returns one.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the worst
 *  case, where <em>V</em> is the number of vertices and <em>E</em> is
 *  the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  See { @link  Topological} to compute a topological order if the
 *  digraph is acyclic.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DirectedCycle   {
     private   boolean []  marked ;          // marked[v] = has vertex v been marked?
     private   int []  edgeTo ;              // edgeTo[v] = previous vertex on path to v
     private   boolean []  onStack ;         // onStack[v] = is vertex on the stack?
     private   Stack < Integer >  cycle ;      // directed cycle (or null if no such cycle)

     /**
     * Determines whether the digraph { @code  G} has a directed cycle and, if so,
     * finds such a cycle.
     *  @param  G the digraph
     */
     public   DirectedCycle ( Digraph  G )   {
        marked   =   new   boolean [ G . V ()];
        onStack  =   new   boolean [ G . V ()];
        edgeTo   =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( ! marked [ v ]   &&  cycle  ==   null )  dfs ( G ,  v );
     }

     // check that algorithm computes either the topological order or finds a directed cycle
     private   void  dfs ( Digraph  G ,   int  v )   {
        onStack [ v ]   =   true ;
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {

             // short circuit if directed cycle found
             if   ( cycle  !=   null )   return ;

             // found new vertex, so recur
             else   if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  v ;
                dfs ( G ,  w );
             }

             // trace back directed cycle
             else   if   ( onStack [ w ])   {
                cycle  =   new   Stack < Integer > ();
                 for   ( int  x  =  v ;  x  !=  w ;  x  =  edgeTo [ x ])   {
                    cycle . push ( x );
                 }
                cycle . push ( w );
                cycle . push ( v );
                 assert  check ();
             }
         }
        onStack [ v ]   =   false ;
     }

     /**
     * Does the digraph have a directed cycle?
     *  @return  { @code  true} if the digraph has a directed cycle, { @code  false} otherwise
     */
     public   boolean  hasCycle ()   {
         return  cycle  !=   null ;
     }

     /**
     * Returns a directed cycle if the digraph has a directed cycle, and { @code  null} otherwise.
     *  @return  a directed cycle (as an iterable) if the digraph has a directed cycle,
     *    and { @code  null} otherwise
     */
     public   Iterable < Integer >  cycle ()   {
         return  cycle ;
     }


     // certify that digraph has a directed cycle if it reports one
     private   boolean  check ()   {

         if   ( hasCycle ())   {
             // verify cycle
             int  first  =   - 1 ,  last  =   - 1 ;
             for   ( int  v  :  cycle ())   {
                 if   ( first  ==   - 1 )  first  =  v ;
                last  =  v ;
             }
             if   ( first  !=  last )   {
                 System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );
                 return   false ;
             }
         }


         return   true ;
     }

     /**
     * Unit tests the { @code  DirectedCycle} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );

         DirectedCycle  finder  =   new   DirectedCycle ( G );
         if   ( finder . hasCycle ())   {
             StdOut . print ( "Directed cycle: " );
             for   ( int  v  :  finder . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

         else   {
             StdOut . println ( "No directed cycle" );
         }
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedCycleX.java

edu/princeton/cs/algs4/DirectedCycleX.java

/******************************************************************************
 *  Compilation:  javac DirectedCycleX.java
 *  Execution:    java DirectedCycleX V E F
 *  Dependencies: Queue.java Digraph.java Stack.java
 *
 *  Find a directed cycle in a digraph, using a nonrecursive, queue-based
 *  algorithm. Runs in O(E + V) time.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DirectedCycleX} class represents a data type for 
 *  determining whether a digraph has a directed cycle.
 *  The <em>hasCycle</em> operation determines whether the digraph has
 *  a simple directed cycle and, if so, the <em>cycle</em> operation
 *  returns one.
 *  <p>
 *  This implementation uses a nonrecursive, queue-based algorithm.
 *  The constructor takes time proportional to <em>V</em> + <em>E</em>
 *  (in the worst case),
 *  where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  See { @link  DirectedCycle} for a recursive version that uses depth-first search.
 *  See { @link  Topological} or { @link  TopologicalX} to compute a topological order
 *  when the digraph is acyclic.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   DirectedCycleX   {
     private   Stack < Integer >  cycle ;       // the directed cycle; null if digraph is acyclic

     public   DirectedCycleX ( Digraph  G )   {

         // indegrees of remaining vertices
         int []  indegree  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            indegree [ v ]   =  G . indegree ( v );
         }

         // initialize queue to contain all vertices with indegree = 0
         Queue < Integer >  queue  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );

         while   ( ! queue . isEmpty ())   {
             int  v  =  queue . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {
                indegree [ w ] -- ;
                 if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );
             }
         }

         // there is a directed cycle in subgraph of vertices with indegree >= 1.
         int []  edgeTo  =   new   int [ G . V ()];
         int  root  =   - 1 ;    // any vertex with indegree >= -1
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( indegree [ v ]   ==   0 )   continue ;
             else  root  =  v ;
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( indegree [ w ]   >   0 )   {
                    edgeTo [ w ]   =  v ;
                 }
             }
         }

         if   ( root  !=   - 1 )   {

             // find any vertex on cycle
             boolean []  visited  =   new   boolean [ G . V ()];
             while   ( ! visited [ root ])   {
                visited [ root ]   =   true ;
                root  =  edgeTo [ root ];
             }

             // extract cycle
            cycle  =   new   Stack < Integer > ();
             int  v  =  root ;
             do   {
                cycle . push ( v );
                v  =  edgeTo [ v ];
             }   while   ( !=  root );
            cycle . push ( root );
         }

         assert  check ();
     }

     /**
     * Returns a directed cycle if the digraph has a directed cycle, and { @code  null} otherwise.
     *  @return  a directed cycle (as an iterable) if the digraph has a directed cycle,
     *    and { @code  null} otherwise
     */
     public   Iterable < Integer >  cycle ()   {
         return  cycle ;
     }

     /**
     * Does the digraph have a directed cycle?
     *  @return  { @code  true} if the digraph has a directed cycle, { @code  false} otherwise
     */
     public   boolean  hasCycle ()   {
         return  cycle  !=   null ;
     }

     // certify that digraph has a directed cycle if it reports one
     private   boolean  check ()   {

         if   ( hasCycle ())   {
             // verify cycle
             int  first  =   - 1 ,  last  =   - 1 ;
             for   ( int  v  :  cycle ())   {
                 if   ( first  ==   - 1 )  first  =  v ;
                last  =  v ;
             }
             if   ( first  !=  last )   {
                 System . err . printf ( "cycle begins with %d and ends with %d\n" ,  first ,  last );
                 return   false ;
             }
         }


         return   true ;
     }


     public   static   void  main ( String []  args )   {

         // create random DAG with V vertices and E edges; then add F random edges
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         int  F  =   Integer . parseInt ( args [ 2 ]);
         Digraph  G  =   DigraphGenerator . dag ( V ,  E );

         // add F extra edges
         for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
            G . addEdge ( v ,  w );
         }

         StdOut . println ( G );


         DirectedCycleX  finder  =   new   DirectedCycleX ( G );
         if   ( finder . hasCycle ())   {
             StdOut . print ( "Directed cycle: " );
             for   ( int  v  :  finder . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

         else   {
             StdOut . println ( "No directed cycle" );
         }
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedDFS.java

edu/princeton/cs/algs4/DirectedDFS.java

/******************************************************************************
 *  Compilation:  javac DirectedDFS.java
 *  Execution:    java DirectedDFS digraph.txt s
 *  Dependencies: Digraph.java Bag.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Determine single-source or multiple-source reachability in a digraph
 *  using depth first search.
 *  Runs in O(E + V) time.
 *
 *  % java DirectedDFS tinyDG.txt 1
 *  1
 *
 *  % java DirectedDFS tinyDG.txt 2
 *  0 1 2 3 4 5
 *
 *  % java DirectedDFS tinyDG.txt 1 2 6
 *  0 1 2 3 4 5 6 8 9 10 11 12 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;
/**
 *  The { @code  DirectedDFS} class represents a data type for 
 *  determining the vertices reachable from a given source vertex <em>s</em>
 *  (or set of source vertices) in a digraph. For versions that find the paths,
 *  see { @link  DepthFirstDirectedPaths} and { @link  BreadthFirstDirectedPaths}.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes time proportional to <em>V</em> + <em>E</em>
 *  (in the worst case),
 *  where <em>V</em> is the number of vertices and <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DirectedDFS   {
     private   boolean []  marked ;    // marked[v] = true iff v is reachable from source(s)
     private   int  count ;           // number of vertices reachable from source(s)

     /**
     * Computes the vertices in digraph { @code  G} that are
     * reachable from the source vertex { @code  s}.
     *  @param  G the digraph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   DirectedDFS ( Digraph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        validateVertex ( s );
        dfs ( G ,  s );
     }

     /**
     * Computes the vertices in digraph { @code  G} that are
     * connected to any of the source vertices { @code  sources}.
     *  @param  G the graph
     *  @param  sources the source vertices
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *         for each vertex { @code  s} in { @code  sources}
     */
     public   DirectedDFS ( Digraph  G ,   Iterable < Integer >  sources )   {
        marked  =   new   boolean [ G . V ()];
        validateVertices ( sources );
         for   ( int  v  :  sources )   {
             if   ( ! marked [ v ])  dfs ( G ,  v );
         }
     }

     private   void  dfs ( Digraph  G ,   int  v )   {  
        count ++ ;
        marked [ v ]   =   true ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])  dfs ( G ,  w );
         }
     }

     /**
     * Is there a directed path from the source vertex (or any
     * of the source vertices) and vertex { @code  v}?
     *  @param   v the vertex
     *  @return  { @code  true} if there is a directed path, { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  marked ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     /**
     * Returns the number of vertices reachable from the source vertex
     * (or source vertices).
     *  @return  the number of vertices reachable from the source vertex
     *   (or source vertices)
     */
     public   int  count ()   {
         return  count ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertices ( Iterable < Integer >  vertices )   {
         if   ( vertices  ==   null )   {
             throw   new   IllegalArgumentException ( "argument is null" );
         }
         int  V  =  marked . length ;
         for   ( int  v  :  vertices )   {
             if   ( <   0   ||  v  >=  V )   {
                 throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
             }
         }
     }


     /**
     * Unit tests the { @code  DirectedDFS} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read in digraph from command-line argument
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );

         // read in sources from command-line arguments
         Bag < Integer >  sources  =   new   Bag < Integer > ();
         for   ( int  i  =   1 ;  i  <  args . length ;  i ++ )   {
             int  s  =   Integer . parseInt ( args [ i ]);
            sources . add ( s );
         }

         // multiple-source reachability
         DirectedDFS  dfs  =   new   DirectedDFS ( G ,  sources );

         // print out vertices reachable from sources
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( dfs . marked ( v ))   StdOut . print ( +   " " );
         }
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedEdge.java

edu/princeton/cs/algs4/DirectedEdge.java

/******************************************************************************
 *  Compilation:  javac DirectedEdge.java
 *  Execution:    java DirectedEdge
 *  Dependencies: StdOut.java
 *
 *  Immutable weighted directed edge.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;
/**
 *  The { @code  DirectedEdge} class represents a weighted edge in an 
 *  { @link  EdgeWeightedDigraph}. Each edge consists of two integers
 *  (naming the two vertices) and a real-value weight. The data type
 *  provides methods for accessing the two endpoints of the directed edge and
 *  the weight.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   DirectedEdge   {  
     private   final   int  v ;
     private   final   int  w ;
     private   final   double  weight ;

     /**
     * Initializes a directed edge from vertex { @code  v} to vertex { @code  w} with
     * the given { @code  weight}.
     *  @param  v the tail vertex
     *  @param  w the head vertex
     *  @param  weight the weight of the directed edge
     *  @throws  IllegalArgumentException if either { @code  v} or { @code  w}
     *    is a negative integer
     *  @throws  IllegalArgumentException if { @code  weight} is { @code  NaN}
     */
     public   DirectedEdge ( int  v ,   int  w ,   double  weight )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Vertex names must be nonnegative integers" );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Vertex names must be nonnegative integers" );
         if   ( Double . isNaN ( weight ))   throw   new   IllegalArgumentException ( "Weight is NaN" );
         this . =  v ;
         this . =  w ;
         this . weight  =  weight ;
     }

     /**
     * Returns the tail vertex of the directed edge.
     *  @return  the tail vertex of the directed edge
     */
     public   int  from ()   {
         return  v ;
     }

     /**
     * Returns the head vertex of the directed edge.
     *  @return  the head vertex of the directed edge
     */
     public   int  to ()   {
         return  w ;
     }

     /**
     * Returns the weight of the directed edge.
     *  @return  the weight of the directed edge
     */
     public   double  weight ()   {
         return  weight ;
     }

     /**
     * Returns a string representation of the directed edge.
     *  @return  a string representation of the directed edge
     */
     public   String  toString ()   {
         return  v  +   "->"   +  w  +   " "   +   String . format ( "%5.2f" ,  weight );
     }

     /**
     * Unit tests the { @code  DirectedEdge} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         DirectedEdge  e  =   new   DirectedEdge ( 12 ,   34 ,   5.67 );
         StdOut . println ( e );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedEulerianCycle.java

edu/princeton/cs/algs4/DirectedEulerianCycle.java

/******************************************************************************
 *  Compilation:  javac DirectedEulerianCycle.java
 *  Execution:    java DirectedEulerianCycle V E
 *  Dependencies: Digraph.java Stack.java StdOut.java
 *                BreadthFirstPaths.java
 *                DigraphGenerator.java StdRandom.java
 *
 *  Find an Eulerian cycle in a digraph, if one exists.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  DirectedEulerianCycle} class represents a data type
 *  for finding an Eulerian cycle or path in a digraph.
 *  An <em>Eulerian cycle</em> is a cycle (not necessarily simple) that
 *  uses every edge in the digraph exactly once.
 *  <p>
 *  This implementation uses a nonrecursive depth-first search.
 *  The constructor takes &Theta;(<em>E</em> + <em>V</em>) time in the worst
 *  case, where <em>E</em> is the number of edges and <em>V</em> is the
 *  number of vertices
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  To compute Eulerian paths in digraphs, see { @link  DirectedEulerianPath}.
 *  To compute Eulerian cycles and paths in undirected graphs, see
 *  { @link  EulerianCycle} and { @link  EulerianPath}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 * 
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *   @author  Nate Liu
 */
public   class   DirectedEulerianCycle   {
     private   Stack < Integer >  cycle  =   null ;    // Eulerian cycle; null if no such cylce

     /**
     * Computes an Eulerian cycle in the specified digraph, if one exists.
     * 
     *  @param  G the digraph
     */
     public   DirectedEulerianCycle ( Digraph  G )   {

         // must have at least one edge
         if   ( G . E ()   ==   0 )   return ;

         // necessary condition: indegree(v) = outdegree(v) for each vertex v
         // (without this check, DFS might return a path instead of a cycle)
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . outdegree ( v )   !=  G . indegree ( v ))
                 return ;

         // create local view of adjacency lists, to iterate one vertex at a time
         Iterator < Integer > []  adj  =   ( Iterator < Integer > [])   new   Iterator [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =  G . adj ( v ). iterator ();

         // initialize stack with any non-isolated vertex
         int  s  =  nonIsolatedVertex ( G );
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        stack . push ( s );

         // greedily add to putative cycle, depth-first search style
        cycle  =   new   Stack < Integer > ();
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . pop ();
             while   ( adj [ v ]. hasNext ())   {
                stack . push ( v );
                v  =  adj [ v ]. next ();
             }
             // add vertex with no more leaving edges to cycle
            cycle . push ( v );
         }

         // check if all edges have been used
         // (in case there are two or more vertex-disjoint Eulerian cycles)
         if   ( cycle . size ()   !=  G . E ()   +   1 )
            cycle  =   null ;

         assert  certifySolution ( G );
     }

     /**
     * Returns the sequence of vertices on an Eulerian cycle.
     * 
     *  @return  the sequence of vertices on an Eulerian cycle;
     *         { @code  null} if no such cycle
     */
     public   Iterable < Integer >  cycle ()   {
         return  cycle ;
     }

     /**
     * Returns true if the digraph has an Eulerian cycle.
     * 
     *  @return  { @code  true} if the digraph has an Eulerian cycle;
     *         { @code  false} otherwise
     */
     public   boolean  hasEulerianCycle ()   {
         return  cycle  !=   null ;
     }

     // returns any non-isolated vertex; -1 if no such vertex
     private   static   int  nonIsolatedVertex ( Digraph  G )   {
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . outdegree ( v )   >   0 )
                 return  v ;
         return   - 1 ;
     }


     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // Determines whether a digraph has an Eulerian cycle using necessary
     // and sufficient conditions (without computing the cycle itself):
     //    - at least one edge
     //    - indegree(v) = outdegree(v) for every vertex
     //    - the graph is connected, when viewed as an undirected graph
     //      (ignoring isolated vertices)
     private   static   boolean  satisfiesNecessaryAndSufficientConditions ( Digraph  G )   {

         // Condition 0: at least 1 edge
         if   ( G . E ()   ==   0 )   return   false ;

         // Condition 1: indegree(v) == outdegree(v) for every vertex
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . outdegree ( v )   !=  G . indegree ( v ))
                 return   false ;

         // Condition 2: graph is connected, ignoring isolated vertices
         Graph  H  =   new   Graph ( G . V ());
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             for   ( int  w  :  G . adj ( v ))
                H . addEdge ( v ,  w );
        
         // check that all non-isolated vertices are conneted
         int  s  =  nonIsolatedVertex ( G );
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( H ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( H . degree ( v )   >   0   &&   ! bfs . hasPathTo ( v ))
                 return   false ;

         return   true ;
     }

     // check that solution is correct
     private   boolean  certifySolution ( Digraph  G )   {

         // internal consistency check
         if   ( hasEulerianCycle ()   ==   ( cycle ()   ==   null ))   return   false ;

         // hashEulerianCycle() returns correct value
         if   ( hasEulerianCycle ()   !=  satisfiesNecessaryAndSufficientConditions ( G ))   return   false ;

         // nothing else to check if no Eulerian cycle
         if   ( cycle  ==   null )   return   true ;

         // check that cycle() uses correct number of edges
         if   ( cycle . size ()   !=  G . E ()   +   1 )   return   false ;

         // check that cycle() is a directed cycle of G
         // TODO

         return   true ;
     }


     private   static   void  unitTest ( Digraph  G ,   String  description )   {
         StdOut . println ( description );
         StdOut . println ( "-------------------------------------" );
         StdOut . print ( G );

         DirectedEulerianCycle  euler  =   new   DirectedEulerianCycle ( G );

         StdOut . print ( "Eulerian cycle: " );
         if   ( euler . hasEulerianCycle ())   {
             for   ( int  v  :  euler . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
         else   {
             StdOut . println ( "none" );
         }
         StdOut . println ();
     }


     /**
     * Unit tests the { @code  DirectedEulerianCycle} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);

         // Eulerian cycle
         Digraph  G1  =   DigraphGenerator . eulerianCycle ( V ,  E );
        unitTest ( G1 ,   "Eulerian cycle" );

         // Eulerian path
         Digraph  G2  =   DigraphGenerator . eulerianPath ( V ,  E );
        unitTest ( G2 ,   "Eulerian path" );

         // empty digraph
         Digraph  G3  =   new   Digraph ( V );
        unitTest ( G3 ,   "empty digraph" );

         // self loop
         Digraph  G4  =   new   Digraph ( V );
         int  v4  =   StdRandom . uniform ( V );
        G4 . addEdge ( v4 ,  v4 );
        unitTest ( G4 ,   "single self loop" );

         // union of two disjoint cycles
         Digraph  H1  =   DigraphGenerator . eulerianCycle ( V / 2 ,  E / 2 );
         Digraph  H2  =   DigraphGenerator . eulerianCycle ( -  V / 2 ,  E  -  E / 2 );
         int []  perm  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            perm [ i ]   =  i ;
         StdRandom . shuffle ( perm );
         Digraph  G5  =   new   Digraph ( V );
         for   ( int  v  =   0 ;  v  <  H1 . V ();  v ++ )
             for   ( int  w  :  H1 . adj ( v ))
                G5 . addEdge ( perm [ v ],  perm [ w ]);
         for   ( int  v  =   0 ;  v  <  H2 . V ();  v ++ )
             for   ( int  w  :  H2 . adj ( v ))
                G5 . addEdge ( perm [ V / 2   +  v ],  perm [ V / 2   +  w ]);
        unitTest ( G5 ,   "Union of two disjoint cycles" );

         // random digraph
         Digraph  G6  =   DigraphGenerator . simple ( V ,  E );
        unitTest ( G6 ,   "simple digraph" );

         // 4-vertex digraph
         Digraph  G7  =   new   Digraph ( new   In ( "eulerianD.txt" ));
        unitTest ( G7 ,   "4-vertex Eulerian digraph" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DirectedEulerianPath.java

edu/princeton/cs/algs4/DirectedEulerianPath.java

/******************************************************************************
 *  Compilation:  javac DirectedEulerianPath.java
 *  Execution:    java DirectedEulerianPath V E
 *  Dependencies: Digraph.java Stack.java StdOut.java
 *                BreadthFirstPaths.java
 *                DigraphGenerator.java StdRandom.java
 *
 *  Find an Eulerian path in a digraph, if one exists.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  DirectedEulerianPath} class represents a data type
 *  for finding an Eulerian path in a digraph.
 *  An <em>Eulerian path</em> is a path (not necessarily simple) that
 *  uses every edge in the digraph exactly once.
 *  <p>
 *  This implementation uses a nonrecursive depth-first search.
 *  The constructor take &Theta;(<em>E</em> + <em>V</em>) time
 *  in the worst case, where <em>E</em> is the number of edges and
 *  <em>V</em> is the number of vertices.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph). 
 *  <p>
 *  To compute Eulerian cycles in digraphs, see { @link  DirectedEulerianCycle}.
 *  To compute Eulerian cycles and paths in undirected graphs, see
 *  { @link  EulerianCycle} and { @link  EulerianPath}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 * 
 *  @author  Robert Sedgewick
 *  @author  Kevin Wayne
 *  @author  Nate Liu
 */
public   class   DirectedEulerianPath   {
     private   Stack < Integer >  path  =   null ;     // Eulerian path; null if no suh path

     /**
     * Computes an Eulerian path in the specified digraph, if one exists.
     * 
     *  @param  G the digraph
     */
     public   DirectedEulerianPath ( Digraph  G )   {

         // find vertex from which to start potential Eulerian path:
         // a vertex v with outdegree(v) > indegree(v) if it exits;
         // otherwise a vertex with outdegree(v) > 0
         int  deficit  =   0 ;
         int  s  =  nonIsolatedVertex ( G );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( G . outdegree ( v )   >  G . indegree ( v ))   {
                deficit  +=   ( G . outdegree ( v )   -  G . indegree ( v ));
                s  =  v ;
             }
         }

         // digraph can't have an Eulerian path
         // (this condition is needed)
         if   ( deficit  >   1 )   return ;

         // special case for digraph with zero edges (has a degenerate Eulerian path)
         if   ( ==   - 1 )  s  =   0 ;

         // create local view of adjacency lists, to iterate one vertex at a time
         Iterator < Integer > []  adj  =   ( Iterator < Integer > [])   new   Iterator [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =  G . adj ( v ). iterator ();

         // greedily add to cycle, depth-first search style
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        stack . push ( s );
        path  =   new   Stack < Integer > ();
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . pop ();
             while   ( adj [ v ]. hasNext ())   {
                stack . push ( v );
                v  =  adj [ v ]. next ();
             }
             // push vertex with no more available edges to path
            path . push ( v );
         }
            
         // check if all edges have been used
         if   ( path . size ()   !=  G . E ()   +   1 )
            path  =   null ;

         assert  check ( G );
     }

     /**
     * Returns the sequence of vertices on an Eulerian path.
     * 
     *  @return  the sequence of vertices on an Eulerian path;
     *         { @code  null} if no such path
     */
     public   Iterable < Integer >  path ()   {
         return  path ;
     }

     /**
     * Returns true if the digraph has an Eulerian path.
     * 
     *  @return  { @code  true} if the digraph has an Eulerian path;
     *         { @code  false} otherwise
     */
     public   boolean  hasEulerianPath ()   {
         return  path  !=   null ;
     }


     // returns any non-isolated vertex; -1 if no such vertex
     private   static   int  nonIsolatedVertex ( Digraph  G )   {
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . outdegree ( v )   >   0 )
                 return  v ;
         return   - 1 ;
     }


     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // Determines whether a digraph has an Eulerian path using necessary
     // and sufficient conditions (without computing the path itself):
     //    - indegree(v) = outdegree(v) for every vertex,
     //      except one vertex v may have outdegree(v) = indegree(v) + 1
     //      (and one vertex v may have indegree(v) = outdegree(v) + 1)
     //    - the graph is connected, when viewed as an undirected graph
     //      (ignoring isolated vertices)
     private   static   boolean  satisfiesNecessaryAndSufficientConditions ( Digraph  G )   {
         if   ( G . E ()   ==   0 )   return   true ;

         // Condition 1: indegree(v) == outdegree(v) for every vertex,
         // except one vertex may have outdegree(v) = indegree(v) + 1
         int  deficit  =   0 ;
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . outdegree ( v )   >  G . indegree ( v ))
                deficit  +=   ( G . outdegree ( v )   -  G . indegree ( v ));
         if   ( deficit  >   1 )   return   false ;

         // Condition 2: graph is connected, ignoring isolated vertices
         Graph  H  =   new   Graph ( G . V ());
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             for   ( int  w  :  G . adj ( v ))
                H . addEdge ( v ,  w );
        
         // check that all non-isolated vertices are connected
         int  s  =  nonIsolatedVertex ( G );
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( H ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( H . degree ( v )   >   0   &&   ! bfs . hasPathTo ( v ))
                 return   false ;

         return   true ;
     }


     private   boolean  check ( Digraph  G )   {

         // internal consistency check
         if   ( hasEulerianPath ()   ==   ( path ()   ==   null ))   return   false ;

         // hashEulerianPath() returns correct value
         if   ( hasEulerianPath ()   !=  satisfiesNecessaryAndSufficientConditions ( G ))   return   false ;

         // nothing else to check if no Eulerian path
         if   ( path  ==   null )   return   true ;

         // check that path() uses correct number of edges
         if   ( path . size ()   !=  G . E ()   +   1 )   return   false ;

         // check that path() is a directed path in G
         // TODO

         return   true ;
     }


     private   static   void  unitTest ( Digraph  G ,   String  description )   {
         StdOut . println ( description );
         StdOut . println ( "-------------------------------------" );
         StdOut . print ( G );

         DirectedEulerianPath  euler  =   new   DirectedEulerianPath ( G );

         StdOut . print ( "Eulerian path:  " );
         if   ( euler . hasEulerianPath ())   {
             for   ( int  v  :  euler . path ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
         else   {
             StdOut . println ( "none" );
         }
         StdOut . println ();
     }

     /**
     * Unit tests the { @code  DirectedEulerianPath} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);


         // Eulerian cycle
         Digraph  G1  =   DigraphGenerator . eulerianCycle ( V ,  E );
        unitTest ( G1 ,   "Eulerian cycle" );

         // Eulerian path
         Digraph  G2  =   DigraphGenerator . eulerianPath ( V ,  E );
        unitTest ( G2 ,   "Eulerian path" );

         // add one random edge
         Digraph  G3  =   new   Digraph ( G2 );
        G3 . addEdge ( StdRandom . uniform ( V ),   StdRandom . uniform ( V ));
        unitTest ( G3 ,   "one random edge added to Eulerian path" );

         // self loop
         Digraph  G4  =   new   Digraph ( V );
         int  v4  =   StdRandom . uniform ( V );
        G4 . addEdge ( v4 ,  v4 );
        unitTest ( G4 ,   "single self loop" );

         // single edge
         Digraph  G5  =   new   Digraph ( V );
        G5 . addEdge ( StdRandom . uniform ( V ),   StdRandom . uniform ( V ));
        unitTest ( G5 ,   "single edge" );

         // empty digraph
         Digraph  G6  =   new   Digraph ( V );
        unitTest ( G6 ,   "empty digraph" );

         // random digraph
         Digraph  G7  =   DigraphGenerator . simple ( V ,  E );
        unitTest ( G7 ,   "simple digraph" );

         // 4-vertex digraph
         Digraph  G8  =   new   Digraph ( new   In ( "eulerianD.txt" ));
        unitTest ( G8 ,   "4-vertex Eulerian digraph" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DoublingRatio.java

edu/princeton/cs/algs4/DoublingRatio.java

/******************************************************************************
 *  Compilation:  javac DoublingRatio.java
 *  Execution:    java DoublingRatio
 *  Dependencies: ThreeSum.java Stopwatch.java StdRandom.java StdOut.java
 *
 *
 *  % java DoublingRatio
 *      250     0.0   2.7
 *      500     0.0   4.8
 *     1000     0.1   6.9
 *     2000     0.6   7.7
 *     4000     4.5   8.0
 *     8000    35.7   8.0
 *     4000     3.9   6.6
 *  ...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DoublingRatio} class provides a client for measuring
 *  the running time of a method using a doubling ratio test.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/14analysis">Section 1.4</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DoublingRatio   {
     private   static   final   int  MAXIMUM_INTEGER  =   1000000 ;

     // This class should not be instantiated.
     private   DoublingRatio ()   {   }

     /**
     * Returns the amount of time to call { @code  ThreeSum.count()} with <em>n</em>
     * random 6-digit integers.
     *  @param  n the number of integers
     *  @return  amount of time (in seconds) to call { @code  ThreeSum.count()}
     *   with <em>n</em> random 6-digit integers
     */
     public   static   double  timeTrial ( int  n )   {
         int []  a  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            a [ i ]   =   StdRandom . uniform ( - MAXIMUM_INTEGER ,  MAXIMUM_INTEGER );
         }
         Stopwatch  timer  =   new   Stopwatch ();
         ThreeSum . count ( a );
         return  timer . elapsedTime ();
     }

     /**
     * Prints table of running times to call { @code  ThreeSum.count()}
     * for arrays of size 250, 500, 1000, 2000, and so forth, along
     * with ratios of running times between successive array sizes.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         double  prev  =  timeTrial ( 125 );
         for   ( int  n  =   250 ;   true ;  n  +=  n )   {
             double  time  =  timeTrial ( n );
             StdOut . printf ( "%7d %7.1f %5.1f\n" ,  n ,  time ,  time / prev );
            prev  =  time ;
         }  
     }  
}  


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DoublingTest.java

edu/princeton/cs/algs4/DoublingTest.java

/******************************************************************************
 *  Compilation:  javac DoublingTest.java
 *  Execution:    java DoublingTest
 *  Dependencies: ThreeSum.java Stopwatch.java StdRandom.java StdOut.java
 *
 *  % java DoublingTest 
 *      250     0.0
 *      500     0.0
 *     1000     0.1
 *     2000     0.6
 *     4000     4.5
 *     8000    35.7
 *  ...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  DoublingTest} class provides a client for measuring
 *  the running time of a method using a doubling test.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/14analysis">Section 1.4</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   DoublingTest   {
     private   static   final   int  MAXIMUM_INTEGER  =   1000000 ;

     // This class should not be instantiated.
     private   DoublingTest ()   {   }

     /**
     * Returns the amount of time to call { @code  ThreeSum.count()} with <em>n</em>
     * random 6-digit integers.
     *  @param  n the number of integers
     *  @return  amount of time (in seconds) to call { @code  ThreeSum.count()}
     *   with <em>n</em> random 6-digit integers
     */
     public   static   double  timeTrial ( int  n )   {
         int []  a  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            a [ i ]   =   StdRandom . uniform ( - MAXIMUM_INTEGER ,  MAXIMUM_INTEGER );
         }
         Stopwatch  timer  =   new   Stopwatch ();
         ThreeSum . count ( a );
         return  timer . elapsedTime ();
     }

     /**
     * Prints table of running times to call { @code  ThreeSum.count()}
     * for arrays of size 250, 500, 1000, 2000, and so forth.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         for   ( int  n  =   250 ;   true ;  n  +=  n )   {
             double  time  =  timeTrial ( n );
             StdOut . printf ( "%7d %7.1f\n" ,  n ,  time );
         }  
     }  
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Draw.java

edu/princeton/cs/algs4/Draw.java

/******************************************************************************
 *  Compilation:  javac Draw.java
 *  Execution:    java Draw
 *  Dependencies: none
 *
 *  Drawing library. This class provides a basic capability for creating
 *  drawings with your programs. It uses a simple graphics model that
 *  allows you to create drawings consisting of points, lines, and curves
 *  in a window on your computer and to save the drawings to a file.
 *  This is the object-oriented version of standard draw; it supports
 *  multiple indepedent drawing windows.
 *
 *  Todo
 *  ----
 *    -  Add support for gradient fill, etc.
 *
 *  Remarks
 *  -------
 *    -  don't use AffineTransform for rescaling since it inverts
 *       images and strings
 *    -  careful using setFont in inner loop within an animation -
 *       it can cause flicker
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . BasicStroke ;
import  java . awt . Color ;
import  java . awt . Component ;
import  java . awt . FileDialog ;
import  java . awt . Font ;
import  java . awt . FontMetrics ;
import  java . awt . Graphics ;
import  java . awt . Graphics2D ;
import  java . awt . Image ;
import  java . awt . MediaTracker ;
import  java . awt . RenderingHints ;
import  java . awt . Toolkit ;

import  java . awt . event . ActionEvent ;
import  java . awt . event . ActionListener ;
import  java . awt . event . MouseEvent ;
import  java . awt . event . MouseListener ;
import  java . awt . event . MouseMotionListener ;
import  java . awt . event . KeyEvent ;
import  java . awt . event . KeyListener ;

import  java . awt . geom . Arc2D ;
import  java . awt . geom . Ellipse2D ;
import  java . awt . geom . GeneralPath ;
import  java . awt . geom . Line2D ;
import  java . awt . geom . Rectangle2D ;

import  java . awt . image . BufferedImage ;
import  java . awt . image . DirectColorModel ;
import  java . awt . image . WritableRaster ;

import  java . io . File ;
import  java . io . IOException ;

import  java . net . MalformedURLException ;
import  java . net . URL ;

import  java . util . ArrayList ;
import  java . util . LinkedList ;
import  java . util . TreeSet ;

import  javax . imageio . ImageIO ;

import  javax . swing . ImageIcon ;
import  javax . swing . JFrame ;
import  javax . swing . JLabel ;
import  javax . swing . JMenu ;
import  javax . swing . JMenuBar ;
import  javax . swing . JMenuItem ;
import  javax . swing . KeyStroke ;

/**
 *  <i>Draw</i>. This class provides a basic capability for
 *  creating drawings with your programs. It uses a simple graphics model that
 *  allows you to create drawings consisting of points, lines, and curves
 *  in a window on your computer and to save the drawings to a file.
 *  This is the object-oriented version of standard draw; it supports
 *  multiple indepedent drawing windows.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   Draw   implements   ActionListener ,   MouseListener ,   MouseMotionListener ,   KeyListener   {

     /**
     *  The color black.
     */
     public   static   final   Color  BLACK  =   Color . BLACK ;

     /**
     *  The color blue.
     */
     public   static   final   Color  BLUE  =   Color . BLUE ;

     /**
     *  The color cyan.
     */
     public   static   final   Color  CYAN  =   Color . CYAN ;

     /**
     *  The color dark gray.
     */
     public   static   final   Color  DARK_GRAY  =   Color . DARK_GRAY ;

     /**
     *  The color gray.
     */
     public   static   final   Color  GRAY  =   Color . GRAY ;

     /**
     *  The color green.
     */
     public   static   final   Color  GREEN   =   Color . GREEN ;

     /**
     *  The color light gray.
     */
     public   static   final   Color  LIGHT_GRAY  =   Color . LIGHT_GRAY ;

     /**
     *  The color magenta.
     */
     public   static   final   Color  MAGENTA  =   Color . MAGENTA ;

     /**
     *  The color orange.
     */
     public   static   final   Color  ORANGE  =   Color . ORANGE ;

     /**
     *  The color pink.
     */
     public   static   final   Color  PINK  =   Color . PINK ;

     /**
     *  The color red.
     */
     public   static   final   Color  RED  =   Color . RED ;

     /**
     *  The color white.
     */
     public   static   final   Color  WHITE  =   Color . WHITE ;

     /**
     *  The color yellow.
     */
     public   static   final   Color  YELLOW  =   Color . YELLOW ;

     /**
     * Shade of blue used in Introduction to Programming in Java.
     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).
     */
     public   static   final   Color  BOOK_BLUE  =   new   Color ( 9 ,   90 ,   166 );

     /**
     * Shade of light blue used in Introduction to Programming in Java.
     * The RGB values are approximately (103, 198, 243).
     */
     public   static   final   Color  BOOK_LIGHT_BLUE  =   new   Color ( 103 ,   198 ,   243 );
    
     /**
     * Shade of red used in <em>Algorithms, 4th edition</em>.
     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).
     */
     public   static   final   Color  BOOK_RED  =   new   Color ( 150 ,   35 ,   31 );

     /**
     * Shade of orange used in Princeton's identity.
     * It is PMS 158. The RGB values are approximately (245, 128, 37).
     */
     public   static   final   Color  PRINCETON_ORANGE  =   new   Color ( 245 ,   128 ,   37 );

     // default colors
     private   static   final   Color  DEFAULT_PEN_COLOR    =  BLACK ;
     private   static   final   Color  DEFAULT_CLEAR_COLOR  =  WHITE ;

     // boundary of drawing canvas, 0% border
     private   static   final   double  BORDER  =   0.0 ;
     private   static   final   double  DEFAULT_XMIN  =   0.0 ;
     private   static   final   double  DEFAULT_XMAX  =   1.0 ;
     private   static   final   double  DEFAULT_YMIN  =   0.0 ;
     private   static   final   double  DEFAULT_YMAX  =   1.0 ;

     // default canvas size is SIZE-by-SIZE
     private   static   final   int  DEFAULT_SIZE  =   512 ;

     // default pen radius
     private   static   final   double  DEFAULT_PEN_RADIUS  =   0.002 ;

     // default font
     private   static   final   Font  DEFAULT_FONT  =   new   Font ( "SansSerif" ,   Font . PLAIN ,   16 );

     // current pen color
     private   Color  penColor ;

     // canvas size
     private   int  width   =  DEFAULT_SIZE ;
     private   int  height  =  DEFAULT_SIZE ;

     // current pen radius
     private   double  penRadius ;

     // show we draw immediately or wait until next show?
     private   boolean  defer  =   false ;

     private   double  xmin ,  ymin ,  xmax ,  ymax ;

     // name of window
     private   String  name  =   "Draw" ;

     // for synchronization
     private   final   Object  mouseLock  =   new   Object ();
     private   final   Object  keyLock  =   new   Object ();

     // current font
     private   Font  font ;

     // the JLabel for drawing
     private   JLabel  draw ;

     // double buffered graphics
     private   BufferedImage  offscreenImage ,  onscreenImage ;
     private   Graphics2D  offscreen ,  onscreen ;

     // the frame for drawing to the screen
     private   JFrame  frame  =   new   JFrame ();

     // mouse state
     private   boolean  isMousePressed  =   false ;
     private   double  mouseX  =   0 ;
     private   double  mouseY  =   0 ;

     // keyboard state
     private   final   LinkedList < Character >  keysTyped  =   new   LinkedList < Character > ();
     private   final   TreeSet < Integer >  keysDown  =   new   TreeSet < Integer > ();

     // event-based listeners
     private   final   ArrayList < DrawListener >  listeners  =   new   ArrayList < DrawListener > ();


     /**
     * Initializes an empty drawing object with the given name.
     *
     *  @param  name the title of the drawing window.
     */
     public   Draw ( String  name )   {
         this . name  =  name ;
        init ();
     }

     /**
     * Initializes an empty drawing object.
     */
     public   Draw ()   {
        init ();
     }

     private   void  init ()   {
         if   ( frame  !=   null )  frame . setVisible ( false );
        frame  =   new   JFrame ();
        offscreenImage  =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );
        onscreenImage   =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );
        offscreen  =  offscreenImage . createGraphics ();
        onscreen   =  onscreenImage . createGraphics ();
        offscreen . scale ( 2.0 ,   2.0 );    // since we made it 2x as big

        setXscale ();
        setYscale ();
        offscreen . setColor ( DEFAULT_CLEAR_COLOR );
        offscreen . fillRect ( 0 ,   0 ,  width ,  height );
        setPenColor ();
        setPenRadius ();
        setFont ();
        clear ();

         // add antialiasing
         RenderingHints  hints  =   new   RenderingHints ( RenderingHints . KEY_ANTIALIASING ,
                                                   RenderingHints . VALUE_ANTIALIAS_ON );
        hints . put ( RenderingHints . KEY_RENDERING ,   RenderingHints . VALUE_RENDER_QUALITY );
        offscreen . addRenderingHints ( hints );

         // frame stuff
         RetinaImageIcon  icon  =   new   RetinaImageIcon ( onscreenImage );
        draw  =   new   JLabel ( icon );

        draw . addMouseListener ( this );
        draw . addMouseMotionListener ( this );

        frame . setContentPane ( draw );
        frame . addKeyListener ( this );      // JLabel cannot get keyboard focus
        frame . setResizable ( false );
         // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            // closes all windows
        frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );        // closes only current window
        frame . setFocusTraversalKeysEnabled ( false );    // to recognize VK_TAB with isKeyPressed()
        frame . setTitle ( name );
        frame . setJMenuBar ( createMenuBar ());
        frame . pack ();
        frame . requestFocusInWindow ();
        frame . setVisible ( true );
     }


     /**
     * Sets the upper-left hand corner of the drawing window to be (x, y), where (0, 0) is upper left.
     *
     *  @param   x the number of pixels from the left
     *  @param   y the number of pixels from the top
     *  @throws  IllegalArgumentException if the width or height is 0 or negative
     */
     public   void  setLocationOnScreen ( int  x ,   int  y )   {
         if   ( <=   0   ||  y  <=   0 )   throw   new   IllegalArgumentException ();
        frame . setLocation ( x ,  y );
     }

     /**
     * Sets the default close operation.
     *
     *  @param   value the value, typically { @code  JFrame.EXIT_ON_CLOSE}
     *         (close all windows) or { @code  JFrame.DISPOSE_ON_CLOSE}
     *         (close current window)
     */
     public   void  setDefaultCloseOperation ( int  value )   {
        frame . setDefaultCloseOperation ( value );
     }
       

     /**
     * Sets the canvas (drawing area) to be <em>width</em>-by-<em>height</em> pixels.
     * This also erases the current drawing and resets the coordinate system, pen radius,
     * pen color, and font back to their default values.
     * Ordinarly, this method is called once, at the very beginning of a program.
     *
     *  @param   canvasWidth the width as a number of pixels
     *  @param   canvasHeight the height as a number of pixels
     *  @throws  IllegalArgumentException unless both { @code  canvasWidth}
     *         and { @code  canvasHeight} are positive
     */
     public   void  setCanvasSize ( int  canvasWidth ,   int  canvasHeight )   {
         if   ( canvasWidth  <   1   ||  canvasHeight  <   1 )   {
             throw   new   IllegalArgumentException ( "width and height must be positive" );
         }
        width  =  canvasWidth ;
        height  =  canvasHeight ;
        init ();
     }


     // create the menu bar (changed to private)
     private   JMenuBar  createMenuBar ()   {
         JMenuBar  menuBar  =   new   JMenuBar ();
         JMenu  menu  =   new   JMenu ( "File" );
        menuBar . add ( menu );
         JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );
        menuItem1 . addActionListener ( this );
         // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()
        menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,
                                 Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));
        menu . add ( menuItem1 );
         return  menuBar ;
     }


    /***************************************************************************
    *  User and screen coordinate systems.
    ***************************************************************************/

     // throw an IllegalArgumentException if x is NaN or infinite
     private   static   void  validate ( double  x ,   String  name )   {
         if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );
         if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );
     }

     // throw an IllegalArgumentException if s is null
     private   static   void  validateNonnegative ( double  x ,   String  name )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );
     }

     // throw an IllegalArgumentException if s is null
     private   static   void  validateNotNull ( Object  x ,   String  name )   {
         if   ( ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );
     }

     /**
     * Sets the x-scale to be the default (between 0.0 and 1.0).
     */
     public   void  setXscale ()   {
        setXscale ( DEFAULT_XMIN ,  DEFAULT_XMAX );
     }

     /**
     * Sets the y-scale to be the default (between 0.0 and 1.0).
     */
     public   void  setYscale ()   {
        setYscale ( DEFAULT_YMIN ,  DEFAULT_YMAX );
     }

     /**
     * Sets the x-scale.
     *
     *  @param  min the minimum value of the x-scale
     *  @param  max the maximum value of the x-scale
     *  @throws  IllegalArgumentException if { @code  (max == min)}
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite
     */
     public   void  setXscale ( double  min ,   double  max )   {
        validate ( min ,   "min" );
        validate ( max ,   "max" );
         double  size  =  max  -  min ;
         if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );
        xmin  =  min  -  BORDER  *  size ;
        xmax  =  max  +  BORDER  *  size ;
     }

     /**
     * Sets the y-scale.
     *
     *  @param  min the minimum value of the y-scale
     *  @param  max the maximum value of the y-scale
     *  @throws  IllegalArgumentException if { @code  (max == min)}
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite
     */
     public   void  setYscale ( double  min ,   double  max )   {
        validate ( min ,   "min" );
        validate ( max ,   "max" );
         double  size  =  max  -  min ;
         if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );
        ymin  =  min  -  BORDER  *  size ;
        ymax  =  max  +  BORDER  *  size ;
     }

     // helper functions that scale from user coordinates to screen coordinates and back
     private   double   scaleX ( double  x )   {   return  width   *   ( -  xmin )   /   ( xmax  -  xmin );   }
     private   double   scaleY ( double  y )   {   return  height  *   ( ymax  -  y )   /   ( ymax  -  ymin );   }
     private   double  factorX ( double  w )   {   return  w  *  width   /   Math . abs ( xmax  -  xmin );    }
     private   double  factorY ( double  h )   {   return  h  *  height  /   Math . abs ( ymax  -  ymin );    }
     private   double    userX ( double  x )   {   return  xmin  +  x  *   ( xmax  -  xmin )   /  width ;      }
     private   double    userY ( double  y )   {   return  ymax  -  y  *   ( ymax  -  ymin )   /  height ;     }


     /**
     * Clears the screen to the default color (white).
     */
     public   void  clear ()   {
        clear ( DEFAULT_CLEAR_COLOR );
     }

     /**
     * Clears the screen to the given color.
     *
     *  @param  color the color to make the background
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   void  clear ( Color  color )   {
        validateNotNull ( color ,   "color" );
        offscreen . setColor ( color );
        offscreen . fillRect ( 0 ,   0 ,  width ,  height );
        offscreen . setColor ( penColor );
        draw ();
     }

     /**
     * Gets the current pen radius.
     *
     *  @return  the current pen radius
     */
     public   double  getPenRadius ()   {
         return  penRadius ;
     }

     /**
     * Sets the pen size to the default (.002).
     */
     public   void  setPenRadius ()   {
        setPenRadius ( DEFAULT_PEN_RADIUS );
     }

     /**
     * Sets the radius of the pen to the given size.
     *
     *  @param   radius the radius of the pen
     *  @throws  IllegalArgumentException if { @code  radius} is negative, NaN, or infinite
     */
     public   void  setPenRadius ( double  radius )   {
        validate ( radius ,   "pen radius" );
        validateNonnegative ( radius ,   "pen radius" );

        penRadius  =  radius  *  DEFAULT_SIZE ;
         BasicStroke  stroke  =   new   BasicStroke (( float )  penRadius ,   BasicStroke . CAP_ROUND ,   BasicStroke . JOIN_ROUND );
         // BasicStroke stroke = new BasicStroke((float) penRadius);
        offscreen . setStroke ( stroke );
     }

     /**
     * Gets the current pen color.
     *
     *  @return  the current pen color
     */
     public   Color  getPenColor ()   {
         return  penColor ;
     }

     /**
     * Sets the pen color to the default color (black).
     */
     public   void  setPenColor ()   {
        setPenColor ( DEFAULT_PEN_COLOR );
     }

     /**
     * Sets the pen color to the given color.
     *
     *  @param  color the color to make the pen
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   void  setPenColor ( Color  color )   {
        validateNotNull ( color ,   "color" );
        penColor  =  color ;
        offscreen . setColor ( penColor );
     }

     /**
     * Sets the pen color to the given RGB color.
     *
     *  @param   red the amount of red (between 0 and 255)
     *  @param   green the amount of green (between 0 and 255)
     *  @param   blue the amount of blue (between 0 and 255)
     *  @throws  IllegalArgumentException if { @code  red}, { @code  green},
     *         or { @code  blue} is outside its prescribed range
     */
     public   void  setPenColor ( int  red ,   int  green ,   int  blue )   {
         if   ( red    <   0   ||  red    >=   256 )   throw   new   IllegalArgumentException ( "red must be between 0 and 255" );
         if   ( green  <   0   ||  green  >=   256 )   throw   new   IllegalArgumentException ( "green must be between 0 and 255" );
         if   ( blue   <   0   ||  blue   >=   256 )   throw   new   IllegalArgumentException ( "blue must be between 0 and 255" );
        setPenColor ( new   Color ( red ,  green ,  blue ));
     }


     /**
     * Turns on xor mode.
     */
     public   void  xorOn ()   {
        offscreen . setXORMode ( DEFAULT_CLEAR_COLOR );
     }

     /**
     * Turns off xor mode.
     */
     public   void  xorOff ()   {
        offscreen . setPaintMode ();
     }

     /**
     * Gets the current { @code  JLabel} for use in some other GUI.
     *
     *  @return  the current { @code  JLabel}
     */
     public   JLabel  getJLabel ()   {
         return  draw ;
     }

     /**
     * Gets the current font.
     *
     *  @return  the current font
     */
     public   Font  getFont ()   {
         return  font ;
     }

     /**
     * Sets the font to the default font (sans serif, 16 point).
     */
     public   void  setFont ()   {
        setFont ( DEFAULT_FONT );
     }

     /**
     * Sets the font to the given value.
     *
     *  @param  font the font
     *  @throws  IllegalArgumentException if { @code  font} is { @code  null}
     */
     public   void  setFont ( Font  font )   {
        validateNotNull ( font ,   "font" );
         this . font  =  font ;
     }


    /***************************************************************************
    *  Drawing geometric shapes.
    ***************************************************************************/

     /**
     * Draws a line from (x0, y0) to (x1, y1).
     *
     *  @param  x0 the x-coordinate of the starting point
     *  @param  y0 the y-coordinate of the starting point
     *  @param  x1 the x-coordinate of the destination point
     *  @param  y1 the y-coordinate of the destination point
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     */
     public   void  line ( double  x0 ,   double  y0 ,   double  x1 ,   double  y1 )   {
        validate ( x0 ,   "x0" );
        validate ( y0 ,   "y0" );
        validate ( x1 ,   "x1" );
        validate ( y1 ,   "y1" );
        offscreen . draw ( new   Line2D . Double ( scaleX ( x0 ),  scaleY ( y0 ),  scaleX ( x1 ),  scaleY ( y1 )));
        draw ();
     }

     /**
     * Draws one pixel at (x, y).
     *
     *  @param  x the x-coordinate of the pixel
     *  @param  y the y-coordinate of the pixel
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     private   void  pixel ( double  x ,   double  y )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        offscreen . fillRect (( int )   Math . round ( scaleX ( x )),   ( int )   Math . round ( scaleY ( y )),   1 ,   1 );
     }

     /**
     * Draws a point at (x, y).
     *
     *  @param  x the x-coordinate of the point
     *  @param  y the y-coordinate of the point
     *  @throws  IllegalArgumentException if either { @code  x} or { @code  y} is either NaN or infinite
     */
     public   void  point ( double  x ,   double  y )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  r  =  penRadius ;
         // double ws = factorX(2*r);
         // double hs = factorY(2*r);
         // if (ws <= 1 && hs <= 1) pixel(x, y);
         if   ( <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  r / 2 ,  ys  -  r / 2 ,  r ,  r ));
        draw ();
     }

     /**
     * Draws a circle of the specified radius, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the x-coordinate of the center of the circle
     *  @param   y the y-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  circle ( double  x ,   double  y ,   double  radius )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "radius" );
        validateNonnegative ( radius ,   "radius" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled circle of the specified radius, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the x-coordinate of the center of the circle
     *  @param   y the y-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  filledCircle ( double  x ,   double  y ,   double  radius )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "radius" );
        validateNonnegative ( radius ,   "radius" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws an ellipse with the specified semimajor and semiminor axes,
     * centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the ellipse
     *  @param   y the <em>y</em>-coordinate of the center of the ellipse
     *  @param   semiMajorAxis is the semimajor axis of the ellipse
     *  @param   semiMinorAxis is the semiminor axis of the ellipse
     *  @throws  IllegalArgumentException if either { @code  semiMajorAxis}
     *         or { @code  semiMinorAxis} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  ellipse ( double  x ,   double  y ,   double  semiMajorAxis ,   double  semiMinorAxis )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( semiMajorAxis ,   "semimajor axis" );
        validate ( semiMinorAxis ,   "semiminor axis" );
        validateNonnegative ( semiMajorAxis ,   "semimajor axis" );
        validateNonnegative ( semiMinorAxis ,   "semiminor axis" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * semiMajorAxis );
         double  hs  =  factorY ( 2 * semiMinorAxis );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled ellipse with the specified semimajor and semiminor axes,
     * centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the ellipse
     *  @param   y the <em>y</em>-coordinate of the center of the ellipse
     *  @param   semiMajorAxis is the semimajor axis of the ellipse
     *  @param   semiMinorAxis is the semiminor axis of the ellipse
     *  @throws  IllegalArgumentException if either { @code  semiMajorAxis}
     *         or { @code  semiMinorAxis} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  filledEllipse ( double  x ,   double  y ,   double  semiMajorAxis ,   double  semiMinorAxis )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( semiMajorAxis ,   "semimajor axis" );
        validate ( semiMinorAxis ,   "semiminor axis" );
        validateNonnegative ( semiMajorAxis ,   "semimajor axis" );
        validateNonnegative ( semiMinorAxis ,   "semiminor axis" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * semiMajorAxis );
         double  hs  =  factorY ( 2 * semiMinorAxis );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a circular arc of the specified radius,
     * centered at (<em>x</em>, <em>y</em>), from angle1 to angle2 (in degrees).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the circle
     *  @param   y the <em>y</em>-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @param   angle1 the starting angle. 0 would mean an arc beginning at 3 o'clock.
     *  @param   angle2 the angle at the end of the arc. For example, if
     *         you want a 90 degree arc, then angle2 should be angle1 + 90.
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  arc ( double  x ,   double  y ,   double  radius ,   double  angle1 ,   double  angle2 )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "arc radius" );
        validate ( angle1 ,   "angle1" );
        validate ( angle2 ,   "angle2" );
        validateNonnegative ( radius ,   "arc radius" );

         while   ( angle2  <  angle1 )  angle2  +=   360 ;
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Arc2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ,  angle1 ,  angle2  -  angle1 ,   Arc2D . OPEN ));
        draw ();
     }

     /**
     * Draws a square of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the square
     *  @param   y the <em>y</em>-coordinate of the center of the square
     *  @param   halfLength one half the length of any side of the square
     *  @throws  IllegalArgumentException if { @code  halfLength} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  square ( double  x ,   double  y ,   double  halfLength )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfLength ,   "halfLength" );
        validateNonnegative ( halfLength ,   "half length" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfLength );
         double  hs  =  factorY ( 2 * halfLength );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a square of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the square
     *  @param   y the <em>y</em>-coordinate of the center of the square
     *  @param   halfLength one half the length of any side of the square
     *  @throws  IllegalArgumentException if { @code  halfLength} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  filledSquare ( double  x ,   double  y ,   double  halfLength )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfLength ,   "halfLength" );
        validateNonnegative ( halfLength ,   "half length" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfLength );
         double  hs  =  factorY ( 2 * halfLength );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws a rectangle of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the rectangle
     *  @param   y the <em>y</em>-coordinate of the center of the rectangle
     *  @param   halfWidth one half the width of the rectangle
     *  @param   halfHeight one half the height of the rectangle
     *  @throws  IllegalArgumentException if either { @code  halfWidth} or { @code  halfHeight} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  rectangle ( double  x ,   double  y ,   double  halfWidth ,   double  halfHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfWidth ,   "halfWidth" );
        validate ( halfHeight ,   "halfHeight" );
        validateNonnegative ( halfWidth ,   "half width" );
        validateNonnegative ( halfHeight ,   "half height" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfWidth );
         double  hs  =  factorY ( 2 * halfHeight );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled rectangle of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the rectangle
     *  @param   y the <em>y</em>-coordinate of the center of the rectangle
     *  @param   halfWidth one half the width of the rectangle
     *  @param   halfHeight one half the height of the rectangle
     *  @throws  IllegalArgumentException if either { @code  halfWidth} or { @code  halfHeight} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   void  filledRectangle ( double  x ,   double  y ,   double  halfWidth ,   double  halfHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfWidth ,   "halfWidth" );
        validate ( halfHeight ,   "halfHeight" );
        validateNonnegative ( halfWidth ,   "half width" );
        validateNonnegative ( halfHeight ,   "half height" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfWidth );
         double  hs  =  factorY ( 2 * halfHeight );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a polygon with the vertices 
     * (<em>x</em><sub>0</sub>, <em>y</em><sub>0</sub>),
     * (<em>x</em><sub>1</sub>, <em>y</em><sub>1</sub>), ...,
     * (<em>x</em><sub><em>n</em>–1</sub>, <em>y</em><sub><em>n</em>–1</sub>).
     *
     *  @param   x an array of all the <em>x</em>-coordinates of the polygon
     *  @param   y an array of all the <em>y</em>-coordinates of the polygon
     *  @throws  IllegalArgumentException unless { @code  x[]} and { @code  y[]}
     *         are of the same length
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     *  @throws  IllegalArgumentException if either { @code  x[]} or { @code  y[]} is { @code  null}
     */
     public   void  polygon ( double []  x ,   double []  y )   {
        validateNotNull ( x ,   "x-coordinate array" );
        validateNotNull ( y ,   "y-coordinate array" );
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )  validate ( x [ i ],   "x["   +  i  +   "]" );
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )  validate ( y [ i ],   "y["   +  i  +   "]" );

         int  n1  =  x . length ;
         int  n2  =  y . length ;
         if   ( n1  !=  n2 )   throw   new   IllegalArgumentException ( "arrays must be of the same length" );
         int  n  =  n1 ;
         if   ( ==   0 )   return ;

         GeneralPath  path  =   new   GeneralPath ();
        path . moveTo (( float )  scaleX ( x [ 0 ]),   ( float )  scaleY ( y [ 0 ]));
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            path . lineTo (( float )  scaleX ( x [ i ]),   ( float )  scaleY ( y [ i ]));
        path . closePath ();
        offscreen . draw ( path );
        draw ();
     }

     /**
     * Draws a filled polygon with the vertices 
     * (<em>x</em><sub>0</sub>, <em>y</em><sub>0</sub>),
     * (<em>x</em><sub>1</sub>, <em>y</em><sub>1</sub>), ...,
     * (<em>x</em><sub><em>n</em>–1</sub>, <em>y</em><sub><em>n</em>–1</sub>).
     *
     *  @param   x an array of all the <em>x</em>-coordinates of the polygon
     *  @param   y an array of all the <em>y</em>-coordinates of the polygon
     *  @throws  IllegalArgumentException unless { @code  x[]} and { @code  y[]}
     *         are of the same length
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     *  @throws  IllegalArgumentException if either { @code  x[]} or { @code  y[]} is { @code  null}
     */
     public   void  filledPolygon ( double []  x ,   double []  y )   {
        validateNotNull ( x ,   "x-coordinate array" );
        validateNotNull ( y ,   "y-coordinate array" );
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )  validate ( x [ i ],   "x["   +  i  +   "]" );
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )  validate ( y [ i ],   "y["   +  i  +   "]" );

         int  n1  =  x . length ;
         int  n2  =  y . length ;
         if   ( n1  !=  n2 )   throw   new   IllegalArgumentException ( "arrays must be of the same length" );
         int  n  =  n1 ;
         if   ( ==   0 )   return ;

         GeneralPath  path  =   new   GeneralPath ();
        path . moveTo (( float )  scaleX ( x [ 0 ]),   ( float )  scaleY ( y [ 0 ]));
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            path . lineTo (( float )  scaleX ( x [ i ]),   ( float )  scaleY ( y [ i ]));
        path . closePath ();
        offscreen . fill ( path );
        draw ();
     }



    /***************************************************************************
    *  Drawing images.
    ***************************************************************************/

     // get an image from the given filename
     private   static   Image  getImage ( String  filename )   {
         if   ( filename  ==   null )   throw   new   IllegalArgumentException ();

         // to read from file
         ImageIcon  icon  =   new   ImageIcon ( filename );

         // try to read from URL
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
             try   {
                URL url  =   new  URL ( filename );
                icon  =   new   ImageIcon ( url );
             }
             catch   ( MalformedURLException  e )   {
                 /* not a url */
             }
         }

         // in case file is inside a .jar (classpath relative to StdDraw)
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
            URL url  =   StdDraw . class . getResource ( filename );
             if   ( url  !=   null )
                icon  =   new   ImageIcon ( url );
         }

         // in case file is inside a .jar (classpath relative to root of jar)
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
            URL url  =   Draw . class . getResource ( "/"   +  filename );
             if   ( url  ==   null )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " not found" );
            icon  =   new   ImageIcon ( url );
         }

         return  icon . getImage ();
     }

     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>).
     * The supported image formats are JPEG, PNG, and GIF.
     * As an optimization, the picture is cached, so there is no performance
     * penalty for redrawing the same image multiple times (e.g., in an animation).
     * However, if you change the picture file after drawing it, subsequent
     * calls will draw the original picture.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if either { @code  x} or { @code  y} is either NaN or infinite
     */
     public   void  picture ( double  x ,   double  y ,   String  filename )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( filename ,   "filename" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  image . getWidth ( null );
         int  hs  =  image . getHeight ( null );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );

        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),   ( int )   Math . round ( ys  -  hs / 2.0 ),   null );
        draw ();
     }

     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>),
     * rotated given number of degrees.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if { @code  x}, { @code  y}, { @code  degrees} is NaN or infinite
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   void  picture ( double  x ,   double  y ,   String  filename ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( filename ,   "filename" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  image . getWidth ( null );
         int  hs  =  image . getHeight ( null );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );

        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),   ( int )   Math . round ( ys  -  hs / 2.0 ),   null );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );

        draw ();
     }

     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>),
     * rescaled to the specified bounding box.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   scaledWidth the width of the scaled image (in screen coordinates)
     *  @param   scaledHeight the height of the scaled image (in screen coordinates)
     *  @throws  IllegalArgumentException if either { @code  scaledWidth}
     *         or { @code  scaledHeight} is negative
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   void  picture ( double  x ,   double  y ,   String  filename ,   double  scaledWidth ,   double  scaledHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( scaledWidth ,   "scaled width" );
        validate ( scaledHeight ,   "scaled height" );
        validateNotNull ( filename ,   "filename" );
        validateNonnegative ( scaledWidth ,   "scaled width" );
        validateNonnegative ( scaledHeight ,   "scaled height" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( scaledWidth );
         double  hs  =  factorY ( scaledHeight );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else   {
            offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),
                                        ( int )   Math . round ( ys  -  hs / 2.0 ),
                                        ( int )   Math . round ( ws ),
                                        ( int )   Math . round ( hs ),   null );
         }
        draw ();
     }


     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>), rotated
     * given number of degrees, and rescaled to the specified bounding box.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   scaledWidth the width of the scaled image (in screen coordinates)
     *  @param   scaledHeight the height of the scaled image (in screen coordinates)
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if either { @code  scaledWidth}
     *         or { @code  scaledHeight} is negative
     *  @throws  IllegalArgumentException if the image filename is invalid
     */
     public   void  picture ( double  x ,   double  y ,   String  filename ,   double  scaledWidth ,   double  scaledHeight ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( scaledWidth ,   "scaled width" );
        validate ( scaledHeight ,   "scaled height" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( filename ,   "filename" );
        validateNonnegative ( scaledWidth ,   "scaled width" );
        validateNonnegative ( scaledHeight ,   "scaled height" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( scaledWidth );
         double  hs  =  factorY ( scaledHeight );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );

        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),
                                    ( int )   Math . round ( ys  -  hs / 2.0 ),
                                    ( int )   Math . round ( ws ),
                                    ( int )   Math . round ( hs ),   null );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );

        draw ();
     }


    /***************************************************************************
    *  Drawing text.
    ***************************************************************************/

     /**
     * Writes the given text string in the current font, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the center <em>x</em>-coordinate of the text
     *  @param   y the center <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   void  text ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  metrics . stringWidth ( text );
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )   ( xs  -  ws / 2.0 ),   ( float )   ( ys  +  hs ));
        draw ();
     }

     /**
     * Writes the given text string in the current font, centered at (<em>x</em>, <em>y</em>) and
     * rotated by the specified number of degrees.
     *  @param   x the center <em>x</em>-coordinate of the text
     *  @param   y the center <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x}, { @code  y}, or { @code  degrees} is either NaN or infinite
     */
     public   void  text ( double  x ,   double  y ,   String  text ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( text ,   "text" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        text ( x ,  y ,  text );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );
     }

     /**
     * Writes the given text string in the current font, left-aligned at (<em>x</em>, <em>y</em>).
     *  @param   x the <em>x</em>-coordinate of the text
     *  @param   y the <em>y</em>-coordinate of the text
     *  @param   text the text
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   void  textLeft ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         // int ws = metrics.stringWidth(text);
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )  xs ,   ( float )   ( ys  +  hs ));
        draw ();
     }

     /**
     * Writes the given text string in the current font, right-aligned at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the text
     *  @param   y the <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   void  textRight ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  metrics . stringWidth ( text );
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )   ( xs  -  ws ),   ( float )   ( ys  +  hs ));
        draw ();
     }

     /**
     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds
     * and enables double buffering.
     *  @param  t number of milliseconds
     *  @deprecated  replaced by { @link  #enableDoubleBuffering()}, { @link  #show()}, and { @link  #pause(int t)}
     */
    @ Deprecated
     public   void  show ( int  t )   {
        show ();
        pause ( t );
        enableDoubleBuffering ();
     }

     /**
     * Pause for t milliseconds. This method is intended to support computer animations.
     *  @param  t number of milliseconds
     */
     public   void  pause ( int  t )   {
         try   {
             Thread . sleep ( t );
         }
         catch   ( InterruptedException  e )   {
             System . out . println ( "Error sleeping" );
         }
     }

     /**
     * Copies offscreen buffer to onscreen buffer. There is no reason to call
     * this method unless double buffering is enabled.
     */
     public   void  show ()   {
        onscreen . drawImage ( offscreenImage ,   0 ,   0 ,   null );
        frame . repaint ();
     }

     // draw onscreen if defer is false
     private   void  draw ()   {
         if   ( ! defer )  show ();
     }

     /**
     * Enable double buffering. All subsequent calls to 
     * drawing methods such as { @code  line()}, { @code  circle()},
     * and { @code  square()} will be deferred until the next call
     * to show(). Useful for animations.
     */
     public   void  enableDoubleBuffering ()   {
        defer  =   true ;
     }

     /**
     * Disable double buffering. All subsequent calls to 
     * drawing methods such as { @code  line()}, { @code  circle()},
     * and { @code  square()} will be displayed on screen when called.
     * This is the default.
     */
     public   void  disableDoubleBuffering ()   {
        defer  =   false ;
     }

     /**
     * Saves the drawing to using the specified filename.
     * The supported image formats are JPEG and PNG;
     * the filename suffix must be { @code  .jpg} or { @code  .png}.
     *
     *  @param   filename the name of the file with one of the required suffixes
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   void  save ( String  filename )   {
        validateNotNull ( filename ,   "filename" );
         File  file  =   new   File ( filename );
         String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );

         // png files
         if   ( "png" . equalsIgnoreCase ( suffix ))   {
             try   {
                 ImageIO . write ( offscreenImage ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }

         // need to change from ARGB to RGB for jpeg
         // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727
         else   if   ( "jpg" . equalsIgnoreCase ( suffix ))   {
             WritableRaster  raster  =  offscreenImage . getRaster ();
             WritableRaster  newRaster ;
            newRaster  =  raster . createWritableChild ( 0 ,   0 ,  width ,  height ,   0 ,   0 ,   new   int []   { 0 ,   1 ,   2 });
             DirectColorModel  cm  =   ( DirectColorModel )  offscreenImage . getColorModel ();
             DirectColorModel  newCM  =   new   DirectColorModel ( cm . getPixelSize (),
                                                          cm . getRedMask (),
                                                          cm . getGreenMask (),
                                                          cm . getBlueMask ());
             BufferedImage  rgbBuffer  =   new   BufferedImage ( newCM ,  newRaster ,   false ,    null );
             try   {
                 ImageIO . write ( rgbBuffer ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }

         else   {
             System . out . println ( "Invalid image file type: "   +  suffix );
         }
     }


     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  actionPerformed ( ActionEvent  e )   {
         FileDialog  chooser  =   new   FileDialog ( frame ,   "Use a .png or .jpg extension" ,   FileDialog . SAVE );
        chooser . setVisible ( true );
         String  filename  =  chooser . getFile ();
         if   ( filename  !=   null )   {
            save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());
         }
     }



    /***************************************************************************
    *  Event-based interactions.
    ***************************************************************************/

     /**
     * Adds a { @link  DrawListener} to listen to keyboard and mouse events.
     *
     *  @param  listener the {\tt DrawListener} argument
     */
     public   void  addListener ( DrawListener  listener )   {
         // ensure there is a window for listenting to events
        show ();
        listeners . add ( listener );
        frame . addKeyListener ( this );
        frame . addMouseListener ( this );
        frame . addMouseMotionListener ( this );
        frame . setFocusable ( true );  
     }




    /***************************************************************************
    *  Mouse interactions.
    ***************************************************************************/

     /**
     * Returns true if the mouse is being pressed.
     *
     *  @return  { @code  true} if the mouse is being pressed;
     *         { @code  false} otherwise
     */
     public   boolean  isMousePressed ()   {
         synchronized   ( mouseLock )   {
             return  isMousePressed ;
         }
     }

     /**
     * Returns true if the mouse is being pressed.
     *
     *  @return  { @code  true} if the mouse is being pressed;
     *         { @code  false} otherwise
     *  @deprecated  replaced by { @link  #isMousePressed()}
     */
    @ Deprecated
     public   boolean  mousePressed ()   {
         synchronized   ( mouseLock )   {
             return  isMousePressed ;
         }
     }

     /**
     * Returns the x-coordinate of the mouse.
     *  @return  the x-coordinate of the mouse
     */
     public   double  mouseX ()   {
         synchronized   ( mouseLock )   {
             return  mouseX ;
         }
     }

     /**
     * Returns the y-coordinate of the mouse.
     *
     *  @return  the y-coordinate of the mouse
     */
     public   double  mouseY ()   {
         synchronized   ( mouseLock )   {
             return  mouseY ;
         }
     }



     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseEntered ( MouseEvent  e )   {
         // this body is intentionally left empty
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseExited ( MouseEvent  e )   {
         // this body is intentionally left empty
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mousePressed ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            mouseX  =  userX ( e . getX ());
            mouseY  =  userY ( e . getY ());
            isMousePressed  =   true ;
         }
         if   ( e . getButton ()   ==   MouseEvent . BUTTON1 )   {
             for   ( DrawListener  listener  :  listeners )
                listener . mousePressed ( userX ( e . getX ()),  userY ( e . getY ()));
         }

     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseReleased ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            isMousePressed  =   false ;
         }
         if   ( e . getButton ()   ==   MouseEvent . BUTTON1 )   {
             for   ( DrawListener  listener  :  listeners )
                listener . mouseReleased ( userX ( e . getX ()),  userY ( e . getY ()));
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseClicked ( MouseEvent  e )   {
         if   ( e . getButton ()   ==   MouseEvent . BUTTON1 )   {
             for   ( DrawListener  listener  :  listeners )
                listener . mouseClicked ( userX ( e . getX ()),  userY ( e . getY ()));
         }
     }


     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseDragged ( MouseEvent  e )    {
         synchronized   ( mouseLock )   {
            mouseX  =  userX ( e . getX ());
            mouseY  =  userY ( e . getY ());
         }
         // doesn't seem to work if a button is specified
         for   ( DrawListener  listener  :  listeners )
            listener . mouseDragged ( userX ( e . getX ()),  userY ( e . getY ()));
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseMoved ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            mouseX  =  userX ( e . getX ());
            mouseY  =  userY ( e . getY ());
         }
     }


    /***************************************************************************
    *  Keyboard interactions.
    ***************************************************************************/

     /**
     * Returns true if the user has typed a key.
     *
     *  @return  { @code  true} if the user has typed a key; { @code  false} otherwise
     */
     public   boolean  hasNextKeyTyped ()   {
         synchronized   ( keyLock )   {
             return   ! keysTyped . isEmpty ();
         }
     }

     /**
     * The next key typed by the user.
     *
     *  @return  the next key typed by the user
     */
     public   char  nextKeyTyped ()   {
         synchronized   ( keyLock )   {
             return  keysTyped . removeLast ();
         }
     }

    /**
     * Returns true if the keycode is being pressed.
     * <p>
     * This method takes as an argument the keycode (corresponding to a physical key).
     * It can handle action keys (such as F1 and arrow keys) and modifier keys
     * (such as shift and control).
     * See { @link  KeyEvent} for a description of key codes.
     *
     *  @param   keycode the keycode to check
     *  @return  { @code  true} if { @code  keycode} is currently being pressed;
     *         { @code  false} otherwise
     */
     public   boolean  isKeyPressed ( int  keycode )   {
         synchronized   ( keyLock )   {
             return  keysDown . contains ( keycode );
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyTyped ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysTyped . addFirst ( e . getKeyChar ());
         }

         // notify all listeners
         for   ( DrawListener  listener  :  listeners )
            listener . keyTyped ( e . getKeyChar ());
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyPressed ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysDown . add ( e . getKeyCode ());
         }

         // notify all listeners
         for   ( DrawListener  listener  :  listeners )
            listener . keyPressed ( e . getKeyCode ());
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyReleased ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysDown . remove ( e . getKeyCode ());
         }

         // notify all listeners
         for   ( DrawListener  listener  :  listeners )
            listener . keyReleased ( e . getKeyCode ());
     }


    /***************************************************************************
    *  For improved resolution on Mac Retina displays.
    ***************************************************************************/

     private   static   class   RetinaImageIcon   extends   ImageIcon   {
    
         public   RetinaImageIcon ( Image  image )   {
             super ( image );
         }

         public   int  getIconWidth ()   {
             return   super . getIconWidth ()   /   2 ;
         }

         /**
         * Gets the height of the icon.
         *
         *  @return  the height in pixels of this icon
         */
         public   int  getIconHeight ()   {
             return   super . getIconHeight ()   /   2 ;
         }

         public   synchronized   void  paintIcon ( Component  c ,   Graphics  g ,   int  x ,   int  y )   {
             Graphics2D  g2  =   ( Graphics2D )  g . create ();
            g2 . setRenderingHint ( RenderingHints . KEY_INTERPOLATION , RenderingHints . VALUE_INTERPOLATION_BICUBIC );
            g2 . setRenderingHint ( RenderingHints . KEY_RENDERING , RenderingHints . VALUE_RENDER_QUALITY );
            g2 . setRenderingHint ( RenderingHints . KEY_ANTIALIASING , RenderingHints . VALUE_ANTIALIAS_ON );
            g2 . scale ( 0.5 ,   0.5 );
             super . paintIcon ( c ,  g2 ,  x  *   2 ,  y  *   2 );
            g2 . dispose ();
         }
     }

     /**
     * Test client.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create one drawing window
         Draw  draw1  =   new   Draw ( "Test client 1" );
        draw1 . square ( 0.2 ,   0.8 ,   0.1 );
        draw1 . filledSquare ( 0.8 ,   0.8 ,   0.2 );
        draw1 . circle ( 0.8 ,   0.2 ,   0.2 );
        draw1 . setPenColor ( Draw . MAGENTA );
        draw1 . setPenRadius ( 0.02 );
        draw1 . arc ( 0.8 ,   0.2 ,   0.1 ,   200 ,   45 );


         // create another one
         Draw  draw2  =   new   Draw ( "Test client 2" );
        draw2 . setCanvasSize ( 900 ,   200 );
         // draw a blue diamond
        draw2 . setPenRadius ();
        draw2 . setPenColor ( Draw . BLUE );
         double []  x  =   {   0.1 ,   0.2 ,   0.3 ,   0.2   };
         double []  y  =   {   0.2 ,   0.3 ,   0.2 ,   0.1   };
        draw2 . filledPolygon ( x ,  y );

         // text
        draw2 . setPenColor ( Draw . BLACK );
        draw2 . text ( 0.2 ,   0.5 ,   "bdfdfdfdlack text" );
        draw2 . setPenColor ( Draw . WHITE );
        draw2 . text ( 0.8 ,   0.8 ,   "white text" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/DrawListener.java

edu/princeton/cs/algs4/DrawListener.java

/******************************************************************************
 *  Compilation:  javac DrawListener.java
 *  Execution:    none
 *  Dependencies: none
 *
 *  Interface that accompanies Draw.java.
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  <i>DrawListener</i>. This interface provides a basic capability for
 *  responding to keyboard in mouse events from { @link  Draw} via callbacks.
 *  You can see some examples in
 *  <a href="https://introcs.cs.princeton.edu/java/36inheritance">Section 3.6</a>.
 *
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   interface   DrawListener   {

     /**
     * Invoked when the mouse has been pressed.
     *
     *  @param  x the x-coordinate of the mouse
     *  @param  y the y-coordinate of the mouse
     */
     void  mousePressed ( double  x ,   double  y );

     /**
     * Invoked when the mouse has been dragged.
     *
     *  @param  x the x-coordinate of the mouse
     *  @param  y the y-coordinate of the mouse
     */
     void  mouseDragged ( double  x ,   double  y );

     /**
     * Invoked when the mouse has been released.
     *
     *  @param  x the x-coordinate of the mouse
     *  @param  y the y-coordinate of the mouse
     */
     void  mouseReleased ( double  x ,   double  y );

     /**
     * Invoked when the mouse has been clicked (pressed and released).
     *
     *  @param  x the x-coordinate of the mouse
     *  @param  y the y-coordinate of the mouse
     */
     void  mouseClicked ( double  x ,   double  y );

     /**
     * Invoked when a key has been typed.
     *
     *  @param  c the character typed
     */
     void  keyTyped ( char  c );

     /**
     * Invoked when a key has been pressed.
     *
     *  @param  keycode the key combination pressed
     */
     void  keyPressed ( int  keycode );

     /**
     * Invoked when a key has been released.
     *
     *  @param  keycode the key combination released
     */
     void  keyReleased ( int  keycode );
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Edge.java

edu/princeton/cs/algs4/Edge.java

/******************************************************************************
 *  Compilation:  javac Edge.java
 *  Execution:    java Edge
 *  Dependencies: StdOut.java
 *
 *  Immutable weighted edge.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Edge} class represents a weighted edge in an 
 *  { @link  EdgeWeightedGraph}. Each edge consists of two integers
 *  (naming the two vertices) and a real-value weight. The data type
 *  provides methods for accessing the two endpoints of the edge and
 *  the weight. The natural order for this data type is by
 *  ascending order of weight.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Edge   implements   Comparable < Edge >   {  

     private   final   int  v ;
     private   final   int  w ;
     private   final   double  weight ;

     /**
     * Initializes an edge between vertices { @code  v} and { @code  w} of
     * the given { @code  weight}.
     *
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @param   weight the weight of this edge
     *  @throws  IllegalArgumentException if either { @code  v} or { @code  w} 
     *         is a negative integer
     *  @throws  IllegalArgumentException if { @code  weight} is { @code  NaN}
     */
     public   Edge ( int  v ,   int  w ,   double  weight )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a nonnegative integer" );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a nonnegative integer" );
         if   ( Double . isNaN ( weight ))   throw   new   IllegalArgumentException ( "Weight is NaN" );
         this . =  v ;
         this . =  w ;
         this . weight  =  weight ;
     }

     /**
     * Returns the weight of this edge.
     *
     *  @return  the weight of this edge
     */
     public   double  weight ()   {
         return  weight ;
     }

     /**
     * Returns either endpoint of this edge.
     *
     *  @return  either endpoint of this edge
     */
     public   int  either ()   {
         return  v ;
     }

     /**
     * Returns the endpoint of this edge that is different from the given vertex.
     *
     *  @param   vertex one endpoint of this edge
     *  @return  the other endpoint of this edge
     *  @throws  IllegalArgumentException if the vertex is not one of the
     *         endpoints of this edge
     */
     public   int  other ( int  vertex )   {
         if        ( vertex  ==  v )   return  w ;
         else   if   ( vertex  ==  w )   return  v ;
         else   throw   new   IllegalArgumentException ( "Illegal endpoint" );
     }

     /**
     * Compares two edges by weight.
     * Note that { @code  compareTo()} is not consistent with { @code  equals()},
     * which uses the reference equality implementation inherited from { @code  Object}.
     *
     *  @param   that the other edge
     *  @return  a negative integer, zero, or positive integer depending on whether
     *         the weight of this is less than, equal to, or greater than the
     *         argument edge
     */
    @ Override
     public   int  compareTo ( Edge  that )   {
         return   Double . compare ( this . weight ,  that . weight );
     }

     /**
     * Returns a string representation of this edge.
     *
     *  @return  a string representation of this edge
     */
     public   String  toString ()   {
         return   String . format ( "%d-%d %.5f" ,  v ,  w ,  weight );
     }

     /**
     * Unit tests the { @code  Edge} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Edge  e  =   new   Edge ( 12 ,   34 ,   5.67 );
         StdOut . println ( e );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/EdgeWeightedDigraph.java

edu/princeton/cs/algs4/EdgeWeightedDigraph.java

/******************************************************************************
 *  Compilation:  javac EdgeWeightedDigraph.java
 *  Execution:    java EdgeWeightedDigraph digraph.txt
 *  Dependencies: Bag.java DirectedEdge.java
 *  Data files:   https://algs4.cs.princeton.edu/44sp/tinyEWD.txt
 *                https://algs4.cs.princeton.edu/44sp/mediumEWD.txt
 *                https://algs4.cs.princeton.edu/44sp/largeEWD.txt
 *
 *  An edge-weighted digraph, implemented using adjacency lists.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  EdgeWeightedDigraph} class represents a edge-weighted
 *  digraph of vertices named 0 through <em>V</em> - 1, where each
 *  directed edge is of type { @link  DirectedEdge} and has a real-valued weight.
 *  It supports the following two primary operations: add a directed edge
 *  to the digraph and iterate over all of edges incident from a given vertex.
 *  It also provides methods for returning the indegree or outdegree of a
 *  vertex, the number of vertices <em>V</em> in the digraph, and
 *  the number of edges <em>E</em> in the digraph.
 *  Parallel edges and self-loops are permitted.
 *  <p>
 *  This implementation uses an <em>adjacency-lists representation</em>, which
 *  is a vertex-indexed array of { @link  Bag} objects.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) space, where <em>E</em> is
 *  the number of edges and <em>V</em> is the number of vertices.
 *  All instance methods take &Theta;(1) time. (Though, iterating over
 *  the edges returned by { @link  #adj(int)} takes time proportional
 *  to the outdegree of the vertex.)
 *  Constructing an empty edge-weighted digraph with <em>V</em> vertices
 *  takes &Theta;(<em>V</em>) time; constructing an edge-weighted digraph
 *  with <em>E</em> edges and <em>V</em> vertices takes
 *  &Theta;(<em>E</em> + <em>V</em>) time. 
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   EdgeWeightedDigraph   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;                  // number of vertices in this digraph
     private   int  E ;                        // number of edges in this digraph
     private   Bag < DirectedEdge > []  adj ;      // adj[v] = adjacency list for vertex v
     private   int []  indegree ;               // indegree[v] = indegree of vertex v
    
     /**
     * Initializes an empty edge-weighted digraph with { @code  V} vertices and 0 edges.
     *
     *  @param   V the number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   EdgeWeightedDigraph ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Digraph must be nonnegative" );
         this . =  V ;
         this . =   0 ;
         this . indegree  =   new   int [ V ];
        adj  =   ( Bag < DirectedEdge > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            adj [ v ]   =   new   Bag < DirectedEdge > ();
     }

     /**
     * Initializes a random edge-weighted digraph with { @code  V} vertices and <em>E</em> edges.
     *
     *  @param   V the number of vertices
     *  @param   E the number of edges
     *  @throws  IllegalArgumentException if { @code  V < 0}
     *  @throws  IllegalArgumentException if { @code  E < 0}
     */
     public   EdgeWeightedDigraph ( int  V ,   int  E )   {
         this ( V );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of edges in a Digraph must be nonnegative" );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  weight  =   0.01   *   StdRandom . uniform ( 100 );
             DirectedEdge  e  =   new   DirectedEdge ( v ,  w ,  weight );
            addEdge ( e );
         }
     }

     /**  
     * Initializes an edge-weighted digraph from the specified input stream.
     * The format is the number of vertices <em>V</em>,
     * followed by the number of edges <em>E</em>,
     * followed by <em>E</em> pairs of vertices and edge weights,
     * with each entry separated by whitespace.
     *
     *  @param   in the input stream
     *  @throws  IllegalArgumentException if { @code  in} is { @code  null}
     *  @throws  IllegalArgumentException if the endpoints of any edge are not in prescribed range
     *  @throws  IllegalArgumentException if the number of vertices or edges is negative
     */
     public   EdgeWeightedDigraph ( In  in )   {
         if   ( in  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );
         try   {
             this . =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Digraph must be nonnegative" );
            indegree  =   new   int [ V ];
            adj  =   ( Bag < DirectedEdge > [])   new   Bag [ V ];
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                adj [ v ]   =   new   Bag < DirectedEdge > ();
             }

             int  E  =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );
             for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
                 int  v  =  in . readInt ();
                 int  w  =  in . readInt ();
                validateVertex ( v );
                validateVertex ( w );
                 double  weight  =  in . readDouble ();
                addEdge ( new   DirectedEdge ( v ,  w ,  weight ));
             }
         }    
         catch   ( NoSuchElementException  e )   {
             throw   new   IllegalArgumentException ( "invalid input format in EdgeWeightedDigraph constructor" ,  e );
         }
     }

     /**
     * Initializes a new edge-weighted digraph that is a deep copy of { @code  G}.
     *
     *  @param   G the edge-weighted digraph to copy
     */
     public   EdgeWeightedDigraph ( EdgeWeightedDigraph  G )   {
         this ( G . V ());
         this . =  G . E ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             this . indegree [ v ]   =  G . indegree ( v );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             // reverse so that adjacency list is in same order as original
             Stack < DirectedEdge >  reverse  =   new   Stack < DirectedEdge > ();
             for   ( DirectedEdge  e  :  G . adj [ v ])   {
                reverse . push ( e );
             }
             for   ( DirectedEdge  e  :  reverse )   {
                adj [ v ]. add ( e );
             }
         }
     }

     /**
     * Returns the number of vertices in this edge-weighted digraph.
     *
     *  @return  the number of vertices in this edge-weighted digraph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in this edge-weighted digraph.
     *
     *  @return  the number of edges in this edge-weighted digraph
     */
     public   int  E ()   {
         return  E ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Adds the directed edge { @code  e} to this edge-weighted digraph.
     *
     *  @param   e the edge
     *  @throws  IllegalArgumentException unless endpoints of edge are between { @code  0}
     *         and { @code  V-1}
     */
     public   void  addEdge ( DirectedEdge  e )   {
         int  v  =  e . from ();
         int  w  =  e . to ();
        validateVertex ( v );
        validateVertex ( w );
        adj [ v ]. add ( e );
        indegree [ w ] ++ ;
        E ++ ;
     }


     /**
     * Returns the directed edges incident from vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the directed edges incident from vertex { @code  v} as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  adj ( int  v )   {
        validateVertex ( v );
         return  adj [ v ];
     }

     /**
     * Returns the number of directed edges incident from vertex { @code  v}.
     * This is known as the <em>outdegree</em> of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the outdegree of vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  outdegree ( int  v )   {
        validateVertex ( v );
         return  adj [ v ]. size ();
     }

     /**
     * Returns the number of directed edges incident to vertex { @code  v}.
     * This is known as the <em>indegree</em> of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the indegree of vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  indegree ( int  v )   {
        validateVertex ( v );
         return  indegree [ v ];
     }

     /**
     * Returns all directed edges in this edge-weighted digraph.
     * To iterate over the edges in this edge-weighted digraph, use foreach notation:
     * { @code  for (DirectedEdge e : G.edges())}.
     *
     *  @return  all edges in this edge-weighted digraph, as an iterable
     */
     public   Iterable < DirectedEdge >  edges ()   {
         Bag < DirectedEdge >  list  =   new   Bag < DirectedEdge > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             for   ( DirectedEdge  e  :  adj ( v ))   {
                list . add ( e );
             }
         }
         return  list ;
     }  

     /**
     * Returns a string representation of this edge-weighted digraph.
     *
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,
     *         followed by the <em>V</em> adjacency lists of edges
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " "   +  E  +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( +   ": " );
             for   ( DirectedEdge  e  :  adj [ v ])   {
                s . append ( +   "  " );
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  EdgeWeightedDigraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( in );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.java

edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.java

/******************************************************************************
 *  Compilation:  javac EdgeWeightedDirectedCycle.java
 *  Execution:    java EdgeWeightedDirectedCycle V E F
 *  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Stack.java
 *
 *  Finds a directed cycle in an edge-weighted digraph.
 *  Runs in O(E + V) time.
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  EdgeWeightedDirectedCycle} class represents a data type for 
 *  determining whether an edge-weighted digraph has a directed cycle.
 *  The <em>hasCycle</em> operation determines whether the edge-weighted
 *  digraph has a directed cycle and, if so, the <em>cycle</em> operation
 *  returns one.
 *  <p>
 *  This implementation uses <em>depth-first search</em>.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the 
 *  edge-weighted digraph).
 *  <p>
 *  See { @link  Topological} to compute a topological order if the
 *  edge-weighted digraph is acyclic.
 *  <p>
 *  For additional documentation,   
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of   
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   EdgeWeightedDirectedCycle   {
     private   boolean []  marked ;               // marked[v] = has vertex v been marked?
     private   DirectedEdge []  edgeTo ;          // edgeTo[v] = previous edge on path to v
     private   boolean []  onStack ;              // onStack[v] = is vertex on the stack?
     private   Stack < DirectedEdge >  cycle ;      // directed cycle (or null if no such cycle)

     /**
     * Determines whether the edge-weighted digraph { @code  G} has a directed cycle and,
     * if so, finds such a cycle.
     *  @param  G the edge-weighted digraph
     */
     public   EdgeWeightedDirectedCycle ( EdgeWeightedDigraph  G )   {
        marked   =   new   boolean [ G . V ()];
        onStack  =   new   boolean [ G . V ()];
        edgeTo   =   new   DirectedEdge [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( ! marked [ v ])  dfs ( G ,  v );

         // check that digraph has a cycle
         assert  check ();
     }

     // check that algorithm computes either the topological order or finds a directed cycle
     private   void  dfs ( EdgeWeightedDigraph  G ,   int  v )   {
        onStack [ v ]   =   true ;
        marked [ v ]   =   true ;
         for   ( DirectedEdge  e  :  G . adj ( v ))   {
             int  w  =  e . to ();

             // short circuit if directed cycle found
             if   ( cycle  !=   null )   return ;

             // found new vertex, so recur
             else   if   ( ! marked [ w ])   {
                edgeTo [ w ]   =  e ;
                dfs ( G ,  w );
             }

             // trace back directed cycle
             else   if   ( onStack [ w ])   {
                cycle  =   new   Stack < DirectedEdge > ();

                 DirectedEdge  f  =  e ;
                 while   ( f . from ()   !=  w )   {
                    cycle . push ( f );
                    f  =  edgeTo [ f . from ()];
                 }
                cycle . push ( f );

                 return ;
             }
         }

        onStack [ v ]   =   false ;
     }

     /**
     * Does the edge-weighted digraph have a directed cycle?
     *  @return  { @code  true} if the edge-weighted digraph has a directed cycle,
     * { @code  false} otherwise
     */
     public   boolean  hasCycle ()   {
         return  cycle  !=   null ;
     }

     /**
     * Returns a directed cycle if the edge-weighted digraph has a directed cycle,
     * and { @code  null} otherwise.
     *  @return  a directed cycle (as an iterable) if the edge-weighted digraph
     *    has a directed cycle, and { @code  null} otherwise
     */
     public   Iterable < DirectedEdge >  cycle ()   {
         return  cycle ;
     }


     // certify that digraph is either acyclic or has a directed cycle
     private   boolean  check ()   {

         // edge-weighted digraph is cyclic
         if   ( hasCycle ())   {
             // verify cycle
             DirectedEdge  first  =   null ,  last  =   null ;
             for   ( DirectedEdge  e  :  cycle ())   {
                 if   ( first  ==   null )  first  =  e ;
                 if   ( last  !=   null )   {
                     if   ( last . to ()   !=  e . from ())   {
                         System . err . printf ( "cycle edges %s and %s not incident\n" ,  last ,  e );
                         return   false ;
                     }
                 }
                last  =  e ;
             }

             if   ( last . to ()   !=  first . from ())   {
                 System . err . printf ( "cycle edges %s and %s not incident\n" ,  last ,  first );
                 return   false ;
             }
         }


         return   true ;
     }

     /**
     * Unit tests the { @code  EdgeWeightedDirectedCycle} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create random DAG with V vertices and E edges; then add F random edges
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         int  F  =   Integer . parseInt ( args [ 2 ]);
         EdgeWeightedDigraph  G  =   new   EdgeWeightedDigraph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v ,  w ;
             do   {
                v  =   StdRandom . uniform ( V );
                w  =   StdRandom . uniform ( V );
             }   while   ( >=  w );
             double  weight  =   StdRandom . uniform ();
            G . addEdge ( new   DirectedEdge ( v ,  w ,  weight ));
         }

         // add F extra edges
         for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  weight  =   StdRandom . uniform ( 0.0 ,   1.0 );
            G . addEdge ( new   DirectedEdge ( v ,  w ,  weight ));
         }

         StdOut . println ( G );

         // find a directed cycle
         EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( G );
         if   ( finder . hasCycle ())   {
             StdOut . print ( "Cycle: " );
             for   ( DirectedEdge  e  :  finder . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

         // or give topologial sort
         else   {
             StdOut . println ( "No directed cycle" );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/EdgeWeightedGraph.java

edu/princeton/cs/algs4/EdgeWeightedGraph.java

/******************************************************************************
 *  Compilation:  javac EdgeWeightedGraph.java
 *  Execution:    java EdgeWeightedGraph filename.txt
 *  Dependencies: Bag.java Edge.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  An edge-weighted undirected graph, implemented using adjacency lists.
 *  Parallel edges and self-loops are permitted.
 *
 *  % java EdgeWeightedGraph tinyEWG.txt 
 *  8 16
 *  0: 6-0 0.58000  0-2 0.26000  0-4 0.38000  0-7 0.16000  
 *  1: 1-3 0.29000  1-2 0.36000  1-7 0.19000  1-5 0.32000  
 *  2: 6-2 0.40000  2-7 0.34000  1-2 0.36000  0-2 0.26000  2-3 0.17000  
 *  3: 3-6 0.52000  1-3 0.29000  2-3 0.17000  
 *  4: 6-4 0.93000  0-4 0.38000  4-7 0.37000  4-5 0.35000  
 *  5: 1-5 0.32000  5-7 0.28000  4-5 0.35000  
 *  6: 6-4 0.93000  6-0 0.58000  3-6 0.52000  6-2 0.40000
 *  7: 2-7 0.34000  1-7 0.19000  0-7 0.16000  5-7 0.28000  4-7 0.37000
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  EdgeWeightedGraph} class represents an edge-weighted
 *  graph of vertices named 0 through <em>V</em> – 1, where each
 *  undirected edge is of type { @link  Edge} and has a real-valued weight.
 *  It supports the following two primary operations: add an edge to the graph,
 *  iterate over all of the edges incident to a vertex. It also provides
 *  methods for returning the degree of a vertex, the number of vertices
 *  <em>V</em> in the graph, and the number of edges <em>E</em> in the graph.
 *  Parallel edges and self-loops are permitted.
 *  By convention, a self-loop <em>v</em>-<em>v</em> appears in the
 *  adjacency list of <em>v</em> twice and contributes two to the degree
 *  of <em>v</em>.
 *  <p>
 *  This implementation uses an <em>adjacency-lists representation</em>, which
 *  is a vertex-indexed array of { @link  Bag} objects.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) space, where <em>E</em> is
 *  the number of edges and <em>V</em> is the number of vertices.
 *  All instance methods take &Theta;(1) time. (Though, iterating over
 *  the edges returned by { @link  #adj(int)} takes time proportional
 *  to the degree of the vertex.)
 *  Constructing an empty edge-weighted graph with <em>V</em> vertices takes
 *  &Theta;(<em>V</em>) time; constructing a edge-weighted graph with
 *  <em>E</em> edges and <em>V</em> vertices takes
 *  &Theta;(<em>E</em> + <em>V</em>) time. 
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   EdgeWeightedGraph   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;
     private   int  E ;
     private   Bag < Edge > []  adj ;
    
     /**
     * Initializes an empty edge-weighted graph with { @code  V} vertices and 0 edges.
     *
     *  @param   V the number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   EdgeWeightedGraph ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );
         this . =  V ;
         this . =   0 ;
        adj  =   ( Bag < Edge > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            adj [ v ]   =   new   Bag < Edge > ();
         }
     }

     /**
     * Initializes a random edge-weighted graph with { @code  V} vertices and <em>E</em> edges.
     *
     *  @param   V the number of vertices
     *  @param   E the number of edges
     *  @throws  IllegalArgumentException if { @code  V < 0}
     *  @throws  IllegalArgumentException if { @code  E < 0}
     */
     public   EdgeWeightedGraph ( int  V ,   int  E )   {
         this ( V );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  weight  =   Math . round ( 100   *   StdRandom . uniform ())   /   100.0 ;
             Edge  e  =   new   Edge ( v ,  w ,  weight );
            addEdge ( e );
         }
     }

     /**  
     * Initializes an edge-weighted graph from an input stream.
     * The format is the number of vertices <em>V</em>,
     * followed by the number of edges <em>E</em>,
     * followed by <em>E</em> pairs of vertices and edge weights,
     * with each entry separated by whitespace.
     *
     *  @param   in the input stream
     *  @throws  IllegalArgumentException if { @code  in} is { @code  null}
     *  @throws  IllegalArgumentException if the endpoints of any edge are not in prescribed range
     *  @throws  IllegalArgumentException if the number of vertices or edges is negative
     */
     public   EdgeWeightedGraph ( In  in )   {
         if   ( in  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );

         try   {
            V  =  in . readInt ();
            adj  =   ( Bag < Edge > [])   new   Bag [ V ];
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                adj [ v ]   =   new   Bag < Edge > ();
             }

             int  E  =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );
             for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
                 int  v  =  in . readInt ();
                 int  w  =  in . readInt ();
                validateVertex ( v );
                validateVertex ( w );
                 double  weight  =  in . readDouble ();
                 Edge  e  =   new   Edge ( v ,  w ,  weight );
                addEdge ( e );
             }
         }    
         catch   ( NoSuchElementException  e )   {
             throw   new   IllegalArgumentException ( "invalid input format in EdgeWeightedGraph constructor" ,  e );
         }

     }

     /**
     * Initializes a new edge-weighted graph that is a deep copy of { @code  G}.
     *
     *  @param   G the edge-weighted graph to copy
     */
     public   EdgeWeightedGraph ( EdgeWeightedGraph  G )   {
         this ( G . V ());
         this . =  G . E ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             // reverse so that adjacency list is in same order as original
             Stack < Edge >  reverse  =   new   Stack < Edge > ();
             for   ( Edge  e  :  G . adj [ v ])   {
                reverse . push ( e );
             }
             for   ( Edge  e  :  reverse )   {
                adj [ v ]. add ( e );
             }
         }
     }


     /**
     * Returns the number of vertices in this edge-weighted graph.
     *
     *  @return  the number of vertices in this edge-weighted graph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in this edge-weighted graph.
     *
     *  @return  the number of edges in this edge-weighted graph
     */
     public   int  E ()   {
         return  E ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Adds the undirected edge { @code  e} to this edge-weighted graph.
     *
     *  @param   e the edge
     *  @throws  IllegalArgumentException unless both endpoints are between { @code  0} and { @code  V-1}
     */
     public   void  addEdge ( Edge  e )   {
         int  v  =  e . either ();
         int  w  =  e . other ( v );
        validateVertex ( v );
        validateVertex ( w );
        adj [ v ]. add ( e );
        adj [ w ]. add ( e );
        E ++ ;
     }

     /**
     * Returns the edges incident on vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the edges incident on vertex { @code  v} as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Edge >  adj ( int  v )   {
        validateVertex ( v );
         return  adj [ v ];
     }

     /**
     * Returns the degree of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the degree of vertex { @code  v}               
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  degree ( int  v )   {
        validateVertex ( v );
         return  adj [ v ]. size ();
     }

     /**
     * Returns all edges in this edge-weighted graph.
     * To iterate over the edges in this edge-weighted graph, use foreach notation:
     * { @code  for (Edge e : G.edges())}.
     *
     *  @return  all edges in this edge-weighted graph, as an iterable
     */
     public   Iterable < Edge >  edges ()   {
         Bag < Edge >  list  =   new   Bag < Edge > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             int  selfLoops  =   0 ;
             for   ( Edge  e  :  adj ( v ))   {
                 if   ( e . other ( v )   >  v )   {
                    list . add ( e );
                 }
                 // add only one copy of each self loop (self loops will be consecutive)
                 else   if   ( e . other ( v )   ==  v )   {
                     if   ( selfLoops  %   2   ==   0 )  list . add ( e );
                    selfLoops ++ ;
                 }
             }
         }
         return  list ;
     }

     /**
     * Returns a string representation of the edge-weighted graph.
     * This method takes time proportional to <em>E</em> + <em>V</em>.
     *
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,
     *         followed by the <em>V</em> adjacency lists of edges
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " "   +  E  +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( +   ": " );
             for   ( Edge  e  :  adj [ v ])   {
                s . append ( +   "  " );
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  EdgeWeightedGraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/EulerianCycle.java

edu/princeton/cs/algs4/EulerianCycle.java

/******************************************************************************
 *  Compilation:  javac EulerianCycle.java
 *  Execution:    java  EulerianCycle V E
 *  Dependencies: Graph.java Stack.java StdOut.java
 *
 *  Find an Eulerian cycle in a graph, if one exists.
 *
 *  Runs in O(E + V) time.
 *
 *  This implementation is tricker than the one for digraphs because
 *  when we use edge v-w from v's adjacency list, we must be careful
 *  not to use the second copy of the edge from w's adjaceny list.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  EulerianCycle} class represents a data type
 *  for finding an Eulerian cycle or path in a graph.
 *  An <em>Eulerian cycle</em> is a cycle (not necessarily simple) that
 *  uses every edge in the graph exactly once.
 *  <p>
 *  This implementation uses a nonrecursive depth-first search.
 *  The constructor takes &Theta;(<em>E</em> + <em>V</em>) time in the worst
 *  case, where <em>E</em> is the number of edges and <em>V</em> is the
 *  number of vertices
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) extra space in the worst case
 *  (not including the graph).
 *  <p>
 *  To compute Eulerian paths in graphs, see { @link  EulerianPath}.
 *  To compute Eulerian cycles and paths in digraphs, see
 *  { @link  DirectedEulerianCycle} and { @link  DirectedEulerianPath}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 * 
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *   @author  Nate Liu
 */
public   class   EulerianCycle   {
     private   Stack < Integer >  cycle  =   new   Stack < Integer > ();    // Eulerian cycle; null if no such cycle

     // an undirected edge, with a field to indicate whether the edge has already been used
     private   static   class   Edge   {
         private   final   int  v ;
         private   final   int  w ;
         private   boolean  isUsed ;

         public   Edge ( int  v ,   int  w )   {
             this . =  v ;
             this . =  w ;
            isUsed  =   false ;
         }

         // returns the other vertex of the edge
         public   int  other ( int  vertex )   {
             if        ( vertex  ==  v )   return  w ;
             else   if   ( vertex  ==  w )   return  v ;
             else   throw   new   IllegalArgumentException ( "Illegal endpoint" );
         }
     }

     /**
     * Computes an Eulerian cycle in the specified graph, if one exists.
     * 
     *  @param  G the graph
     */
     public   EulerianCycle ( Graph  G )   {

         // must have at least one edge
         if   ( G . E ()   ==   0 )   return ;

         // necessary condition: all vertices have even degree
         // (this test is needed or it might find an Eulerian path instead of cycle)
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )  
             if   ( G . degree ( v )   %   2   !=   0 )
                 return ;

         // create local view of adjacency lists, to iterate one vertex at a time
         // the helper Edge data type is used to avoid exploring both copies of an edge v-w
         Queue < Edge > []  adj  =   ( Queue < Edge > [])   new   Queue [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =   new   Queue < Edge > ();

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             int  selfLoops  =   0 ;
             for   ( int  w  :  G . adj ( v ))   {
                 // careful with self loops
                 if   ( ==  w )   {
                     if   ( selfLoops  %   2   ==   0 )   {
                         Edge  e  =   new   Edge ( v ,  w );
                        adj [ v ]. enqueue ( e );
                        adj [ w ]. enqueue ( e );
                     }
                    selfLoops ++ ;
                 }
                 else   if   ( <  w )   {
                     Edge  e  =   new   Edge ( v ,  w );
                    adj [ v ]. enqueue ( e );
                    adj [ w ]. enqueue ( e );
                 }
             }
         }

         // initialize stack with any non-isolated vertex
         int  s  =  nonIsolatedVertex ( G );
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        stack . push ( s );

         // greedily search through edges in iterative DFS style
        cycle  =   new   Stack < Integer > ();
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . pop ();
             while   ( ! adj [ v ]. isEmpty ())   {
                 Edge  edge  =  adj [ v ]. dequeue ();
                 if   ( edge . isUsed )   continue ;
                edge . isUsed  =   true ;
                stack . push ( v );
                v  =  edge . other ( v );
             }
             // push vertex with no more leaving edges to cycle
            cycle . push ( v );
         }

         // check if all edges are used
         if   ( cycle . size ()   !=  G . E ()   +   1 )
            cycle  =   null ;

         assert  certifySolution ( G );
     }

     /**
     * Returns the sequence of vertices on an Eulerian cycle.
     * 
     *  @return  the sequence of vertices on an Eulerian cycle;
     *         { @code  null} if no such cycle
     */
     public   Iterable < Integer >  cycle ()   {
         return  cycle ;
     }

     /**
     * Returns true if the graph has an Eulerian cycle.
     * 
     *  @return  { @code  true} if the graph has an Eulerian cycle;
     *         { @code  false} otherwise
     */
     public   boolean  hasEulerianCycle ()   {
         return  cycle  !=   null ;
     }

     // returns any non-isolated vertex; -1 if no such vertex
     private   static   int  nonIsolatedVertex ( Graph  G )   {
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   >   0 )
                 return  v ;
         return   - 1 ;
     }

     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // Determines whether a graph has an Eulerian cycle using necessary
     // and sufficient conditions (without computing the cycle itself):
     //    - at least one edge
     //    - degree(v) is even for every vertex v
     //    - the graph is connected (ignoring isolated vertices)
     private   static   boolean  satisfiesNecessaryAndSufficientConditions ( Graph  G )   {

         // Condition 0: at least 1 edge
         if   ( G . E ()   ==   0 )   return   false ;

         // Condition 1: degree(v) is even for every vertex
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   %   2   !=   0 )
                 return   false ;

         // Condition 2: graph is connected, ignoring isolated vertices
         int  s  =  nonIsolatedVertex ( G );
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   >   0   &&   ! bfs . hasPathTo ( v ))
                 return   false ;

         return   true ;
     }

     // check that solution is correct
     private   boolean  certifySolution ( Graph  G )   {

         // internal consistency check
         if   ( hasEulerianCycle ()   ==   ( cycle ()   ==   null ))   return   false ;

         // hashEulerianCycle() returns correct value
         if   ( hasEulerianCycle ()   !=  satisfiesNecessaryAndSufficientConditions ( G ))   return   false ;

         // nothing else to check if no Eulerian cycle
         if   ( cycle  ==   null )   return   true ;

         // check that cycle() uses correct number of edges
         if   ( cycle . size ()   !=  G . E ()   +   1 )   return   false ;

         // check that cycle() is a cycle of G
         // TODO

         // check that first and last vertices in cycle() are the same
         int  first  =   - 1 ,  last  =   - 1 ;
         for   ( int  v  :  cycle ())   {
             if   ( first  ==   - 1 )  first  =  v ;
            last  =  v ;
         }
         if   ( first  !=  last )   return   false ;

         return   true ;
     }

     private   static   void  unitTest ( Graph  G ,   String  description )   {
         StdOut . println ( description );
         StdOut . println ( "-------------------------------------" );
         StdOut . print ( G );

         EulerianCycle  euler  =   new   EulerianCycle ( G );

         StdOut . print ( "Eulerian cycle: " );
         if   ( euler . hasEulerianCycle ())   {
             for   ( int  v  :  euler . cycle ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
         else   {
             StdOut . println ( "none" );
         }
         StdOut . println ();
     }


     /**
     * Unit tests the { @code  EulerianCycle} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);

         // Eulerian cycle
         Graph  G1  =   GraphGenerator . eulerianCycle ( V ,  E );
        unitTest ( G1 ,   "Eulerian cycle" );

         // Eulerian path
         Graph  G2  =   GraphGenerator . eulerianPath ( V ,  E );
        unitTest ( G2 ,   "Eulerian path" );

         // empty graph
         Graph  G3  =   new   Graph ( V );
        unitTest ( G3 ,   "empty graph" );

         // self loop
         Graph  G4  =   new   Graph ( V );
         int  v4  =   StdRandom . uniform ( V );
        G4 . addEdge ( v4 ,  v4 );
        unitTest ( G4 ,   "single self loop" );

         // union of two disjoint cycles
         Graph  H1  =   GraphGenerator . eulerianCycle ( V / 2 ,  E / 2 );
         Graph  H2  =   GraphGenerator . eulerianCycle ( -  V / 2 ,  E  -  E / 2 );
         int []  perm  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            perm [ i ]   =  i ;
         StdRandom . shuffle ( perm );
         Graph  G5  =   new   Graph ( V );
         for   ( int  v  =   0 ;  v  <  H1 . V ();  v ++ )
             for   ( int  w  :  H1 . adj ( v ))
                G5 . addEdge ( perm [ v ],  perm [ w ]);
         for   ( int  v  =   0 ;  v  <  H2 . V ();  v ++ )
             for   ( int  w  :  H2 . adj ( v ))
                G5 . addEdge ( perm [ V / 2   +  v ],  perm [ V / 2   +  w ]);
        unitTest ( G5 ,   "Union of two disjoint cycles" );

         // random digraph
         Graph  G6  =   GraphGenerator . simple ( V ,  E );
        unitTest ( G6 ,   "simple graph" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/EulerianPath.java

edu/princeton/cs/algs4/EulerianPath.java

/******************************************************************************
 *  Compilation:  javac EulerianPath.java
 *  Execution:    java EulerianPath V E
 *  Dependencies: Graph.java Stack.java StdOut.java
 *
 *  Find an Eulerian path in a graph, if one exists.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  EulerianPath} class represents a data type
 *  for finding an Eulerian path in a graph.
 *  An <em>Eulerian path</em> is a path (not necessarily simple) that
 *  uses every edge in the graph exactly once.
 *  <p>
 *  This implementation uses a nonrecursive depth-first search.
 *  The constructor takes &Theta;(<em>E</em> + <em>V</em>) time in the worst
 *  case, where <em>E</em> is the number of edges and <em>V</em> is
 *  the number of vertices.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) extra space in the worst case
 *  (not including the digraph).
 *  <p>
 *  To compute Eulerian cycles in graphs, see { @link  EulerianCycle}.
 *  To compute Eulerian cycles and paths in digraphs, see
 *  { @link  DirectedEulerianCycle} and { @link  DirectedEulerianPath}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 * 
 *  @author  Robert Sedgewick
 *  @author  Kevin Wayne
 *  @author  Nate Liu
 */
public   class   EulerianPath   {
     private   Stack < Integer >  path  =   null ;     // Eulerian path; null if no suh path

     // an undirected edge, with a field to indicate whether the edge has already been used
     private   static   class   Edge   {
         private   final   int  v ;
         private   final   int  w ;
         private   boolean  isUsed ;

         public   Edge ( int  v ,   int  w )   {
             this . =  v ;
             this . =  w ;
            isUsed  =   false ;
         }

         // returns the other vertex of the edge
         public   int  other ( int  vertex )   {
             if        ( vertex  ==  v )   return  w ;
             else   if   ( vertex  ==  w )   return  v ;
             else   throw   new   IllegalArgumentException ( "Illegal endpoint" );
         }
     }

     /**
     * Computes an Eulerian path in the specified graph, if one exists.
     * 
     *  @param  G the graph
     */
     public   EulerianPath ( Graph  G )   {

         // find vertex from which to start potential Eulerian path:
         // a vertex v with odd degree(v) if it exits;
         // otherwise a vertex with degree(v) > 0
         int  oddDegreeVertices  =   0 ;
         int  s  =  nonIsolatedVertex ( G );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( G . degree ( v )   %   2   !=   0 )   {
                oddDegreeVertices ++ ;
                s  =  v ;
             }
         }

         // graph can't have an Eulerian path
         // (this condition is needed for correctness)
         if   ( oddDegreeVertices  >   2 )   return ;

         // special case for graph with zero edges (has a degenerate Eulerian path)
         if   ( ==   - 1 )  s  =   0 ;

         // create local view of adjacency lists, to iterate one vertex at a time
         // the helper Edge data type is used to avoid exploring both copies of an edge v-w
         Queue < Edge > []  adj  =   ( Queue < Edge > [])   new   Queue [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =   new   Queue < Edge > ();

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             int  selfLoops  =   0 ;
             for   ( int  w  :  G . adj ( v ))   {
                 // careful with self loops
                 if   ( ==  w )   {
                     if   ( selfLoops  %   2   ==   0 )   {
                         Edge  e  =   new   Edge ( v ,  w );
                        adj [ v ]. enqueue ( e );
                        adj [ w ]. enqueue ( e );
                     }
                    selfLoops ++ ;
                 }
                 else   if   ( <  w )   {
                     Edge  e  =   new   Edge ( v ,  w );
                    adj [ v ]. enqueue ( e );
                    adj [ w ]. enqueue ( e );
                 }
             }
         }

         // initialize stack with any non-isolated vertex
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        stack . push ( s );

         // greedily search through edges in iterative DFS style
        path  =   new   Stack < Integer > ();
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . pop ();
             while   ( ! adj [ v ]. isEmpty ())   {
                 Edge  edge  =  adj [ v ]. dequeue ();
                 if   ( edge . isUsed )   continue ;
                edge . isUsed  =   true ;
                stack . push ( v );
                v  =  edge . other ( v );
             }
             // push vertex with no more leaving edges to path
            path . push ( v );
         }

         // check if all edges are used
         if   ( path . size ()   !=  G . E ()   +   1 )
            path  =   null ;

         assert  certifySolution ( G );
     }

     /**
     * Returns the sequence of vertices on an Eulerian path.
     * 
     *  @return  the sequence of vertices on an Eulerian path;
     *         { @code  null} if no such path
     */
     public   Iterable < Integer >  path ()   {
         return  path ;
     }

     /**
     * Returns true if the graph has an Eulerian path.
     * 
     *  @return  { @code  true} if the graph has an Eulerian path;
     *         { @code  false} otherwise
     */
     public   boolean  hasEulerianPath ()   {
         return  path  !=   null ;
     }


     // returns any non-isolated vertex; -1 if no such vertex
     private   static   int  nonIsolatedVertex ( Graph  G )   {
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   >   0 )
                 return  v ;
         return   - 1 ;
     }


     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // Determines whether a graph has an Eulerian path using necessary
     // and sufficient conditions (without computing the path itself):
     //    - degree(v) is even for every vertex, except for possibly two
     //    - the graph is connected (ignoring isolated vertices)
     // This method is solely for unit testing.
     private   static   boolean  satisfiesNecessaryAndSufficientConditions ( Graph  G )   {
         if   ( G . E ()   ==   0 )   return   true ;

         // Condition 1: degree(v) is even except for possibly two
         int  oddDegreeVertices  =   0 ;
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   %   2   !=   0 )
                oddDegreeVertices ++ ;
         if   ( oddDegreeVertices  >   2 )   return   false ;

         // Condition 2: graph is connected, ignoring isolated vertices
         int  s  =  nonIsolatedVertex ( G );
         BreadthFirstPaths  bfs  =   new   BreadthFirstPaths ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( G . degree ( v )   >   0   &&   ! bfs . hasPathTo ( v ))
                 return   false ;

         return   true ;
     }

     // check that solution is correct
     private   boolean  certifySolution ( Graph  G )   {

         // internal consistency check
         if   ( hasEulerianPath ()   ==   ( path ()   ==   null ))   return   false ;

         // hashEulerianPath() returns correct value
         if   ( hasEulerianPath ()   !=  satisfiesNecessaryAndSufficientConditions ( G ))   return   false ;

         // nothing else to check if no Eulerian path
         if   ( path  ==   null )   return   true ;

         // check that path() uses correct number of edges
         if   ( path . size ()   !=  G . E ()   +   1 )   return   false ;

         // check that path() is a path in G
         // TODO

         return   true ;
     }


     private   static   void  unitTest ( Graph  G ,   String  description )   {
         StdOut . println ( description );
         StdOut . println ( "-------------------------------------" );
         StdOut . print ( G );

         EulerianPath  euler  =   new   EulerianPath ( G );

         StdOut . print ( "Eulerian path:  " );
         if   ( euler . hasEulerianPath ())   {
             for   ( int  v  :  euler . path ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
         else   {
             StdOut . println ( "none" );
         }
         StdOut . println ();
     }


     /**
     * Unit tests the { @code  EulerianPath} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);


         // Eulerian cycle
         Graph  G1  =   GraphGenerator . eulerianCycle ( V ,  E );
        unitTest ( G1 ,   "Eulerian cycle" );

         // Eulerian path
         Graph  G2  =   GraphGenerator . eulerianPath ( V ,  E );
        unitTest ( G2 ,   "Eulerian path" );

         // add one random edge
         Graph  G3  =   new   Graph ( G2 );
        G3 . addEdge ( StdRandom . uniform ( V ),   StdRandom . uniform ( V ));
        unitTest ( G3 ,   "one random edge added to Eulerian path" );

         // self loop
         Graph  G4  =   new   Graph ( V );
         int  v4  =   StdRandom . uniform ( V );
        G4 . addEdge ( v4 ,  v4 );
        unitTest ( G4 ,   "single self loop" );

         // single edge
         Graph  G5  =   new   Graph ( V );
        G5 . addEdge ( StdRandom . uniform ( V ),   StdRandom . uniform ( V ));
        unitTest ( G5 ,   "single edge" );

         // empty graph
         Graph  G6  =   new   Graph ( V );
        unitTest ( G6 ,   "empty graph" );

         // random graph
         Graph  G7  =   GraphGenerator . simple ( V ,  E );
        unitTest ( G7 ,   "simple graph" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FarthestPair.java

edu/princeton/cs/algs4/FarthestPair.java

/******************************************************************************
 *  Compilation:  javac FarthestPair.java
 *  Execution:    java FarthestPair < input.txt
 *  Dependencies: GrahamScan.java Point2D.java
 *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt
 *                https://algs4.cs.princeton.edu/99hull/kw1260.txt
 *  
 *  Given a set of n points in the plane, find the farthest pair
 *  (equivalently, compute the diameter of the set of points).
 *
 *  Computes the convex hull of the set of points and using the
 *  rotating calipers method to find all antipodal point pairs
 *  and the farthest pair.
 *
 *  % java FarthestPair < input100.txt
 *  42697.98170874122 from (32011.0, 3140.0) to (822.0, 32301.0)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  FarthestPair} data type computes the farthest pair of points
 *  in a set of <em>n</em> points in the plane and provides accessor methods
 *  for getting the farthest pair of points and the distance between them.
 *  The distance between two points is their Euclidean distance.
 *  <p>
 *  This implementation computes the convex hull of the set of points and
 *  uses the rotating calipers method to find all antipodal point pairs
 *  and the farthest pair.
 *  It runs in O(<em>n</em> log <em>n</em>) time in the worst case and uses
 *  O(<em>N</em>) extra space.
 *  See also { @link  ClosestPair} and { @link  GrahamScan}.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/99hull">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FarthestPair   {

     // farthest pair of points and distance
     private   Point2D  best1 ,  best2 ;
     private   double  bestDistanceSquared  =   Double . NEGATIVE_INFINITY ;

     /**
     * Computes the farthest pair of points in the specified array of points.
     *
     *  @param   points the array of points
     *  @throws  IllegalArgumentException if { @code  points} is { @code  null} or if any
     *         entry in { @code  points[]} is { @code  null}
     */
     public   FarthestPair ( Point2D []  points )   {
         if   ( points  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );
         for   ( int  i  =   0 ;  i  <  points . length ;  i ++ )   {
             if   ( points [ i ]   ==   null )   throw   new   IllegalArgumentException ( "array element "   +  i  +   " is null" );
         }

         GrahamScan  graham  =   new   GrahamScan ( points );

         // single point
         if   ( points . length  <=   1 )   return ;

         // number of points on the hull
         int  m  =   0 ;
         for   ( Point2D  p  :  graham . hull ())
            m ++ ;

         // the hull, in counterclockwise order hull[1] to hull[m]
         Point2D []  hull  =   new   Point2D [ m + 1 ];
        m  =   1 ;
         for   ( Point2D  p  :  graham . hull ())   {
            hull [ m ++ ]   =  p ;
         }
        m -- ;

         // all points are equal
         if   ( ==   1 )   return ;

         // points are collinear
         if   ( ==   2 )   {
            best1  =  hull [ 1 ];
            best2  =  hull [ 2 ];
            bestDistanceSquared  =  best1 . distanceSquaredTo ( best2 );
             return ;
         }

         // k = farthest vertex from edge from hull[1] to hull[m]
         int  k  =   2 ;
         while   ( Point2D . area2 ( hull [ m ],  hull [ 1 ],  hull [ k + 1 ])   >   Point2D . area2 ( hull [ m ],  hull [ 1 ],  hull [ k ]))   {
            k ++ ;
         }

         int  j  =  k ;
         for   ( int  i  =   1 ;  i  <=  k  &&  j  <=  m ;  i ++ )   {
             // StdOut.println("hull[i] + " and " + hull[j] + " are antipodal");
             if   ( hull [ i ]. distanceSquaredTo ( hull [ j ])   >  bestDistanceSquared )   {
                best1  =  hull [ i ];
                best2  =  hull [ j ];
                bestDistanceSquared  =  hull [ i ]. distanceSquaredTo ( hull [ j ]);
             }
             while   (( <  m )   &&   Point2D . area2 ( hull [ i ],  hull [ i + 1 ],  hull [ j + 1 ])   >   Point2D . area2 ( hull [ i ],  hull [ i + 1 ],  hull [ j ]))   {
                j ++ ;
                 // StdOut.println(hull[i] + " and " + hull[j] + " are antipodal");
                 double  distanceSquared  =  hull [ i ]. distanceSquaredTo ( hull [ j ]);
                 if   ( distanceSquared  >  bestDistanceSquared )   {
                    best1  =  hull [ i ];
                    best2  =  hull [ j ];
                    bestDistanceSquared  =  hull [ i ]. distanceSquaredTo ( hull [ j ]);
                 }
             }
         }
     }

     /**
     * Returns one of the points in the farthest pair of points.
     *
     *  @return  one of the two points in the farthest pair of points;
     *         { @code  null} if no such point (because there are fewer than 2 points)
     */
     public   Point2D  either ()   {
         return  best1 ;
     }

     /**
     * Returns the other point in the farthest pair of points.
     *
     *  @return  the other point in the farthest pair of points
     *         { @code  null} if no such point (because there are fewer than 2 points)
     */
     public   Point2D  other ()   {
         return  best2 ;
     }

     /**
     * Returns the Eucliden distance between the farthest pair of points.
     * This quantity is also known as the <em>diameter</em> of the set of points.
     *
     *  @return  the Euclidean distance between the farthest pair of points
     *         { @code  Double.POSITIVE_INFINITY} if no such pair of points
     *         exist (because there are fewer than 2 points)
     */
     public   double  distance ()   {
         return   Math . sqrt ( bestDistanceSquared );
     }

    /**
     * Unit tests the { @code  FarthestPair} data type.
     * Reads in an integer { @code  n} and { @code  n} points (specified by
     * their <em>x</em>- and <em>y</em>-coordinates) from standard input;
     * computes a farthest pair of points; and prints the pair to standard
     * output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         Point2D []  points  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  x  =   StdIn . readInt ();
             int  y  =   StdIn . readInt ();
            points [ i ]   =   new   Point2D ( x ,  y );
         }
         FarthestPair  farthest  =   new   FarthestPair ( points );
         StdOut . println ( farthest . distance ()   +   " from "   +  farthest . either ()   +   " to "   +  farthest . other ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FenwickTree.java

edu/princeton/cs/algs4/FenwickTree.java

/******************************************************************************
 *  Compilation:  javac FenwickTree.java
 *  Execution:    java FenwickTree
 *
 *  A Fenwick tree.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . ArrayList ;
import  java . util . Arrays ;

/**
 * Created by ricardodpsx @gmail .com on 4/01/15.
 * <p>
 * In { @code  Fenwick Tree} structure We arrange the array in an smart way to perform efficient <em>range queries and updates</em>.
 * The key point is this: In a fenwick array, each position "responsible" for storing cumulative data of N previous positions (N could be 1)
 * For example:
 * array[40] stores: array[40] + array[39] ... + array[32] (8 positions)
 * array[32] stores: array[32] + array[31] ... + array[1]  (32 positions)
 * <p>
 * <strong>But, how do you know how much positions a given index is "responsible" for?</strong>
 * <p>
 * To know the number of items that a given array position 'ind' is responsible for
 * We should extract from 'ind' the portion up to the first significant one of the binary representation of 'ind'
 * for example, given ind == 40 (101000 in binary), according to Fenwick algorithm
 * what We want is to extract 1000(8 in decimal).
 * <p>
 * This means that array[40] has cumulative information of 8 array items.
 * But We still need to know the cumulative data bellow array[40 - 8 = 32]
 * 32 is  100000 in binnary, and the portion up to the least significant one is 32 itself!
 * So array[32] has information of 32 items, and We are done!
 * <p>
 * So cummulative data of array[1...40] = array[40] + array[32]
 * Because 40 has information of items from 40 to 32, and 32 has information of items from 32 to  1
 * <p>
 * Memory usage:  O(n)
 *
 *  @author  Ricardo Pacheco 
 */
public   class   FenwickTree   {

     int []  array ;   // 1-indexed array, In this array We save cumulative information to perform efficient range queries and updates

     public   FenwickTree ( int  size )   {
        array  =   new   int [ size  +   1 ];
     }

     /**
     * Range Sum query from 1 to ind
     * ind is 1-indexed
     * <p>
     * Time-Complexity:    O(log(n))
     *
     *  @param   ind index
     *  @return  sum
     */
     public   int  rsq ( int  ind )   {
         assert  ind  >   0 ;
         int  sum  =   0 ;
         while   ( ind  >   0 )   {
            sum  +=  array [ ind ];
             //Extracting the portion up to the first significant one of the binary representation of 'ind' and decrementing ind by that number
            ind  -=  ind  &   ( - ind );
         }

         return  sum ;
     }

     /**
     * Range Sum Query from a to b.
     * Search for the sum from array index from a to b
     * a and b are 1-indexed
     * <p>
     * Time-Complexity:    O(log(n))
     *
     *  @param   a left index
     *  @param   b right index
     *  @return  sum
     */
     public   int  rsq ( int  a ,   int  b )   {
         assert  b  >=  a  &&  a  >   0   &&  b  >   0 ;

         return  rsq ( b )   -  rsq ( -   1 );
     }

     /**
     * Update the array at ind and all the affected regions above ind.
     * ind is 1-indexed
     * <p>
     * Time-Complexity:    O(log(n))
     *
     *  @param   ind   index
     *  @param   value value
     */
     public   void  update ( int  ind ,   int  value )   {
         assert  ind  >   0 ;
         while   ( ind  <  array . length )   {
            array [ ind ]   +=  value ;
             //Extracting the portion up to the first significant one of the binary representation of 'ind' and incrementing ind by that number
            ind  +=  ind  &   ( - ind );
         }
     }

     public   int  size ()   {
         return  array . length  -   1 ;
     }


     /**
     * Read the following commands:
     * init n     Initializes the array of size n all zeroes
     * set a b c    Initializes the array  with [a, b, c ...]
     * rsq a b      Range Sum Query for the range [a,b]
     * up  i v      Update the i position of the array with value v.
     * exit
     * <p>
     * The array is 1-indexed
     * Example:
     * set 1 2 3 4 5 6
     * rsq 1 3
     * Sum from 1 to 3 = 6
     * rmq 1 3
     * Min from 1 to 3 = 1
     * input up 1 3
     * [3,2,3,4,5,6]
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {


         FenwickTree  ft  =   null ;

         String  cmd  =   "cmp" ;
         while   ( true )   {
             String []  line  =   StdIn . readLine (). split ( " " );

             if   ( line [ 0 ]. equals ( "exit" ))   break ;

             int  arg1  =   0 ,  arg2  =   0 ;

             if   ( line . length  >   1 )   {
                arg1  =   Integer . parseInt ( line [ 1 ]);
             }
             if   ( line . length  >   2 )   {
                arg2  =   Integer . parseInt ( line [ 2 ]);
             }

             if   (( ! line [ 0 ]. equals ( "set" )   &&   ! line [ 0 ]. equals ( "init" ))   &&  ft  ==   null )   {
                 StdOut . println ( "FenwickTree not initialized" );
                 continue ;
             }

             if   ( line [ 0 ]. equals ( "init" ))   {
                ft  =   new   FenwickTree ( arg1 );
                 for   ( int  i  =   1 ;  i  <=  ft . size ();  i ++ )   {
                     StdOut . print ( ft . rsq ( i ,  i )   +   " " );
                 }
                 StdOut . println ();
             }
             else   if   ( line [ 0 ]. equals ( "set" ))   {
                ft  =   new   FenwickTree ( line . length  -   1 );
                 for   ( int  i  =   1 ;  i  <=  line . length  -   1 ;  i ++ )   {
                    ft . update ( i ,   Integer . parseInt ( line [ i ]));
                 }
             }

             else   if   ( line [ 0 ]. equals ( "up" ))   {
                ft . update ( arg1 ,  arg2 );
                 for   ( int  i  =   1 ;  i  <=  ft . size ();  i ++ )   {
                     StdOut . print ( ft . rsq ( i ,  i )   +   " " );
                 }
                 StdOut . println ();
             }
             else   if   ( line [ 0 ]. equals ( "rsq" ))   {
                 StdOut . printf ( "Sum from %d to %d = %d%n" ,  arg1 ,  arg2 ,  ft . rsq ( arg1 ,  arg2 ));
             }
             else   {
                 StdOut . println ( "Invalid command" );
             }

         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FFT.java

edu/princeton/cs/algs4/FFT.java

/******************************************************************************
 *  Compilation:  javac FFT.java
 *  Execution:    java FFT n
 *  Dependencies: Complex.java
 *
 *  Compute the FFT and inverse FFT of a length n complex sequence.
 *  Bare bones implementation that runs in O(n log n) time. Our goal
 *  is to optimize the clarity of the code, rather than performance.
 *
 *  Limitations
 *  -----------
 *   -  assumes n is a power of 2
 *
 *   -  not the most memory efficient algorithm (because it uses
 *      an object type for representing complex numbers and because
 *      it re-allocates memory for the subarray, instead of doing
 *      in-place or reusing a single temporary array)
 *  
 *
 *  % java FFT 4
 *  x
 *  -------------------
 *  -0.03480425839330703
 *  0.07910192950176387
 *  0.7233322451735928
 *  0.1659819820667019
 *
 *  y = fft(x)
 *  -------------------
 *  0.9336118983487516
 *  -0.7581365035668999 + 0.08688005256493803i
 *  0.44344407521182005
 *  -0.7581365035668999 - 0.08688005256493803i
 *
 *  z = ifft(y)
 *  -------------------
 *  -0.03480425839330703
 *  0.07910192950176387 + 2.6599344570851287E-18i
 *  0.7233322451735928
 *  0.1659819820667019 - 2.6599344570851287E-18i
 *
 *  c = cconvolve(x, x)
 *  -------------------
 *  0.5506798633981853
 *  0.23461407150576394 - 4.033186818023279E-18i
 *  -0.016542951108772352
 *  0.10288019294318276 + 4.033186818023279E-18i
 *
 *  d = convolve(x, x)
 *  -------------------
 *  0.001211336402308083 - 3.122502256758253E-17i
 *  -0.005506167987577068 - 5.058885073636224E-17i
 *  -0.044092969479563274 + 2.1934338938072244E-18i
 *  0.10288019294318276 - 3.6147323062478115E-17i
 *  0.5494685269958772 + 3.122502256758253E-17i
 *  0.240120239493341 + 4.655566391833896E-17i
 *  0.02755001837079092 - 2.1934338938072244E-18i
 *  4.01805098805014E-17i
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  FFT} class provides methods for computing the 
 *  FFT (Fast-Fourier Transform), inverse FFT, linear convolution,
 *  and circular convolution of a complex array.
 *  <p>
 *  It is a bare-bones implementation that runs in <em>n</em> log <em>n</em> time,
 *  where <em>n</em> is the length of the complex array. For simplicity,
 *  <em>n</em> must be a power of 2.
 *  Our goal is to optimize the clarity of the code, rather than performance.
 *  It is not the most memory efficient implementation because it uses
 *  objects to represents complex numbers and it it re-allocates memory
 *  for the subarray, instead of doing in-place or reusing a single temporary array.
 *  
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  FFT  {

     private   static   final   Complex  ZERO  =   new   Complex ( 0 ,   0 );

     // Do not instantiate.
     private  FFT ()   {   }

     /**
     * Returns the FFT of the specified complex array.
     *
     *  @param   x the complex array
     *  @return  the FFT of the complex array { @code  x}
     *  @throws  IllegalArgumentException if the length of { @code  x} is not a power of 2
     */
     public   static   Complex []  fft ( Complex []  x )   {
         int  n  =  x . length ;

         // base case
         if   ( ==   1 )   {
             return   new   Complex []   {  x [ 0 ]   };
         }

         // radix 2 Cooley-Tukey FFT
         if   ( %   2   !=   0 )   {
             throw   new   IllegalArgumentException ( "n is not a power of 2" );
         }

         // fft of even terms
         Complex []  even  =   new   Complex [ n / 2 ];
         for   ( int  k  =   0 ;  k  <  n / 2 ;  k ++ )   {
            even [ k ]   =  x [ 2 * k ];
         }
         Complex []  q  =  fft ( even );

         // fft of odd terms
         Complex []  odd   =  even ;    // reuse the array
         for   ( int  k  =   0 ;  k  <  n / 2 ;  k ++ )   {
            odd [ k ]   =  x [ 2 * +   1 ];
         }
         Complex []  r  =  fft ( odd );

         // combine
         Complex []  y  =   new   Complex [ n ];
         for   ( int  k  =   0 ;  k  <  n / 2 ;  k ++ )   {
             double  kth  =   - 2   *  k  *   Math . PI  /  n ;
             Complex  wk  =   new   Complex ( Math . cos ( kth ),   Math . sin ( kth ));
            y [ k ]         =  q [ k ]. plus ( wk . times ( r [ k ]));
            y [ +  n / 2 ]   =  q [ k ]. minus ( wk . times ( r [ k ]));
         }
         return  y ;
     }


     /**
     * Returns the inverse FFT of the specified complex array.
     *
     *  @param   x the complex array
     *  @return  the inverse FFT of the complex array { @code  x}
     *  @throws  IllegalArgumentException if the length of { @code  x} is not a power of 2
     */
     public   static   Complex []  ifft ( Complex []  x )   {
         int  n  =  x . length ;
         Complex []  y  =   new   Complex [ n ];

         // take conjugate
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            y [ i ]   =  x [ i ]. conjugate ();
         }

         // compute forward FFT
        y  =  fft ( y );

         // take conjugate again
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            y [ i ]   =  y [ i ]. conjugate ();
         }

         // divide by n
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            y [ i ]   =  y [ i ]. scale ( 1.0   /  n );
         }

         return  y ;

     }

     /**
     * Returns the circular convolution of the two specified complex arrays.
     *
     *  @param   x one complex array
     *  @param   y the other complex array
     *  @return  the circular convolution of { @code  x} and { @code  y}
     *  @throws  IllegalArgumentException if the length of { @code  x} does not equal
     *         the length of { @code  y} or if the length is not a power of 2
     */
     public   static   Complex []  cconvolve ( Complex []  x ,   Complex []  y )   {

         // should probably pad x and y with 0s so that they have same length
         // and are powers of 2
         if   ( x . length  !=  y . length )   {
             throw   new   IllegalArgumentException ( "Dimensions don't agree" );
         }

         int  n  =  x . length ;

         // compute FFT of each sequence
         Complex []  a  =  fft ( x );
         Complex []  b  =  fft ( y );

         // point-wise multiply
         Complex []  c  =   new   Complex [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            c [ i ]   =  a [ i ]. times ( b [ i ]);
         }

         // compute inverse FFT
         return  ifft ( c );
     }

     /**
     * Returns the linear convolution of the two specified complex arrays.
     *
     *  @param   x one complex array
     *  @param   y the other complex array
     *  @return  the linear convolution of { @code  x} and { @code  y}
     *  @throws  IllegalArgumentException if the length of { @code  x} does not equal
     *         the length of { @code  y} or if the length is not a power of 2
     */
     public   static   Complex []  convolve ( Complex []  x ,   Complex []  y )   {
         Complex []  a  =   new   Complex [ 2 * x . length ];
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )
            a [ i ]   =  x [ i ];
         for   ( int  i  =  x . length ;  i  <   2 * x . length ;  i ++ )
            a [ i ]   =  ZERO ;

         Complex []  b  =   new   Complex [ 2 * y . length ];
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )
            b [ i ]   =  y [ i ];
         for   ( int  i  =  y . length ;  i  <   2 * y . length ;  i ++ )
            b [ i ]   =  ZERO ;

         return  cconvolve ( a ,  b );
     }

     // display an array of Complex numbers to standard output
     private   static   void  show ( Complex []  x ,   String  title )   {
         StdOut . println ( title );
         StdOut . println ( "-------------------" );
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )   {
             StdOut . println ( x [ i ]);
         }
         StdOut . println ();
     }


    /***************************************************************************
    *  Test client.
    ***************************************************************************/

     /**
     * Unit tests the { @code  FFT} class.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         int  n  =   Integer . parseInt ( args [ 0 ]);
         Complex []  x  =   new   Complex [ n ];

         // original data
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            x [ i ]   =   new   Complex ( i ,   0 );
            x [ i ]   =   new   Complex ( StdRandom . uniform ( - 1.0 ,   1.0 ),   0 );
         }
        show ( x ,   "x" );

         // FFT of original data
         Complex []  y  =  fft ( x );
        show ( y ,   "y = fft(x)" );

         // take inverse FFT
         Complex []  z  =  ifft ( y );
        show ( z ,   "z = ifft(y)" );

         // circular convolution of x with itself
         Complex []  c  =  cconvolve ( x ,  x );
        show ( c ,   "c = cconvolve(x, x)" );

         // linear convolution of x with itself
         Complex []  d  =  convolve ( x ,  x );
        show ( d ,   "d = convolve(x, x)" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FibonacciMinPQ.java

edu/princeton/cs/algs4/FibonacciMinPQ.java

/******************************************************************************
 *  Compilation: javac FibonacciMinPQ.java
 *  Execution:
 *
 *  A Fibonacci heap.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . HashMap ;
import  java . util . NoSuchElementException ;
import  java . util . Comparator ;

/*
 *  The FibonacciMinPQ class represents a priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations, 
 *  along with the merging of two heaps together.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  It is possible to build the priority queue using a Comparator.
 *  If not, the natural order relation between the keys will be used.
 *  
 *  This implementation uses a Fibonacci heap.
 *  The delete-the-minimum operation takes amortized logarithmic time.
 *  The insert, min-key, is-empty, size, union and constructor take constant time.
 *
 *  @author Tristan Claverie
 */
public   class   FibonacciMinPQ < Key >   implements   Iterable < Key >   {
     private   Node  head ;                    //Head of the circular root list
     private   Node  min ;                     //Minimum Node of the root list
     private   int  size ;                     //Number of keys in the heap
     private   final   Comparator < Key >  comp ;   //Comparator over the keys
     private   HashMap < Integer ,   Node >  table  =   new   HashMap < Integer ,   Node > ();   //Used for the consolidate operation
    
     //Represents a Node of a tree
     private   class   Node   {
         Key  key ;                          //Key of this Node
         int  order ;                        //Order of the tree rooted by this Node
         Node  prev ,  next ;                  //Siblings of this Node
         Node  child ;                       //Child of this Node
     }
    
     /**
     * Initializes an empty priority queue
     * Worst case is O(1)
     *  @param  C a Comparator over the Keys
     */
     public   FibonacciMinPQ ( Comparator < Key >  C )   {
        comp  =  C ;
     }
    
     /**
     * Initializes an empty priority queue
     * Worst case is O(1)
     */
     public   FibonacciMinPQ ()   {
        comp  =   new   MyComparator ();
     }
    
     /**
     * Initializes a priority queue with given keys
     * Worst case is O(n)
     *  @param  a an array of keys
     */
     public   FibonacciMinPQ ( Key []  a )   {
        comp  =   new   MyComparator ();
         for   ( Key  k  :  a )  insert ( k );
     }
    
     /**
     * Initializes a priority queue with given keys
     * Worst case is O(n)
     *  @param  C a comparator over the keys
     *  @param  a an array of keys
     */
     public   FibonacciMinPQ ( Comparator < Key >  C ,   Key []  a )   {
        comp  =  C ;
         for   ( Key  k  :  a )  insert ( k );
     }

     /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
     public   boolean  isEmpty ()   {
         return  size  ==   0 ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(1)
     *  @return  the number of elements on the priority queue
     */
     public   int  size ()   {
         return  size ;
     }

     /**
     * Insert a key in the queue
     * Worst case is O(1)
     *  @param  key a Key
     */
     public   void  insert ( Key  key )   {
         Node  x  =   new   Node ();
        x . key  =  key ;
        size ++ ;
        head  =  insert ( x ,  head );
         if   ( min  ==   null )  min  =  head ;
         else              min  =   ( greater ( min . key ,  key ))   ?  head  :  min ;
     }

     /**
     * Gets the minimum key currently in the queue
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  min . key ;
     }

     /**
     * Deletes the minimum key
     * Worst case is O(log(n)) (amortized)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key
     */
     public   Key  delMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
        head  =  cut ( min ,  head );
         Node  x  =  min . child ;
         Key  key  =  min . key ;
        min . key  =   null ;
         if   ( !=   null )   {
            head  =  meld ( head ,  x );
            min . child  =   null ;
         }
        size -- ;
         if   ( ! isEmpty ())  consolidate ();
         else             min  =   null ;
         return  key ;
     }
    
     /**
     * Merges two heaps together
     * This operation is destructive
     * Worst case is O(1)
     *  @param  that a Fibonacci heap
     *  @return  the union of the two heaps
     */
     public   FibonacciMinPQ < Key >  union ( FibonacciMinPQ < Key >  that )   {
         this . head  =  meld ( head ,  that . head );
         this . min  =   ( greater ( this . min . key ,  that . min . key ))   ?  that . min  :   this . min ;
         this . size  =   this . size + that . size ;
         return   this ;
     }
    
     /*************************************
     * General helper functions
     ************************************/
    
     //Compares two keys
     private   boolean  greater ( Key  n ,   Key  m )   {
         if   ( ==   null )   return   false ;
         if   ( ==   null )   return   true ;
         return  comp . compare ( n , m )   >   0 ;
     }
    
     //Assuming root1 holds a greater key than root2, root2 becomes the new root
     private   void  link ( Node  root1 ,   Node  root2 )   {
        root2 . child  =  insert ( root1 ,  root2 . child );
        root2 . order ++ ;
     }
    
     /*************************************
     * Function for consolidating all trees in the root list
     ************************************/
    
     //Coalesce the roots, thus reshapes the tree
     private   void  consolidate ()   {
        table . clear ();
         Node  x  =  head ;
         int  maxOrder  =   0 ;
        min  =  head ;
         Node  y  =   null ;   Node  z  =   null ;
         do   {
            y  =  x ;
            x  =  x . next ;
            z  =  table . get ( y . order );
             while   ( !=   null )   {
                table . remove ( y . order );
                 if   ( greater ( y . key ,  z . key ))   {
                    link ( y ,  z );
                    y  =  z ;
                 }   else   {
                    link ( z ,  y );
                 }
                z  =  table . get ( y . order );
             }
            table . put ( y . order ,  y );
             if   ( y . order  >  maxOrder )  maxOrder  =  y . order ;
         }   while   ( !=  head );
        head  =   null ;
         for   ( Node  n  :  table . values ())   {
             if   ( !=   null )   {
                min  =  greater ( min . key ,  n . key )   ?  n  :  min ;
                head  =  insert ( n ,  head );
             }
         }
     }
    
     /*************************************
     * General helper functions for manipulating circular lists
     ************************************/
    
     //Inserts a Node in a circular list containing head, returns a new head
     private   Node  insert ( Node  x ,   Node  head )   {
         if   ( head  ==   null )   {
            x . prev  =  x ;
            x . next  =  x ;
         }   else   {
            head . prev . next  =  x ;
            x . next  =  head ;
            x . prev  =  head . prev ;
            head . prev  =  x ;
         }
         return  x ;
     }
    
     //Removes a tree from the list defined by the head pointer
     private   Node  cut ( Node  x ,   Node  head )   {
         if   ( x . next  ==  x )   {
            x . next  =   null ;
            x . prev  =   null ;
             return   null ;
         }   else   {
            x . next . prev  =  x . prev ;
            x . prev . next  =  x . next ;
             Node  res  =  x . next ;
            x . next  =   null ;
            x . prev  =   null ;
             if   ( head  ==  x )    return  res ;
             else              return  head ;
         }
     }
    
     //Merges two root lists together
     private   Node  meld ( Node  x ,   Node  y )   {
         if   ( ==   null )   return  y ;
         if   ( ==   null )   return  x ;
        x . prev . next  =  y . next ;
        y . next . prev  =  x . prev ;
        x . prev  =  y ;
        y . next  =  x ;
         return  x ;
     }
    
     /*************************************
     * Iterator
     ************************************/
    
     /**
     * Gets an Iterator over the Keys in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(log(n)) (amortized)
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the Keys in the priority queue in ascending order
     */
    
     public   Iterator < Key >  iterator ()   {
         return   new   MyIterator ();
     }
    
     private   class   MyIterator   implements   Iterator < Key >   {
         private   FibonacciMinPQ < Key >  copy ;
        
        
         //Constructor takes linear time
         public   MyIterator ()   {
            copy  =   new   FibonacciMinPQ < Key > ( comp );
            insertAll ( head );
         }
        
         private   void  insertAll ( Node  head )   {
             if   ( head  ==   null )   return ;
             Node  x  =  head ;
             do   {
                copy . insert ( x . key );
                insertAll ( x . child );
                x  =  x . next ;
             }   while   ( !=  head );
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
        
         public   boolean  hasNext ()   {
             return   ! copy . isEmpty ();
         }
        
         //Takes amortized logarithmic time
         public   Key  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMin ();
         }
     }
    
     /*************************************
     * Comparator
     ************************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }
    
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FileIndex.java

edu/princeton/cs/algs4/FileIndex.java

/******************************************************************************
 *  Compilation:  javac FileIndex.java
 *  Execution:    java FileIndex file1.txt file2.txt file3.txt ...
 *  Dependencies: ST.java SET.java In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/ex1.txt
 *                https://algs4.cs.princeton.edu/35applications/ex2.txt
 *                https://algs4.cs.princeton.edu/35applications/ex3.txt
 *                https://algs4.cs.princeton.edu/35applications/ex4.txt
 *
 *  % java FileIndex ex*.txt
 *  age
 *   ex3.txt
 *   ex4.txt 
 * best
 *   ex1.txt 
 * was
 *   ex1.txt
 *   ex2.txt
 *   ex3.txt
 *   ex4.txt 
 *
 *  % java FileIndex *.txt
 *
 *  % java FileIndex *.java
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . File ;

/**
 *  The { @code  FileIndex} class provides a client for indexing a set of files,
 *  specified as command-line arguments. It takes queries from standard input
 *  and prints each file that contains the given query.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FileIndex   {  

     // Do not instantiate.
     private   FileIndex ()   {   }

     public   static   void  main ( String []  args )   {

         // key = word, value = set of files containing that word
        ST < String ,  SET < File >>  st  =   new  ST < String ,  SET < File >> ();

         // create inverted index of all files
         StdOut . println ( "Indexing files" );
         for   ( String  filename  :  args )   {
             StdOut . println ( "  "   +  filename );
             File  file  =   new   File ( filename );
             In  in  =   new   In ( file );
             while   ( ! in . isEmpty ())   {
                 String  word  =  in . readString ();
                 if   ( ! st . contains ( word ))  st . put ( word ,   new  SET < File > ());
                SET < File >  set  =  st . get ( word );
                set . add ( file );
             }
         }


         // read queries from standard input, one per line
         while   ( ! StdIn . isEmpty ())   {
             String  query  =   StdIn . readString ();
             if   ( st . contains ( query ))   {
                SET < File >  set  =  st . get ( query );
                 for   ( File  file  :  set )   {
                     StdOut . println ( "  "   +  file . getName ());
                 }
             }
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FlowEdge.java

edu/princeton/cs/algs4/FlowEdge.java

/******************************************************************************
 *  Compilation:  javac FlowEdge.java
 *  Execution:    java FlowEdge
 *  Dependencies: StdOut.java
 *
 *  Capacitated edge with a flow in a flow network.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  FlowEdge} class represents a capacitated edge with a 
  * flow in a { @link  FlowNetwork}. Each edge consists of two integers
 *  (naming the two vertices), a real-valued capacity, and a real-valued
 *  flow. The data type provides methods for accessing the two endpoints
 *  of the directed edge and the weight. It also provides methods for
 *  changing the amount of flow on the edge and determining the residual
 *  capacity of the edge.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/64maxflow">Section 6.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FlowEdge   {
     // to deal with floating-point roundoff errors
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-10 ;

     private   final   int  v ;               // from
     private   final   int  w ;               // to 
     private   final   double  capacity ;     // capacity
     private   double  flow ;               // flow

     /**
     * Initializes an edge from vertex { @code  v} to vertex { @code  w} with
     * the given { @code  capacity} and zero flow.
     *  @param  v the tail vertex
     *  @param  w the head vertex
     *  @param  capacity the capacity of the edge
     *  @throws  IllegalArgumentException if either { @code  v} or { @code  w}
     *    is a negative integer
     *  @throws  IllegalArgumentException if { @code  capacity < 0.0}
     */
     public   FlowEdge ( int  v ,   int  w ,   double  capacity )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );
         if   ( ! ( capacity  >=   0.0 ))   throw   new   IllegalArgumentException ( "Edge capacity must be non-negative" );
         this . v          =  v ;
         this . w          =  w ;   
         this . capacity   =  capacity ;
         this . flow       =   0.0 ;
     }

     /**
     * Initializes an edge from vertex { @code  v} to vertex { @code  w} with
     * the given { @code  capacity} and { @code  flow}.
     *  @param  v the tail vertex
     *  @param  w the head vertex
     *  @param  capacity the capacity of the edge
     *  @param  flow the flow on the edge
     *  @throws  IllegalArgumentException if either { @code  v} or { @code  w}
     *    is a negative integer
     *  @throws  IllegalArgumentException if { @code  capacity} is negative
     *  @throws  IllegalArgumentException unless { @code  flow} is between 
     *    { @code  0.0} and { @code  capacity}.
     */
     public   FlowEdge ( int  v ,   int  w ,   double  capacity ,   double  flow )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "vertex index must be a non-negative integer" );
         if   ( ! ( capacity  >=   0.0 ))    throw   new   IllegalArgumentException ( "edge capacity must be non-negative" );
         if   ( ! ( flow  <=  capacity ))   throw   new   IllegalArgumentException ( "flow exceeds capacity" );
         if   ( ! ( flow  >=   0.0 ))        throw   new   IllegalArgumentException ( "flow must be non-negative" );
         this . v          =  v ;
         this . w          =  w ;   
         this . capacity   =  capacity ;
         this . flow       =  flow ;
     }

     /**
     * Initializes a flow edge from another flow edge.
     *  @param  e the edge to copy
     */
     public   FlowEdge ( FlowEdge  e )   {
         this . v          =  e . v ;
         this . w          =  e . w ;
         this . capacity   =  e . capacity ;
         this . flow       =  e . flow ;
     }

     /**
     * Returns the tail vertex of the edge.
     *  @return  the tail vertex of the edge
     */
     public   int  from ()   {
         return  v ;
     }   

     /**
     * Returns the head vertex of the edge.
     *  @return  the head vertex of the edge
     */
     public   int  to ()   {
         return  w ;
     }   

     /**
     * Returns the capacity of the edge.
     *  @return  the capacity of the edge
     */
     public   double  capacity ()   {
         return  capacity ;
     }

     /**
     * Returns the flow on the edge.
     *  @return  the flow on the edge
     */
     public   double  flow ()   {
         return  flow ;
     }

     /**
     * Returns the endpoint of the edge that is different from the given vertex
     * (unless the edge represents a self-loop in which case it returns the same vertex).
     *  @param  vertex one endpoint of the edge
     *  @return  the endpoint of the edge that is different from the given vertex
     *   (unless the edge represents a self-loop in which case it returns the same vertex)
     *  @throws  IllegalArgumentException if { @code  vertex} is not one of the endpoints
     *   of the edge
     */
     public   int  other ( int  vertex )   {
         if        ( vertex  ==  v )   return  w ;
         else   if   ( vertex  ==  w )   return  v ;
         else   throw   new   IllegalArgumentException ( "invalid endpoint" );
     }

     /**
     * Returns the residual capacity of the edge in the direction
     *  to the given { @code  vertex}.
     *  @param  vertex one endpoint of the edge
     *  @return  the residual capacity of the edge in the direction to the given vertex
     *   If { @code  vertex} is the tail vertex, the residual capacity equals
     *   { @code  capacity() - flow()}; if { @code  vertex} is the head vertex, the
     *   residual capacity equals { @code  flow()}.
     *  @throws  IllegalArgumentException if { @code  vertex} is not one of the endpoints of the edge
     */
     public   double  residualCapacityTo ( int  vertex )   {
         if        ( vertex  ==  v )   return  flow ;                // backward edge
         else   if   ( vertex  ==  w )   return  capacity  -  flow ;     // forward edge
         else   throw   new   IllegalArgumentException ( "invalid endpoint" );
     }

     /**
     * Increases the flow on the edge in the direction to the given vertex.
     *   If { @code  vertex} is the tail vertex, this increases the flow on the edge by { @code  delta};
     *   if { @code  vertex} is the head vertex, this decreases the flow on the edge by { @code  delta}.
     *  @param  vertex one endpoint of the edge
     *  @param  delta amount by which to increase flow
     *  @throws  IllegalArgumentException if { @code  vertex} is not one of the endpoints
     *   of the edge
     *  @throws  IllegalArgumentException if { @code  delta} makes the flow on
     *   on the edge either negative or larger than its capacity
     *  @throws  IllegalArgumentException if { @code  delta} is { @code  NaN}
     */
     public   void  addResidualFlowTo ( int  vertex ,   double  delta )   {
         if   ( ! ( delta  >=   0.0 ))   throw   new   IllegalArgumentException ( "Delta must be nonnegative" );

         if        ( vertex  ==  v )  flow  -=  delta ;             // backward edge
         else   if   ( vertex  ==  w )  flow  +=  delta ;             // forward edge
         else   throw   new   IllegalArgumentException ( "invalid endpoint" );

         // round flow to 0 or capacity if within floating-point precision
         if   ( Math . abs ( flow )   <=  FLOATING_POINT_EPSILON )
            flow  =   0 ;
         if   ( Math . abs ( flow  -  capacity )   <=  FLOATING_POINT_EPSILON )
            flow  =  capacity ;

         if   ( ! ( flow  >=   0.0 ))        throw   new   IllegalArgumentException ( "Flow is negative" );
         if   ( ! ( flow  <=  capacity ))   throw   new   IllegalArgumentException ( "Flow exceeds capacity" );
     }


     /**
     * Returns a string representation of the edge.
     *  @return  a string representation of the edge
     */
     public   String  toString ()   {
         return  v  +   "->"   +  w  +   " "   +  flow  +   "/"   +  capacity ;
     }


    /**
     * Unit tests the { @code  FlowEdge} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         FlowEdge  e  =   new   FlowEdge ( 12 ,   23 ,   4.56 );
         StdOut . println ( e );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FlowNetwork.java

edu/princeton/cs/algs4/FlowNetwork.java

/******************************************************************************
 *  Compilation:  javac FlowNetwork.java
 *  Execution:    java FlowNetwork V E
 *  Dependencies: Bag.java FlowEdge.java
 *
 *  A capacitated flow network, implemented using adjacency lists.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  FlowNetwork} class represents a capacitated network
 *  with vertices named 0 through <em>V</em> - 1, where each directed
 *  edge is of type { @link  FlowEdge} and has a real-valued capacity
 *  and flow.
 *  It supports the following two primary operations: add an edge to the network,
 *  iterate over all of the edges incident to or from a vertex. It also provides
 *  methods for returning the number of vertices <em>V</em> and the number
 *  of edges <em>E</em>. Parallel edges and self-loops are permitted.
 *  <p>
 *  This implementation uses an adjacency-lists representation, which 
 *  is a vertex-indexed array of { @link  Bag} objects.
 *  All operations take constant time (in the worst case) except
 *  iterating over the edges incident to a given vertex, which takes
 *  time proportional to the number of such edges.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/64maxflow">Section 6.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FlowNetwork   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;
     private   int  E ;
     private   Bag < FlowEdge > []  adj ;
    
     /**
     * Initializes an empty flow network with { @code  V} vertices and 0 edges.
     *  @param  V the number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   FlowNetwork ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices in a Graph must be nonnegative" );
         this . =  V ;
         this . =   0 ;
        adj  =   ( Bag < FlowEdge > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            adj [ v ]   =   new   Bag < FlowEdge > ();
     }

     /**
     * Initializes a random flow network with { @code  V} vertices and <em>E</em> edges.
     * The capacities are integers between 0 and 99 and the flow values are zero.
     *  @param  V the number of vertices
     *  @param  E the number of edges
     *  @throws  IllegalArgumentException if { @code  V < 0}
     *  @throws  IllegalArgumentException if { @code  E < 0}
     */
     public   FlowNetwork ( int  V ,   int  E )   {
         this ( V );
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of edges must be nonnegative" );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  capacity  =   StdRandom . uniform ( 100 );
            addEdge ( new   FlowEdge ( v ,  w ,  capacity ));
         }
     }

     /**  
     * Initializes a flow network from an input stream.
     * The format is the number of vertices <em>V</em>,
     * followed by the number of edges <em>E</em>,
     * followed by <em>E</em> pairs of vertices and edge capacities,
     * with each entry separated by whitespace.
     *  @param  in the input stream
     *  @throws  IllegalArgumentException if the endpoints of any edge are not in prescribed range
     *  @throws  IllegalArgumentException if the number of vertices or edges is negative
     */
     public   FlowNetwork ( In  in )   {
         this ( in . readInt ());
         int  E  =  in . readInt ();
         if   ( <   0 )   throw   new   IllegalArgumentException ( "number of edges must be nonnegative" );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v  =  in . readInt ();
             int  w  =  in . readInt ();
            validateVertex ( v );
            validateVertex ( w );
             double  capacity  =  in . readDouble ();
            addEdge ( new   FlowEdge ( v ,  w ,  capacity ));
         }
     }


     /**
     * Returns the number of vertices in the edge-weighted graph.
     *  @return  the number of vertices in the edge-weighted graph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in the edge-weighted graph.
     *  @return  the number of edges in the edge-weighted graph
     */
     public   int  E ()   {
         return  E ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Adds the edge { @code  e} to the network.
     *  @param  e the edge
     *  @throws  IllegalArgumentException unless endpoints of edge are between
     *         { @code  0} and { @code  V-1}
     */
     public   void  addEdge ( FlowEdge  e )   {
         int  v  =  e . from ();
         int  w  =  e . to ();
        validateVertex ( v );
        validateVertex ( w );
        adj [ v ]. add ( e );
        adj [ w ]. add ( e );
        E ++ ;
     }

     /**
     * Returns the edges incident on vertex { @code  v} (includes both edges pointing to
     * and from { @code  v}).
     *  @param  v the vertex
     *  @return  the edges incident on vertex { @code  v} as an Iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < FlowEdge >  adj ( int  v )   {
        validateVertex ( v );
         return  adj [ v ];
     }

     // return list of all edges - excludes self loops
     public   Iterable < FlowEdge >  edges ()   {
         Bag < FlowEdge >  list  =   new   Bag < FlowEdge > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( FlowEdge  e  :  adj ( v ))   {
                 if   ( e . to ()   !=  v )
                    list . add ( e );
             }
         return  list ;
     }


     /**
     * Returns a string representation of the flow network.
     * This method takes time proportional to <em>E</em> + <em>V</em>.
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,  
     *    followed by the <em>V</em> adjacency lists
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " "   +  E  +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( +   ":  " );
             for   ( FlowEdge  e  :  adj [ v ])   {
                 if   ( e . to ()   !=  v )  s . append ( +   "  " );
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  FlowNetwork} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         FlowNetwork  G  =   new   FlowNetwork ( in );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FloydWarshall.java

edu/princeton/cs/algs4/FloydWarshall.java

/******************************************************************************
 *  Compilation:  javac FloydWarshall.java
 *  Execution:    java FloydWarshall V E
 *  Dependencies: AdjMatrixEdgeWeightedDigraph.java
 *
 *  Floyd-Warshall all-pairs shortest path algorithm.
 *
 *  % java FloydWarshall 100 500
 *
 *  Should check for negative cycles during triple loop; otherwise
 *  intermediate numbers can get exponentially large.
 *  Reference: "The Floyd-Warshall algorithm on graphs with negative cycles"
 *  by Stefan Hougardy
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  FloydWarshall} class represents a data type for solving the
 *  all-pairs shortest paths problem in edge-weighted digraphs with
 *  no negative cycles.
 *  The edge weights can be positive, negative, or zero.
 *  This class finds either a shortest path between every pair of vertices
 *  or a negative cycle.
 *  <p>
 *  This implementation uses the Floyd-Warshall algorithm.
 *  The constructor takes &Theta;(<em>V</em><sup>3</sup>) time,
 *  where <em>V</em> is the number of vertices.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em><sup>2</sup>) extra space
 *  (not including the edge-weighted digraph).
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/44sp">Section 4.4</a> of    
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FloydWarshall   {
     private   boolean  hasNegativeCycle ;    // is there a negative cycle?
     private   double [][]  distTo ;           // distTo[v][w] = length of shortest v->w path
     private   DirectedEdge [][]  edgeTo ;     // edgeTo[v][w] = last edge on shortest v->w path

     /**
     * Computes a shortest paths tree from each vertex to to every other vertex in
     * the edge-weighted digraph { @code  G}. If no such shortest path exists for
     * some pair of vertices, it computes a negative cycle.
     *  @param  G the edge-weighted digraph
     */
     public   FloydWarshall ( AdjMatrixEdgeWeightedDigraph  G )   {
         int  V  =  G . V ();
        distTo  =   new   double [ V ][ V ];
        edgeTo  =   new   DirectedEdge [ V ][ V ];

         // initialize distances to infinity
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {
                distTo [ v ][ w ]   =   Double . POSITIVE_INFINITY ;
             }
         }

         // initialize distances using edge-weighted digraph's
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( DirectedEdge  e  :  G . adj ( v ))   {
                distTo [ e . from ()][ e . to ()]   =  e . weight ();
                edgeTo [ e . from ()][ e . to ()]   =  e ;
             }
             // in case of self-loops
             if   ( distTo [ v ][ v ]   >=   0.0 )   {
                distTo [ v ][ v ]   =   0.0 ;
                edgeTo [ v ][ v ]   =   null ;
             }
         }

         // Floyd-Warshall updates
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )   {
             // compute shortest paths using only 0, 1, ..., i as intermediate vertices
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                 if   ( edgeTo [ v ][ i ]   ==   null )   continue ;    // optimization
                 for   ( int  w  =   0 ;  w  <  V ;  w ++ )   {
                     if   ( distTo [ v ][ w ]   >  distTo [ v ][ i ]   +  distTo [ i ][ w ])   {
                        distTo [ v ][ w ]   =  distTo [ v ][ i ]   +  distTo [ i ][ w ];
                        edgeTo [ v ][ w ]   =  edgeTo [ i ][ w ];
                     }
                 }
                 // check for negative cycle
                 if   ( distTo [ v ][ v ]   <   0.0 )   {
                    hasNegativeCycle  =   true ;
                     return ;
                 }
             }
         }
         assert  check ( G );
     }

     /**
     * Is there a negative cycle?
     *  @return  { @code  true} if there is a negative cycle, and { @code  false} otherwise
     */
     public   boolean  hasNegativeCycle ()   {
         return  hasNegativeCycle ;
     }

     /**
     * Returns a negative cycle, or { @code  null} if there is no such cycle.
     *  @return  a negative cycle as an iterable of edges,
     * or { @code  null} if there is no such cycle
     */
     public   Iterable < DirectedEdge >  negativeCycle ()   {
         for   ( int  v  =   0 ;  v  <  distTo . length ;  v ++ )   {
             // negative cycle in v's predecessor graph
             if   ( distTo [ v ][ v ]   <   0.0 )   {
                 int  V  =  edgeTo . length ;
                 EdgeWeightedDigraph  spt  =   new   EdgeWeightedDigraph ( V );
                 for   ( int  w  =   0 ;  w  <  V ;  w ++ )
                     if   ( edgeTo [ v ][ w ]   !=   null )
                        spt . addEdge ( edgeTo [ v ][ w ]);
                 EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( spt );
                 assert  finder . hasCycle ();
                 return  finder . cycle ();
             }
         }
         return   null ;
     }

     /**
     * Is there a path from the vertex { @code  s} to vertex { @code  t}?
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  { @code  true} if there is a path from vertex { @code  s}
     *         to vertex { @code  t}, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= t < V}
     */
     public   boolean  hasPath ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         return  distTo [ s ][ t ]   <   Double . POSITIVE_INFINITY ;
     }

     /**
     * Returns the length of a shortest path from vertex { @code  s} to vertex { @code  t}.
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  the length of a shortest path from vertex { @code  s} to vertex { @code  t};
     *         { @code  Double.POSITIVE_INFINITY} if no such path
     *  @throws  UnsupportedOperationException if there is a negative cost cycle
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   double  dist ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         if   ( hasNegativeCycle ())
             throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );
         return  distTo [ s ][ t ];
     }

     /**
     * Returns a shortest path from vertex { @code  s} to vertex { @code  t}.
     *  @param   s the source vertex
     *  @param   t the destination vertex
     *  @return  a shortest path from vertex { @code  s} to vertex { @code  t}
     *         as an iterable of edges, and { @code  null} if no such path
     *  @throws  UnsupportedOperationException if there is a negative cost cycle
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < DirectedEdge >  path ( int  s ,   int  t )   {
        validateVertex ( s );
        validateVertex ( t );
         if   ( hasNegativeCycle ())
             throw   new   UnsupportedOperationException ( "Negative cost cycle exists" );
         if   ( ! hasPath ( s ,  t ))   return   null ;
         Stack < DirectedEdge >  path  =   new   Stack < DirectedEdge > ();
         for   ( DirectedEdge  e  =  edgeTo [ s ][ t ];  e  !=   null ;  e  =  edgeTo [ s ][ e . from ()])   {
            path . push ( e );
         }
         return  path ;
     }

     // check optimality conditions
     private   boolean  check ( AdjMatrixEdgeWeightedDigraph  G )   {

         // no negative cycle
         if   ( ! hasNegativeCycle ())   {
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( DirectedEdge  e  :  G . adj ( v ))   {
                     int  w  =  e . to ();
                     for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                         if   ( distTo [ i ][ w ]   >  distTo [ i ][ v ]   +  e . weight ())   {
                             System . err . println ( "edge "   +  e  +   " is eligible" );
                             return   false ;
                         }
                     }
                 }
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  distTo . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  FloydWarshall} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // random graph with V vertices and E edges, parallel edges allowed
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         AdjMatrixEdgeWeightedDigraph  G  =   new   AdjMatrixEdgeWeightedDigraph ( V );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             double  weight  =   Math . round ( 100   *   ( StdRandom . uniform ()   -   0.15 ))   /   100.0 ;
             if   ( ==  w )  G . addEdge ( new   DirectedEdge ( v ,  w ,   Math . abs ( weight )));
             else  G . addEdge ( new   DirectedEdge ( v ,  w ,  weight ));
         }

         StdOut . println ( G );

         // run Floyd-Warshall algorithm
         FloydWarshall  spt  =   new   FloydWarshall ( G );

         // print all-pairs shortest path distances
         StdOut . printf ( "  " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%6d " ,  v );
         }
         StdOut . println ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%3d: " ,  v );
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( spt . hasPath ( v ,  w ))   StdOut . printf ( "%6.2f " ,  spt . dist ( v ,  w ));
                 else   StdOut . printf ( "  Inf " );
             }
             StdOut . println ();
         }

         // print negative cycle
         if   ( spt . hasNegativeCycle ())   {
             StdOut . println ( "Negative cost cycle:" );
             for   ( DirectedEdge  e  :  spt . negativeCycle ())
                 StdOut . println ( e );
             StdOut . println ();
         }

         // print all-pairs shortest paths
         else   {
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                     if   ( spt . hasPath ( v ,  w ))   {
                         StdOut . printf ( "%d to %d (%5.2f)  " ,  v ,  w ,  spt . dist ( v ,  w ));
                         for   ( DirectedEdge  e  :  spt . path ( v ,  w ))
                             StdOut . print ( +   "  " );
                         StdOut . println ();
                     }
                     else   {
                         StdOut . printf ( "%d to %d no path\n" ,  v ,  w );
                     }
                 }
             }
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FordFulkerson.java

edu/princeton/cs/algs4/FordFulkerson.java

/******************************************************************************
 *  Compilation:  javac FordFulkerson.java
 *  Execution:    java FordFulkerson V E
 *  Dependencies: FlowNetwork.java FlowEdge.java Queue.java
 *  Data files:   https://algs4.cs.princeton.edu/65maxflow/tinyFN.txt
 *
 *  Ford-Fulkerson algorithm for computing a max flow and 
 *  a min cut using shortest augmenting path rule.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  FordFulkerson} class represents a data type for computing a
 *  <em>maximum st-flow</em> and <em>minimum st-cut</em> in a flow
 *  network.
 *  <p>
 *  This implementation uses the <em>Ford-Fulkerson</em> algorithm with
 *  the <em>shortest augmenting path</em> heuristic.
 *  The constructor takes <em>O</em>(<em>E V</em> (<em>E</em> + <em>V</em>))
 *  time, where <em>V</em> is the number of vertices and <em>E</em> is
 *  the number of edges. In practice, the algorithm will run much faster.
 *  The { @code  inCut()} and { @code  value()} methods take &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the network).
 *  <p>
 *  If the capacities and initial flow values are all integers, then this
 *  implementation guarantees to compute an integer-valued maximum flow.
 *  If the capacities are floating-point numbers, then floating-point
 *  roundoff error can accumulate.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/64maxflow">Section 6.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FordFulkerson   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-11 ;

     private   final   int  V ;            // number of vertices
     private   boolean []  marked ;       // marked[v] = true iff s->v path in residual graph
     private   FlowEdge []  edgeTo ;      // edgeTo[v] = last edge on shortest residual s->v path
     private   double  value ;           // current value of max flow
  
     /**
     * Compute a maximum flow and minimum cut in the network { @code  G}
     * from vertex { @code  s} to vertex { @code  t}.
     *
     *  @param   G the flow network
     *  @param   s the source vertex
     *  @param   t the sink vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= t < V}
     *  @throws  IllegalArgumentException if { @code  s == t}
     *  @throws  IllegalArgumentException if initial flow is infeasible
     */
     public   FordFulkerson ( FlowNetwork  G ,   int  s ,   int  t )   {
        V  =  G . V ();
        validate ( s );
        validate ( t );
         if   ( ==  t )                 throw   new   IllegalArgumentException ( "Source equals sink" );
         if   ( ! isFeasible ( G ,  s ,  t ))   throw   new   IllegalArgumentException ( "Initial flow is infeasible" );

         // while there exists an augmenting path, use it
        value  =  excess ( G ,  t );
         while   ( hasAugmentingPath ( G ,  s ,  t ))   {

             // compute bottleneck capacity
             double  bottle  =   Double . POSITIVE_INFINITY ;
             for   ( int  v  =  t ;  v  !=  s ;  v  =  edgeTo [ v ]. other ( v ))   {
                bottle  =   Math . min ( bottle ,  edgeTo [ v ]. residualCapacityTo ( v ));
             }

             // augment flow
             for   ( int  v  =  t ;  v  !=  s ;  v  =  edgeTo [ v ]. other ( v ))   {
                edgeTo [ v ]. addResidualFlowTo ( v ,  bottle );  
             }

            value  +=  bottle ;
         }

         // check optimality conditions
         assert  check ( G ,  s ,  t );
     }

     /**
     * Returns the value of the maximum flow.
     *
     *  @return  the value of the maximum flow
     */
     public   double  value ()    {
         return  value ;
     }

     /**
     * Returns true if the specified vertex is on the { @code  s} side of the mincut.
     *
     *  @param   v vertex
     *  @return  { @code  true} if vertex { @code  v} is on the { @code  s} side of the micut;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  inCut ( int  v )    {
        validate ( v );
         return  marked [ v ];
     }

     // throw an IllegalArgumentException if v is outside prescibed range
     private   void  validate ( int  v )    {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }


     // is there an augmenting path? 
     // if so, upon termination edgeTo[] will contain a parent-link representation of such a path
     // this implementation finds a shortest augmenting path (fewest number of edges),
     // which performs well both in theory and in practice
     private   boolean  hasAugmentingPath ( FlowNetwork  G ,   int  s ,   int  t )   {
        edgeTo  =   new   FlowEdge [ G . V ()];
        marked  =   new   boolean [ G . V ()];

         // breadth-first search
         Queue < Integer >  queue  =   new   Queue < Integer > ();
        queue . enqueue ( s );
        marked [ s ]   =   true ;
         while   ( ! queue . isEmpty ()   &&   ! marked [ t ])   {
             int  v  =  queue . dequeue ();

             for   ( FlowEdge  e  :  G . adj ( v ))   {
                 int  w  =  e . other ( v );

                 // if residual capacity from v to w
                 if   ( e . residualCapacityTo ( w )   >   0 )   {
                     if   ( ! marked [ w ])   {
                        edgeTo [ w ]   =  e ;
                        marked [ w ]   =   true ;
                        queue . enqueue ( w );
                     }
                 }
             }
         }

         // is there an augmenting path?
         return  marked [ t ];
     }



     // return excess flow at vertex v
     private   double  excess ( FlowNetwork  G ,   int  v )   {
         double  excess  =   0.0 ;
         for   ( FlowEdge  e  :  G . adj ( v ))   {
             if   ( ==  e . from ())  excess  -=  e . flow ();
             else                excess  +=  e . flow ();
         }
         return  excess ;
     }

     // return excess flow at vertex v
     private   boolean  isFeasible ( FlowNetwork  G ,   int  s ,   int  t )   {

         // check that capacity constraints are satisfied
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( FlowEdge  e  :  G . adj ( v ))   {
                 if   ( e . flow ()   <   - FLOATING_POINT_EPSILON  ||  e . flow ()   >  e . capacity ()   +  FLOATING_POINT_EPSILON )   {
                     System . err . println ( "Edge does not satisfy capacity constraints: "   +  e );
                     return   false ;
                 }
             }
         }

         // check that net flow into a vertex equals zero, except at source and sink
         if   ( Math . abs ( value  +  excess ( G ,  s ))   >  FLOATING_POINT_EPSILON )   {
             System . err . println ( "Excess at source = "   +  excess ( G ,  s ));
             System . err . println ( "Max flow         = "   +  value );
             return   false ;
         }
         if   ( Math . abs ( value  -  excess ( G ,  t ))   >  FLOATING_POINT_EPSILON )   {
             System . err . println ( "Excess at sink   = "   +  excess ( G ,  t ));
             System . err . println ( "Max flow         = "   +  value );
             return   false ;
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ==  s  ||  v  ==  t )   continue ;
             else   if   ( Math . abs ( excess ( G ,  v ))   >  FLOATING_POINT_EPSILON )   {
                 System . err . println ( "Net flow out of "   +  v  +   " doesn't equal zero" );
                 return   false ;
             }
         }
         return   true ;
     }



     // check optimality conditions
     private   boolean  check ( FlowNetwork  G ,   int  s ,   int  t )   {

         // check that flow is feasible
         if   ( ! isFeasible ( G ,  s ,  t ))   {
             System . err . println ( "Flow is infeasible" );
             return   false ;
         }

         // check that s is on the source side of min cut and that t is not on source side
         if   ( ! inCut ( s ))   {
             System . err . println ( "source "   +  s  +   " is not on source side of min cut" );
             return   false ;
         }
         if   ( inCut ( t ))   {
             System . err . println ( "sink "   +  t  +   " is on source side of min cut" );
             return   false ;
         }

         // check that value of min cut = value of max flow
         double  mincutValue  =   0.0 ;
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( FlowEdge  e  :  G . adj ( v ))   {
                 if   (( ==  e . from ())   &&  inCut ( e . from ())   &&   ! inCut ( e . to ()))
                    mincutValue  +=  e . capacity ();
             }
         }

         if   ( Math . abs ( mincutValue  -  value )   >  FLOATING_POINT_EPSILON )   {
             System . err . println ( "Max flow value = "   +  value  +   ", min cut value = "   +  mincutValue );
             return   false ;
         }

         return   true ;
     }


     /**
     * Unit tests the { @code  FordFulkerson} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create flow network with V vertices and E edges
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         int  s  =   0 ,  t  =  V - 1 ;
         FlowNetwork  G  =   new   FlowNetwork ( V ,  E );
         StdOut . println ( G );

         // compute maximum flow and minimum cut
         FordFulkerson  maxflow  =   new   FordFulkerson ( G ,  s ,  t );
         StdOut . println ( "Max flow from "   +  s  +   " to "   +  t );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( FlowEdge  e  :  G . adj ( v ))   {
                 if   (( ==  e . from ())   &&  e . flow ()   >   0 )
                     StdOut . println ( "   "   +  e );
             }
         }

         // print min-cut
         StdOut . print ( "Min cut: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( maxflow . inCut ( v ))   StdOut . print ( +   " " );
         }
         StdOut . println ();

         StdOut . println ( "Max flow value = "   +   maxflow . value ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/FrequencyCounter.java

edu/princeton/cs/algs4/FrequencyCounter.java

/******************************************************************************
 *  Compilation:  javac FrequencyCounter.java
 *  Execution:    java FrequencyCounter L < input.txt
 *  Dependencies: ST.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyTale.txt
 *                https://algs4.cs.princeton.edu/31elementary/tale.txt
 *                https://algs4.cs.princeton.edu/31elementary/leipzig100K.txt
 *                https://algs4.cs.princeton.edu/31elementary/leipzig300K.txt
 *                https://algs4.cs.princeton.edu/31elementary/leipzig1M.txt
 *
 *  Read in a list of words from standard input and print out
 *  the most frequently occurring word that has length greater than
 *  a given threshold.
 *
 *  % java FrequencyCounter 1 < tinyTale.txt
 *  it 10
 *
 *  % java FrequencyCounter 8 < tale.txt
 *  business 122
 *
 *  % java FrequencyCounter 10 < leipzig1M.txt
 *  government 24763
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  FrequencyCounter} class provides a client for 
 *  reading in a sequence of words and printing a word (exceeding
 *  a given length) that occurs most frequently. It is useful as
 *  a test client for various symbol table implementations.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   FrequencyCounter   {

     // Do not instantiate.
     private   FrequencyCounter ()   {   }

     /**
     * Reads in a command-line integer and sequence of words from
     * standard input and prints out a word (whose length exceeds
     * the threshold) that occurs most frequently to standard output.
     * It also prints out the number of words whose length exceeds
     * the threshold and the number of distinct such words.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  distinct  =   0 ,  words  =   0 ;
         int  minlen  =   Integer . parseInt ( args [ 0 ]);
        ST < String ,   Integer >  st  =   new  ST < String ,   Integer > ();

         // compute frequency counts
         while   ( ! StdIn . isEmpty ())   {
             String  key  =   StdIn . readString ();
             if   ( key . length ()   <  minlen )   continue ;
            words ++ ;
             if   ( st . contains ( key ))   {
                st . put ( key ,  st . get ( key )   +   1 );
             }
             else   {
                st . put ( key ,   1 );
                distinct ++ ;
             }
         }

         // find a key with the highest frequency count
         String  max  =   "" ;
        st . put ( max ,   0 );
         for   ( String  word  :  st . keys ())   {
             if   ( st . get ( word )   >  st . get ( max ))
                max  =  word ;
         }

         StdOut . println ( max  +   " "   +  st . get ( max ));
         StdOut . println ( "distinct = "   +  distinct );
         StdOut . println ( "words    = "   +  words );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GabowSCC.java

edu/princeton/cs/algs4/GabowSCC.java

/******************************************************************************
 *  Compilation:  javac GabowSCC.java
 *  Execution:    java GabowSCC V E
 *  Dependencies: Digraph.java Stack.java TransitiveClosure.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Compute the strongly-connected components of a digraph using 
 *  Gabow's algorithm (aka Cheriyan-Mehlhorn algorithm).
 *
 *  Runs in O(E + V) time.
 *
 *  % java GabowSCC tinyDG.txt
 *  5 components
 *  1 
 *  0 2 3 4 5
 *  9 10 11 12
 *  6 8
 *  7 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;
/**
 *  The { @code  GabowSCC} class represents a data type for 
 *  determining the strong components in a digraph.
 *  The <em>id</em> operation determines in which strong component
 *  a given vertex lies; the <em>areStronglyConnected</em> operation
 *  determines whether two vertices are in the same strong component;
 *  and the <em>count</em> operation determines the number of strong
 *  components.

 *  The <em>component identifier</em> of a component is one of the
 *  vertices in the strong component: two vertices have the same component
 *  identifier if and only if they are in the same strong component.

 *  <p>
 *  This implementation uses the Gabow's algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em> is
 *  the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  For alternative implementations of the same API, see
 *  { @link  KosarajuSharirSCC} and { @link  TarjanSCC}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   GabowSCC   {

     private   boolean []  marked ;          // marked[v] = has v been visited?
     private   int []  id ;                  // id[v] = id of strong component containing v
     private   int []  preorder ;            // preorder[v] = preorder of v
     private   int  pre ;                   // preorder number counter
     private   int  count ;                 // number of strongly-connected components
     private   Stack < Integer >  stack1 ;
     private   Stack < Integer >  stack2 ;


     /**
     * Computes the strong components of the digraph { @code  G}.
     *  @param  G the digraph
     */
     public   GabowSCC ( Digraph  G )   {
        marked  =   new   boolean [ G . V ()];
        stack1  =   new   Stack < Integer > ();
        stack2  =   new   Stack < Integer > ();
        id  =   new   int [ G . V ()];  
        preorder  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            id [ v ]   =   - 1 ;

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ! marked [ v ])  dfs ( G ,  v );
         }

         // check that id[] gives strong components
         assert  check ( G );
     }

     private   void  dfs ( Digraph  G ,   int  v )   {  
        marked [ v ]   =   true ;
        preorder [ v ]   =  pre ++ ;
        stack1 . push ( v );
        stack2 . push ( v );
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])  dfs ( G ,  w );
             else   if   ( id [ w ]   ==   - 1 )   {
                 while   ( preorder [ stack2 . peek ()]   >  preorder [ w ])
                    stack2 . pop ();
             }
         }

         // found strong component containing v
         if   ( stack2 . peek ()   ==  v )   {
            stack2 . pop ();
             int  w ;
             do   {
                w  =  stack1 . pop ();
                id [ w ]   =  count ;
             }   while   ( !=  v );
            count ++ ;
         }
     }

     /**
     * Returns the number of strong components.
     *  @return  the number of strong components
     */
     public   int  count ()   {
         return  count ;
     }

     /**
     * Are vertices { @code  v} and { @code  w} in the same strong component?
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same
     *         strong component, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     */
     public   boolean  stronglyConnected ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  id [ v ]   ==  id [ w ];
     }

     /**
     * Returns the component id of the strong component containing vertex { @code  v}.
     *  @param   v the vertex
     *  @return  the component id of the strong component containing vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  id ( int  v )   {
        validateVertex ( v );
         return  id [ v ];
     }

     // does the id[] array contain the strongly connected components?
     private   boolean  check ( Digraph  G )   {
         TransitiveClosure  tc  =   new   TransitiveClosure ( G );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))
                     return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  GabowSCC} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         GabowSCC  scc  =   new   GabowSCC ( G );

         // number of connected components
         int  m  =  scc . count ();
         StdOut . println ( +   " components" );

         // compute list of vertices in each strong component
         Queue < Integer > []  components  =   ( Queue < Integer > [])   new   Queue [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
            components [ i ]   =   new   Queue < Integer > ();
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            components [ scc . id ( v )]. enqueue ( v );
         }

         // print results
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  v  :  components [ i ])   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GaussianElimination.java

edu/princeton/cs/algs4/GaussianElimination.java

/******************************************************************************
 *  Compilation:  javac GaussianElimination.java
 *  Execution:    java GaussianElimination m n
 *  Dependencies: StdOut.java
 * 
 *  Gaussian elimination with partial pivoting for m-by-n system.
 *
 *  % java GaussianElimination m n
 *  -1.000000
 *  2.000000
 *  2.000000
 *
 *  3.000000
 *  -1.000000
 *  -2.000000
 * 
 *  System is infeasible
 *
 *  -6.250000
 *  -4.500000
 *  0.000000
 *  0.000000
 *  1.000000
 *
 *  System is infeasible
 *
 *  -1.375000
 *  1.625000
 *  0.000000
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  GaussianElimination} data type provides methods
 *  to solve a linear system of equations <em>Ax</em> = <em>b</em>,
 *  where <em>A</em> is an <em>m</em>-by-<em>n</em> matrix
 *  and <em>b</em> is a length <em>n</em> vector.
 *  <p>
 *  This is a bare-bones implementation that uses Gaussian elimination
 *  with partial pivoting.
 *  See <a href = "https://algs4.cs.princeton.edu/99scientific/GaussianEliminationLite.java.html">GaussianEliminationLite.java</a>
 *  for a stripped-down version that assumes the matrix <em>A</em> is square
 *  and nonsingular. See { @link  GaussJordanElimination} for an alternate
 *  implementation that uses Gauss-Jordan elimination.
 *  For an industrial-strength numerical linear algebra library,
 *  see <a href = "http://math.nist.gov/javanumerics/jama/">JAMA</a>.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   GaussianElimination   {
     private   static   final   double  EPSILON  =   1e-8 ;

     private   final   int  m ;        // number of rows
     private   final   int  n ;        // number of columns
     private   double [][]  a ;       // m-by-(n+1) augmented matrix

     /**
     * Solves the linear system of equations <em>Ax</em> = <em>b</em>,
     * where <em>A</em> is an <em>m</em>-by-<em>n</em> matrix and <em>b</em>
     * is a length <em>m</em> vector.
     *
     *  @param   A the <em>m</em>-by-<em>n</em> constraint matrix
     *  @param   b the length <em>m</em> right-hand-side vector
     *  @throws  IllegalArgumentException if the dimensions disagree, i.e.,
     *         the length of { @code  b} does not equal { @code  m}
     */
     public   GaussianElimination ( double [][]  A ,   double []  b )   {
        m  =  A . length ;
        n  =  A [ 0 ]. length ;

         if   ( b . length  !=  m )   throw   new   IllegalArgumentException ( "Dimensions disagree" );

         // build augmented matrix
        a  =   new   double [ m ][ n + 1 ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                a [ i ][ j ]   =  A [ i ][ j ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            a [ i ][ n ]   =  b [ i ];

        forwardElimination ();

         assert  certifySolution ( A ,  b );
     }

     // forward elimination
     private   void  forwardElimination ()   {
         for   ( int  p  =   0 ;  p  <   Math . min ( m ,  n );  p ++ )   {

             // find pivot row using partial pivoting
             int  max  =  p ;
             for   ( int  i  =  p + 1 ;  i  <  m ;  i ++ )   {
                 if   ( Math . abs ( a [ i ][ p ])   >   Math . abs ( a [ max ][ p ]))   {
                    max  =  i ;
                 }
             }

             // swap
            swap ( p ,  max );

             // singular or nearly singular
             if   ( Math . abs ( a [ p ][ p ])   <=  EPSILON )   {
                 continue ;
             }

             // pivot
            pivot ( p );
         }
     }

     // swap row1 and row2
     private   void  swap ( int  row1 ,   int  row2 )   {
         double []  temp  =  a [ row1 ];
        a [ row1 ]   =  a [ row2 ];
        a [ row2 ]   =  temp ;
     }

     // pivot on a[p][p]
     private   void  pivot ( int  p )   {
         for   ( int  i  =  p + 1 ;  i  <  m ;  i ++ )   {
             double  alpha  =  a [ i ][ p ]   /  a [ p ][ p ];
             for   ( int  j  =  p ;  j  <=  n ;  j ++ )   {
                a [ i ][ j ]   -=  alpha  *  a [ p ][ j ];
             }
         }
     }

     /**
     * Returns a solution to the linear system of equations <em>Ax</em> = <em>b</em>.
     *      
     *  @return  a solution <em>x</em> to the linear system of equations
     *         <em>Ax</em> = <em>b</em>; { @code  null} if no such solution
     */
     public   double []  primal ()   {
         // back substitution
         double []  x  =   new   double [ n ];
         for   ( int  i  =   Math . min ( n - 1 ,  m - 1 );  i  >=   0 ;  i -- )   {
             double  sum  =   0.0 ;
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                sum  +=  a [ i ][ j ]   *  x [ j ];
             }

             if   ( Math . abs ( a [ i ][ i ])   >  EPSILON )
                x [ i ]   =   ( a [ i ][ n ]   -  sum )   /  a [ i ][ i ];
             else   if   ( Math . abs ( a [ i ][ n ]   -  sum )   >  EPSILON )
                 return   null ;
         }

         // redundant rows
         for   ( int  i  =  n ;  i  <  m ;  i ++ )   {
             double  sum  =   0.0 ;
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                sum  +=  a [ i ][ j ]   *  x [ j ];
             }
             if   ( Math . abs ( a [ i ][ n ]   -  sum )   >  EPSILON )
                 return   null ;
         }
         return  x ;
     }

     /**
     * Returns true if there exists a solution to the linear system of
     * equations <em>Ax</em> = <em>b</em>.
     *      
     *  @return  { @code  true} if there exists a solution to the linear system
     *         of equations <em>Ax</em> = <em>b</em>; { @code  false} otherwise
     */
     public   boolean  isFeasible ()   {
         return  primal ()   !=   null ;
     }


     // check that Ax = b
     private   boolean  certifySolution ( double [][]  A ,   double []  b )   {
         if   ( ! isFeasible ())   return   true ;
         double []  x  =  primal ();
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             double  sum  =   0.0 ;
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                sum  +=  A [ i ][ j ]   *  x [ j ];
             }
             if   ( Math . abs ( sum  -  b [ i ])   >  EPSILON )   {
                 StdOut . println ( "not feasible" );
                 StdOut . println ( "b["   +  i  +   "] = "   +  b [ i ]   +   ", sum = "   +  sum );
                 return   false ;
             }
         }
         return   true ;
     }


     /**
     * Unit tests the { @code  GaussianElimination} data type.
     */
     private   static   void  test ( String  name ,   double [][]  A ,   double []  b )   {
         StdOut . println ( "----------------------------------------------------" );
         StdOut . println ( name );
         StdOut . println ( "----------------------------------------------------" );
         GaussianElimination  gaussian  =   new   GaussianElimination ( A ,  b );
         double []  x  =  gaussian . primal ();
         if   ( gaussian . isFeasible ())   {
             for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )   {
                 StdOut . printf ( "%.6f\n" ,  x [ i ]);
             }
         }
         else   {
             StdOut . println ( "System is infeasible" );
         }
         StdOut . println ();
         StdOut . println ();
     }


     // 3-by-3 nonsingular system
     private   static   void  test1 ()   {
         double [][]  A  =   {
             {   0 ,   1 ,    1   },
             {   2 ,   4 ,   - 2   },
             {   0 ,   3 ,   15   }
         };
         double []  b  =   {   4 ,   2 ,   36   };
        test ( "test 1 (3-by-3 system, nonsingular)" ,  A ,  b );
     }

     // 3-by-3 nonsingular system
     private   static   void  test2 ()   {
         double [][]  A  =   {
             {    1 ,   - 3 ,     1   },
             {    2 ,   - 8 ,     8   },
             {   - 6 ,    3 ,   - 15   }
         };
         double []  b  =   {   4 ,   - 2 ,   9   };
        test ( "test 2 (3-by-3 system, nonsingular)" ,  A ,  b );
     }

     // 5-by-5 singular: no solutions
     private   static   void  test3 ()   {
         double [][]  A  =   {
             {    2 ,   - 3 ,   - 1 ,    2 ,    3   },
             {    4 ,   - 4 ,   - 1 ,    4 ,   11   },
             {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },
             {    0 ,    2 ,    1 ,    0 ,    4   },
             {   - 4 ,    6 ,    0 ,    0 ,    7   },
         };
         double []  b  =   {   4 ,   4 ,   9 ,   - 6 ,   5   };
        test ( "test 3 (5-by-5 system, no solutions)" ,  A ,  b );
     }

     // 5-by-5 singular: infinitely many solutions
     private   static   void  test4 ()   {
         double [][]  A  =   {
             {    2 ,   - 3 ,   - 1 ,    2 ,    3   },
             {    4 ,   - 4 ,   - 1 ,    4 ,   11   },
             {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },
             {    0 ,    2 ,    1 ,    0 ,    4   },
             {   - 4 ,    6 ,    0 ,    0 ,    7   },
         };
         double []  b  =   {   4 ,   4 ,   9 ,   - 5 ,   5   };
        test ( "test 4 (5-by-5 system, infinitely many solutions)" ,  A ,  b );
     }

     // 3-by-3 singular: no solutions
     private   static   void  test5 ()   {
         double [][]  A  =   {
             {    2 ,   - 1 ,    1   },
             {    3 ,    2 ,   - 4   },
             {   - 6 ,    3 ,   - 3   },
         };
         double []  b  =   {   1 ,   4 ,   2   };
        test ( "test 5 (3-by-3 system, no solutions)" ,  A ,  b );
     }

     // 3-by-3 singular: infinitely many solutions
     private   static   void  test6 ()   {
         double [][]  A  =   {
             {    1 ,   - 1 ,    2   },
             {    4 ,    4 ,   - 2   },
             {   - 2 ,    2 ,   - 4   },
         };
         double []  b  =   {   - 3 ,   1 ,   6   };
        test ( "test 6 (3-by-3 system, infinitely many solutions)" ,  A ,  b );
     }

     // 4-by-3 full rank and feasible system
     private   static   void  test7 ()   {
         double [][]  A  =   {
             {   0 ,   1 ,    1   },
             {   2 ,   4 ,   - 2   },
             {   0 ,   3 ,   15   },
             {   2 ,   8 ,   14   }
         };
         double []  b  =   {   4 ,   2 ,   36 ,   42   };
        test ( "test 7 (4-by-3 system, full rank)" ,  A ,  b );
     }

     // 4-by-3 full rank and infeasible system
     private   static   void  test8 ()   {
         double [][]  A  =   {
             {   0 ,   1 ,    1   },
             {   2 ,   4 ,   - 2   },
             {   0 ,   3 ,   15   },
             {   2 ,   8 ,   14   }
         };
         double []  b  =   {   4 ,   2 ,   36 ,   40   };
        test ( "test 8 (4-by-3 system, no solution)" ,  A ,  b );
     }

     // 3-by-4 full rank system
     private   static   void  test9 ()   {
         double [][]  A  =   {
             {    1 ,   - 3 ,     1 ,    1   },
             {    2 ,   - 8 ,     8 ,    2   },
             {   - 6 ,    3 ,   - 15 ,    3   }
         };
         double []  b  =   {   4 ,   - 2 ,   9   };
        test ( "test 9 (3-by-4 system, full rank)" ,  A ,  b );
     }

     /**
     * Unit tests the { @code  GaussianElimination} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
        test1 ();
        test2 ();
        test3 ();
        test4 ();
        test5 ();
        test6 ();
        test7 ();
        test8 ();
        test9 ();

         // n-by-n random system
         int  n  =   Integer . parseInt ( args [ 0 ]);
         double [][]  A  =   new   double [ n ][ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                A [ i ][ j ]   =   StdRandom . uniform ( 1000 );
         double []  b  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            b [ i ]   =   StdRandom . uniform ( 1000 );

        test ( +   "-by-"   +  n  +   " (probably nonsingular)" ,  A ,  b );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GaussJordanElimination.java

edu/princeton/cs/algs4/GaussJordanElimination.java

/******************************************************************************
 *  Compilation:  javac GaussJordanElimination.java
 *  Execution:    java GaussJordanElimination n
 *  Dependencies: StdOut.java
 * 
 *  Finds a solutions to Ax = b using Gauss-Jordan elimination with partial
 *  pivoting. If no solution exists, find a solution to yA = 0, yb != 0,
 *  which serves as a certificate of infeasibility.
 *
 *  % java GaussJordanElimination
 *  -1.000000
 *  2.000000
 *  2.000000
 *
 *  3.000000
 *  -1.000000
 *  -2.000000
 * 
 *  System is infeasible
 *
 *  -6.250000
 *  -4.500000
 *  0.000000
 *  0.000000
 *  1.000000
 *
 *  System is infeasible
 *
 *  -1.375000
 *  1.625000
 *  0.000000
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  GaussJordanElimination} data type provides methods
 *  to solve a linear system of equations <em>Ax</em> = <em>b</em>,
 *  where <em>A</em> is an <em>n</em>-by-<em>n</em> matrix
 *  and <em>b</em> is a length <em>n</em> vector.
 *  If no solution exists, it finds a solution <em>y</em> to
 *  <em>yA</em> = 0, <em>yb</em> &ne; 0, which
 *  which serves as a certificate of infeasibility.
 *  <p>
 *  This implementation uses Gauss-Jordan elimination with partial pivoting.
 *  See { @link  GaussianElimination} for an implementation that uses
 *  Gaussian elimination (but does not provide the certificate of infeasibility).
 *  For an industrial-strength numerical linear algebra library,
 *  see <a href = "http://math.nist.gov/javanumerics/jama/">JAMA</a>. 
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   GaussJordanElimination   {
     private   static   final   double  EPSILON  =   1e-8 ;

     private   final   int  n ;        // n-by-n system
     private   double [][]  a ;       // n-by-(n+1) augmented matrix

     // Gauss-Jordan elimination with partial pivoting
     /**
     * Solves the linear system of equations <em>Ax</em> = <em>b</em>,
     * where <em>A</em> is an <em>n</em>-by-<em>n</em> matrix and <em>b</em>
     * is a length <em>n</em> vector.
     *
     *  @param   A the <em>n</em>-by-<em>n</em> constraint matrix
     *  @param   b the length <em>n</em> right-hand-side vector
     */
     public   GaussJordanElimination ( double [][]  A ,   double []  b )   {
        n  =  b . length ;

         // build augmented matrix
        a  =   new   double [ n ][ n + n + 1 ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                a [ i ][ j ]   =  A [ i ][ j ];

         // only needed if you want to find certificate of infeasibility (or compute inverse)
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            a [ i ][ n + i ]   =   1.0 ;

         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            a [ i ][ n + n ]   =  b [ i ];

        solve ();

         assert  certifySolution ( A ,  b );
     }

     private   void  solve ()   {

         // Gauss-Jordan elimination
         for   ( int  p  =   0 ;  p  <  n ;  p ++ )   {
             // show();

             // find pivot row using partial pivoting
             int  max  =  p ;
             for   ( int  i  =  p + 1 ;  i  <  n ;  i ++ )   {
                 if   ( Math . abs ( a [ i ][ p ])   >   Math . abs ( a [ max ][ p ]))   {
                    max  =  i ;
                 }
             }

             // exchange row p with row max
            swap ( p ,  max );

             // singular or nearly singular
             if   ( Math . abs ( a [ p ][ p ])   <=  EPSILON )   {
                 continue ;
                 // throw new ArithmeticException("Matrix is singular or nearly singular");
             }

             // pivot
            pivot ( p ,  p );
         }
         // show();
     }

     // swap row1 and row2
     private   void  swap ( int  row1 ,   int  row2 )   {
         double []  temp  =  a [ row1 ];
        a [ row1 ]   =  a [ row2 ];
        a [ row2 ]   =  temp ;
     }


     // pivot on entry (p, q) using Gauss-Jordan elimination
     private   void  pivot ( int  p ,   int  q )   {

         // everything but row p and column q
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             double  alpha  =  a [ i ][ q ]   /  a [ p ][ q ];
             for   ( int  j  =   0 ;  j  <=  n + n ;  j ++ )   {
                 if   ( !=  p  &&  j  !=  q )  a [ i ][ j ]   -=  alpha  *  a [ p ][ j ];
             }
         }

         // zero out column q
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             if   ( !=  p )  a [ i ][ q ]   =   0.0 ;

         // scale row p (ok to go from q+1 to n, but do this for consistency with simplex pivot)
         for   ( int  j  =   0 ;  j  <=  n + n ;  j ++ )
             if   ( !=  q )  a [ p ][ j ]   /=  a [ p ][ q ];
        a [ p ][ q ]   =   1.0 ;
     }

     /**
     * Returns a solution to the linear system of equations <em>Ax</em> = <em>b</em>.
     *      
     *  @return  a solution <em>x</em> to the linear system of equations
     *         <em>Ax</em> = <em>b</em>; { @code  null} if no such solution
     */
     public   double []  primal ()   {
         double []  x  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( Math . abs ( a [ i ][ i ])   >  EPSILON )
                x [ i ]   =  a [ i ][ n + n ]   /  a [ i ][ i ];
             else   if   ( Math . abs ( a [ i ][ n + n ])   >  EPSILON )
                 return   null ;
         }
         return  x ;
     }

     /**
     * Returns a solution to the linear system of equations <em>yA</em> = 0,
     * <em>yb</em> &ne; 0.
     *      
     *  @return  a solution <em>y</em> to the linear system of equations
     *         <em>yA</em> = 0, <em>yb</em> &ne; 0; { @code  null} if no such solution
     */
     public   double []  dual ()   {
         double []  y  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   (( Math . abs ( a [ i ][ i ])   <=  EPSILON )   &&   ( Math . abs ( a [ i ][ n + n ])   >  EPSILON ))   {
                 for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                    y [ j ]   =  a [ i ][ n + j ];
                 return  y ;
             }
         }
         return   null ;
     }

     /**
     * Returns true if there exists a solution to the linear system of
     * equations <em>Ax</em> = <em>b</em>.
     *      
     *  @return  { @code  true} if there exists a solution to the linear system
     *         of equations <em>Ax</em> = <em>b</em>; { @code  false} otherwise
     */
     public   boolean  isFeasible ()   {
         return  primal ()   !=   null ;
     }

     // print the tableaux
     private   void  show ()   {
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 StdOut . printf ( "%8.3f " ,  a [ i ][ j ]);
             }
             StdOut . printf ( "| " );
             for   ( int  j  =  n ;  j  <  n + n ;  j ++ )   {
                 StdOut . printf ( "%8.3f " ,  a [ i ][ j ]);
             }
             StdOut . printf ( "| %8.3f\n" ,  a [ i ][ n + n ]);
         }
         StdOut . println ();
     }


     // check that Ax = b or yA = 0, yb != 0
     private   boolean  certifySolution ( double [][]  A ,   double []  b )   {

         // check that Ax = b
         if   ( isFeasible ())   {
             double []  x  =  primal ();
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 double  sum  =   0.0 ;
                 for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                    sum  +=  A [ i ][ j ]   *  x [ j ];
                 }
                 if   ( Math . abs ( sum  -  b [ i ])   >  EPSILON )   {
                     StdOut . println ( "not feasible" );
                     StdOut . printf ( "b[%d] = %8.3f, sum = %8.3f\n" ,  i ,  b [ i ],  sum );
                     return   false ;
                 }
             }
             return   true ;
         }

         // or that yA = 0, yb != 0
         else   {
             double []  y  =  dual ();
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 double  sum  =   0.0 ;
                 for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                    sum  +=  A [ i ][ j ]   *  y [ i ];
                 }
                 if   ( Math . abs ( sum )   >  EPSILON )   {
                     StdOut . println ( "invalid certificate of infeasibility" );
                     StdOut . printf ( "sum = %8.3f\n" ,  sum );
                     return   false ;
                 }
             }
             double  sum  =   0.0 ;
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                sum  +=  y [ i ]   *  b [ i ];
             }
             if   ( Math . abs ( sum )   <  EPSILON )   {
                 StdOut . println ( "invalid certificate of infeasibility" );
                 StdOut . printf ( "yb  = %8.3f\n" ,  sum );
                 return   false ;
             }
             return   true ;
         }
     }


     private   static   void  test ( String  name ,   double [][]  A ,   double []  b )   {
         StdOut . println ( "----------------------------------------------------" );
         StdOut . println ( name );
         StdOut . println ( "----------------------------------------------------" );
         GaussJordanElimination  gaussian  =   new   GaussJordanElimination ( A ,  b );
         if   ( gaussian . isFeasible ())   {
             StdOut . println ( "Solution to Ax = b" );
             double []  x  =  gaussian . primal ();
             for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )   {
                 StdOut . printf ( "%10.6f\n" ,  x [ i ]);
             }
         }
         else   {
             StdOut . println ( "Certificate of infeasibility" );
             double []  y  =  gaussian . dual ();
             for   ( int  j  =   0 ;  j  <  y . length ;  j ++ )   {
                 StdOut . printf ( "%10.6f\n" ,  y [ j ]);
             }
         }
         StdOut . println ();
         StdOut . println ();
     }


     // 3-by-3 nonsingular system
     private   static   void  test1 ()   {
         double [][]  A  =   {
             {   0 ,   1 ,    1   },
             {   2 ,   4 ,   - 2   },
             {   0 ,   3 ,   15   }
         };
         double []  b  =   {   4 ,   2 ,   36   };
        test ( "test 1" ,  A ,  b );
     }

     // 3-by-3 nonsingular system
     private   static   void  test2 ()   {
         double [][]  A  =   {
             {    1 ,   - 3 ,     1   },
             {    2 ,   - 8 ,     8   },
             {   - 6 ,    3 ,   - 15   }
         };
         double []  b  =   {   4 ,   - 2 ,   9   };
        test ( "test 2" ,  A ,  b );
     }

     // 5-by-5 singular: no solutions
     // y = [ -1, 0, 1, 1, 0 ]
     private   static   void  test3 ()   {
         double [][]  A  =   {
             {    2 ,   - 3 ,   - 1 ,    2 ,    3   },
             {    4 ,   - 4 ,   - 1 ,    4 ,   11   },
             {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },
             {    0 ,    2 ,    1 ,    0 ,    4   },
             {   - 4 ,    6 ,    0 ,    0 ,    7   },
         };
         double []  b  =   {   4 ,   4 ,   9 ,   - 6 ,   5   };
        test ( "test 3" ,  A ,  b );
     }

     // 5-by-5 singluar: infinitely many solutions
     private   static   void  test4 ()   {
         double [][]  A  =   {
             {    2 ,   - 3 ,   - 1 ,    2 ,    3   },
             {    4 ,   - 4 ,   - 1 ,    4 ,   11   },
             {    2 ,   - 5 ,   - 2 ,    2 ,   - 1   },
             {    0 ,    2 ,    1 ,    0 ,    4   },
             {   - 4 ,    6 ,    0 ,    0 ,    7   },
         };
         double []  b  =   {   4 ,   4 ,   9 ,   - 5 ,   5   };
        test ( "test 4" ,  A ,  b );
     }

     // 3-by-3 singular: no solutions
     // y = [ 1, 0, 1/3 ]
     private   static   void  test5 ()   {
         double [][]  A  =   {
             {    2 ,   - 1 ,    1   },
             {    3 ,    2 ,   - 4   },
             {   - 6 ,    3 ,   - 3   },
         };
         double []  b  =   {   1 ,   4 ,   2   };
        test ( "test 5" ,  A ,  b );
     }

     // 3-by-3 singular: infinitely many solutions
     private   static   void  test6 ()   {
         double [][]  A  =   {
             {    1 ,   - 1 ,    2   },
             {    4 ,    4 ,   - 2   },
             {   - 2 ,    2 ,   - 4   },
         };
         double []  b  =   {   - 3 ,   1 ,   6   };
        test ( "test 6 (infinitely many solutions)" ,  A ,  b );
     }

     /**
     * Unit tests the { @code  GaussJordanElimination} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

        test1 ();
        test2 ();
        test3 ();
        test4 ();
        test5 ();
        test6 ();

         // n-by-n random system (likely full rank)
         int  n  =   Integer . parseInt ( args [ 0 ]);
         double [][]  A  =   new   double [ n ][ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                A [ i ][ j ]   =   StdRandom . uniform ( 1000 );
         double []  b  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            b [ i ]   =   StdRandom . uniform ( 1000 );
        test ( "random "   +  n  +   "-by-"   +  n  +   " (likely full rank)" ,  A ,  b );


         // n-by-n random system (likely infeasible)
        A  =   new   double [ n ][ n ];
         for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                A [ i ][ j ]   =   StdRandom . uniform ( 1000 );
         for   ( int  i  =   0 ;  i  <  n - 1 ;  i ++ )   {
             double  alpha  =   StdRandom . uniform ( 11 )   -   5.0 ;
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                A [ n - 1 ][ j ]   +=  alpha  *  A [ i ][ j ];
             }
         }
        b  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            b [ i ]   =   StdRandom . uniform ( 1000 );
        test ( "random "   +  n  +   "-by-"   +  n  +   " (likely infeasible)" ,  A ,  b );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Genome.java

edu/princeton/cs/algs4/Genome.java

/******************************************************************************
 *  Compilation:  javac Genome.java
 *  Execution:    java Genome - < input.txt   (compress)
 *  Execution:    java Genome + < input.txt   (expand)
 *  Dependencies: BinaryIn.java BinaryOut.java
 *  Data files:   https://algs4.cs.princeton.edu/55compression/genomeTiny.txt
 *
 *  Compress or expand a genomic sequence using a 2-bit code.
 *
 *  % more genomeTiny.txt
 *  ATAGATGCATAGCGCATAGCTAGATGTGCTAGC
 *
 *  % java Genome - < genomeTiny.txt | java Genome +
 *  ATAGATGCATAGCGCATAGCTAGATGTGCTAGC
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Genome} class provides static methods for compressing
 *  and expanding a genomic sequence using a 2-bit code.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Genome   {

     // Do not instantiate.
     private   Genome ()   {   }

     /**
     * Reads a sequence of 8-bit extended ASCII characters over the alphabet
     * { A, C, T, G } from standard input; compresses them using two bits per
     * character; and writes the results to standard output.
     */
     public   static   void  compress ()   {  
         Alphabet  DNA  =   Alphabet . DNA ;
         String  s  =   BinaryStdIn . readString ();
         int  n  =  s . length ();
         BinaryStdOut . write ( n );

         // Write two-bit code for char. 
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  d  =  DNA . toIndex ( s . charAt ( i ));
             BinaryStdOut . write ( d ,   2 );
         }
         BinaryStdOut . close ();
     }  

     /**
     * Reads a binary sequence from standard input; converts each two bits
     * to an 8-bit extended ASCII character over the alphabet { A, C, T, G };
     * and writes the results to standard output.
     */
     public   static   void  expand ()   {
         Alphabet  DNA  =   Alphabet . DNA ;
         int  n  =   BinaryStdIn . readInt ();
         // Read two bits; write char. 
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             char  c  =   BinaryStdIn . readChar ( 2 );
             BinaryStdOut . write ( DNA . toChar ( c ),   8 );
         }
         BinaryStdOut . close ();
     }


     /**
     * Sample client that calls { @code  compress()} if the command-line
     * argument is "-" an { @code  expand()} if it is "+".
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         if        ( args [ 0 ]. equals ( "-" ))  compress ();
         else   if   ( args [ 0 ]. equals ( "+" ))  expand ();
         else   throw   new   IllegalArgumentException ( "Illegal command line argument" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GlobalMincut.java

edu/princeton/cs/algs4/GlobalMincut.java

/******************************************************************************
 *  Compilation:  javac GlobalMincut.java
 *  Execution:    java  GlobalMincut filename.txt
 *  Dependencies: EdgeWeightedGraph.java Edge.java UF.java 
 *                IndexMaxPQ.java FlowNetwork.java FlowEdge.java 
 *                FordFulkerson.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *
 *  Computes a minimum cut using Stoer-Wagner's algorithm.
 *
 *  % java GlobalMincut tinyEWG.txt 
 *    Min cut: 5 
 *    Min cut weight = 0.9500000000000001
 *    
 *  % java GlobalMincut mediumEWG.txt 
 *    Min cut: 25 60 63 96 199 237 
 *    Min cut weight = 0.14021
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  GlobalMincut} class represents a data type for computing a
 *  <em>global minimum cut</em> in a graph with non-negative edge weights.
 *  A <em>cut</em> is a partition of the vertices into two nonempty subsets.
 *  An edge that has one
 *  endpoint in each subset of a cut is a <em>crossing edge</em>. The weight
 *  of a cut is the sum of the weights of its crossing edges.
 *  A <em>global minimum cut</em> whose weight is no larger than the weight
 *  of any other cut.
 *  <p>
 *  This is an implementation of <em>Stoer-Wagner's algorithm</em>.
 *  The constructor takes
 *  <em>O</em>(<em>V</em> (<em>V</em> + <em>E</em>) log <em>V</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges. 
 *  The <em>weight</em> and <em>isCut</em> methods take &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph).
 *  <p>
 *  For additional documentation, see
 *  <ul>
 *  <li>M. Stoer and F. Wagner (1997). A simple min-cut algorithm. <em>Journal of
 *  the ACM </em>, 44(4):585-591.
 *  </ul>
 * 
 *  @author  Marcelo Silva
 */
public   class   GlobalMincut   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-11 ;

     // the weight of the minimum cut
     private   double  weight  =   Double . POSITIVE_INFINITY ;

     // cut[v] = true if v is on the first subset of vertices of the minimum cut;
     // or false if v is on the second subset
     private   boolean []  cut ;

     // number of vertices
     private   int  V ;

     /**
     * This helper class represents the <em>cut-of-the-phase</em>. The
     * cut-of-the-phase is a <em>minimum s-t-cut</em> in the current graph,
     * where { @code  s} and { @code  t} are the two vertices added last in the
     * phase.
     */
     private   class   CutPhase   {
         private   double  weight ;   // the weight of the minimum s-t cut
         private   int  s ;           // the vertex s
         private   int  t ;           // the vertex t

         public   CutPhase ( double  weight ,   int  s ,   int  t )   {
             this . weight  =  weight ;
             this . =  s ;
             this . =  t ;
         }
     }

     /**
     * Computes a minimum cut in an edge-weighted graph.
     * 
     *  @param  G the edge-weighted graph
     *  @throws  IllegalArgumentException if the number of vertices of { @code  G}
     *             is less than { @code  2}.
     *  @throws  IllegalArgumentException if any edge weight is negative
     */
     public   GlobalMincut ( EdgeWeightedGraph  G )   {
        V  =  G . V ();
        validate ( G );
        minCut ( G ,   0 );
         assert  check ( G );
     }

     /**
     * Validates the edge-weighted graph.
     * 
     *  @param  G the edge-weighted graph
     *  @throws  IllegalArgumentException if the number of vertices of { @code  G}
     *             is less than { @code  2} or if any edge weight is negative
     */
     private   void  validate ( EdgeWeightedGraph  G )   {
         if   ( G . V ()   <   2 )   throw   new   IllegalArgumentException ( "number of vertices of G is less than 2" );
         for   ( Edge  e  :  G . edges ())   {
             if   ( e . weight ()   <   0 )   throw   new   IllegalArgumentException ( "edge "   +  e  +   " has negative weight" );
         }
     }

     /**
     * Returns the weight of the minimum cut.
     * 
     *  @return  the weight of the minimum cut
     */
     public   double  weight ()   {
         return  weight ;
     }

     /**
     * Returns { @code  true} if the vertex { @code  v} is one side of the
     * mincut and { @code  false} otherwise. An edge <em>v</em>-<em>w</em>
     * crosses the mincut if and only if <em>v</em> and <em>w</em> have
     * opposite parity.
     * 
     *  @param  v the vertex to check
     *  @return  { @code  true} if the vertex { @code  v} is on the first subset of
     *         vertices of the minimum cut; or { @code  false} if the vertex
     *         { @code  v} is on the second subset.
     *  @throws  IllegalArgumentException unless vertex { @code  v} is between
     *             { @code  0 <= v < V}
     */
     public   boolean  cut ( int  v )   {
        validateVertex ( v );
         return  cut [ v ];
     }

     /**
     * Makes a cut for the current edge-weighted graph by partitioning its
     * vertices into two nonempty subsets. The vertices connected to the
     * vertex { @code  t} belong to the first subset. Other vertices not connected
     * to { @code  t} belong to the second subset.
     * 
     *  @param  t the vertex { @code  t}
     *  @param  uf the union-find data type
     */
     private   void  makeCut ( int  t ,  UF uf )   {
         for   ( int  v  =   0 ;  v  <  cut . length ;  v ++ )   {
            cut [ v ]   =   ( uf . find ( v )   ==  uf . find ( t ));
         }
     }

     /**
     * Computes a minimum cut of the edge-weighted graph. Precisely, it computes
     * the lightest of the cuts-of-the-phase which yields the desired minimum
     * cut.
     * 
     *  @param  G the edge-weighted graph
     *  @param  a the starting vertex
     */
     private   void  minCut ( EdgeWeightedGraph  G ,   int  a )   {
        UF uf  =   new  UF ( G . V ());
         boolean []  marked  =   new   boolean [ G . V ()];
        cut  =   new   boolean [ G . V ()];
         CutPhase  cp  =   new   CutPhase ( 0.0 ,  a ,  a );
         for   ( int  v  =  G . V ();  v  >   1 ;  v -- )   {
            cp  =  minCutPhase ( G ,  marked ,  cp );
             if   ( cp . weight  <  weight )   {
                weight  =  cp . weight ;
                makeCut ( cp . t ,  uf );
             }
            G  =  contractEdge ( G ,  cp . s ,  cp . t );
            marked [ cp . t ]   =   true ;
            uf . union ( cp . s ,  cp . t );
         }
     }

     /**
     * Returns the cut-of-the-phase. The cut-of-the-phase is a minimum s-t-cut
     * in the current graph, where { @code  s} and { @code  t} are the two vertices
     * added last in the phase. This algorithm is known in the literature as
     * <em>maximum adjacency search</em> or <em>maximum cardinality search</em>.
     * 
     *  @param  G the edge-weighted graph
     *  @param  marked the array of contracted vertices, where { @code  marked[v]}
     *            is { @code  true} if the vertex { @code  v} was already
     *            contracted; or { @code  false} otherwise
     *  @param  cp the previous cut-of-the-phase
     *  @return  the cut-of-the-phase
     */
     private   CutPhase  minCutPhase ( EdgeWeightedGraph  G ,   boolean []  marked ,   CutPhase  cp )   {
         IndexMaxPQ < Double >  pq  =   new   IndexMaxPQ < Double > ( G . V ());
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( !=  cp . &&   ! marked [ v ])  pq . insert ( v ,   0.0 );
         }
        pq . insert ( cp . s ,   Double . POSITIVE_INFINITY );
         while   ( ! pq . isEmpty ())   {
             int  v  =  pq . delMax ();
            cp . =  cp . t ;
            cp . =  v ;
             for   ( Edge  e  :  G . adj ( v ))   {
                 int  w  =  e . other ( v );
                 if   ( pq . contains ( w ))  pq . increaseKey ( w ,  pq . keyOf ( w )   +  e . weight ());
             }
         }
        cp . weight  =   0.0 ;
         for   ( Edge  e  :  G . adj ( cp . t ))   {
            cp . weight  +=  e . weight ();
         }
         return  cp ;
     }

     /**
     * Contracts the edges incidents on the vertices { @code  s} and { @code  t} of
     * the given edge-weighted graph.
     * 
     *  @param  G the edge-weighted graph
     *  @param  s the vertex { @code  s}
     *  @param  t the vertex { @code  t}
     *  @return  a new edge-weighted graph for which the edges incidents on the
     *         vertices { @code  s} and { @code  t} were contracted
     */
     private   EdgeWeightedGraph  contractEdge ( EdgeWeightedGraph  G ,   int  s ,   int  t )   {
         EdgeWeightedGraph  H  =   new   EdgeWeightedGraph ( G . V ());
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( Edge  e  :  G . adj ( v ))   {
                 int  w  =  e . other ( v );
                 if   ( ==  s  &&  w  ==  t  ||  v  ==  t  &&  w  ==  s )   continue ;
                 if   ( <  w )   {
                     if   ( ==  t )       H . addEdge ( new   Edge ( v ,  s ,  e . weight ()));
                     else   if   ( ==  t )  H . addEdge ( new   Edge ( w ,  s ,  e . weight ()));
                     else              H . addEdge ( new   Edge ( v ,  w ,  e . weight ()));
                 }
             }
         }
         return  H ;
     }

     /**
     * Checks optimality conditions.
     * 
     *  @param  G the edge-weighted graph
     *  @return  { @code  true} if optimality conditions are fine
     */
     private   boolean  check ( EdgeWeightedGraph  G )   {

         // compute min st-cut for all pairs s and t
         // shortcut: s must appear on one side of global mincut,
         // so it suffices to try all pairs s-v for some fixed s
         double  value  =   Double . POSITIVE_INFINITY ;
         for   ( int  s  =   0 ,  t  =   1 ;  t  <  G . V ();  t ++ )   {
             FlowNetwork  F  =   new   FlowNetwork ( G . V ());
             for   ( Edge  e  :  G . edges ())   {
                 int  v  =  e . either (),  w  =  e . other ( v );
                F . addEdge ( new   FlowEdge ( v ,  w ,  e . weight ()));
                F . addEdge ( new   FlowEdge ( w ,  v ,  e . weight ()));
             }
             FordFulkerson  maxflow  =   new   FordFulkerson ( F ,  s ,  t );
            value  =   Math . min ( value ,  maxflow . value ());
         }
         if   ( Math . abs ( weight  -  value )   >  FLOATING_POINT_EPSILON )   {
             System . err . println ( "Min cut weight = "   +  weight  +   " , max flow value = "   +  value );
             return   false ;
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }


     /**
     * Unit tests the { @code  GlobalMincut} data type.
     * 
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         GlobalMincut  mc  =   new   GlobalMincut ( G );
         StdOut . print ( "Min cut: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( mc . cut ( v ))   StdOut . print ( +   " " );
         }
         StdOut . println ();
         StdOut . println ( "Min cut weight = "   +  mc . weight ());
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GrahamScan.java

edu/princeton/cs/algs4/GrahamScan.java

/******************************************************************************
 *  Compilation:  javac GrahamaScan.java
 *  Execution:    java GrahamScan < input.txt
 *  Dependencies: Point2D.java
 *  Data files:   https://algs4.cs.princeton.edu/99hull/rs1423.txt
 *                https://algs4.cs.princeton.edu/99hull/kw1260.txt
 * 
 *  Create points from standard input and compute the convex hull using
 *  Graham scan algorithm.
 *
 *  May be floating-point issues if x- and y-coordinates are not integers.
 *
 *  % java GrahamScan < input100.txt 
 *  (7486.0, 422.0)
 *  (29413.0, 596.0)
 *  (32011.0, 3140.0)
 *  (30875.0, 28560.0)
 *  (28462.0, 32343.0)
 *  (15731.0, 32661.0)
 *  (822.0, 32301.0)
 *  (823.0, 15895.0)
 *  (1444.0, 10362.0)
 *  (4718.0, 4451.0)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;


/**
 *  The { @code  GrahamScan} data type provides methods for computing the 
 *  convex hull of a set of <em>n</em> points in the plane.
 *  <p>
 *  The implementation uses the Graham-Scan convex hull algorithm.
 *  It runs in O(<em>n</em> log <em>n</em>) time in the worst case
 *  and uses O(<em>n</em>) extra memory.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   GrahamScan   {
     private   Stack < Point2D >  hull  =   new   Stack < Point2D > ();

     /**
     * Computes the convex hull of the specified array of points.
     *
     *  @param   points the array of points
     *  @throws  IllegalArgumentException if { @code  points} is { @code  null}
     *  @throws  IllegalArgumentException if any entry in { @code  points[]} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  points.length} is { @code  0}
     */
     public   GrahamScan ( Point2D []  points )   {
         if   ( points  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );
         if   ( points . length  ==   0 )   throw   new   IllegalArgumentException ( "array is of length 0" );

         // defensive copy
         int  n  =  points . length ;
         Point2D []  a  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( points [ i ]   ==   null )
                 throw   new   IllegalArgumentException ( "points["   +  i  +   "] is null" );
            a [ i ]   =  points [ i ];
         }

         // preprocess so that a[0] has lowest y-coordinate; break ties by x-coordinate
         // a[0] is an extreme point of the convex hull
         // (alternatively, could do easily in linear time)
         Arrays . sort ( a );

         // sort by polar angle with respect to base point a[0],
         // breaking ties by distance to a[0]
         Arrays . sort ( a ,   1 ,  n ,  a [ 0 ]. polarOrder ());

        hull . push ( a [ 0 ]);         // a[0] is first extreme point

         // find index k1 of first point not equal to a[0]
         int  k1 ;
         for   ( k1  =   1 ;  k1  <  n ;  k1 ++ )
             if   ( ! a [ 0 ]. equals ( a [ k1 ]))   break ;
         if   ( k1  ==  n )   return ;          // all points equal

         // find index k2 of first point not collinear with a[0] and a[k1]
         int  k2 ;
         for   ( k2  =  k1 + 1 ;  k2  <  n ;  k2 ++ )
             if   ( Point2D . ccw ( a [ 0 ],  a [ k1 ],  a [ k2 ])   !=   0 )   break ;
        hull . push ( a [ k2 - 1 ]);      // a[k2-1] is second extreme point

         // Graham scan; note that a[n-1] is extreme point different from a[0]
         for   ( int  i  =  k2 ;  i  <  n ;  i ++ )   {
             Point2D  top  =  hull . pop ();
             while   ( Point2D . ccw ( hull . peek (),  top ,  a [ i ])   <=   0 )   {
                top  =  hull . pop ();
             }
            hull . push ( top );
            hull . push ( a [ i ]);
         }

         assert  isConvex ();
     }

     /**
     * Returns the extreme points on the convex hull in counterclockwise order.
     *
     *  @return  the extreme points on the convex hull in counterclockwise order
     */
     public   Iterable < Point2D >  hull ()   {
         Stack < Point2D >  s  =   new   Stack < Point2D > ();
         for   ( Point2D  p  :  hull )  s . push ( p );
         return  s ;
     }

     // check that boundary of hull is strictly convex
     private   boolean  isConvex ()   {
         int  n  =  hull . size ();
         if   ( <=   2 )   return   true ;

         Point2D []  points  =   new   Point2D [ n ];
         int  k  =   0 ;
         for   ( Point2D  p  :  hull ())   {
            points [ k ++ ]   =  p ;
         }

         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( Point2D . ccw ( points [ i ],  points [( i + 1 )   %  n ],  points [( i + 2 )   %  n ])   <=   0 )   {
                 return   false ;
             }
         }
         return   true ;
     }

    /**
     * Unit tests the { @code  GrahamScan} data type.
     * Reads in an integer { @code  n} and { @code  n} points (specified by
     * their <em>x</em>- and <em>y</em>-coordinates) from standard input;
     * computes their convex hull; and prints out the points on the
     * convex hull to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         Point2D []  points  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  x  =   StdIn . readInt ();
             int  y  =   StdIn . readInt ();
            points [ i ]   =   new   Point2D ( x ,  y );
         }
         GrahamScan  graham  =   new   GrahamScan ( points );
         for   ( Point2D  p  :  graham . hull ())
             StdOut . println ( p );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GraphGenerator.java

edu/princeton/cs/algs4/GraphGenerator.java

/******************************************************************************
 *  Compilation:  javac GraphGenerator.java
 *  Execution:    java GraphGenerator V E
 *  Dependencies: Graph.java
 *
 *  A graph generator.
 *
 *  For many more graph generators, see
 *  http://networkx.github.io/documentation/latest/reference/generators.html
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  GraphGenerator} class provides static methods for creating
 *  various graphs, including Erdos-Renyi random graphs, random bipartite
 *  graphs, random k-regular graphs, and random rooted trees.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   GraphGenerator   {
     private   static   final   class   Edge   implements   Comparable < Edge >   {
         private   int  v ;
         private   int  w ;

         private   Edge ( int  v ,   int  w )   {
             if   ( <  w )   {
                 this . =  v ;
                 this . =  w ;
             }
             else   {
                 this . =  w ;
                 this . =  v ;
             }
         }

         public   int  compareTo ( Edge  that )   {
             if   ( this . <  that . v )   return   - 1 ;
             if   ( this . >  that . v )   return   + 1 ;
             if   ( this . <  that . w )   return   - 1 ;
             if   ( this . >  that . w )   return   + 1 ;
             return   0 ;
         }
     }

     // this class cannot be instantiated
     private   GraphGenerator ()   {   }

     /**
     * Returns a random simple graph containing { @code  V} vertices and { @code  E} edges.
     *  @param  V the number of vertices
     *  @param  E the number of vertices
     *  @return  a random simple graph on { @code  V} vertices, containing a total
     *     of { @code  E} edges
     *  @throws  IllegalArgumentException if no such simple graph exists
     */
     public   static   Graph  simple ( int  V ,   int  E )   {
         if   ( >   ( long )  V * ( V - 1 ) / 2 )   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <   0 )                  throw   new   IllegalArgumentException ( "Too few edges" );
         Graph  G  =   new   Graph ( V );
        SET < Edge >  set  =   new  SET < Edge > ();
         while   ( G . E ()   <  E )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
             Edge  e  =   new   Edge ( v ,  w );
             if   (( !=  w )   &&   ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( v ,  w );
             }
         }
         return  G ;
     }

     /**
     * Returns a random simple graph on { @code  V} vertices, with an 
     * edge between any two vertices with probability { @code  p}. This is sometimes
     * referred to as the Erdos-Renyi random graph model.
     *  @param  V the number of vertices
     *  @param  p the probability of choosing an edge
     *  @return  a random simple graph on { @code  V} vertices, with an edge between
     *     any two vertices with probability { @code  p}
     *  @throws  IllegalArgumentException if probability is not between 0 and 1
     */
     public   static   Graph  simple ( int  V ,   double  p )   {
         if   ( <   0.0   ||  p  >   1.0 )
             throw   new   IllegalArgumentException ( "Probability must be between 0 and 1" );
         Graph  G  =   new   Graph ( V );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( int  w  =  v + 1 ;  w  <  V ;  w ++ )
                 if   ( StdRandom . bernoulli ( p ))
                    G . addEdge ( v ,  w );
         return  G ;
     }

     /**
     * Returns the complete graph on { @code  V} vertices.
     *  @param  V the number of vertices
     *  @return  the complete graph on { @code  V} vertices
     */
     public   static   Graph  complete ( int  V )   {
         return  simple ( V ,   1.0 );
     }

     /**
     * Returns a complete bipartite graph on { @code  V1} and { @code  V2} vertices.
     *  @param  V1 the number of vertices in one partition
     *  @param  V2 the number of vertices in the other partition
     *  @return  a complete bipartite graph on { @code  V1} and { @code  V2} vertices
     *  @throws  IllegalArgumentException if probability is not between 0 and 1
     */
     public   static   Graph  completeBipartite ( int  V1 ,   int  V2 )   {
         return  bipartite ( V1 ,  V2 ,  V1 * V2 );
     }

     /**
     * Returns a random simple bipartite graph on { @code  V1} and { @code  V2} vertices
     * with { @code  E} edges.
     *  @param  V1 the number of vertices in one partition
     *  @param  V2 the number of vertices in the other partition
     *  @param  E the number of edges
     *  @return  a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,
     *    containing a total of { @code  E} edges
     *  @throws  IllegalArgumentException if no such simple bipartite graph exists
     */
     public   static   Graph  bipartite ( int  V1 ,   int  V2 ,   int  E )   {
         if   ( >   ( long )  V1 * V2 )   throw   new   IllegalArgumentException ( "Too many edges" );
         if   ( <   0 )              throw   new   IllegalArgumentException ( "Too few edges" );
         Graph  G  =   new   Graph ( V1  +  V2 );

         int []  vertices  =   new   int [ V1  +  V2 ];
         for   ( int  i  =   0 ;  i  <  V1  +  V2 ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );

        SET < Edge >  set  =   new  SET < Edge > ();
         while   ( G . E ()   <  E )   {
             int  i  =   StdRandom . uniform ( V1 );
             int  j  =  V1  +   StdRandom . uniform ( V2 );
             Edge  e  =   new   Edge ( vertices [ i ],  vertices [ j ]);
             if   ( ! set . contains ( e ))   {
                set . add ( e );
                G . addEdge ( vertices [ i ],  vertices [ j ]);
             }
         }
         return  G ;
     }

     /**
     * Returns a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,
     * containing each possible edge with probability { @code  p}.
     *  @param  V1 the number of vertices in one partition
     *  @param  V2 the number of vertices in the other partition
     *  @param  p the probability that the graph contains an edge with one endpoint in either side
     *  @return  a random simple bipartite graph on { @code  V1} and { @code  V2} vertices,
     *    containing each possible edge with probability { @code  p}
     *  @throws  IllegalArgumentException if probability is not between 0 and 1
     */
     public   static   Graph  bipartite ( int  V1 ,   int  V2 ,   double  p )   {
         if   ( <   0.0   ||  p  >   1.0 )
             throw   new   IllegalArgumentException ( "Probability must be between 0 and 1" );
         int []  vertices  =   new   int [ V1  +  V2 ];
         for   ( int  i  =   0 ;  i  <  V1  +  V2 ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         Graph  G  =   new   Graph ( V1  +  V2 );
         for   ( int  i  =   0 ;  i  <  V1 ;  i ++ )
             for   ( int  j  =   0 ;  j  <  V2 ;  j ++ )
                 if   ( StdRandom . bernoulli ( p ))
                    G . addEdge ( vertices [ i ],  vertices [ V1 + j ]);
         return  G ;
     }

     /**
     * Returns a path graph on { @code  V} vertices.
     *  @param  V the number of vertices in the path
     *  @return  a path graph on { @code  V} vertices
     */
     public   static   Graph  path ( int  V )   {
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
         return  G ;
     }

     /**
     * Returns a complete binary tree graph on { @code  V} vertices.
     *  @param  V the number of vertices in the binary tree
     *  @return  a complete binary tree graph on { @code  V} vertices
     */
     public   static   Graph  binaryTree ( int  V )   {
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [( i - 1 ) / 2 ]);
         }
         return  G ;
     }

     /**
     * Returns a cycle graph on { @code  V} vertices.
     *  @param  V the number of vertices in the cycle
     *  @return  a cycle graph on { @code  V} vertices
     */
     public   static   Graph  cycle ( int  V )   {
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
        G . addEdge ( vertices [ V - 1 ],  vertices [ 0 ]);
         return  G ;
     }

     /**
     * Returns an Eulerian cycle graph on { @code  V} vertices.
     *
     *  @param   V the number of vertices in the cycle
     *  @param   E the number of edges in the cycle
     *  @return  a graph that is an Eulerian cycle on { @code  V} vertices
     *         and { @code  E} edges
     *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E <= 0}
     */
     public   static   Graph  eulerianCycle ( int  V ,   int  E )   {
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one edge" );
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian cycle must have at least one vertex" );
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ E ];
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )
            vertices [ i ]   =   StdRandom . uniform ( V );
         for   ( int  i  =   0 ;  i  <  E - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
        G . addEdge ( vertices [ E - 1 ],  vertices [ 0 ]);
         return  G ;
     }

     /**
     * Returns an Eulerian path graph on { @code  V} vertices.
     *
     *  @param   V the number of vertices in the path
     *  @param   E the number of edges in the path
     *  @return  a graph that is an Eulerian path on { @code  V} vertices
     *         and { @code  E} edges
     *  @throws  IllegalArgumentException if either { @code  V <= 0} or { @code  E < 0}
     */
     public   static   Graph  eulerianPath ( int  V ,   int  E )   {
         if   ( <   0 )
             throw   new   IllegalArgumentException ( "negative number of edges" );
         if   ( <=   0 )
             throw   new   IllegalArgumentException ( "An Eulerian path must have at least one vertex" );
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ E + 1 ];
         for   ( int  i  =   0 ;  i  <  E + 1 ;  i ++ )
            vertices [ i ]   =   StdRandom . uniform ( V );
         for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
         return  G ;
     }

     /**
     * Returns a wheel graph on { @code  V} vertices.
     *  @param  V the number of vertices in the wheel
     *  @return  a wheel graph on { @code  V} vertices: a single vertex connected to
     *     every vertex in a cycle on { @code  V-1} vertices
     */
     public   static   Graph  wheel ( int  V )   {
         if   ( <=   1 )   throw   new   IllegalArgumentException ( "Number of vertices must be at least 2" );
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );

         // simple cycle on V-1 vertices
         for   ( int  i  =   1 ;  i  <  V - 1 ;  i ++ )   {
            G . addEdge ( vertices [ i ],  vertices [ i + 1 ]);
         }
        G . addEdge ( vertices [ V - 1 ],  vertices [ 1 ]);

         // connect vertices[0] to every vertex on cycle
         for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {
            G . addEdge ( vertices [ 0 ],  vertices [ i ]);
         }

         return  G ;
     }

     /**
     * Returns a star graph on { @code  V} vertices.
     *  @param  V the number of vertices in the star
     *  @return  a star graph on { @code  V} vertices: a single vertex connected to
     *     every other vertex
     */
     public   static   Graph  star ( int  V )   {
         if   ( <=   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be at least 1" );
         Graph  G  =   new   Graph ( V );
         int []  vertices  =   new   int [ V ];
         for   ( int  i  =   0 ;  i  <  V ;  i ++ )
            vertices [ i ]   =  i ;
         StdRandom . shuffle ( vertices );

         // connect vertices[0] to every other vertex
         for   ( int  i  =   1 ;  i  <  V ;  i ++ )   {
            G . addEdge ( vertices [ 0 ],  vertices [ i ]);
         }

         return  G ;
     }

     /**
     * Returns a uniformly random { @code  k}-regular graph on { @code  V} vertices
     * (not necessarily simple). The graph is simple with probability only about e^(-k^2/4),
     * which is tiny when k = 14.
     *
     *  @param  V the number of vertices in the graph
     *  @param  k degree of each vertex
     *  @return  a uniformly random { @code  k}-regular graph on { @code  V} vertices.
     */
     public   static   Graph  regular ( int  V ,   int  k )   {
         if   ( V * %   2   !=   0 )   throw   new   IllegalArgumentException ( "Number of vertices * k must be even" );
         Graph  G  =   new   Graph ( V );

         // create k copies of each vertex
         int []  vertices  =   new   int [ V * k ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             for   ( int  j  =   0 ;  j  <  k ;  j ++ )   {
                vertices [ +  V * j ]   =  v ;
             }
         }

         // pick a random perfect matching
         StdRandom . shuffle ( vertices );
         for   ( int  i  =   0 ;  i  <  V * k / 2 ;  i ++ )   {
            G . addEdge ( vertices [ 2 * i ],  vertices [ 2 * +   1 ]);
         }
         return  G ;
     }

     // http://www.proofwiki.org/wiki/Labeled_Tree_from_Prüfer_Sequence
     // http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.36.6484&rep=rep1&type=pdf
     /**
     * Returns a uniformly random tree on { @code  V} vertices.
     * This algorithm uses a Prufer sequence and takes time proportional to <em>V log V</em>.
     *  @param  V the number of vertices in the tree
     *  @return  a uniformly random tree on { @code  V} vertices
     */
     public   static   Graph  tree ( int  V )   {
         Graph  G  =   new   Graph ( V );

         // special case
         if   ( ==   1 )   return  G ;

         // Cayley's theorem: there are V^(V-2) labeled trees on V vertices
         // Prufer sequence: sequence of V-2 values between 0 and V-1
         // Prufer's proof of Cayley's theorem: Prufer sequences are in 1-1
         // with labeled trees on V vertices
         int []  prufer  =   new   int [ V - 2 ];
         for   ( int  i  =   0 ;  i  <  V - 2 ;  i ++ )
            prufer [ i ]   =   StdRandom . uniform ( V );

         // degree of vertex v = 1 + number of times it appers in Prufer sequence
         int []  degree  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            degree [ v ]   =   1 ;
         for   ( int  i  =   0 ;  i  <  V - 2 ;  i ++ )
            degree [ prufer [ i ]] ++ ;

         // pq contains all vertices of degree 1
         MinPQ < Integer >  pq  =   new   MinPQ < Integer > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             if   ( degree [ v ]   ==   1 )  pq . insert ( v );

         // repeatedly delMin() degree 1 vertex that has the minimum index
         for   ( int  i  =   0 ;  i  <  V - 2 ;  i ++ )   {
             int  v  =  pq . delMin ();
            G . addEdge ( v ,  prufer [ i ]);
            degree [ v ] -- ;
            degree [ prufer [ i ]] -- ;
             if   ( degree [ prufer [ i ]]   ==   1 )  pq . insert ( prufer [ i ]);
         }
        G . addEdge ( pq . delMin (),  pq . delMin ());
         return  G ;
     }

     /**
     * Unit tests the { @code  GraphGenerator} library.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         int  V1  =  V / 2 ;
         int  V2  =  V  -  V1 ;

         StdOut . println ( "complete graph" );
         StdOut . println ( complete ( V ));
         StdOut . println ();

         StdOut . println ( "simple" );
         StdOut . println ( simple ( V ,  E ));
         StdOut . println ();

         StdOut . println ( "Erdos-Renyi" );
         double  p  =   ( double )  E  /   ( V * ( V - 1 ) / 2.0 );
         StdOut . println ( simple ( V ,  p ));
         StdOut . println ();

         StdOut . println ( "complete bipartite" );
         StdOut . println ( completeBipartite ( V1 ,  V2 ));
         StdOut . println ();

         StdOut . println ( "bipartite" );
         StdOut . println ( bipartite ( V1 ,  V2 ,  E ));
         StdOut . println ();

         StdOut . println ( "Erdos Renyi bipartite" );
         double  q  =   ( double )  E  /   ( V1 * V2 );
         StdOut . println ( bipartite ( V1 ,  V2 ,  q ));
         StdOut . println ();

         StdOut . println ( "path" );
         StdOut . println ( path ( V ));
         StdOut . println ();

         StdOut . println ( "cycle" );
         StdOut . println ( cycle ( V ));
         StdOut . println ();

         StdOut . println ( "binary tree" );
         StdOut . println ( binaryTree ( V ));
         StdOut . println ();

         StdOut . println ( "tree" );
         StdOut . println ( tree ( V ));
         StdOut . println ();

         StdOut . println ( "4-regular" );
         StdOut . println ( regular ( V ,   4 ));
         StdOut . println ();

         StdOut . println ( "star" );
         StdOut . println ( star ( V ));
         StdOut . println ();

         StdOut . println ( "wheel" );
         StdOut . println ( wheel ( V ));
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Graph.java

edu/princeton/cs/algs4/Graph.java

/******************************************************************************
 *  Compilation:  javac Graph.java        
 *  Execution:    java Graph input.txt
 *  Dependencies: Bag.java Stack.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *                https://algs4.cs.princeton.edu/41graph/largeG.txt
 *
 *  A graph, implemented using an array of sets.
 *  Parallel edges and self-loops allowed.
 *
 *  % java Graph tinyG.txt
 *  13 vertices, 13 edges 
 *  0: 6 2 1 5 
 *  1: 0 
 *  2: 0 
 *  3: 5 4 
 *  4: 5 6 3 
 *  5: 3 4 0 
 *  6: 0 4 
 *  7: 8 
 *  8: 7 
 *  9: 11 10 12 
 *  10: 9 
 *  11: 9 12 
 *  12: 11 9 
 *
 *  % java Graph mediumG.txt
 *  250 vertices, 1273 edges 
 *  0: 225 222 211 209 204 202 191 176 163 160 149 114 97 80 68 59 58 49 44 24 15 
 *  1: 220 203 200 194 189 164 150 130 107 72 
 *  2: 141 110 108 86 79 51 42 18 14 
 *  ...
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  Graph} class represents an undirected graph of vertices
 *  named 0 through <em>V</em> – 1.
 *  It supports the following two primary operations: add an edge to the graph,
 *  iterate over all of the vertices adjacent to a vertex. It also provides
 *  methods for returning the degree of a vertex, the number of vertices
 *  <em>V</em> in the graph, and the number of edges <em>E</em> in the graph.
 *  Parallel edges and self-loops are permitted.
 *  By convention, a self-loop <em>v</em>-<em>v</em> appears in the
 *  adjacency list of <em>v</em> twice and contributes two to the degree
 *  of <em>v</em>.
 *  <p>
 *  This implementation uses an <em>adjacency-lists representation</em>, which
 *  is a vertex-indexed array of { @link  Bag} objects.
 *  It uses &Theta;(<em>E</em> + <em>V</em>) space, where <em>E</em> is
 *  the number of edges and <em>V</em> is the number of vertices.
 *  All instance methods take &Theta;(1) time. (Though, iterating over
 *  the vertices returned by { @link  #adj(int)} takes time proportional
 *  to the degree of the vertex.)
 *  Constructing an empty graph with <em>V</em> vertices takes
 *  &Theta;(<em>V</em>) time; constructing a graph with <em>E</em> edges
 *  and <em>V</em> vertices takes &Theta;(<em>E</em> + <em>V</em>) time. 
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Graph   {
     private   static   final   String  NEWLINE  =   System . getProperty ( "line.separator" );

     private   final   int  V ;
     private   int  E ;
     private   Bag < Integer > []  adj ;
    
     /**
     * Initializes an empty graph with { @code  V} vertices and 0 edges.
     * param V the number of vertices
     *
     *  @param   V number of vertices
     *  @throws  IllegalArgumentException if { @code  V < 0}
     */
     public   Graph ( int  V )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );
         this . =  V ;
         this . =   0 ;
        adj  =   ( Bag < Integer > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            adj [ v ]   =   new   Bag < Integer > ();
         }
     }

     /**  
     * Initializes a graph from the specified input stream.
     * The format is the number of vertices <em>V</em>,
     * followed by the number of edges <em>E</em>,
     * followed by <em>E</em> pairs of vertices, with each entry separated by whitespace.
     *
     *  @param   in the input stream
     *  @throws  IllegalArgumentException if { @code  in} is { @code  null}
     *  @throws  IllegalArgumentException if the endpoints of any edge are not in prescribed range
     *  @throws  IllegalArgumentException if the number of vertices or edges is negative
     *  @throws  IllegalArgumentException if the input stream is in the wrong format
     */
     public   Graph ( In  in )   {
         if   ( in  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );
         try   {
             this . =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "number of vertices in a Graph must be nonnegative" );
            adj  =   ( Bag < Integer > [])   new   Bag [ V ];
             for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
                adj [ v ]   =   new   Bag < Integer > ();
             }
             int  E  =  in . readInt ();
             if   ( <   0 )   throw   new   IllegalArgumentException ( "number of edges in a Graph must be nonnegative" );
             for   ( int  i  =   0 ;  i  <  E ;  i ++ )   {
                 int  v  =  in . readInt ();
                 int  w  =  in . readInt ();
                validateVertex ( v );
                validateVertex ( w );
                addEdge ( v ,  w );  
             }
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   IllegalArgumentException ( "invalid input format in Graph constructor" ,  e );
         }
     }


     /**
     * Initializes a new graph that is a deep copy of { @code  G}.
     *
     *  @param   G the graph to copy
     *  @throws  IllegalArgumentException if { @code  G} is { @code  null}
     */
     public   Graph ( Graph  G )   {
         this . =  G . V ();
         this . =  G . E ();
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Number of vertices must be nonnegative" );

         // update adjacency lists
        adj  =   ( Bag < Integer > [])   new   Bag [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            adj [ v ]   =   new   Bag < Integer > ();
         }

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             // reverse so that adjacency list is in same order as original
             Stack < Integer >  reverse  =   new   Stack < Integer > ();
             for   ( int  w  :  G . adj [ v ])   {
                reverse . push ( w );
             }
             for   ( int  w  :  reverse )   {
                adj [ v ]. add ( w );
             }
         }
     }

     /**
     * Returns the number of vertices in this graph.
     *
     *  @return  the number of vertices in this graph
     */
     public   int  V ()   {
         return  V ;
     }

     /**
     * Returns the number of edges in this graph.
     *
     *  @return  the number of edges in this graph
     */
     public   int  E ()   {
         return  E ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Adds the undirected edge v-w to this graph.
     *
     *  @param   v one vertex in the edge
     *  @param   w the other vertex in the edge
     *  @throws  IllegalArgumentException unless both { @code  0 <= v < V} and { @code  0 <= w < V}
     */
     public   void  addEdge ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
        E ++ ;
        adj [ v ]. add ( w );
        adj [ w ]. add ( v );
     }


     /**
     * Returns the vertices adjacent to vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the vertices adjacent to vertex { @code  v}, as an iterable
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   Iterable < Integer >  adj ( int  v )   {
        validateVertex ( v );
         return  adj [ v ];
     }

     /**
     * Returns the degree of vertex { @code  v}.
     *
     *  @param   v the vertex
     *  @return  the degree of vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  degree ( int  v )   {
        validateVertex ( v );
         return  adj [ v ]. size ();
     }


     /**
     * Returns a string representation of this graph.
     *
     *  @return  the number of vertices <em>V</em>, followed by the number of edges <em>E</em>,
     *         followed by the <em>V</em> adjacency lists
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( +   " vertices, "   +  E  +   " edges "   +  NEWLINE );
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
            s . append ( +   ": " );
             for   ( int  w  :  adj [ v ])   {
                s . append ( +   " " );
             }
            s . append ( NEWLINE );
         }
         return  s . toString ();
     }


     /**
     * Unit tests the { @code  Graph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         StdOut . println ( G );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GrayscalePicture.java

edu/princeton/cs/algs4/GrayscalePicture.java

/******************************************************************************
 *  Compilation:  javac GrayscalePicture.java
 *  Execution:    java GrayscalePicture imagename
 *  Dependencies: none
 *
 *  Data type for manipulating individual pixels of a grayscale image. The
 *  original image can be read from a file in JPEG, GIF, or PNG format, or the
 *  user can create a blank image of a given dimension. Includes methods for
 *  displaying the image in a window on the screen or saving to a file.
 *
 *  % java GrayscalePicture mandrill.jpg
 *
 *  Remarks
 *  -------
 *   - pixel (x, y) is column x and row y, where (0, 0) is upper left
 *
 *   - uses BufferedImage.TYPE_INT_RGB because BufferedImage.TYPE_BYTE_GRAY
 *     seems to do some undesirable olor correction when calling getRGB() and
 *     setRGB()
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . Color ;
import  java . awt . FileDialog ;
import  java . awt . Toolkit ;
import  java . awt . event . ActionEvent ;
import  java . awt . event . ActionListener ;
import  java . awt . event . KeyEvent ;
import  java . awt . image . BufferedImage ;
import  java . io . File ;
import  java . io . IOException ;
import  java . net . URL ;
import  javax . imageio . ImageIO ;
import  javax . swing . ImageIcon ;
import  javax . swing . JFrame ;
import  javax . swing . JLabel ;
import  javax . swing . JMenu ;
import  javax . swing . JMenuBar ;
import  javax . swing . JMenuItem ;
import  javax . swing . JPanel ;
import  javax . swing . KeyStroke ;


/**
 *  This class provides methods for manipulating individual pixels of
 *  a grayscale image.
 *  The original image can be read from a { @code  PNG}, { @code  GIF},
 *  or { @code  JPEG} file or the user can create a blank image of a given dimension.
 *  This class includes methods for displaying the image in a window on
 *  the screen or saving it to a file.
 *  <p>
 *  Pixel (<em>col</em>, <em>row</em>) is column <em>col</em> and row <em>row</em>.
 *  By default, the origin (0, 0) is the pixel in the top-left corner,
 *  which is a common convention in image processing.
 *  The method { @link  #setOriginLowerLeft()} change the origin to the lower left.
 *  <p>
 *  The { @code  get()} and { @code  set()} methods use { @link  Color} objects to get
 *  or set the color of the specified pixel. The { @link  Color} objects are converted
 *  to grayscale if they have different values for the R, G, and B channels.
 *  The { @code  getGrayscale()} and { @code  setGrayscale()} methods use an
 *  8-bit { @code  int} to encode the grayscale value, thereby avoiding the need to
 *  create temporary { @code  Color} objects.
 *  <p>
 *  A <em>W</em>-by-<em>H</em> picture uses ~ 4 <em>W H</em> bytes of memory,
 *  since the color of each pixel is encoded as a 32-bit <code>int</code>
 *  (even though, in principle, only ~ <em>W H</em> bytes are needed).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *  See { @link  Picture} for a version that supports 32-bit RGB color images.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   GrayscalePicture   implements   ActionListener   {
     private   BufferedImage  image ;                 // the rasterized image
     private   JFrame  frame ;                        // on-screen view
     private   String  filename ;                     // name of file
     private   boolean  isOriginUpperLeft  =   true ;    // location of origin
     private   final   int  width ,  height ;             // width and height

    /**
     * Creates a { @code  width}-by-{ @code  height} picture, with { @code  width} columns
     * and { @code  height} rows, where each pixel is black.
     *
     *  @param  width the width of the picture
     *  @param  height the height of the picture
     *  @throws  IllegalArgumentException if { @code  width} is negative
     *  @throws  IllegalArgumentException if { @code  height} is negative
     */
     public   GrayscalePicture ( int  width ,   int  height )   {
         if   ( width   <   0 )   throw   new   IllegalArgumentException ( "width must be non-negative" );
         if   ( height  <   0 )   throw   new   IllegalArgumentException ( "height must be non-negative" );
         this . width   =  width ;
         this . height  =  height ;
        image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );
     }

    /**
     * Creates a new grayscale picture that is a deep copy of the argument picture.
     *
     *  @param   picture the picture to copy
     *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}
     */
     public   GrayscalePicture ( GrayscalePicture  picture )   {
         if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );

        width   =  picture . width ();
        height  =  picture . height ();
        image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );
        filename  =  picture . filename ;
        isOriginUpperLeft  =  picture . isOriginUpperLeft ;
         for   ( int  col  =   0 ;  col  <  width ();  col ++ )
             for   ( int  row  =   0 ;  row  <  height ();  row ++ )
                image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));
     }

    /**
     * Creates a grayscale picture by reading an image from a file or URL.
     *
     *  @param   name the name of the file (.png, .gif, or .jpg) or URL.
     *  @throws  IllegalArgumentException if cannot read image
     *  @throws  IllegalArgumentException if { @code  name} is { @code  null}
     */
     public   GrayscalePicture ( String  name )   {
         if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );
         this . filename  =  name ;
         try   {
             // try to read from file in working directory
             File  file  =   new   File ( name );
             if   ( file . isFile ())   {
                image  =   ImageIO . read ( file );
             }

             else   {

                 // resource relative to .class file
                URL url  =  getClass (). getResource ( name );

                 // resource relative to classloader root
                 if   ( url  ==   null )   {
                    url  =  getClass (). getClassLoader (). getResource ( name );
                 }
     
                 // or URL from web
                 if   ( url  ==   null )   {
                    url  =   new  URL ( name );
                 }
        
                image  =   ImageIO . read ( url );
             }

             if   ( image  ==   null )   {
                 throw   new   IllegalArgumentException ( "could not read image: "   +  name );
             }

            width   =  image . getWidth ( null );
            height  =  image . getHeight ( null );

             // convert to grayscale inplace
             for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {
                 for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {
                     Color  color  =   new   Color ( image . getRGB ( col ,  row ));
                     Color  gray  =  toGray ( color );
                    image . setRGB ( col ,  row ,  gray . getRGB ());
                 }
             }
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );
         }
     }

      // Returns a grayscale version of the given color as a Color object.
     private   static   Color  toGray ( Color  color )   {
         int  r  =  color . getRed ();
         int  g  =  color . getGreen ();
         int  b  =  color . getBlue ();
         int  y  =   ( int )   ( Math . round ( 0.299 * +   0.587 * +   0.114 * b ));
         return   new   Color ( y ,  y ,  y );
     }

    /**
     * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},
     * { @link  JFrame} or other GUI widget.
     *
     *  @return  the { @code  JLabel}
     */
     public   JLabel  getJLabel ()   {
         if   ( image  ==   null )   return   null ;           // no image available
         ImageIcon  icon  =   new   ImageIcon ( image );
         return   new   JLabel ( icon );
     }

    /**
     * Sets the origin to be the upper left pixel. This is the default.
     */
     public   void  setOriginUpperLeft ()   {
        isOriginUpperLeft  =   true ;
     }

    /**
     * Sets the origin to be the lower left pixel.
     */
     public   void  setOriginLowerLeft ()   {
        isOriginUpperLeft  =   false ;
     }

    /**
     * Displays the picture in a window on the screen.
     */
     public   void  show ()   {

         // create the GUI for viewing the image if needed
         if   ( frame  ==   null )   {
            frame  =   new   JFrame ();

             JMenuBar  menuBar  =   new   JMenuBar ();
             JMenu  menu  =   new   JMenu ( "File" );
            menuBar . add ( menu );
             JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );
            menuItem1 . addActionListener ( this );
             // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)
            menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,
                                      Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));
            menu . add ( menuItem1 );
            frame . setJMenuBar ( menuBar );



            frame . setContentPane ( getJLabel ());
             // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );
             if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );
             else                   frame . setTitle ( filename );
            frame . setResizable ( false );
            frame . pack ();
            frame . setVisible ( true );
         }

         // draw
        frame . repaint ();
     }

    /**
     * Returns the height of the picture.
     *
     *  @return  the height of the picture (in pixels)
     */
     public   int  height ()   {
         return  height ;
     }

    /**
     * Returns the width of the picture.
     *
     *  @return  the width of the picture (in pixels)
     */
     public   int  width ()   {
         return  width ;
     }

     private   void  validateRowIndex ( int  row )   {
         if   ( row  <   0   ||  row  >=  height ())
             throw   new   IllegalArgumentException ( "row index must be between 0 and "   +   ( height ()   -   1 )   +   ": "   +  row );
     }

     private   void  validateColumnIndex ( int  col )   {
         if   ( col  <   0   ||  col  >=  width ())
             throw   new   IllegalArgumentException ( "column index must be between 0 and "   +   ( width ()   -   1 )   +   ": "   +  col );
     }

     private   void  validateGrayscaleValue ( int  gray )   {
         if   ( gray  <   0   ||  gray  >=   256 )
             throw   new   IllegalArgumentException ( "grayscale value must be between 0 and 255" );
     }

    /**
     * Returns the grayscale value of pixel ({ @code  col}, { @code  row}) as a { @link  java.awt.Color}.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @return  the grayscale value of pixel ({ @code  col}, { @code  row})
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   Color  get ( int  col ,   int  row )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         Color  color  =   new   Color ( image . getRGB ( col ,  row ));
         return  toGray ( color );
     }

    /**
     * Returns the grayscale value of pixel ({ @code  col}, { @code  row}) as an { @code  int}
     * between 0 and 255.
     * Using this method can be more efficient than { @link  #get(int, int)} because
     * it does not create a { @code  Color} object.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @return  the 8-bit integer representation of the grayscale value of pixel ({ @code  col}, { @code  row})
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   int  getGrayscale ( int  col ,   int  row )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row )   &   0xFF ;
         else                     return  image . getRGB ( col ,  height  -  row  -   1 )   &   0xFF ;
     }

    /**
     * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @param  color the color (converts to grayscale if color is not a shade of gray)
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   void  set ( int  col ,   int  row ,   Color  color )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );
         Color  gray  =  toGray ( color );
        image . setRGB ( col ,  row ,  gray . getRGB ());
     }

    /**
     * Sets the color of pixel ({ @code  col}, { @code  row}) to the given grayscale value
     * between 0 and 255.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @param  gray the 8-bit integer representation of the grayscale value
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   void  setGrayscale ( int  col ,   int  row ,   int  gray )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
        validateGrayscaleValue ( gray );
         int  rgb  =  gray  |   ( gray  <<   8 )   |   ( gray  <<   16 );
         if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );
         else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );
     }

    /**
     * Returns true if this picture is equal to the argument picture.
     *
     *  @param  other the other picture
     *  @return  { @code  true} if this picture is the same dimension as { @code  other}
     *         and if all pixels have the same color; { @code  false} otherwise
     */
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         GrayscalePicture  that  =   ( GrayscalePicture )  other ;
         if   ( this . width ()    !=  that . width ())    return   false ;
         if   ( this . height ()   !=  that . height ())   return   false ;
         for   ( int  col  =   0 ;  col  <  width ();  col ++ )
             for   ( int  row  =   0 ;  row  <  height ();  row ++ )
                 if   ( this . getGrayscale ( col ,  row )   !=  that . getGrayscale ( col ,  row ))   return   false ;
         return   true ;
     }

    /**
     * Returns a string representation of this picture.
     * The result is a <code>width</code>-by-<code>height</code> matrix of pixels,
     * where the grayscale value of a pixel is an integer between 0 and 255.
     *
     *  @return  a string representation of this picture
     */
     public   String  toString ()   {
         StringBuilder  sb  =   new   StringBuilder ();
        sb . append ( width  + "-by-"   +  height  +   " grayscale picture (grayscale values given in hex)\n" );
         for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {
             for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {
                 int  gray  =   0 ;
                 if   ( isOriginUpperLeft )  gray  =   0xFF   &  image . getRGB ( col ,  row );
                 else                    gray  =   0xFF   &  image . getRGB ( col ,  height  -  row  -   1 );
                sb . append ( String . format ( "%3d " ,  gray ));
             }
            sb . append ( "\n" );
         }
         return  sb . toString (). trim ();
     }

     /**
     * This operation is not supported because pictures are mutable.
     *
     *  @return  does not return a value
     *  @throws  UnsupportedOperationException if called
     */
     public   int  hashCode ()   {
         throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );
     }

    /**
     * Saves the picture to a file in either PNG or JPEG format.
     * The filetype extension must be either .png or .jpg.
     *
     *  @param  name the name of the file
     *  @throws  IllegalArgumentException if { @code  name} is { @code  null}
     */
     public   void  save ( String  name )   {
         if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );
        save ( new   File ( name ));
        filename  =  name ;
     }

    /**
     * Saves the picture to a file in a PNG or JPEG image format.
     *
     *  @param   file the file
     *  @throws  IllegalArgumentException if { @code  file} is { @code  null}
     */
     public   void  save ( File  file )   {
         if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );
        filename  =  file . getName ();
         if   ( frame  !=   null )  frame . setTitle ( filename );
         String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );
         if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {
             try   {
                 ImageIO . write ( image ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }
         else   {
             System . out . println ( "Error: filename must end in .jpg or .png" );
         }
     }

    /**
     * Opens a save dialog box when the user selects "Save As" from the menu.
     */
    @ Override
     public   void  actionPerformed ( ActionEvent  e )   {
         FileDialog  chooser  =   new   FileDialog ( frame ,
                              "Use a .png or .jpg extension" ,   FileDialog . SAVE );
        chooser . setVisible ( true );
         if   ( chooser . getFile ()   !=   null )   {
            save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());
         }
     }

    /**
     * Unit tests this { @code  Picture} data type.
     * Reads a picture specified by the command-line argument,
     * and shows it in a window on the screen.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         GrayscalePicture  picture  =   new   GrayscalePicture ( args [ 0 ]);
         StdOut . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());
         GrayscalePicture  copy  =   new   GrayscalePicture ( picture );
        picture . show ();
        copy . show ();
         while   ( ! StdIn . isEmpty ())   {
             int  row  =   StdIn . readInt ();
             int  col  =   StdIn . readInt ();
             int  gray  =   StdIn . readInt ();
            picture . setGrayscale ( row ,  col ,  gray );
             StdOut . println ( picture . get ( row ,  col ));
             StdOut . println ( picture . getGrayscale ( row ,  col ));
         }
     }

}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/GREP.java

edu/princeton/cs/algs4/GREP.java

/******************************************************************************
 *  Compilation:  javac GREP.java
 *  Execution:    java GREP regexp < input.txt
 *  Dependencies: NFA.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/54regexp/tinyL.txt
 *
 *  This program takes an RE as a command-line argument and prints
 *  the lines from standard input having some substring that
 *  is in the language described by the RE. 
 *
 *  % more tinyL.txt
 *  AC
 *  AD
 *  AAA
 *  ABD
 *  ADD
 *  BCD
 *  ABCCBD
 *  BABAAA
 *  BABBAAA
 *
 *  %  java GREP "(A*B|AC)D" < tinyL.txt
 *  ABD
 *  ABCCBD
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  GREP} class provides a client for reading in a sequence of
 *  lines from standard input and printing to standard output those lines
 *  that contain a substring matching a specified regular expression.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  GREP  {

     // do not instantiate
     private  GREP ()   {   }

     /**
     * Interprets the command-line argument as a regular expression
     * (supporting closure, binary or, parentheses, and wildcard)
     * reads in lines from standard input; writes to standard output
     * those lines that contain a substring matching the regular
     * expression.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         String  regexp  =   "(.*"   +  args [ 0 ]   +   ".*)" ;
        NFA nfa  =   new  NFA ( regexp );
         while   ( StdIn . hasNextLine ())   {  
             String  line  =   StdIn . readLine ();
             if   ( nfa . recognizes ( line ))   {
                 StdOut . println ( line );
             }
         }
     }  
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Heap.java

edu/princeton/cs/algs4/Heap.java

/******************************************************************************
 *  Compilation:  javac Heap.java
 *  Execution:    java Heap < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/24pq/tiny.txt
 *                https://algs4.cs.princeton.edu/24pq/words3.txt
 *  
 *  Sorts a sequence of strings from standard input using heapsort.
 *
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Heap < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *
 *  % java Heap < words3.txt
 *  all bad bed bug dad ... yes yet zoo   [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Heap} class provides a static method to sort an array
 *  using <em>heapsort</em>.
 *  <p>
 *  This implementation takes &Theta;(<em>n</em> log <em>n</em>) time
 *  to sort any array of length <em>n</em> (assuming comparisons
 *  take constant time). It makes at most 
 *  2 <em>n</em> log<sub>2</sub> <em>n</em> compares.
 *  <p>
 *  This sorting algorithm is not stable.
 *  It uses &Theta;(1) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Heap   {

     // This class should not be instantiated.
     private   Heap ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  pq the array to be sorted
     */
     public   static   void  sort ( Comparable []  pq )   {
         int  n  =  pq . length ;
         for   ( int  k  =  n / 2 ;  k  >=   1 ;  k -- )
            sink ( pq ,  k ,  n );
         while   ( >   1 )   {
            exch ( pq ,   1 ,  n -- );
            sink ( pq ,   1 ,  n );
         }
     }

    /***************************************************************************
    * Helper functions to restore the heap invariant.
    ***************************************************************************/

     private   static   void  sink ( Comparable []  pq ,   int  k ,   int  n )   {
         while   ( 2 * <=  n )   {
             int  j  =   2 * k ;
             if   ( <  n  &&  less ( pq ,  j ,  j + 1 ))  j ++ ;
             if   ( ! less ( pq ,  k ,  j ))   break ;
            exch ( pq ,  k ,  j );
            k  =  j ;
         }
     }

    /***************************************************************************
    * Helper functions for comparisons and swaps.
    * Indices are "off-by-one" to support 1-based indexing.
    ***************************************************************************/
     private   static   boolean  less ( Comparable []  pq ,   int  i ,   int  j )   {
         return  pq [ i - 1 ]. compareTo ( pq [ j - 1 ])   <   0 ;
     }

     private   static   void  exch ( Object []  pq ,   int  i ,   int  j )   {
         Object  swap  =  pq [ i - 1 ];
        pq [ i - 1 ]   =  pq [ j - 1 ];
        pq [ j - 1 ]   =  swap ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; heapsorts them; 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Heap . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/HexDump.java

edu/princeton/cs/algs4/HexDump.java

/******************************************************************************
 *  Compilation:  javac HexDump.java
 *  Execution:    java HexDump < file
 *  Dependencies: BinaryStdIn.java StdOut.java
 *  Data file:    https://algs4.cs.princeton.edu/55compression/abra.txt
 *  
 *  Reads in a binary file and writes out the bytes in hex, 16 per line.
 *
 *  % more abra.txt
 *  ABRACADABRA!
 *
 *  % java HexDump 16 < abra.txt
 *  41 42 52 41 43 41 44 41 42 52 41 21
 *  96 bits
 *
 *
 *  Remark
 *  --------------------------
 *   - Similar to the Unix utilities od (octal dump) or hexdump (hexadecimal dump).
 *
 *  % od -t x1 < abra.txt 
 *  0000000 41 42 52 41 43 41 44 41 42 52 41 21
 *  0000014
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  HexDump} class provides a client for displaying the contents
 *  of a binary file in hexadecimal.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  See also { @link  BinaryDump} and { @link  PictureDump}.
 *  For more full-featured versions, see the Unix utilities
 *  { @code  od} (octal dump) and { @code  hexdump} (hexadecimal dump).
 *  <p>
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   HexDump   {

     // Do not instantiate.
     private   HexDump ()   {   }

     /**
     * Reads in a sequence of bytes from standard input and writes
     * them to standard output using hexademical notation, k hex digits
     * per line, where k is given as a command-line integer (defaults
     * to 16 if no integer is specified); also writes the number
     * of bits.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  bytesPerLine  =   16 ;
         if   ( args . length  ==   1 )   {
            bytesPerLine  =   Integer . parseInt ( args [ 0 ]);
         }

         int  i ;
         for   ( =   0 ;   ! BinaryStdIn . isEmpty ();  i ++ )   {
             if   ( bytesPerLine  ==   0 )   {
                 BinaryStdIn . readChar ();
                 continue ;
             }
             if   ( ==   0 )   StdOut . printf ( "" );
             else   if   ( %  bytesPerLine  ==   0 )   StdOut . printf ( "\n" ,  i );
             else   StdOut . print ( " " );
             char  c  =   BinaryStdIn . readChar ();
             StdOut . printf ( "%02x" ,  c  &   0xff );
         }
         if   ( bytesPerLine  !=   0 )   StdOut . println ();
         StdOut . println (( i * 8 )   +   " bits" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/HopcroftKarp.java

edu/princeton/cs/algs4/HopcroftKarp.java

/******************************************************************************
 *  Compilation:  javac HopcroftKarp.java
 *  Execution:    java HopcroftKarp V1 V2 E
 *  Dependencies: FordFulkerson.java FlowNetwork.java FlowEdge.java
 *                BipartiteX.java
 *
 *  Find a maximum cardinality matching (and minimum cardinality vertex cover)
 *  in a bipartite graph using Hopcroft-Karp algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  HopcroftKarp} class represents a data type for computing a
 *  <em>maximum (cardinality) matching</em> and a
 *  <em>minimum (cardinality) vertex cover</em> in a bipartite graph.
 *  A <em>bipartite graph</em> in a graph whose vertices can be partitioned
 *  into two disjoint sets such that every edge has one endpoint in either set.
 *  A <em>matching</em> in a graph is a subset of its edges with no common
 *  vertices. A <em>maximum matching</em> is a matching with the maximum number
 *  of edges.
 *  A <em>perfect matching</em> is a matching which matches all vertices in the graph.
 *  A <em>vertex cover</em> in a graph is a subset of its vertices such that
 *  every edge is incident to at least one vertex. A <em>minimum vertex cover</em>
 *  is a vertex cover with the minimum number of vertices.
 *  By Konig's theorem, in any biparite
 *  graph, the maximum number of edges in matching equals the minimum number
 *  of vertices in a vertex cover.
 *  The maximum matching problem in <em>nonbipartite</em> graphs is
 *  also important, but all known algorithms for this more general problem
 *  are substantially more complicated.
 *  <p>
 *  This implementation uses the <em>Hopcroft-Karp algorithm</em>.
 *  The order of growth of the running time in the worst case is
 *  (<em>E</em> + <em>V</em>) sqrt(<em>V</em>),
 *  where <em>E</em> is the number of edges and <em>V</em> is the number
 *  of vertices in the graph. It uses extra space (not including the graph)
 *  proportional to <em>V</em>.
 *  <p>
 *  See also { @link  BipartiteMatching}, which solves the problem in
 *  O(<em>E V</em>) time using the <em>alternating path algorithm</em>
 *  and <a href = "https://algs4.cs.princeton.edu/65reductions/BipartiteMatchingToMaxflow.java.html">BipartiteMatchingToMaxflow</a>,
 *  which solves the problem in O(<em>E V</em>) time via a reduction
 *  to the maxflow problem.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/65reductions">Section 6.5</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   HopcroftKarp   {
     private   static   final   int  UNMATCHED  =   - 1 ;

     private   final   int  V ;                   // number of vertices in the graph
     private   BipartiteX  bipartition ;        // the bipartition
     private   int  cardinality ;               // cardinality of current matching
     private   int []  mate ;                    // mate[v] =  w if v-w is an edge in current matching
                                          //         = -1 if v is not in current matching
     private   boolean []  inMinVertexCover ;    // inMinVertexCover[v] = true iff v is in min vertex cover
     private   boolean []  marked ;              // marked[v] = true iff v is reachable via alternating path
     private   int []  distTo ;                  // distTo[v] = number of edges on shortest path to v

     /**
     * Determines a maximum matching (and a minimum vertex cover)
     * in a bipartite graph.
     *
     *  @param   G the bipartite graph
     *  @throws  IllegalArgumentException if { @code  G} is not bipartite
     */
     public   HopcroftKarp ( Graph  G )   {
        bipartition  =   new   BipartiteX ( G );
         if   ( ! bipartition . isBipartite ())   {
             throw   new   IllegalArgumentException ( "graph is not bipartite" );
         }

         // initialize empty matching
         this . =  G . V ();
        mate  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            mate [ v ]   =  UNMATCHED ;

         // the call to hasAugmentingPath() provides enough info to reconstruct level graph
         while   ( hasAugmentingPath ( G ))   {

             // to be able to iterate over each adjacency list, keeping track of which
             // vertex in each adjacency list needs to be explored next
             Iterator < Integer > []  adj  =   ( Iterator < Integer > [])   new   Iterator [ G . V ()];
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
                adj [ v ]   =  G . adj ( v ). iterator ();

             // for each unmatched vertex s on one side of bipartition
             for   ( int  s  =   0 ;  s  <  V ;  s ++ )   {
                 if   ( isMatched ( s )   ||   ! bipartition . color ( s ))   continue ;     // or use distTo[s] == 0

                 // find augmenting path from s using nonrecursive DFS
                 Stack < Integer >  path  =   new   Stack < Integer > ();
                path . push ( s );
                 while   ( ! path . isEmpty ())   {
                     int  v  =  path . peek ();

                     // retreat, no more edges in level graph leaving v
                     if   ( ! adj [ v ]. hasNext ())
                        path . pop ();

                     // advance
                     else   {
                         // process edge v-w only if it is an edge in level graph
                         int  w  =  adj [ v ]. next ();
                         if   ( ! isLevelGraphEdge ( v ,  w ))   continue ;

                         // add w to augmenting path
                        path . push ( w );

                         // augmenting path found: update the matching
                         if   ( ! isMatched ( w ))   {
                             // StdOut.println("augmenting path: " + toString(path));

                             while   ( ! path . isEmpty ())   {
                                 int  x  =  path . pop ();
                                 int  y  =  path . pop ();
                                mate [ x ]   =  y ;
                                mate [ y ]   =  x ;
                             }
                            cardinality ++ ;
                         }
                     }
                 }
             }
         }

         // also find a min vertex cover
        inMinVertexCover  =   new   boolean [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( bipartition . color ( v )   &&   ! marked [ v ])  inMinVertexCover [ v ]   =   true ;
             if   ( ! bipartition . color ( v )   &&  marked [ v ])  inMinVertexCover [ v ]   =   true ;
         }

         assert  certifySolution ( G );
     }

     // string representation of augmenting path (chop off last vertex)
     private   static   String  toString ( Iterable < Integer >  path )   {
         StringBuilder  sb  =   new   StringBuilder ();
         for   ( int  v  :  path )
            sb . append ( +   "-" );
         String  s  =  sb . toString ();
        s  =  s . substring ( 0 ,  s . lastIndexOf ( '-' ));
         return  s ;
     }

    // is the edge v-w in the level graph?
     private   boolean  isLevelGraphEdge ( int  v ,   int  w )   {
         return   ( distTo [ w ]   ==  distTo [ v ]   +   1 )   &&  isResidualGraphEdge ( v ,  w );
     }

    // is the edge v-w a forward edge not in the matching or a reverse edge in the matching?
     private   boolean  isResidualGraphEdge ( int  v ,   int  w )   {
         if   (( mate [ v ]   !=  w )   &&   bipartition . color ( v ))   return   true ;
         if   (( mate [ v ]   ==  w )   &&   ! bipartition . color ( v ))   return   true ;
         return   false ;
     }

     /*
     * is there an augmenting path?
     *   - if so, upon termination adj[] contains the level graph;
     *   - if not, upon termination marked[] specifies those vertices reachable via an alternating
     *     path from one side of the bipartition
     *
     * an alternating path is a path whose edges belong alternately to the matching and not
     * to the matching
     *
     * an augmenting path is an alternating path that starts and ends at unmatched vertices
     */
     private   boolean  hasAugmentingPath ( Graph  G )   {

         // shortest path distances
        marked  =   new   boolean [ V ];
        distTo  =   new   int [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
            distTo [ v ]   =   Integer . MAX_VALUE ;

         // breadth-first search (starting from all unmatched vertices on one side of bipartition)
         Queue < Integer >  queue  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( bipartition . color ( v )   &&   ! isMatched ( v ))   {
                queue . enqueue ( v );
                marked [ v ]   =   true ;
                distTo [ v ]   =   0 ;
             }
         }

         // run BFS until an augmenting path is found
         // (and keep going until all vertices at that distance are explored)
         boolean  hasAugmentingPath  =   false ;
         while   ( ! queue . isEmpty ())   {
             int  v  =  queue . dequeue ();
             for   ( int  w  :  G . adj ( v ))   {

                 // forward edge not in matching or backwards edge in matching
                 if   ( isResidualGraphEdge ( v ,  w ))   {
                     if   ( ! marked [ w ])   {
                        distTo [ w ]   =  distTo [ v ]   +   1 ;
                        marked [ w ]   =   true ;
                         if   ( ! isMatched ( w ))
                            hasAugmentingPath  =   true ;

                         // stop enqueuing vertices once an alternating path has been discovered
                         // (no vertex on same side will be marked if its shortest path distance longer)
                         if   ( ! hasAugmentingPath )  queue . enqueue ( w );
                     }
                 }
             }
         }

         return  hasAugmentingPath ;
     }

     /**
     * Returns the vertex to which the specified vertex is matched in
     * the maximum matching computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  the vertex to which vertex { @code  v} is matched in the
     *         maximum matching; { @code  -1} if the vertex is not matched
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *
     */
     public   int  mate ( int  v )   {
        validate ( v );
         return  mate [ v ];
     }

     /**
     * Returns true if the specified vertex is matched in the maximum matching
     * computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  { @code  true} if vertex { @code  v} is matched in maximum matching;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *
     */
     public   boolean  isMatched ( int  v )   {
        validate ( v );
         return  mate [ v ]   !=  UNMATCHED ;
     }

     /**
     * Returns the number of edges in any maximum matching.
     *
     *  @return  the number of edges in any maximum matching
     */
     public   int  size ()   {
         return  cardinality ;
     }

     /**
     * Returns true if the graph contains a perfect matching.
     * That is, the number of edges in a maximum matching is equal to one half
     * of the number of vertices in the graph (so that every vertex is matched).
     *
     *  @return  { @code  true} if the graph contains a perfect matching;
     *         { @code  false} otherwise
     */
     public   boolean  isPerfect ()   {
         return  cardinality  *   2   ==  V ;
     }

     /**
     * Returns true if the specified vertex is in the minimum vertex cover
     * computed by the algorithm.
     *
     *  @param   v the vertex
     *  @return  { @code  true} if vertex { @code  v} is in the minimum vertex cover;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  inMinVertexCover ( int  v )   {
        validate ( v );
         return  inMinVertexCover [ v ];
     }

     // throw an exception if vertex is invalid
     private   void  validate ( int  v )   {
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**************************************************************************
     *   
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // check that mate[] and inVertexCover[] define a max matching and min vertex cover, respectively
     private   boolean  certifySolution ( Graph  G )   {

         // check that mate(v) = w iff mate(w) = v
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   ==   - 1 )   continue ;
             if   ( mate ( mate ( v ))   !=  v )   return   false ;
         }

         // check that size() is consistent with mate()
         int  matchedVertices  =   0 ;
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   !=   - 1 )  matchedVertices ++ ;
         }
         if   ( 2 * size ()   !=  matchedVertices )   return   false ;

         // check that size() is consistent with minVertexCover()
         int  sizeOfMinVertexCover  =   0 ;
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             if   ( inMinVertexCover ( v ))  sizeOfMinVertexCover ++ ;
         if   ( size ()   !=  sizeOfMinVertexCover )   return   false ;

         // check that mate() uses each vertex at most once
         boolean []  isMatched  =   new   boolean [ V ];
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             int  w  =  mate [ v ];
             if   ( ==   - 1 )   continue ;
             if   ( ==  w )   return   false ;
             if   ( >=  w )   continue ;
             if   ( isMatched [ v ]   ||  isMatched [ w ])   return   false ;
            isMatched [ v ]   =   true ;
            isMatched [ w ]   =   true ;
         }

         // check that mate() uses only edges that appear in the graph
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )   {
             if   ( mate ( v )   ==   - 1 )   continue ;
             boolean  isEdge  =   false ;
             for   ( int  w  :  G . adj ( v ))   {
                 if   ( mate ( v )   ==  w )  isEdge  =   true ;
             }
             if   ( ! isEdge )   return   false ;
         }

         // check that inMinVertexCover() is a vertex cover
         for   ( int  v  =   0 ;  v  <  V ;  v ++ )
             for   ( int  w  :  G . adj ( v ))
                 if   ( ! inMinVertexCover ( v )   &&   ! inMinVertexCover ( w ))   return   false ;

         return   true ;
     }

     /** 
     * Unit tests the { @code  HopcroftKarp} data type.   
     * Takes three command-line arguments { @code  V1}, { @code  V2}, and { @code  E};
     * creates a random bipartite graph with { @code  V1} + { @code  V2} vertices
     * and { @code  E} edges; computes a maximum matching and minimum vertex cover;
     * and prints the results.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         int  V1  =   Integer . parseInt ( args [ 0 ]);
         int  V2  =   Integer . parseInt ( args [ 1 ]);
         int  E   =   Integer . parseInt ( args [ 2 ]);
         Graph  G  =   GraphGenerator . bipartite ( V1 ,  V2 ,  E );
         if   ( G . V ()   <   1000 )   StdOut . println ( G );

         HopcroftKarp  matching  =   new   HopcroftKarp ( G );

         // print maximum matching
         StdOut . printf ( "Number of edges in max matching        = %d\n" ,  matching . size ());
         StdOut . printf ( "Number of vertices in min vertex cover = %d\n" ,  matching . size ());
         StdOut . printf ( "Graph has a perfect matching           = %b\n" ,  matching . isPerfect ());
         StdOut . println ();

         if   ( G . V ()   >=   1000 )   return ;

         StdOut . print ( "Max matching: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             int  w  =  matching . mate ( v );
             if   ( matching . isMatched ( v )   &&  v  <  w )    // print each edge only once
                 StdOut . print ( +   "-"   +  w  +   " " );
         }
         StdOut . println ();

         // print minimum vertex cover
         StdOut . print ( "Min vertex cover: " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( matching . inMinVertexCover ( v ))
                 StdOut . print ( +   " " );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Huffman.java

edu/princeton/cs/algs4/Huffman.java

/******************************************************************************
 *  Compilation:  javac Huffman.java
 *  Execution:    java Huffman - < input.txt   (compress)
 *  Execution:    java Huffman + < input.txt   (expand)
 *  Dependencies: BinaryIn.java BinaryOut.java
 *  Data files:   https://algs4.cs.princeton.edu/55compression/abra.txt
 *                https://algs4.cs.princeton.edu/55compression/tinytinyTale.txt
 *                https://algs4.cs.princeton.edu/55compression/medTale.txt
 *                https://algs4.cs.princeton.edu/55compression/tale.txt
 *
 *  Compress or expand a binary input stream using the Huffman algorithm.
 *
 *  % java Huffman - < abra.txt | java BinaryDump 60
 *  010100000100101000100010010000110100001101010100101010000100
 *  000000000000000000000000000110001111100101101000111110010100
 *  120 bits
 *
 *  % java Huffman - < abra.txt | java Huffman +
 *  ABRACADABRA!
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Huffman} class provides static methods for compressing
 *  and expanding a binary input using Huffman codes over the 8-bit extended
 *  ASCII alphabet.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Huffman   {

     // alphabet size of extended ASCII
     private   static   final   int  R  =   256 ;

     // Do not instantiate.
     private   Huffman ()   {   }

     // Huffman trie node
     private   static   class   Node   implements   Comparable < Node >   {
         private   final   char  ch ;
         private   final   int  freq ;
         private   final   Node  left ,  right ;

         Node ( char  ch ,   int  freq ,   Node  left ,   Node  right )   {
             this . ch     =  ch ;
             this . freq   =  freq ;
             this . left   =  left ;
             this . right  =  right ;
         }

         // is the node a leaf node?
         private   boolean  isLeaf ()   {
             assert   (( left  ==   null )   &&   ( right  ==   null ))   ||   (( left  !=   null )   &&   ( right  !=   null ));
             return   ( left  ==   null )   &&   ( right  ==   null );
         }

         // compare, based on frequency
         public   int  compareTo ( Node  that )   {
             return   this . freq  -  that . freq ;
         }
     }

     /**
     * Reads a sequence of 8-bit bytes from standard input; compresses them
     * using Huffman codes with an 8-bit alphabet; and writes the results
     * to standard output.
     */
     public   static   void  compress ()   {
         // read the input
         String  s  =   BinaryStdIn . readString ();
         char []  input  =  s . toCharArray ();

         // tabulate frequency counts
         int []  freq  =   new   int [ R ];
         for   ( int  i  =   0 ;  i  <  input . length ;  i ++ )
            freq [ input [ i ]] ++ ;

         // build Huffman trie
         Node  root  =  buildTrie ( freq );

         // build code table
         String []  st  =   new   String [ R ];
        buildCode ( st ,  root ,   "" );

         // print trie for decoder
        writeTrie ( root );

         // print number of bytes in original uncompressed message
         BinaryStdOut . write ( input . length );

         // use Huffman code to encode input
         for   ( int  i  =   0 ;  i  <  input . length ;  i ++ )   {
             String  code  =  st [ input [ i ]];
             for   ( int  j  =   0 ;  j  <  code . length ();  j ++ )   {
                 if   ( code . charAt ( j )   ==   '0' )   {
                     BinaryStdOut . write ( false );
                 }
                 else   if   ( code . charAt ( j )   ==   '1' )   {
                     BinaryStdOut . write ( true );
                 }
                 else   throw   new   IllegalStateException ( "Illegal state" );
             }
         }

         // close output stream
         BinaryStdOut . close ();
     }

     // build the Huffman trie given frequencies
     private   static   Node  buildTrie ( int []  freq )   {

         // initialze priority queue with singleton trees
         MinPQ < Node >  pq  =   new   MinPQ < Node > ();
         for   ( char  c  =   0 ;  c  <  R ;  c ++ )
             if   ( freq [ c ]   >   0 )
                pq . insert ( new   Node ( c ,  freq [ c ],   null ,   null ));

         // merge two smallest trees
         while   ( pq . size ()   >   1 )   {
             Node  left   =  pq . delMin ();
             Node  right  =  pq . delMin ();
             Node  parent  =   new   Node ( '\0' ,  left . freq  +  right . freq ,  left ,  right );
            pq . insert ( parent );
         }
         return  pq . delMin ();
     }


     // write bitstring-encoded trie to standard output
     private   static   void  writeTrie ( Node  x )   {
         if   ( x . isLeaf ())   {
             BinaryStdOut . write ( true );
             BinaryStdOut . write ( x . ch ,   8 );
             return ;
         }
         BinaryStdOut . write ( false );
        writeTrie ( x . left );
        writeTrie ( x . right );
     }

     // make a lookup table from symbols and their encodings
     private   static   void  buildCode ( String []  st ,   Node  x ,   String  s )   {
         if   ( ! x . isLeaf ())   {
            buildCode ( st ,  x . left ,   s  +   '0' );
            buildCode ( st ,  x . right ,  s  +   '1' );
         }
         else   {
            st [ x . ch ]   =  s ;
         }
     }

     /**
     * Reads a sequence of bits that represents a Huffman-compressed message from
     * standard input; expands them; and writes the results to standard output.
     */
     public   static   void  expand ()   {

         // read in Huffman trie from input stream
         Node  root  =  readTrie ();  

         // number of bytes to write
         int  length  =   BinaryStdIn . readInt ();

         // decode using the Huffman trie
         for   ( int  i  =   0 ;  i  <  length ;  i ++ )   {
             Node  x  =  root ;
             while   ( ! x . isLeaf ())   {
                 boolean  bit  =   BinaryStdIn . readBoolean ();
                 if   ( bit )  x  =  x . right ;
                 else      x  =  x . left ;
             }
             BinaryStdOut . write ( x . ch ,   8 );
         }
         BinaryStdOut . close ();
     }


     private   static   Node  readTrie ()   {
         boolean  isLeaf  =   BinaryStdIn . readBoolean ();
         if   ( isLeaf )   {
             return   new   Node ( BinaryStdIn . readChar (),   - 1 ,   null ,   null );
         }
         else   {
             return   new   Node ( '\0' ,   - 1 ,  readTrie (),  readTrie ());
         }
     }

     /**
     * Sample client that calls { @code  compress()} if the command-line
     * argument is "-" an { @code  expand()} if it is "+".
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         if        ( args [ 0 ]. equals ( "-" ))  compress ();
         else   if   ( args [ 0 ]. equals ( "+" ))  expand ();
         else   throw   new   IllegalArgumentException ( "Illegal command line argument" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/IndexBinomialMinPQ.java

edu/princeton/cs/algs4/IndexBinomialMinPQ.java

/******************************************************************************
 *  Compilation: javac IndexBinomialMinPQ.java
 *  Execution:
 *  
 *  An index binomial heap.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;
import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The IndexBinomialMinPQ class represents an indexed priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations,
 *  along with delete and change-the-key methods. 
 *  In order to let the client refer to keys on the priority queue,
 *  an integer between 0 and N-1 is associated with each key ; the client
 *  uses this integer to specify which key to delete or change.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  
 *  This implementation uses a binomial heap along with an array to associate
 *  keys with integers in the given range.
 *  The insert, delete-the-minimum, delete, change-key, decrease-key,
 *  increase-key and size operations take logarithmic time.
 *  The is-empty, min-index, min-key, and key-of operations take constant time.
 *  Construction takes time proportional to the specified capacity.
 *
 *   @author  Tristan Claverie
 */
public   class   IndexBinomialMinPQ < Key >   implements   Iterable < Integer >   {
     private   Node < Key >  head ;               //Head of the list of roots
     private   Node < Key > []  nodes ;            //Array of indexed Nodes of the heap
     private   int  n ;                    //Maximum size of the tree
     private   final   Comparator < Key >  comparator ;     //Comparator over the keys
    
     //Represents a node of a Binomial Tree
     private   class   Node < Key >   {
         Key  key ;                  //Key contained by the Node
         int  order ;                //The order of the Binomial Tree rooted by this Node
         int  index ;                //Index associated with the Key
         Node < Key >  parent ;             //parent of this Node
         Node < Key >  child ,  sibling ;         //child and sibling of this Node
     }
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} to { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     */
     public   IndexBinomialMinPQ ( int  N )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );
        comparator  =   new   MyComparator ();
        nodes  =   ( Node < Key > [])   new   Node [ N ];
         this . =  N ;
     }
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} to { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @param  comparator a Comparator over the keys
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     */
     public   IndexBinomialMinPQ ( int  N ,   Comparator < Key >  comparator )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );
         this . comparator  =  comparator ;
        nodes  =   ( Node < Key > [])   new   Node [ N ];
         this . =  N ;
     }

     /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
     public   boolean  isEmpty ()   {
         return  head  ==   null ;
     }

     /**
     * Does the priority queue contains the index i ?
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @return  true if i is on the priority queue, false if not
     */
     public   boolean  contains ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         else   return  nodes [ i ]   !=   null ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(log(n))
     *  @return  the number of elements on the priority queue
     */
     public   int  size ()   {
         int  result  =   0 ,  tmp ;
         for   ( Node < Key >  node  =  head ;  node  !=   null ;  node  =  node . sibling )   {
             if   ( node . order  >   30 )   {   throw   new   ArithmeticException ( "The number of elements cannot be evaluated, but the priority queue is still valid." );   }
            tmp  =    1   <<  node . order ;
            result  |=  tmp ;
         }
         return  result ;
     }

     /**
     * Associates a key with an index
     * Worst case is O(log(n))
     *  @param  i an index
     *  @param  key a Key associated with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index is already in the queue
     */
     public   void  insert ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         if   ( contains ( i ))   throw   new   IllegalArgumentException ( "Specified index is already in the queue" );
         Node < Key >  x  =   new   Node < Key > ();
        x . key  =  key ;
        x . index  =  i ;
        x . order  =   0 ;
        nodes [ i ]   =  x ;
         IndexBinomialMinPQ < Key >  H  =   new   IndexBinomialMinPQ < Key > ();
        H . head  =  x ;
        head  =  union ( H ). head ;
     }

     /**
     * Gets the index associated with the minimum key
     * Worst case is O(log(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
    
     public   int  minIndex ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         Node < Key >  min  =  head ;
         Node < Key >  current  =  head ;
         while   ( current . sibling  !=   null )   {
            min  =   ( greater ( min . key ,  current . sibling . key ))   ?  current . sibling  :  min ;
            current  =  current . sibling ;
         }
         return  min . index ;
     }

     /**
     * Gets the minimum key currently in the queue
     * Worst case is O(log(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
    
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         Node < Key >  min  =  head ;
         Node < Key >  current  =  head ;
         while   ( current . sibling  !=   null )   {
            min  =   ( greater ( min . key ,  current . sibling . key ))   ?  current . sibling  :  min ;
            current  =  current . sibling ;
         }
         return  min . key ;
     }

     /**
     * Deletes the minimum key
     * Worst case is O(log(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
    
     public   int  delMin ()   {
         if ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         Node < Key >  min  =  eraseMin ();
         Node < Key >  x  =   ( min . child  ==   null )   ?  min  :  min . child ;
         if   ( min . child  !=   null )   {
            min . child  =   null ;
             Node < Key >  prevx  =   null ,  nextx  =  x . sibling ;
             while   ( nextx  !=   null )   {
                x . parent  =   null ;   // for garbage collection
                x . sibling  =  prevx ;
                prevx  =  x ;
                x  =  nextx ; nextx  =  nextx . sibling ;
             }
            x . parent  =   null ;
            x . sibling  =  prevx ;
             IndexBinomialMinPQ < Key >  H  =   new   IndexBinomialMinPQ < Key > ();
            H . head  =  x ;
            head  =  union ( H ). head ;
         }
         return  min . index ;
     }

     /**
     * Gets the key associated with index i
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index is not in the queue
     *  @return  the key associated with index i
     */
    
     public   Key  keyOf ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))   throw   new   IllegalArgumentException ( "Specified index is not in the queue" );
         return  nodes [ i ]. key ;
     }

     /**
     * Changes the key associated with index i to the given key
     * Worst case is O(log(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index has no key associated with
     */
    
     public   void  changeKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   IllegalArgumentException ( "Specified index is not in the queue" );
         if   ( greater ( nodes [ i ]. key ,  key ))   decreaseKey ( i ,  key );
         else                              increaseKey ( i ,  key );
     }

     /**
     * Decreases the key associated with index i to the given key
     * Worst case is O(log(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is greater than the current key
     */
    
     public   void  decreaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( greater ( key ,  nodes [ i ]. key ))    throw   new   IllegalArgumentException ( "Calling with this argument would not decrease the key" );
         Node < Key >  x  =  nodes [ i ];
        x . key  =  key ;
        swim ( i );
     }

     /**
     * Increases the key associated with index i to the given key
     * Worst case is O(log(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is lower than the current key
     */
    
     public   void  increaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( greater ( nodes [ i ]. key ,  key ))    throw   new   IllegalArgumentException ( "Calling with this argument would not increase the key" );
        delete ( i );
        insert ( i ,  key );
     }

     /**
     * Deletes the key associated the given index
     * Worst case is O(log(n))
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the given index has no key associated with
     */
    
     public   void  delete ( int  i )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
        toTheRoot ( i );
         Node < Key >  x  =  erase ( i );
         if   ( x . child  !=   null )   {
             Node < Key >  y  =  x ;
            x  =  x . child ;
            y . child  =   null ;
             Node < Key >  prevx  =   null ,  nextx  =  x . sibling ;
             while   ( nextx  !=   null )   {
                x . parent  =   null ;
                x . sibling  =  prevx ;
                prevx  =  x ;
                x  =  nextx ;  nextx  =  nextx . sibling ;
             }
            x . parent  =   null ;
            x . sibling  =  prevx ;
             IndexBinomialMinPQ < Key >  H  =   new   IndexBinomialMinPQ < Key > ();
            H . head  =  x ;
            head  =  union ( H ). head ;
         }
     }
    
     /*************************************************
     * General helper functions
     ************************************************/
    
     //Compares two keys
     private   boolean  greater ( Key  n ,   Key  m )   {
         if   ( ==   null )   return   false ;
         if   ( ==   null )   return   true ;
         return  comparator . compare ( n ,  m )   >   0 ;
     }
    
     //Exchanges the positions of two nodes
     private   void  exchange ( Node < Key >  x ,   Node < Key >  y )   {
         Key  tempKey  =  x . key ;  x . key  =  y . key ;  y . key  =  tempKey ;
         int  tempInt  =  x . index ;  x . index  =  y . index ;  y . index  =  tempInt ;
        nodes [ x . index ]   =  x ;
        nodes [ y . index ]   =  y ;
     }
    
     //Assuming root1 holds a greater key than root2, root2 becomes the new root
     private   void  link ( Node < Key >  root1 ,   Node < Key >  root2 )   {
        root1 . sibling  =  root2 . child ;
        root1 . parent  =  root2 ;
        root2 . child  =  root1 ;
        root2 . order ++ ;
     }
    
     /*************************************************
     * Functions for moving upward
     ************************************************/
    
     //Moves a Node upward
     private   void  swim ( int  i )   {
         Node < Key >  x  =  nodes [ i ];
         Node < Key >  parent  =  x . parent ;
         if   ( parent  !=   null   &&  greater ( parent . key ,  x . key ))   {
            exchange ( x ,  parent );
            swim ( i );
         }
     }
    
     //The key associated with i becomes the root of its Binomial Tree,
     //regardless of the order relation defined for the keys
     private   void  toTheRoot ( int  i )   {
         Node < Key >  x  =  nodes [ i ];
         Node < Key >  parent  =  x . parent ;
         if   ( parent  !=   null )   {
            exchange ( x ,  parent );
            toTheRoot ( i );
         }
     }
    
     /**************************************************
     * Functions for deleting a key
     *************************************************/
    
     //Assuming the key associated with i is in the root list,
     //deletes and return the node of index i
     private   Node < Key >  erase ( int  i )   {
         Node < Key >  reference  =  nodes [ i ];
         Node < Key >  x  =  head ;
         Node < Key >  previous  =   null ;
         while   ( !=  reference )   {
            previous  =  x ;
            x  =  x . sibling ;
         }
        previous . sibling  =  x . sibling ;
         if   ( ==  head )  head  =  head . sibling ;
        nodes [ i ]   =   null ;
         return  x ;
     }
    
     //Deletes and return the node containing the minimum key
     private   Node < Key >  eraseMin ()   {
         Node < Key >  min  =  head ;
         Node < Key >  previous  =   null ;
         Node < Key >  current  =  head ;
         while   ( current . sibling  !=   null )   {
             if   ( greater ( min . key ,  current . sibling . key ))   {
                previous  =  current ;
                min  =  current . sibling ;
             }
            current  =  current . sibling ;
         }
        previous . sibling  =  min . sibling ;
         if   ( min  ==  head )  head  =  min . sibling ;
        nodes [ min . index ]   =   null ;
         return  min ;
     }
    
     /**************************************************
     * Functions for inserting a key in the heap
     *************************************************/
    
     //Merges two root lists into one, there can be up to 2 Binomial Trees of same order
     private   Node < Key >  merge ( Node < Key >  h ,   Node < Key >  x ,   Node < Key >  y )   {
         if   ( ==   null   &&  y  ==   null )   return  h ;
         else   if   ( ==   null )          h . sibling  =  merge ( y ,   null ,  y . sibling );
         else   if   ( ==   null )          h . sibling  =  merge ( x ,  x . sibling ,   null );
         else   if   ( x . order  <  y . order )  h . sibling  =  merge ( x ,  x . sibling ,  y );
         else                         h . sibling  =  merge ( y ,  x ,  y . sibling );
         return  h ;
     }
    
     //Merges two Binomial Heaps together and returns the resulting Binomial Heap
     //It destroys the two Heaps in parameter, which should not be used any after.
     //To guarantee logarithmic time, this function assumes the arrays are up-to-date
     private   IndexBinomialMinPQ < Key >  union ( IndexBinomialMinPQ < Key >  heap )   {
         this . head  =  merge ( new   Node < Key > (),   this . head ,  heap . head ). sibling ;
         Node < Key >  x  =   this . head ;
         Node < Key >  prevx  =   null ,  nextx  =  x . sibling ;
         while   ( nextx  !=   null )   {
             if   ( x . order  <  nextx . order  ||
                ( nextx . sibling  !=   null   &&  nextx . sibling . order  ==  x . order ))   {
                prevx  =  x ;  x  =  nextx ;
             }   else   if   ( greater ( nextx . key ,  x . key ))   {
                x . sibling  =  nextx . sibling ;
                link ( nextx ,  x );
             }   else   {
                 if   ( prevx  ==   null )   {   this . head  =  nextx ;   }
                 else   {  prevx . sibling  =  nextx ;   }
                link ( x ,  nextx );
                x  =  nextx ;
             }
            nextx  =  x . sibling ;
         }
         return   this ;
     }
    
     /******************************************************************
     * Constructor
     *****************************************************************/
    
     //Creates an empty heap
     //The comparator is instanciated because it needs to,
     //but won't be used by any heap created by this constructor
     private   IndexBinomialMinPQ ()   {  comparator  =   null ;   }
    
     /******************************************************************
     * Iterator
     *****************************************************************/
    
     /**
     * Gets an Iterator over the indexes in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(log(n))
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the indexes in the priority queue in ascending order
     */
    
     public   Iterator < Integer >  iterator ()   {
         return   new   MyIterator ();
     }
    
     private   class   MyIterator   implements   Iterator < Integer >   {
         IndexBinomialMinPQ < Key >  data ;
        
         //Constructor clones recursively the elements in the queue
         //It takes linear time
         public   MyIterator ()   {
            data  =   new   IndexBinomialMinPQ < Key > ( n ,  comparator );
            data . head  =  clone ( head ,   null );
         }
        
         private   Node < Key >  clone ( Node < Key >  x ,   Node < Key >  parent )   {
             if   ( ==   null )   return   null ;
             Node < Key >  node  =   new   Node < Key > ();
            node . index  =  x . index ;
            node . key  =  x . key ;
            data . nodes [ node . index ]   =  node ;
            node . parent  =  parent ;
            node . sibling  =  clone ( x . sibling ,  parent );
            node . child  =  clone ( x . child ,  node );
             return  node ;
         }
        
         public   boolean  hasNext ()   {
             return   ! data . isEmpty ();
         }
        
         public   Integer  next ()   {
                         if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  data . delMin ();
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
     }
    
     /***************************
     * Comparator
     **************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }
    
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/IndexFibonacciMinPQ.java

edu/princeton/cs/algs4/IndexFibonacciMinPQ.java

/******************************************************************************
 *  Compilation: javac IndexFibonacciMinPQ.java
 *  Execution:
 *  
 *  An index Fibonacci heap.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;
import  java . util . Iterator ;
import  java . util . HashMap ;
import  java . util . NoSuchElementException ;

/*
 *  The IndexFibonacciMinPQ class represents an indexed priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations,
 *  along with delete and change-the-key methods. 
 *  In order to let the client refer to keys on the priority queue,
 *  an integer between 0 and N-1 is associated with each key ; the client
 *  uses this integer to specify which key to delete or change.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  
 *  This implementation uses a Fibonacci heap along with an array to associate
 *  keys with integers in the given range.
 *  The insert, size, is-empty, contains, minimum-index, minimum-key
 *  and key-of take constant time.
 *  The decrease-key operation takes amortized constant time.
 *  The delete, increase-key, delete-the-minimum, change-key take amortized logarithmic time.
 *  Construction takes time proportional to the specified capacity
 *
 *  @author Tristan Claverie
 */
public   class   IndexFibonacciMinPQ < Key >   implements   Iterable < Integer >   {
     private   Node < Key > []  nodes ;            //Array of Nodes in the heap
     private   Node < Key >  head ;               //Head of the circular root list
     private   Node < Key >  min ;                //Minimum Node in the heap
     private   int  size ;                     //Number of keys in the heap
     private   int  n ;                        //Maximum number of elements in the heap
     private   final   Comparator < Key >  comp ;   //Comparator over the keys
     private   HashMap < Integer ,   Node < Key >>  table  =   new   HashMap < Integer ,   Node < Key >> ();   //Used for the consolidate operation
    
     //Represents a Node of a tree
     private   class   Node < Key >   {
         Key  key ;                          //Key of the Node
         int  order ;                        //The order of the tree rooted by this Node
         int  index ;                        //Index associated with the key
         Node < Key >  prev ,  next ;             //siblings of the Node
         Node < Key >  parent ,  child ;          //parent and child of this Node
         boolean  mark ;                     //Indicates if this Node already lost a child
     }
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} and { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     */
     public   IndexFibonacciMinPQ ( int  N )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );
        n  =  N ;
        nodes  =   ( Node < Key > [])   new   Node [ n ];
        comp  =   new   MyComparator ();
     }
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} and { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @param  C a Comparator over the keys
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     */
     public   IndexFibonacciMinPQ ( Comparator < Key >  C ,   int  N )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Cannot create a priority queue of negative size" );
        n  =  N ;
        nodes  =   ( Node < Key > [])   new   Node [ n ];
        comp  =  C ;
     }

     /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
    
     public   boolean  isEmpty ()   {
         return  size  ==   0 ;
     }

     /**
     * Does the priority queue contains the index i ?
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @return  true if i is on the priority queue, false if not
     */
    
     public   boolean  contains ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         else                   return  nodes [ i ]   !=   null ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(1)
     *  @return  the number of elements on the priority queue
     */
    
     public   int  size ()   {
         return  size ;
     }

     /**
     * Associates a key with an index
     * Worst case is O(1)
     *  @param  i an index
     *  @param  key a Key associated with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index is already in the queue
     */
    
     public   void  insert ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         if   ( contains ( i ))   throw   new   IllegalArgumentException ( "Specified index is already in the queue" );
         Node < Key >  x  =   new   Node < Key > ();
        x . key  =  key ;
        x . index  =  i ;
        nodes [ i ]   =  x ;
        size ++ ;
        head  =  insert ( x ,  head );
         if   ( min  ==   null )  min  =  head ;
         else              min  =   ( greater ( min . key ,  key ))   ?  head  :  min ;
     }

     /**
     * Get the index associated with the minimum key
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
    
     public   int  minIndex ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  min . index ;
     }

     /**
     * Get the minimum key currently in the queue
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
    
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  min . key ;
     }

     /**
     * Delete the minimum key
     * Worst case is O(log(n)) (amortized)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
    
     public   int  delMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
        head  =  cut ( min ,  head );
         Node < Key >  x  =  min . child ;
         int  index  =  min . index ;
        min . key  =   null ;                   //For garbage collection
         if   ( !=   null )   {
             do   {
                x . parent  =   null ;
                x  =  x . next ;
             }   while   ( !=  min . child );
            head  =  meld ( head ,  x );
            min . child  =   null ;             //For garbage collection
         }
        size -- ;
         if   ( ! isEmpty ())  consolidate ();
         else             min  =   null ;
        nodes [ index ]   =   null ;
         return  index ;
     }

     /**
     * Get the key associated with index i
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index is not in the queue
     *  @return  the key associated with index i
     */
    
     public   Key  keyOf ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         return  nodes [ i ]. key ;
     }

     /**
     * Changes the key associated with index i to the given key
     * If the given key is greater, Worst case is O(log(n))
     * If the given key is lower, Worst case is O(1) (amortized)
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     */
    
     public   void  changeKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( greater ( key ,  nodes [ i ]. key ))   increaseKey ( i ,  key );
         else                              decreaseKey ( i ,  key );
     }

     /**
     * Decreases the key associated with index i to the given key
     * Worst case is O(1) (amortized).
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is greater than the current key
     */
    
     public   void  decreaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( greater ( key ,  nodes [ i ]. key ))    throw   new   IllegalArgumentException ( "Calling with this argument would not decrease the key" );
         Node < Key >  x  =  nodes [ i ];
        x . key  =  key ;
         if   ( greater ( min . key ,  key ))  min  =  x ;
         if   ( x . parent  !=   null   &&  greater ( x . parent . key ,  key ))   {
            cut ( i );
         }
     }

     /**
     * Increases the key associated with index i to the given key
     * Worst case is O(log(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is lower than the current key
     */
    
     public   void  increaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( greater ( nodes [ i ]. key ,  key ))    throw   new   IllegalArgumentException ( "Calling with this argument would not increase the key" );
        delete ( i );
        insert ( i ,  key );
     }

     /**
     * Deletes the key associated the given index
     * Worst case is O(log(n)) (amortized)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the given index has no key associated with
     */
    
     public   void  delete ( int  i )   {
         if   ( <   0   ||  i  >=  n )          throw   new   IllegalArgumentException ();
         if   ( ! contains ( i ))             throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         Node < Key >  x  =  nodes [ i ];
        x . key  =   null ;                 //For garbage collection
         if   ( x . parent  !=   null )   {
            cut ( i );
         }
        head  =  cut ( x ,  head );
         if   ( x . child  !=   null )   {
             Node < Key >  child  =  x . child ;
            x . child  =   null ;           //For garbage collection
            x  =  child ;
             do   {
                child . parent  =   null ;
                child  =  child . next ;
             }   while   ( child  !=  x );
            head  =  meld ( head ,  child );
         }
         if   ( ! isEmpty ())  consolidate ();
         else             min  =   null ;
        nodes [ i ]   =   null ;
        size -- ;
     }
    
     /*************************************
     * General helper functions
     ************************************/
    
     //Compares two keys
     private   boolean  greater ( Key  n ,   Key  m )   {
         if   ( ==   null )   return   false ;
         if   ( ==   null )   return   true ;
         return  comp . compare ( n ,   m )   >   0 ;
     }
    
     //Assuming root1 holds a greater key than root2, root2 becomes the new root
     private   void  link ( Node < Key >  root1 ,   Node < Key >  root2 )   {
        root1 . parent  =  root2 ;
        root2 . child  =  insert ( root1 ,  root2 . child );
        root2 . order ++ ;
     }
    
     /*************************************
     * Function for decreasing a key
     ************************************/
    
     //Removes a Node from its parent's child list and insert it in the root list
     //If the parent Node already lost a child, reshapes the heap accordingly
     private   void  cut ( int  i )   {
         Node < Key >  x  =  nodes [ i ];
         Node < Key >  parent  =  x . parent ;
        parent . child  =  cut ( x ,  parent . child );
        x . parent  =   null ;
        parent . order -- ;
        head  =  insert ( x ,  head );
        parent . mark  =   ! parent . mark ;
         if   ( ! parent . mark  &&  parent . parent  !=   null )   {
            cut ( parent . index );}
     }
    
     /*************************************
     * Function for consolidating all trees in the root list
     ************************************/
    
     //Coalesces the roots, thus reshapes the heap
     //Caching a HashMap improves greatly performances
     private   void  consolidate ()   {
        table . clear ();
         Node < Key >  x  =  head ;
         int  maxOrder  =   0 ;
        min  =  head ;
         Node < Key >  y  =   null ,  z  =   null ;
         do   {
            y  =  x ;
            x  =  x . next ;
            z  =  table . get ( y . order );
             while   ( !=   null )   {
                table . remove ( y . order );
                 if   ( greater ( y . key ,  z . key ))   {
                    link ( y ,  z );
                    y  =  z ;
                 }   else   {
                    link ( z ,  y );
                 }
                z  =  table . get ( y . order );
             }
            table . put ( y . order ,  y );
             if   ( y . order  >  maxOrder )  maxOrder  =  y . order ;
         }   while   ( !=  head );
        head  =   null ;
         for   ( Node < Key >  n  :  table . values ())   {
            min  =  greater ( min . key ,  n . key )   ?  n  :  min ;
            head  =  insert ( n ,  head );
         }
     }
    
     /*************************************
     * General helper functions for manipulating circular lists
     ************************************/
    
     //Inserts a Node in a circular list containing head, returns a new head
     private   Node < Key >  insert ( Node < Key >  x ,   Node < Key >  head )   {
         if   ( head  ==   null )   {
            x . prev  =  x ;
            x . next  =  x ;
         }   else   {
            head . prev . next  =  x ;
            x . next  =  head ;
            x . prev  =  head . prev ;
            head . prev  =  x ;
         }
         return  x ;
     }
    
     //Removes a tree from the list defined by the head pointer
     private   Node < Key >  cut ( Node < Key >  x ,   Node < Key >  head )   {
         if   ( x . next  ==  x )   {
            x . next  =   null ;
            x . prev  =   null ;
             return   null ;
         }   else   {
            x . next . prev  =  x . prev ;
            x . prev . next  =  x . next ;
             Node < Key >  res  =  x . next ;
            x . next  =   null ;
            x . prev  =   null ;
             if   ( head  ==  x )    return  res ;
             else              return  head ;
         }
     }
    
     //Merges two lists together.
     private   Node < Key >  meld ( Node < Key >  x ,   Node < Key >  y )   {
         if   ( ==   null )   return  y ;
         if   ( ==   null )   return  x ;
        x . prev . next  =  y . next ;
        y . next . prev  =  x . prev ;
        x . prev  =  y ;
        y . next  =  x ;
         return  x ;
     }
    
     /*************************************
     * Iterator
     ************************************/
    
     /**
     * Get an Iterator over the indexes in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(log(n)) (amortized)
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the indexes in the priority queue in ascending order
     */
    
     public   Iterator < Integer >  iterator ()   {
         return   new   MyIterator ();
     }
    
     private   class   MyIterator   implements   Iterator < Integer >   {
         private   IndexFibonacciMinPQ < Key >  copy ;
        
        
         //Constructor takes linear time
         public   MyIterator ()   {
            copy  =   new   IndexFibonacciMinPQ < Key > ( comp ,  n );
             for   ( Node < Key >  x  :  nodes )   {
                 if   ( !=   null )  copy . insert ( x . index ,  x . key );
             }
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
        
         public   boolean  hasNext ()   {
             return   ! copy . isEmpty ();
         }
        
         //Takes amortized logarithmic time
         public   Integer  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMin ();
         }
     }
    
     /***************************
     * Comparator
     **************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }
    
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/IndexMaxPQ.java

edu/princeton/cs/algs4/IndexMaxPQ.java

/******************************************************************************
 *  Compilation:  javac IndexMaxPQ.java
 *  Execution:    java IndexMaxPQ
 *  Dependencies: StdOut.java
 *
 *  Maximum-oriented indexed PQ implementation using a binary heap.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  IndexMaxPQ} class represents an indexed priority queue of generic keys.
 *  It supports the usual <em>insert</em> and <em>delete-the-maximum</em>
 *  operations, along with <em>delete</em> and <em>change-the-key</em> 
 *  methods. In order to let the client refer to items on the priority queue,
 *  an integer between { @code  0} and { @code  maxN - 1}
 *  is associated with each key—the client
 *  uses this integer to specify which key to delete or change.
 *  It also supports methods for peeking at a maximum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  <p>
 *  This implementation uses a <em>binary heap</em> along with an
 *  array to associate keys with integers in the given range.
 *  The <em>insert</em>, <em>delete-the-maximum</em>, <em>delete</em>,
 *  <em>change-key</em>, <em>decrease-key</em>, and <em>increase-key</em>
 *  operations take &Theta;(log <em>n</em>) time in the worst case,
 *  where <em>n</em> is the number of elements in the priority queue.
 *  Construction takes time proportional to the specified capacity.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of key on this priority queue
 */
public   class   IndexMaxPQ < Key   extends   Comparable < Key >>   implements   Iterable < Integer >   {
     private   int  maxN ;          // maximum number of elements on PQ
     private   int  n ;             // number of elements on PQ
     private   int []  pq ;          // binary heap using 1-based indexing
     private   int []  qp ;          // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
     private   Key []  keys ;        // keys[i] = priority of i

     /**
     * Initializes an empty indexed priority queue with indices between { @code  0}
     * and { @code  maxN - 1}.
     *
     *  @param   maxN the keys on this priority queue are index from { @code  0} to { @code  maxN - 1}
     *  @throws  IllegalArgumentException if { @code  maxN < 0}
     */
     public   IndexMaxPQ ( int  maxN )   {
         if   ( maxN  <   0 )   throw   new   IllegalArgumentException ();
         this . maxN  =  maxN ;
        n  =   0 ;
        keys  =   ( Key [])   new   Comparable [ maxN  +   1 ];      // make this of length maxN??
        pq    =   new   int [ maxN  +   1 ];
        qp    =   new   int [ maxN  +   1 ];                     // make this of length maxN??
         for   ( int  i  =   0 ;  i  <=  maxN ;  i ++ )
            qp [ i ]   =   - 1 ;
     }

     /**
     * Returns true if this priority queue is empty.
     *
     *  @return  { @code  true} if this priority queue is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Is { @code  i} an index on this priority queue?
     *
     *  @param   i an index
     *  @return  { @code  true} if { @code  i} is an index on this priority queue;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     */
     public   boolean  contains ( int  i )   {
        validateIndex ( i );
         return  qp [ i ]   !=   - 1 ;
     }

     /**
     * Returns the number of keys on this priority queue.
     *
     *  @return  the number of keys on this priority queue 
     */
     public   int  size ()   {
         return  n ;
     }

    /**
     * Associate key with index i.
     *
     *  @param   i an index
     *  @param   key the key to associate with index { @code  i}
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if there already is an item
     *         associated with index { @code  i}
     */
     public   void  insert ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( contains ( i ))   throw   new   IllegalArgumentException ( "index is already in the priority queue" );
        n ++ ;
        qp [ i ]   =  n ;
        pq [ n ]   =  i ;
        keys [ i ]   =  key ;
        swim ( n );
     }

     /**
     * Returns an index associated with a maximum key.
     *
     *  @return  an index associated with a maximum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   int  maxIndex ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  pq [ 1 ];
     }

     /**
     * Returns a maximum key.
     *
     *  @return  a maximum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  maxKey ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  keys [ pq [ 1 ]];
     }

     /**
     * Removes a maximum key and returns its associated index.
     *
     *  @return  an index associated with a maximum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   int  delMax ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         int  max  =  pq [ 1 ];
        exch ( 1 ,  n -- );
        sink ( 1 );

         assert  pq [ n + 1 ]   ==  max ;
        qp [ max ]   =   - 1 ;          // delete
        keys [ max ]   =   null ;      // to help with garbage collection
        pq [ n + 1 ]   =   - 1 ;          // not needed
         return  max ;
     }

     /**
     * Returns the key associated with index { @code  i}.
     *
     *  @param   i the index of the key to return
     *  @return  the key associated with index { @code  i}
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   Key  keyOf ( int  i )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         else   return  keys [ i ];
     }

     /**
     * Change the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to change
     *  @param   key change the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     */
     public   void  changeKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
        keys [ i ]   =  key ;
        swim ( qp [ i ]);
        sink ( qp [ i ]);
     }

    /**
     * Change the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to change
     *  @param   key change the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @deprecated  Replaced by { @code  changeKey(int, Key)}.
     */
    @ Deprecated
     public   void  change ( int  i ,   Key  key )   {
        validateIndex ( i );
        changeKey ( i ,  key );
     }

     /**
     * Increase the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to increase
     *  @param   key increase the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if { @code  key <= keyOf(i)}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  increaseKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   ==   0 )
             throw   new   IllegalArgumentException ( "Calling increaseKey() with a key equal to the key in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   >   0 )
             throw   new   IllegalArgumentException ( "Calling increaseKey() with a key that is strictly less than the key in the priority queue" );

        keys [ i ]   =  key ;
        swim ( qp [ i ]);
     }

     /**
     * Decrease the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to decrease
     *  @param   key decrease the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if { @code  key >= keyOf(i)}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  decreaseKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   ==   0 )
             throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key equal to the key in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   <   0 )
             throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key that is strictly greater than the key in the priority queue" );
        keys [ i ]   =  key ;
        sink ( qp [ i ]);
     }

     /**
     * Remove the key on the priority queue associated with index { @code  i}.
     *
     *  @param   i the index of the key to remove
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  delete ( int  i )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         int  index  =  qp [ i ];
        exch ( index ,  n -- );
        swim ( index );
        sink ( index );
        keys [ i ]   =   null ;
        qp [ i ]   =   - 1 ;
     }

     // throw an IllegalArgumentException if i is an invalid index
     private   void  validateIndex ( int  i )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "index is negative: "   +  i );
         if   ( >=  maxN )   throw   new   IllegalArgumentException ( "index >= capacity: "   +  i );
     }

    /***************************************************************************
    * General helper functions.
    ***************************************************************************/
     private   boolean  less ( int  i ,   int  j )   {
         return  keys [ pq [ i ]]. compareTo ( keys [ pq [ j ]])   <   0 ;
     }

     private   void  exch ( int  i ,   int  j )   {
         int  swap  =  pq [ i ];
        pq [ i ]   =  pq [ j ];
        pq [ j ]   =  swap ;
        qp [ pq [ i ]]   =  i ;
        qp [ pq [ j ]]   =  j ;
     }


    /***************************************************************************
    * Heap helper functions.
    ***************************************************************************/
     private   void  swim ( int  k )   {
         while   ( >   1   &&  less ( k / 2 ,  k ))   {
            exch ( k ,  k / 2 );
            k  =  k / 2 ;
         }
     }

     private   void  sink ( int  k )   {
         while   ( 2 * <=  n )   {
             int  j  =   2 * k ;
             if   ( <  n  &&  less ( j ,  j + 1 ))  j ++ ;
             if   ( ! less ( k ,  j ))   break ;
            exch ( k ,  j );
            k  =  j ;
         }
     }


     /**
     * Returns an iterator that iterates over the keys on the
     * priority queue in descending order.
     * The iterator doesn't implement { @code  remove()} since it's optional.
     *
     *  @return  an iterator that iterates over the keys in descending order
     */
     public   Iterator < Integer >  iterator ()   {
         return   new   HeapIterator ();
     }

     private   class   HeapIterator   implements   Iterator < Integer >   {
         // create a new pq
         private   IndexMaxPQ < Key >  copy ;

         // add all elements to copy of heap
         // takes linear time since already in heap order so no keys move
         public   HeapIterator ()   {
            copy  =   new   IndexMaxPQ < Key > ( pq . length  -   1 );
             for   ( int  i  =   1 ;  i  <=  n ;  i ++ )
                copy . insert ( pq [ i ],  keys [ pq [ i ]]);
         }

         public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Integer  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMax ();
         }
     }

     /**
     * Unit tests the { @code  IndexMaxPQ} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         // insert a bunch of strings
         String []  strings  =   {   "it" ,   "was" ,   "the" ,   "best" ,   "of" ,   "times" ,   "it" ,   "was" ,   "the" ,   "worst"   };

         IndexMaxPQ < String >  pq  =   new   IndexMaxPQ < String > ( strings . length );
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {
            pq . insert ( i ,  strings [ i ]);
         }

         // print each key using the iterator
         for   ( int  i  :  pq )   {
             StdOut . println ( +   " "   +  strings [ i ]);
         }

         StdOut . println ();

         // increase or decrease the key
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {
             if   ( StdRandom . uniform ()   <   0.5 )
                pq . increaseKey ( i ,  strings [ i ]   +  strings [ i ]);
             else
                pq . decreaseKey ( i ,  strings [ i ]. substring ( 0 ,   1 ));
         }

         // delete and print each key
         while   ( ! pq . isEmpty ())   {
             String  key  =  pq . maxKey ();
             int  i  =  pq . delMax ();
             StdOut . println ( +   " "   +  key );
         }
         StdOut . println ();

         // reinsert the same strings
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {
            pq . insert ( i ,  strings [ i ]);
         }

         // delete them in random order
         int []  perm  =   new   int [ strings . length ];
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )
            perm [ i ]   =  i ;
         StdRandom . shuffle ( perm );
         for   ( int  i  =   0 ;  i  <  perm . length ;  i ++ )   {
             String  key  =  pq . keyOf ( perm [ i ]);
            pq . delete ( perm [ i ]);
             StdOut . println ( perm [ i ]   +   " "   +  key );
         }

     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/IndexMinPQ.java

edu/princeton/cs/algs4/IndexMinPQ.java

/******************************************************************************
 *  Compilation:  javac IndexMinPQ.java
 *  Execution:    java IndexMinPQ
 *  Dependencies: StdOut.java
 *
 *  Minimum-oriented indexed PQ implementation using a binary heap.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  IndexMinPQ} class represents an indexed priority queue of generic keys.
 *  It supports the usual <em>insert</em> and <em>delete-the-minimum</em>
 *  operations, along with <em>delete</em> and <em>change-the-key</em> 
 *  methods. In order to let the client refer to keys on the priority queue,
 *  an integer between { @code  0} and { @code  maxN - 1}
 *  is associated with each key—the client uses this integer to specify
 *  which key to delete or change.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  <p>
 *  This implementation uses a binary heap along with an array to associate
 *  keys with integers in the given range.
 *  The <em>insert</em>, <em>delete-the-minimum</em>, <em>delete</em>,
 *  <em>change-key</em>, <em>decrease-key</em>, and <em>increase-key</em>
 *  operations take &Theta;(log <em>n</em>) time in the worst case,
 *  where <em>n</em> is the number of elements in the priority queue.
 *  Construction takes time proportional to the specified capacity.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of key on this priority queue
 */
public   class   IndexMinPQ < Key   extends   Comparable < Key >>   implements   Iterable < Integer >   {
     private   int  maxN ;          // maximum number of elements on PQ
     private   int  n ;             // number of elements on PQ
     private   int []  pq ;          // binary heap using 1-based indexing
     private   int []  qp ;          // inverse of pq - qp[pq[i]] = pq[qp[i]] = i
     private   Key []  keys ;        // keys[i] = priority of i

     /**
     * Initializes an empty indexed priority queue with indices between { @code  0}
     * and { @code  maxN - 1}.
     *  @param   maxN the keys on this priority queue are index from { @code  0}
     *         { @code  maxN - 1}
     *  @throws  IllegalArgumentException if { @code  maxN < 0}
     */
     public   IndexMinPQ ( int  maxN )   {
         if   ( maxN  <   0 )   throw   new   IllegalArgumentException ();
         this . maxN  =  maxN ;
        n  =   0 ;
        keys  =   ( Key [])   new   Comparable [ maxN  +   1 ];      // make this of length maxN??
        pq    =   new   int [ maxN  +   1 ];
        qp    =   new   int [ maxN  +   1 ];                     // make this of length maxN??
         for   ( int  i  =   0 ;  i  <=  maxN ;  i ++ )
            qp [ i ]   =   - 1 ;
     }

     /**
     * Returns true if this priority queue is empty.
     *
     *  @return  { @code  true} if this priority queue is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Is { @code  i} an index on this priority queue?
     *
     *  @param   i an index
     *  @return  { @code  true} if { @code  i} is an index on this priority queue;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     */
     public   boolean  contains ( int  i )   {
        validateIndex ( i );
         return  qp [ i ]   !=   - 1 ;
     }

     /**
     * Returns the number of keys on this priority queue.
     *
     *  @return  the number of keys on this priority queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Associates key with index { @code  i}.
     *
     *  @param   i an index
     *  @param   key the key to associate with index { @code  i}
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if there already is an item associated
     *         with index { @code  i}
     */
     public   void  insert ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( contains ( i ))   throw   new   IllegalArgumentException ( "index is already in the priority queue" );
        n ++ ;
        qp [ i ]   =  n ;
        pq [ n ]   =  i ;
        keys [ i ]   =  key ;
        swim ( n );
     }

     /**
     * Returns an index associated with a minimum key.
     *
     *  @return  an index associated with a minimum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   int  minIndex ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  pq [ 1 ];
     }

     /**
     * Returns a minimum key.
     *
     *  @return  a minimum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  minKey ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  keys [ pq [ 1 ]];
     }

     /**
     * Removes a minimum key and returns its associated index.
     *  @return  an index associated with a minimum key
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   int  delMin ()   {
         if   ( ==   0 )   throw   new   NoSuchElementException ( "Priority queue underflow" );
         int  min  =  pq [ 1 ];
        exch ( 1 ,  n -- );
        sink ( 1 );
         assert  min  ==  pq [ n + 1 ];
        qp [ min ]   =   - 1 ;          // delete
        keys [ min ]   =   null ;      // to help with garbage collection
        pq [ n + 1 ]   =   - 1 ;          // not needed
         return  min ;
     }

     /**
     * Returns the key associated with index { @code  i}.
     *
     *  @param   i the index of the key to return
     *  @return  the key associated with index { @code  i}
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   Key  keyOf ( int  i )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         else   return  keys [ i ];
     }

     /**
     * Change the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to change
     *  @param   key change the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  changeKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
        keys [ i ]   =  key ;
        swim ( qp [ i ]);
        sink ( qp [ i ]);
     }

     /**
     * Change the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to change
     *  @param   key change the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @deprecated  Replaced by { @code  changeKey(int, Key)}.
     */
    @ Deprecated
     public   void  change ( int  i ,   Key  key )   {
        changeKey ( i ,  key );
     }

     /**
     * Decrease the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to decrease
     *  @param   key decrease the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if { @code  key >= keyOf(i)}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  decreaseKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   ==   0 )
             throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key equal to the key in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   <   0 )
             throw   new   IllegalArgumentException ( "Calling decreaseKey() with a key strictly greater than the key in the priority queue" );
        keys [ i ]   =  key ;
        swim ( qp [ i ]);
     }

     /**
     * Increase the key associated with index { @code  i} to the specified value.
     *
     *  @param   i the index of the key to increase
     *  @param   key increase the key associated with index { @code  i} to this key
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  IllegalArgumentException if { @code  key <= keyOf(i)}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  increaseKey ( int  i ,   Key  key )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   ==   0 )
             throw   new   IllegalArgumentException ( "Calling increaseKey() with a key equal to the key in the priority queue" );
         if   ( keys [ i ]. compareTo ( key )   >   0 )
             throw   new   IllegalArgumentException ( "Calling increaseKey() with a key strictly less than the key in the priority queue" );
        keys [ i ]   =  key ;
        sink ( qp [ i ]);
     }

     /**
     * Remove the key associated with index { @code  i}.
     *
     *  @param   i the index of the key to remove
     *  @throws  IllegalArgumentException unless { @code  0 <= i < maxN}
     *  @throws  NoSuchElementException no key is associated with index { @code  i}
     */
     public   void  delete ( int  i )   {
        validateIndex ( i );
         if   ( ! contains ( i ))   throw   new   NoSuchElementException ( "index is not in the priority queue" );
         int  index  =  qp [ i ];
        exch ( index ,  n -- );
        swim ( index );
        sink ( index );
        keys [ i ]   =   null ;
        qp [ i ]   =   - 1 ;
     }

     // throw an IllegalArgumentException if i is an invalid index
     private   void  validateIndex ( int  i )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "index is negative: "   +  i );
         if   ( >=  maxN )   throw   new   IllegalArgumentException ( "index >= capacity: "   +  i );
     }

    /***************************************************************************
    * General helper functions.
    ***************************************************************************/
     private   boolean  greater ( int  i ,   int  j )   {
         return  keys [ pq [ i ]]. compareTo ( keys [ pq [ j ]])   >   0 ;
     }

     private   void  exch ( int  i ,   int  j )   {
         int  swap  =  pq [ i ];
        pq [ i ]   =  pq [ j ];
        pq [ j ]   =  swap ;
        qp [ pq [ i ]]   =  i ;
        qp [ pq [ j ]]   =  j ;
     }


    /***************************************************************************
    * Heap helper functions.
    ***************************************************************************/
     private   void  swim ( int  k )   {
         while   ( >   1   &&  greater ( k / 2 ,  k ))   {
            exch ( k ,  k / 2 );
            k  =  k / 2 ;
         }
     }

     private   void  sink ( int  k )   {
         while   ( 2 * <=  n )   {
             int  j  =   2 * k ;
             if   ( <  n  &&  greater ( j ,  j + 1 ))  j ++ ;
             if   ( ! greater ( k ,  j ))   break ;
            exch ( k ,  j );
            k  =  j ;
         }
     }


    /***************************************************************************
    * Iterators.
    ***************************************************************************/

     /**
     * Returns an iterator that iterates over the keys on the
     * priority queue in ascending order.
     * The iterator doesn't implement { @code  remove()} since it's optional.
     *
     *  @return  an iterator that iterates over the keys in ascending order
     */
     public   Iterator < Integer >  iterator ()   {   return   new   HeapIterator ();   }

     private   class   HeapIterator   implements   Iterator < Integer >   {
         // create a new pq
         private   IndexMinPQ < Key >  copy ;

         // add all elements to copy of heap
         // takes linear time since already in heap order so no keys move
         public   HeapIterator ()   {
            copy  =   new   IndexMinPQ < Key > ( pq . length  -   1 );
             for   ( int  i  =   1 ;  i  <=  n ;  i ++ )
                copy . insert ( pq [ i ],  keys [ pq [ i ]]);
         }

         public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Integer  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMin ();
         }
     }


     /**
     * Unit tests the { @code  IndexMinPQ} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         // insert a bunch of strings
         String []  strings  =   {   "it" ,   "was" ,   "the" ,   "best" ,   "of" ,   "times" ,   "it" ,   "was" ,   "the" ,   "worst"   };

         IndexMinPQ < String >  pq  =   new   IndexMinPQ < String > ( strings . length );
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {
            pq . insert ( i ,  strings [ i ]);
         }

         // delete and print each key
         while   ( ! pq . isEmpty ())   {
             int  i  =  pq . delMin ();
             StdOut . println ( +   " "   +  strings [ i ]);
         }
         StdOut . println ();

         // reinsert the same strings
         for   ( int  i  =   0 ;  i  <  strings . length ;  i ++ )   {
            pq . insert ( i ,  strings [ i ]);
         }

         // print each key using the iterator
         for   ( int  i  :  pq )   {
             StdOut . println ( +   " "   +  strings [ i ]);
         }
         while   ( ! pq . isEmpty ())   {
            pq . delMin ();
         }

     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/IndexMultiwayMinPQ.java

edu/princeton/cs/algs4/IndexMultiwayMinPQ.java

/******************************************************************************
 *  Compilation: javac IndexMultiwayMinPQ.java
 *  Execution:
 *
 *  An inde  multiway heap.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;
import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The IndexMultiwayMinPQ class represents an indexed priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations,
 *  along with delete and change-the-key methods. 
 *  In order to let the client refer to keys on the priority queue,
 *  an integer between 0 and N-1 is associated with each key ; the client
 *  uses this integer to specify which key to delete or change.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  
 *  This implementation uses a multiway heap along with an array to associate
 *  keys with integers in the given range.
 *  For simplified notations, logarithm in base d will be referred as log-d
 *  The delete-the-minimum, delete, change-key and increase-key operations
 *  take time proportional to d*log-d(n)
 *  The insert and decrease-key take time proportional to log-d(n)
 *  The is-empty, min-index, min-key, size, contains and key-of operations take constant time.
 *  Construction takes time proportional to the specified capacity.
 *  
 *  The arrays used in this structure have the first d indices empty,
 *  it apparently helps with caching effects.
 *
 *   @author  Tristan Claverie
 */
public   class   IndexMultiwayMinPQ < Key >   implements   Iterable < Integer >   {
     private   final   int  d ;                  //Dimension of the heap
     private   int  n ;                        //Number of keys currently in the queue
     private   int  nmax ;                     //Maximum number of items in the queue
     private   int []  pq ;                     //Multiway heap
     private   int []  qp ;                     //Inverse of pq : qp[pq[i]] = pq[qp[i]] = i
     private   Key []  keys ;                   //keys[i] = priority of i
     private   final   Comparator < Key >  comp ;   //Comparator over the keys
    
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} to { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @param  D dimension of the heap
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     *  @throws  java.lang.IllegalArgumentException if { @code  D < 2}
     */
     public   IndexMultiwayMinPQ ( int  N ,   int  D )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Maximum number of elements cannot be negative" );
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  D ;
        nmax  =  N ;
        pq  =   new   int [ nmax + D ];
        qp  =   new   int [ nmax + D ];
        keys  =   ( Key [])   new   Comparable [ nmax + D ];
         for   ( int  i  =   0 ;  i  <  nmax + D ;  qp [ i ++ ]   =   - 1 );
        comp  =   new   MyComparator ();
     }
    
     /**
     * Initializes an empty indexed priority queue with indices between { @code  0} to { @code  N-1}
     * Worst case is O(n)
     *  @param  N number of keys in the priority queue, index from { @code  0} to { @code  N-1}
     *  @param  D dimension of the heap
     *  @param  C a Comparator over the keys
     *  @throws  java.lang.IllegalArgumentException if { @code  N < 0}
     *  @throws  java.lang.IllegalArgumentException if { @code  D < 2}
     */
     public   IndexMultiwayMinPQ ( int  N ,   Comparator < Key >  C ,   int  D )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "Maximum number of elements cannot be negative" );
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  D ;
        nmax  =  N ;
        pq  =   new   int [ nmax + D ];
        qp  =   new   int [ nmax + D ];
        keys  =   ( Key [])   new   Comparable [ nmax + D ];
         for   ( int  i  =   0 ;  i  <  nmax + D ;  qp [ i ++ ]   =   - 1 );
        comp  =  C ;
     }

     /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Does the priority queue contains the index i ?
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @return  true if i is on the priority queue, false if not
     */
     public   boolean  contains ( int  i )   {
         if   ( <   0   || >=  nmax )   throw   new   IllegalArgumentException ();
         return  qp [ i + d ]   !=   - 1 ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(1)
     *  @return  the number of elements on the priority queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Associates a key with an index
     * Worst case is O(log-d(n))
     *  @param  i an index
     *  @param  key a Key associated with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index is already in the queue
     */
     public   void  insert ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  nmax )   throw   new   IllegalArgumentException ();
         if   ( contains ( i ))   throw   new   IllegalArgumentException ( "Index already there" );
        keys [ i + d ]   =  key ;
        pq [ n + d ]   =  i ;
        qp [ i + d ]   =  n ;
        swim ( n ++ );
     }

     /**
     * Gets the index associated with the minimum key
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
     public   int  minIndex ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  pq [ d ];
     }

     /**
     * Gets the minimum key currently in the queue
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  keys [ pq [ d ] + d ];
     }

     /**
     * Deletes the minimum key
     * Worst case is O(d*log-d(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the index associated with the minimum key
     */
     public   int  delMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         int  min  =  pq [ d ];
        exch ( 0 ,   -- n );
        sink ( 0 );
        qp [ min + d ]   =   - 1 ;
        keys [ pq [ n + d ] + d ]   =   null ;
        pq [ n + d ]   =   - 1 ;
         return  min ;
     }

     /**
     * Gets the key associated with index i
     * Worst case is O(1)
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index is not in the queue
     *  @return  the key associated with index i
     */
     public   Key  keyOf ( int  i )   {
         if   ( <   0   ||  i  >=  nmax )   throw   new   IllegalArgumentException ();
         if   ( !  contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         return  keys [ i + d ];
     }

     /**
     * Changes the key associated with index i to the given key
     * If the given key is greater, Worst case is O(d*log-d(n))
     * If the given key is lower,   Worst case is O(log-d(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.lang.IllegalArgumentException if the index has no key associated with
     */
     public   void  changeKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >=  nmax )   throw   new   IllegalArgumentException ();
         if   ( !  contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         Key  tmp  =  keys [ i + d ];
        keys [ i + d ]   =  key ;
         if   ( comp . compare ( key ,  tmp )   <=   0 )   {  swim ( qp [ i + d ]);}
         else                               {  sink ( qp [ i + d ]);}
     }

     /**
     * Decreases the key associated with index i to the given key
     * Worst case is O(log-d(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is greater than the current key
     */
     public   void  decreaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >= nmax )   throw   new   IllegalArgumentException ();
         if   ( !  contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( comp . compare ( keys [ i + d ],  key )   <=   0 )   throw   new   IllegalArgumentException ( "Calling with this argument would not decrease the Key" );
        keys [ i + d ]   =  key ;
        swim ( qp [ i + d ]);
     }

     /**
     * Increases the key associated with index i to the given key
     * Worst case is O(d*log-d(n))
     *  @param  i an index
     *  @param  key the key to associate with i
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the index has no key associated with
     *  @throws  java.lang.IllegalArgumentException if the given key is lower than the current key
     */
     public   void  increaseKey ( int  i ,   Key  key )   {
         if   ( <   0   ||  i  >= nmax )   throw   new   IllegalArgumentException ();
         if   ( !  contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         if   ( comp . compare ( keys [ i + d ],  key )   >=   0 )   throw   new   IllegalArgumentException ( "Calling with this argument would not increase the Key" );
        keys [ i + d ]   =  key ;
        sink ( qp [ i + d ]);
     }

     /**
     * Deletes the key associated to the given index
     * Worst case is O(d*log-d(n))
     *  @param  i an index
     *  @throws  java.lang.IllegalArgumentException if the specified index is invalid
     *  @throws  java.util.NoSuchElementException if the given index has no key associated with
     */
     public   void  delete ( int  i )   {
         if   ( <   0   ||  i  >=  nmax )   throw   new   IllegalArgumentException ();
         if   ( !  contains ( i ))   throw   new   NoSuchElementException ( "Specified index is not in the queue" );
         int  idx  =  qp [ i + d ];
        exch ( idx ,   -- n );
        swim ( idx );
        sink ( idx );
        keys [ i + d ]   =   null ;
        qp [ i + d ]   =   - 1 ;
     }
    
     /***************************
     * General helper functions
     **************************/
    
     //Compares two keys
     private   boolean  greater ( int  i ,   int  j )   {
         return  comp . compare ( keys [ pq [ i + d ] + d ],  keys [ pq [ j + d ] + d ])   >   0 ;
     }
    
     //Exchanges two keys
     private   void  exch ( int  x ,   int  y )   {
         int  i  =  x + d ,  j  =  y + d ;
         int  swap  =  pq [ i ];
        pq [ i ]   =  pq [ j ];
        pq [ j ]   =  swap ;
        qp [ pq [ i ] + d ]   =  x ;
        qp [ pq [ j ] + d ]   =  y ;
     }
    
     /***************************
     * Functions for moving upward or downward
     **************************/
    
     //Moves upward
     private   void  swim ( int  i )   {
         if   ( >   0   &&  greater (( i - 1 ) / d ,  i ))   {
            exch ( i ,   ( i - 1 ) / d );
            swim (( i - 1 ) / d );
         }
     }
    
     //Moves downward
     private   void  sink ( int  i )   {
         if   ( d * i + 1   >=  n )   return ;
         int  min  =  minChild ( i );
         while   ( min  <  n  &&  greater ( i ,  min ))   {
            exch ( i ,  min );
            i  =  min ;
            min  =  minChild ( i );
         }
     }
    
     /***************************
     * Deletes the minimum child
     **************************/
    
     //Return the minimum child of i
     private   int  minChild ( int  i )   {
         int  loBound  =  d * i + 1 ,  hiBound  =  d * i + d ;
         int  min  =  loBound ;
         for   ( int  cur  =  loBound ;  cur  <=  hiBound ;  cur ++ )   {
             if   ( cur  <  n  &&  greater ( min ,  cur ))  min  =  cur ;
         }
         return  min ;
     }
    
     /***************************
     * Iterator
     **************************/
    
     /**
     * Gets an Iterator over the indexes in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(d*log-d(n))
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the indexes in the priority queue in ascending order
     */
    
     public   Iterator < Integer >  iterator ()   {
         return   new   MyIterator ();
     }
    
     //Constructs an Iterator over the indices in linear time
     private   class   MyIterator   implements   Iterator < Integer >   {
         IndexMultiwayMinPQ < Key >  clone ;
        
         public   MyIterator ()   {
            clone  =   new   IndexMultiwayMinPQ < Key > ( nmax ,  comp ,  d );
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                clone . insert ( pq [ i + d ],  keys [ pq [ i + d ] + d ]);
             }
         }

         public   boolean  hasNext ()   {
             return   ! clone . isEmpty ();
         }
        
         public   Integer  next ()   {
                         if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  clone . delMin ();
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
     }
    
     /***************************
     * Comparator
     **************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/In.java

edu/princeton/cs/algs4/In.java

/******************************************************************************
 *  Compilation:  javac In.java
 *  Execution:    java In   (basic test --- see source for required files)
 *  Dependencies: none
 *
 *  Reads in data of various types from standard input, files, and URLs.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . BufferedInputStream ;
import  java . io . File ;
import  java . io . FileInputStream ;
import  java . io . IOException ;
import  java . io . InputStream ;
import  java . net . URL ;
import  java . net . Socket ;
// import java.net.HttpURLConnection;
import  java . net . URLConnection ;
import  java . util . ArrayList ;
import  java . util . InputMismatchException ;
import  java . util . Locale ;
import  java . util . NoSuchElementException ;
import  java . util . Scanner ;
import  java . util . regex . Pattern ;

/**
 *  <i>Input</i>. This class provides methods for reading strings
 *  and numbers from standard input, file input, URLs, and sockets. 
 *  <p>
 *  The Locale used is: language = English, country = US. This is consistent
 *  with the formatting conventions with Java floating-point literals,
 *  command-line arguments (via { @link  Double#parseDouble(String)})
 *  and standard output. 
 *  <p>
 *  For additional documentation, see 
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i> 
 *  by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  Like { @link  Scanner}, reading a token also consumes preceding Java
 *  whitespace, reading a full line consumes
 *  the following end-of-line delimeter, while reading a character consumes
 *  nothing extra. 
 *  <p>
 *  Whitespace is defined in { @link  Character#isWhitespace(char)}. Newlines
 *  consist of \n, \r, \r\n, and Unicode hex code points 0x2028, 0x2029, 0x0085;
 *  see <a href="http://www.docjar.com/html/api/java/util/Scanner.java.html">
 *  Scanner.java</a> (NB: Java 6u23 and earlier uses only \r, \r, \r\n).
 *
 *   @author  David Pritchard
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   In   {
    
     ///// begin: section (1 of 2) of code duplicated from In to StdIn.
    
     // assume Unicode UTF-8 encoding
     private   static   final   String  CHARSET_NAME  =   "UTF-8" ;

     // assume language = English, country = US for consistency with System.out.
     private   static   final   Locale  LOCALE  =   Locale . US ;

     // the default token separator; we maintain the invariant that this value 
     // is held by the scanner's delimiter between calls
     private   static   final   Pattern  WHITESPACE_PATTERN  =   Pattern . compile ( "\\p{javaWhitespace}+" );

     // makes whitespace characters significant 
     private   static   final   Pattern  EMPTY_PATTERN  =   Pattern . compile ( "" );

     // used to read the entire input. source:
     // http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
     private   static   final   Pattern  EVERYTHING_PATTERN  =   Pattern . compile ( "\\A" );

     //// end: section (1 of 2) of code duplicated from In to StdIn.

     private   Scanner  scanner ;

    /**
     * Initializes an input stream from standard input.
     */
     public   In ()   {
        scanner  =   new   Scanner ( new   BufferedInputStream ( System . in ),  CHARSET_NAME );
        scanner . useLocale ( LOCALE );
     }

    /**
     * Initializes an input stream from a socket.
     *
     *  @param   socket the socket
     *  @throws  IllegalArgumentException if cannot open { @code  socket}
     *  @throws  IllegalArgumentException if { @code  socket} is { @code  null}
     */
     public   In ( Socket  socket )   {
         if   ( socket  ==   null )   throw   new   IllegalArgumentException ( "socket argument is null" );
         try   {
             InputStream  is  =  socket . getInputStream ();
            scanner  =   new   Scanner ( new   BufferedInputStream ( is ),  CHARSET_NAME );
            scanner . useLocale ( LOCALE );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "Could not open "   +  socket ,  ioe );
         }
     }

    /**
     * Initializes an input stream from a URL.
     *
     *  @param   url the URL
     *  @throws  IllegalArgumentException if cannot open { @code  url}
     *  @throws  IllegalArgumentException if { @code  url} is { @code  null}
     */
     public   In ( URL url )   {
         if   ( url  ==   null )   throw   new   IllegalArgumentException ( "url argument is null" );
         try   {
             URLConnection  site  =  url . openConnection ();
             InputStream  is      =  site . getInputStream ();
            scanner             =   new   Scanner ( new   BufferedInputStream ( is ),  CHARSET_NAME );
            scanner . useLocale ( LOCALE );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "Could not open "   +  url ,  ioe );
         }
     }

    /**
     * Initializes an input stream from a file.
     *
     *  @param   file the file
     *  @throws  IllegalArgumentException if cannot open { @code  file}
     *  @throws  IllegalArgumentException if { @code  file} is { @code  null}
     */
     public   In ( File  file )   {
         if   ( file  ==   null )   throw   new   IllegalArgumentException ( "file argument is null" );
         try   {
             // for consistency with StdIn, wrap with BufferedInputStream instead of use
             // file as argument to Scanner
             FileInputStream  fis  =   new   FileInputStream ( file );
            scanner  =   new   Scanner ( new   BufferedInputStream ( fis ),  CHARSET_NAME );
            scanner . useLocale ( LOCALE );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "Could not open "   +  file ,  ioe );
         }
     }


    /**
     * Initializes an input stream from a filename or web page name.
     *
     *  @param   name the filename or web page name
     *  @throws  IllegalArgumentException if cannot open { @code  name} as
     *         a file or URL
     *  @throws  IllegalArgumentException if { @code  name} is { @code  null}
     */
     public   In ( String  name )   {
         if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument is null" );
         try   {
             // first try to read file from local file system
             File  file  =   new   File ( name );
             if   ( file . exists ())   {
                 // for consistency with StdIn, wrap with BufferedInputStream instead of use
                 // file as argument to Scanner
                 FileInputStream  fis  =   new   FileInputStream ( file );
                scanner  =   new   Scanner ( new   BufferedInputStream ( fis ),  CHARSET_NAME );
                scanner . useLocale ( LOCALE );
                 return ;
             }

             // resource relative to .class file
            URL url  =  getClass (). getResource ( name );

             // resource relative to classloader root
             if   ( url  ==   null )   {
                url  =  getClass (). getClassLoader (). getResource ( name );
             }

             // or URL from web
             if   ( url  ==   null )   {
                url  =   new  URL ( name );
             }

             URLConnection  site  =  url . openConnection ();

             // in order to set User-Agent, replace above line with these two
             // HttpURLConnection site = (HttpURLConnection) url.openConnection();
             // site.addRequestProperty("User-Agent", "Mozilla/4.76");

             InputStream  is      =  site . getInputStream ();
            scanner             =   new   Scanner ( new   BufferedInputStream ( is ),  CHARSET_NAME );
            scanner . useLocale ( LOCALE );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "Could not open "   +  name ,  ioe );
         }
     }

     /**
     * Initializes an input stream from a given { @link  Scanner} source; use with 
     * { @code  new Scanner(String)} to read from a string.
     * <p>
     * Note that this does not create a defensive copy, so the
     * scanner will be mutated as you read on. 
     *
     *  @param   scanner the scanner
     *  @throws  IllegalArgumentException if { @code  scanner} is { @code  null}
     */
     public   In ( Scanner  scanner )   {
         if   ( scanner  ==   null )   throw   new   IllegalArgumentException ( "scanner argument is null" );
         this . scanner  =  scanner ;
     }

     /**
     * Returns true if this input stream exists.
     *
     *  @return  { @code  true} if this input stream exists; { @code  false} otherwise
     */
     public   boolean  exists ()    {
         return  scanner  !=   null ;
     }
    
     ////  begin: section (2 of 2) of code duplicated from In to StdIn,
     ////  with all methods changed from "public" to "public static".

    /**
     * Returns true if input stream is empty (except possibly whitespace).
     * Use this to know whether the next call to { @link  #readString()}, 
     * { @link  #readDouble()}, etc will succeed.
     *
     *  @return  { @code  true} if this input stream is empty (except possibly whitespace);
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return   ! scanner . hasNext ();
     }

    /** 
     * Returns true if this input stream has a next line.
     * Use this method to know whether the
     * next call to { @link  #readLine()} will succeed.
     * This method is functionally equivalent to { @link  #hasNextChar()}.
     *
     *  @return  { @code  true} if this input stream has more input (including whitespace);
     *         { @code  false} otherwise
     */
     public   boolean  hasNextLine ()   {
         return  scanner . hasNextLine ();
     }

     /**
     * Returns true if this input stream has more input (including whitespace).
     * Use this method to know whether the next call to { @link  #readChar()} will succeed.
     * This method is functionally equivalent to { @link  #hasNextLine()}.
     * 
     *  @return  { @code  true} if this input stream has more input (including whitespace);
     *         { @code  false} otherwise   
     */
     public   boolean  hasNextChar ()   {
        scanner . useDelimiter ( EMPTY_PATTERN );
         boolean  result  =  scanner . hasNext ();
        scanner . useDelimiter ( WHITESPACE_PATTERN );
         return  result ;
     }


    /**
     * Reads and returns the next line in this input stream.
     *
     *  @return  the next line in this input stream; { @code  null} if no such line
     */
     public   String  readLine ()   {
         String  line ;
         try   {
            line  =  scanner . nextLine ();
         }
         catch   ( NoSuchElementException  e )   {
            line  =   null ;
         }
         return  line ;
     }

     /**
     * Reads and returns the next character in this input stream.
     *
     *  @return  the next { @code  char} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     */
     public   char  readChar ()   {
        scanner . useDelimiter ( EMPTY_PATTERN );
         try   {
             String  ch  =  scanner . next ();
             assert  ch . length ()   ==   1   :   "Internal (Std)In.readChar() error!"
                 +   " Please contact the authors." ;
            scanner . useDelimiter ( WHITESPACE_PATTERN );
             return  ch . charAt ( 0 );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'char' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }   


    /**
     * Reads and returns the remainder of this input stream, as a string.
     *
     *  @return  the remainder of this input stream, as a string
     */
     public   String  readAll ()   {
         if   ( ! scanner . hasNextLine ())
             return   "" ;

         String  result  =  scanner . useDelimiter ( EVERYTHING_PATTERN ). next ();
         // not that important to reset delimeter, since now scanner is empty
        scanner . useDelimiter ( WHITESPACE_PATTERN );   // but let's do it anyway
         return  result ;
     }


    /**
     * Reads the next token from this input stream and returns it as a { @code  String}.
     *
     *  @return  the next { @code  String} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     */
     public   String  readString ()   {
         try   {
             return  scanner . next ();
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'String' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  int},
     * and returns the { @code  int}.
     *
     *  @return  the next { @code  int} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as an { @code  int}
     */
     public   int  readInt ()   {
         try   {
             return  scanner . nextInt ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read an 'int' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read an 'int' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  double},
     * and returns the { @code  double}.
     *
     *  @return  the next { @code  double} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  double}
     */
     public   double  readDouble ()   {
         try   {
             return  scanner . nextDouble ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'double' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read a 'double' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  float},
     * and returns the { @code  float}.
     *
     *  @return  the next { @code  float} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  float}
     */
     public   float  readFloat ()   {
         try   {
             return  scanner . nextFloat ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'float' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read a 'float' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  long},
     * and returns the { @code  long}.
     *
     *  @return  the next { @code  long} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  long}
     */
     public   long  readLong ()   {
         try   {
             return  scanner . nextLong ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'long' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read a 'long' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  short},
     * and returns the { @code  short}.
     *
     *  @return  the next { @code  short} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  short}
     */
     public   short  readShort ()   {
         try   {
             return  scanner . nextShort ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'short' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read a 'short' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from this input stream, parses it as a { @code  byte},
     * and returns the { @code  byte}.
     * <p>
     * To read binary data, use { @link  BinaryIn}.
     *
     *  @return  the next { @code  byte} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  byte}
     */
     public   byte  readByte ()   {
         try   {
             return  scanner . nextByte ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'byte' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read a 'byte' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

     /**
     * Reads the next token from this input stream, parses it as a { @code  boolean}
     * (interpreting either { @code  "true"} or { @code  "1"} as { @code  true},
     * and either { @code  "false"} or { @code  "0"} as { @code  false}).
     *
     *  @return  the next { @code  boolean} in this input stream
     *  @throws  NoSuchElementException if the input stream is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  boolean}
     */
     public   boolean  readBoolean ()   {
         try   {
             String  token  =  readString ();
             if   ( "true" . equalsIgnoreCase ( token ))    return   true ;
             if   ( "false" . equalsIgnoreCase ( token ))   return   false ;
             if   ( "1" . equals ( token ))                 return   true ;
             if   ( "0" . equals ( token ))                 return   false ;
             throw   new   InputMismatchException ( "attempts to read a 'boolean' value from the input stream, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'boolean' value from the input stream, "
                                            +   "but no more tokens are available" );
         }
     }

     /**
     * Reads all remaining tokens from this input stream and returns them as
     * an array of strings.
     *
     *  @return  all remaining tokens in this input stream, as an array of strings
     */
     public   String []  readAllStrings ()   {
         // we could use readAll.trim().split(), but that's not consistent
         // since trim() uses characters 0x00..0x20 as whitespace
         String []  tokens  =  WHITESPACE_PATTERN . split ( readAll ());
         if   ( tokens . length  ==   0   ||  tokens [ 0 ]. length ()   >   0 )
             return  tokens ;
         String []  decapitokens  =   new   String [ tokens . length - 1 ];
         for   ( int  i  =   0 ;  i  <  tokens . length - 1 ;  i ++ )
            decapitokens [ i ]   =  tokens [ i + 1 ];
         return  decapitokens ;
     }

     /**
     * Reads all remaining lines from this input stream and returns them as
     * an array of strings.
     *
     *  @return  all remaining lines in this input stream, as an array of strings
     */
     public   String []  readAllLines ()   {
         ArrayList < String >  lines  =   new   ArrayList < String > ();
         while   ( hasNextLine ())   {
            lines . add ( readLine ());
         }
         return  lines . toArray ( new   String [ lines . size ()]);
     }


     /**
     * Reads all remaining tokens from this input stream, parses them as integers,
     * and returns them as an array of integers.
     *
     *  @return  all remaining lines in this input stream, as an array of integers
     */
     public   int []  readAllInts ()   {
         String []  fields  =  readAllStrings ();
         int []  vals  =   new   int [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Integer . parseInt ( fields [ i ]);
         return  vals ;
     }

     /**
     * Reads all remaining tokens from this input stream, parses them as longs,
     * and returns them as an array of longs.
     *
     *  @return  all remaining lines in this input stream, as an array of longs
     */
     public   long []  readAllLongs ()   {
         String []  fields  =  readAllStrings ();
         long []  vals  =   new   long [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Long . parseLong ( fields [ i ]);
         return  vals ;
     }

     /**
     * Reads all remaining tokens from this input stream, parses them as doubles,
     * and returns them as an array of doubles.
     *
     *  @return  all remaining lines in this input stream, as an array of doubles
     */
     public   double []  readAllDoubles ()   {
         String []  fields  =  readAllStrings ();
         double []  vals  =   new   double [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Double . parseDouble ( fields [ i ]);
         return  vals ;
     }
    
     ///// end: section (2 of 2) of code duplicated from In to StdIn */

    /**
     * Closes this input stream.
     */
     public   void  close ()   {
        scanner . close ();   
     }

     /**
     * Reads all integers from a file and returns them as
     * an array of integers.
     *
     *  @param       filename the name of the file
     *  @return      the integers in the file
     *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllInts()}.
     */
    @ Deprecated
     public   static   int []  readInts ( String  filename )   {
         return   new   In ( filename ). readAllInts ();
     }

    /**
     * Reads all doubles from a file and returns them as
     * an array of doubles.
     *
     *  @param       filename the name of the file
     *  @return      the doubles in the file
     *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllDoubles()}.
     */
    @ Deprecated
     public   static   double []  readDoubles ( String  filename )   {
         return   new   In ( filename ). readAllDoubles ();
     }

    /**
     * Reads all strings from a file and returns them as
     * an array of strings.
     *
     *  @param       filename the name of the file
     *  @return      the strings in the file
     *  @deprecated  Replaced by { @code  new In(filename)}.{ @link  #readAllStrings()}.
     */
    @ Deprecated
     public   static   String []  readStrings ( String  filename )   {
         return   new   In ( filename ). readAllStrings ();
     }

     /**
     * Reads all integers from standard input and returns them
     * an array of integers.
     *
     *  @return      the integers on standard input
     *  @deprecated  Replaced by { @link  StdIn#readAllInts()}.
     */
    @ Deprecated
     public   static   int []  readInts ()   {
         return   new   In (). readAllInts ();
     }

    /**
     * Reads all doubles from standard input and returns them as
     * an array of doubles.
     *
     *  @return      the doubles on standard input
     *  @deprecated  Replaced by { @link  StdIn#readAllDoubles()}.
     */
    @ Deprecated
     public   static   double []  readDoubles ()   {
         return   new   In (). readAllDoubles ();
     }

    /**
     * Reads all strings from standard input and returns them as
     *  an array of strings.
     *
     *  @return      the strings on standard input
     *  @deprecated  Replaced by { @link  StdIn#readAllStrings()}.
     */
    @ Deprecated
     public   static   String []  readStrings ()   {
         return   new   In (). readAllStrings ();
     }
    
    /**
     * Unit tests the { @code  In} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in ;
         String  urlName  =   "https://introcs.cs.princeton.edu/java/stdlib/InTest.txt" ;

         // read from a URL
         System . out . println ( "readAll() from URL "   +  urlName );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( urlName );
             System . out . println ( in . readAll ());
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();

         // read one line at a time from URL
         System . out . println ( "readLine() from URL "   +  urlName );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( urlName );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readLine ();
                 System . out . println ( s );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();

         // read one string at a time from URL
         System . out . println ( "readString() from URL "   +  urlName );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( urlName );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readString ();
                 System . out . println ( s );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();


         // read one line at a time from file in current directory
         System . out . println ( "readLine() from current directory" );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( "./InTest.txt" );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readLine ();
                 System . out . println ( s );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();


         // read one line at a time from file using relative path
         System . out . println ( "readLine() from relative path" );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( "../stdlib/InTest.txt" );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readLine ();
                 System . out . println ( s );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();

         // read one char at a time
         System . out . println ( "readChar() from file" );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( "InTest.txt" );
             while   ( ! in . isEmpty ())   {
                 char  c  =  in . readChar ();
                 System . out . print ( c );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();
         System . out . println ();

         // read one line at a time from absolute OS X / Linux path
         System . out . println ( "readLine() from absolute OS X / Linux path" );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( "/n/fs/introcs/www/java/stdlib/InTest.txt" );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readLine ();
                 System . out . println ( s );
             }
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();


         // read one line at a time from absolute Windows path
         System . out . println ( "readLine() from absolute Windows path" );
         System . out . println ( "---------------------------------------------------------------------------" );
         try   {
            in  =   new   In ( "G:\\www\\introcs\\stdlib\\InTest.txt" );
             while   ( ! in . isEmpty ())   {
                 String  s  =  in . readLine ();
                 System . out . println ( s );
             }
             System . out . println ();
         }
         catch   ( IllegalArgumentException  e )   {
             System . out . println ( e );
         }
         System . out . println ();

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/InplaceMSD.java

edu/princeton/cs/algs4/InplaceMSD.java

/******************************************************************************
 *  Compilation: javac InplaceMSD.java
 *  Execution:   java InplaceMSD < input.txt
 *  Dependencies: StdIn.java StdOut.java 
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *                https://algs4.cs.princeton.edu/51radix/shells.txt
 *
 *  Sort an array of strings or integers using in-place MSD radix sort.
 *
 *  % java InplaceMSD < shells.txt 
 *  are
 *  by
 *  sea
 *  seashells
 *  seashells
 *  sells
 *  sells
 *  she
 *  she
 *  shells
 *  shore
 *  surely
 *  the
 *  the
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  InplaceMSD} class provides static methods for sorting an
 *  array of extended ASCII strings using in-place MSD radix sort.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Ivan Pesin
 */

public   class   InplaceMSD   {
     private   static   final   int  R              =   256 ;     // extended ASCII alphabet size
     private   static   final   int  CUTOFF         =    15 ;     // cutoff to insertion sort

     // do not instantiate
     private   InplaceMSD ()   {   }  

    /**
     * Rearranges the array of extended ASCII strings in ascending order.
     * This is an unstable sorting algorithm.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( String []  a )   {
         int  n  =  a . length ;
        sort ( a ,   0 ,  n - 1 ,   0 );
     }

     // return dth character of s, -1 if d = length of string
     private   static   int  charAt ( String  s ,   int  d )   {
         assert  d  >=   0   &&  d  <=  s . length ();
         if   ( ==  s . length ())   return   - 1 ;
         return  s . charAt ( d );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d )   {

         // cutoff to insertion sort for small subarrays
         if   ( hi  <=  lo  +  CUTOFF )   {
            insertion ( a ,  lo ,  hi ,  d );
             return ;
         }

         // compute frequency counts
         int []  heads  =   new   int [ R + 2 ];
         int []  tails  =   new   int [ R + 1 ];
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             int  c  =  charAt ( a [ i ],  d );
            heads [ c + 2 ] ++ ;
         }

         // transform counts to indices
        heads [ 0 ]   =  lo ;
         for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )   {
            heads [ r + 1 ]   +=  heads [ r ];
            tails [ r ]   =  heads [ r + 1 ];
         }

         // sort by d-th character in-place
         for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )   {
             while   ( heads [ r ]   <  tails [ r ])   {
                 int  c  =  charAt ( a [ heads [ r ]],  d );
                 while   ( +   1   !=  r )   {
                    exch ( a ,  heads [ r ],  heads [ c + 1 ] ++ );
                    c  =  charAt ( a [ heads [ r ]],  d );
                 }
                heads [ r ] ++ ;
             }
         }
              
         // recursively sort for each character (excludes sentinel -1)
         for   ( int  r  =   0 ;  r  <  R ;  r ++ )
            sort ( a ,  tails [ r ],  tails [ r + 1 ]   -   1 ,  d + 1 );
     }


     // insertion sort a[lo..hi], starting at dth character
     private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( String []  a ,   int  i ,   int  j )   {
         String  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }

     // is v less than w, starting at character d
     private   static   boolean  less ( String  v ,   String  w ,   int  d )   {
         // assert v.substring(0, d).equals(w.substring(0, d));
         for   ( int  i  =  d ;  i  <   Math . min ( v . length (),  w . length ());  i ++ )   {
             if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;
             if   ( v . charAt ( i )   >  w . charAt ( i ))   return   false ;
         }
         return  v . length ()   <  w . length ();
     }


     /**
     * Reads in a sequence of extended ASCII strings from standard input;
     * in-place MSD radix sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         int  n  =  a . length ;
        sort ( a );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Insertion.java

edu/princeton/cs/algs4/Insertion.java

/******************************************************************************
 *  Compilation:  javac Insertion.java
 *  Execution:    java Insertion < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt
 *                https://algs4.cs.princeton.edu/21elementary/words3.txt
 *  
 *  Sorts a sequence of strings from standard input using insertion sort.
 *
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Insertion < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *
 *  % java Insertion < words3.txt
 *  all bad bed bug dad ... yes yet zoo   [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;

/**
 *  The { @code  Insertion} class provides static methods for sorting an
 *  array using insertion sort.
 *  <p>
 *  In the worst case, this implementation makes ~ &frac12; <em>n</em><sup>2</sup>
 *  compares and ~ &frac12; <em>n</em><sup>2</sup> exchanges to sort an array
 *  of length <em>n</em>. So, it is not suitable for sorting large arbitrary
 *  arrays. More precisely, the number of exchanges is exactly equal to the
 *  number of inversions. So, for example, it sorts a partially-sorted array
 *  in linear time.
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(1) extra memory (not including the input array).
 *  <p>
 *  See <a href="https://algs4.cs.princeton.edu/21elementary/InsertionPedantic.java.html">InsertionPedantic.java</a>
 *  for a version that eliminates the compiler warning.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Insertion   {

     // This class should not be instantiated.
     private   Insertion ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   1 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i ;  j  >   0   &&  less ( a [ j ],  a [ j - 1 ]);  j -- )   {
                exch ( a ,  j ,  j - 1 );
             }
             assert  isSorted ( a ,   0 ,  i );
         }
         assert  isSorted ( a );
     }

     /**
     * Rearranges the subarray a[lo..hi) in ascending order, using the natural order.
     *  @param  a the array to be sorted
     *  @param  lo left endpoint (inclusive)
     *  @param  hi right endpoint (exclusive)
     */
     public   static   void  sort ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )   {
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ]);  j -- )   {
                exch ( a ,  j ,  j - 1 );
             }
         }
         assert  isSorted ( a ,  lo ,  hi );
     }

     /**
     * Rearranges the array in ascending order, using a comparator.
     *  @param  a the array
     *  @param  comparator the comparator specifying the order
     */
     public   static   void  sort ( Object []  a ,   Comparator  comparator )   {
         int  n  =  a . length ;
         for   ( int  i  =   1 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i ;  j  >   0   &&  less ( a [ j ],  a [ j - 1 ],  comparator );  j -- )   {
                exch ( a ,  j ,  j - 1 );
             }
             assert  isSorted ( a ,   0 ,  i ,  comparator );
         }
         assert  isSorted ( a ,  comparator );
     }

     /**
     * Rearranges the subarray a[lo..hi) in ascending order, using a comparator.
     *  @param  a the array
     *  @param  lo left endpoint (inclusive)
     *  @param  hi right endpoint (exclusive)
     *  @param  comparator the comparator specifying the order
     */
     public   static   void  sort ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {
         for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )   {
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  comparator );  j -- )   {
                exch ( a ,  j ,  j - 1 );
             }
         }
         assert  isSorted ( a ,  lo ,  hi ,  comparator );
     }


     // return a permutation that gives the elements in a[] in ascending order
     // do not change the original array a[]
     /**
     * Returns a permutation that gives the elements in the array in ascending order.
     *  @param  a the array
     *  @return  a permutation { @code  p[]} such that { @code  a[p[0]]}, { @code  a[p[1]]},
     *    ..., { @code  a[p[n-1]]} are in ascending order
     */
     public   static   int []  indexSort ( Comparable []  a )   {
         int  n  =  a . length ;
         int []  index  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            index [ i ]   =  i ;

         for   ( int  i  =   1 ;  i  <  n ;  i ++ )
             for   ( int  j  =  i ;  j  >   0   &&  less ( a [ index [ j ]],  a [ index [ j - 1 ]]);  j -- )
                exch ( index ,  j ,  j - 1 );

         return  index ;
     }

    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }

     // is v < w ?
     private   static   boolean  less ( Object  v ,   Object  w ,   Comparator  comparator )   {
         return  comparator . compare ( v ,  w )   <   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }

     // exchange a[i] and a[j]  (for indirect sort)
     private   static   void  exch ( int []  a ,   int  i ,   int  j )   {
         int  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }

    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length );
     }

     // is the array a[lo..hi) sorted
     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {
         return  isSorted ( a ,   0 ,  a . length ,  comparator );
     }

     // is the array a[lo..hi) sorted
     private   static   boolean  isSorted ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {
         for   ( int  i  =  lo  +   1 ;  i  <  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ],  comparator ))   return   false ;
         return   true ;
     }

    // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; insertion sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Insertion . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/InsertionX.java

edu/princeton/cs/algs4/InsertionX.java

/******************************************************************************
 *  Compilation:  javac InsertionX.java
 *  Execution:    java InsertionX < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt
 *                https://algs4.cs.princeton.edu/21elementary/words3.txt
 *  
 *  Sorts a sequence of strings from standard input using an optimized
 *  version of insertion sort that uses half exchanges instead of 
 *  full exchanges to reduce data movement..
 *
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java InsertionX < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *
 *  % java InsertionX < words3.txt
 *  all bad bed bug dad ... yes yet zoo   [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;
/**
 *  The { @code  InsertionX} class provides static methods for sorting
 *  an array using an optimized version of insertion sort (with half exchanges
 *  and a sentinel).
 *  <p>
 *  In the worst case, this implementation makes ~ 1/2 <em>n</em><sup>2</sup>
 *  compares to sort an array of length <em>n</em>.
 *  So, it is not suitable for sorting large arrays
 *  (unless the number of inversions is small).
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(1) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   InsertionX   {

     // This class should not be instantiated.
     private   InsertionX ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;

         // put smallest element in position to serve as sentinel
         int  exchanges  =   0 ;
         for   ( int  i  =  n - 1 ;  i  >   0 ;  i -- )   {
             if   ( less ( a [ i ],  a [ i - 1 ]))   {
                exch ( a ,  i ,  i - 1 );
                exchanges ++ ;
             }
         }
         if   ( exchanges  ==   0 )   return ;


         // insertion sort with half-exchanges
         for   ( int  i  =   2 ;  i  <  n ;  i ++ )   {
             Comparable  v  =  a [ i ];
             int  j  =  i ;
             while   ( less ( v ,  a [ j - 1 ]))   {
                a [ j ]   =  a [ j - 1 ];
                j -- ;
             }
            a [ j ]   =  v ;
         }

         assert  isSorted ( a );
     }


    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; insertion sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         InsertionX . sort ( a );
        show ( a );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Interval1D.java

edu/princeton/cs/algs4/Interval1D.java

/******************************************************************************
 *  Compilation:  javac Interval1D.java
 *  Execution:    java Interval1D
 *  Dependencies: StdOut.java
 *  
 *  1-dimensional interval data type.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;
import  java . util . Comparator ;

/**
 *  The { @code  Interval1D} class represents a one-dimensional interval.
 *  The interval is <em>closed</em>—it contains both endpoints.
 *  Intervals are immutable: their values cannot be changed after they are created.
 *  The class { @code  Interval1D} includes methods for checking whether
 *  an interval contains a point and determining whether two intervals intersect.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Interval1D   {

     /**
     * Compares two intervals by min endpoint.
     */
     public   static   final   Comparator < Interval1D >  MIN_ENDPOINT_ORDER   =   new   MinEndpointComparator ();

     /**
     * Compares two intervals by max endpoint.
     */
     public   static   final   Comparator < Interval1D >  MAX_ENDPOINT_ORDER  =   new   MaxEndpointComparator ();

     /**
     * Compares two intervals by length.
     */
     public   static   final   Comparator < Interval1D >  LENGTH_ORDER  =   new   LengthComparator ();

     private   final   double  min ;
     private   final   double  max ;

     /**
     * Initializes a closed interval [min, max].
     *
     *  @param   min the smaller endpoint
     *  @param   max the larger endpoint
     *  @throws  IllegalArgumentException if the min endpoint is greater than the max endpoint
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max}
     *         is { @code  Double.NaN}, { @code  Double.POSITIVE_INFINITY} or
     *         { @code  Double.NEGATIVE_INFINITY}

     */
     public   Interval1D ( double  min ,   double  max )   {
         if   ( Double . isInfinite ( min )   ||   Double . isInfinite ( max ))
             throw   new   IllegalArgumentException ( "Endpoints must be finite" );
         if   ( Double . isNaN ( min )   ||   Double . isNaN ( max ))
             throw   new   IllegalArgumentException ( "Endpoints cannot be NaN" );

         // convert -0.0 to +0.0
         if   ( min  ==   0.0 )  min  =   0.0 ;
         if   ( max  ==   0.0 )  max  =   0.0 ;

         if   ( min  <=  max )   {
             this . min  =  min ;
             this . max  =  max ;
         }
         else   throw   new   IllegalArgumentException ( "Illegal interval" );
     }

     /**
     * Returns the left endpoint of this interval.
     *
     *  @return  the left endpoint of this interval
     *  @deprecated  Replaced by { @link  #min()}.
     */
    @ Deprecated
     public   double  left ()   {  
         return  min ;
     }

     /**
     * Returns the right endpoint of this interval.
     *  @return  the right endpoint of this interval
     *  @deprecated  Replaced by { @link  #max()}.
     */
    @ Deprecated
     public   double  right ()   {  
         return  max ;
     }

     /**
     * Returns the min endpoint of this interval.
     *
     *  @return  the min endpoint of this interval
     */
     public   double  min ()   {  
         return  min ;
     }

     /**
     * Returns the max endpoint of this interval.
     *
     *  @return  the max endpoint of this interval
     */
     public   double  max ()   {  
         return  max ;
     }

     /**
     * Returns true if this interval intersects the specified interval.
     *
     *  @param   that the other interval
     *  @return  { @code  true} if this interval intersects the argument interval;
     *         { @code  false} otherwise
     */
     public   boolean  intersects ( Interval1D  that )   {
         if   ( this . max  <  that . min )   return   false ;
         if   ( that . max  <   this . min )   return   false ;
         return   true ;
     }

     /**
     * Returns true if this interval contains the specified value.
     *
     *  @param  x the value
     *  @return  { @code  true} if this interval contains the value { @code  x};
     *         { @code  false} otherwise
     */
     public   boolean  contains ( double  x )   {
         return   ( min  <=  x )   &&   ( <=  max );
     }

     /**
     * Returns the length of this interval.
     *
     *  @return  the length of this interval (max - min)
     */
     public   double  length ()   {
         return  max  -  min ;
     }

     /**
     * Returns a string representation of this interval.
     *
     *  @return  a string representation of this interval in the form [min, max]
     */
     public   String  toString ()   {
         return   "["   +  min  +   ", "   +  max  +   "]" ;
     }

     /**
     * Compares this transaction to the specified object.
     *
     *  @param   other the other interval
     *  @return  { @code  true} if this interval equals the other interval;
     *         { @code  false} otherwise
     */
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Interval1D  that  =   ( Interval1D )  other ;
         return   this . min  ==  that . min  &&   this . max  ==  that . max ;
     }

     /**
     * Returns an integer hash code for this interval.
     *
     *  @return  an integer hash code for this interval
     */
     public   int  hashCode ()   {
         int  hash1  =   (( Double )  min ). hashCode ();
         int  hash2  =   (( Double )  max ). hashCode ();
         return   31 * hash1  +  hash2 ;
     }

     // ascending order of min endpoint, breaking ties by max endpoint
     private   static   class   MinEndpointComparator   implements   Comparator < Interval1D >   {
         public   int  compare ( Interval1D  a ,   Interval1D  b )   {
             if        ( a . min  <  b . min )   return   - 1 ;
             else   if   ( a . min  >  b . min )   return   + 1 ;
             else   if   ( a . max  <  b . max )   return   - 1 ;
             else   if   ( a . max  >  b . max )   return   + 1 ;
             else                      return    0 ;
         }
     }

     // ascending order of max endpoint, breaking ties by min endpoint
     private   static   class   MaxEndpointComparator   implements   Comparator < Interval1D >   {
         public   int  compare ( Interval1D  a ,   Interval1D  b )   {
             if        ( a . max  <  b . max )   return   - 1 ;
             else   if   ( a . max  >  b . max )   return   + 1 ;
             else   if   ( a . min  <  b . min )   return   - 1 ;
             else   if   ( a . min  >  b . min )   return   + 1 ;
             else                      return    0 ;
         }
     }

     // ascending order of length
     private   static   class   LengthComparator   implements   Comparator < Interval1D >   {
         public   int  compare ( Interval1D  a ,   Interval1D  b )   {
             double  alen  =  a . length ();
             double  blen  =  b . length ();
             if        ( alen  <  blen )   return   - 1 ;
             else   if   ( alen  >  blen )   return   + 1 ;
             else                    return    0 ;
         }
     }




     /**
     * Unit tests the { @code  Interval1D} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Interval1D []  intervals  =   new   Interval1D [ 4 ];
        intervals [ 0 ]   =   new   Interval1D ( 15.0 ,   33.0 );
        intervals [ 1 ]   =   new   Interval1D ( 45.0 ,   60.0 );
        intervals [ 2 ]   =   new   Interval1D ( 20.0 ,   70.0 );
        intervals [ 3 ]   =   new   Interval1D ( 46.0 ,   55.0 );

         StdOut . println ( "Unsorted" );
         for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )
             StdOut . println ( intervals [ i ]);
         StdOut . println ();
        
         StdOut . println ( "Sort by min endpoint" );
         Arrays . sort ( intervals ,   Interval1D . MIN_ENDPOINT_ORDER );
         for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )
             StdOut . println ( intervals [ i ]);
         StdOut . println ();

         StdOut . println ( "Sort by max endpoint" );
         Arrays . sort ( intervals ,   Interval1D . MAX_ENDPOINT_ORDER );
         for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )
             StdOut . println ( intervals [ i ]);
         StdOut . println ();

         StdOut . println ( "Sort by length" );
         Arrays . sort ( intervals ,   Interval1D . LENGTH_ORDER );
         for   ( int  i  =   0 ;  i  <  intervals . length ;  i ++ )
             StdOut . println ( intervals [ i ]);
         StdOut . println ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Interval2D.java

edu/princeton/cs/algs4/Interval2D.java

/******************************************************************************
 *  Compilation:  javac Interval2D.java
 *  Execution:    java Interval2D
 *  Dependencies: StdOut.java Interval1D.java StdDraw.java
 *  
 *  2-dimensional interval data type.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Interval2D} class represents a closed two-dimensional interval,
 *  which represents all points (x, y) with both { @code  xmin <= x <= xmax} and
 *  { @code  ymin <= y <= ymax}.
 *  Two-dimensional intervals are immutable: their values cannot be changed
 *  after they are created.
 *  The class { @code  Interval2D} includes methods for checking whether
 *  a two-dimensional interval contains a point and determining whether
 *  two two-dimensional intervals intersect.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Interval2D   {
     private   final   Interval1D  x ;
     private   final   Interval1D  y ;

     /**
     * Initializes a two-dimensional interval.
     *  @param  x the one-dimensional interval of x-coordinates
     *  @param  y the one-dimensional interval of y-coordinates
     */
     public   Interval2D ( Interval1D  x ,   Interval1D  y )   {
         this . =  x ;
         this . =  y ;
     }

     /**
     * Does this two-dimensional interval intersect that two-dimensional interval?
     *  @param  that the other two-dimensional interval
     *  @return  true if this two-dimensional interval intersects
     *    that two-dimensional interval; false otherwise
     */
     public   boolean  intersects ( Interval2D  that )   {
         if   ( ! this . x . intersects ( that . x ))   return   false ;
         if   ( ! this . y . intersects ( that . y ))   return   false ;
         return   true ;
     }

     /**
     * Does this two-dimensional interval contain the point p?
     *  @param  p the two-dimensional point
     *  @return  true if this two-dimensional interval contains the point p; false otherwise
     */
     public   boolean  contains ( Point2D  p )   {
         return  x . contains ( p . x ())    &&  y . contains ( p . y ());
     }

     /**
     * Returns the area of this two-dimensional interval.
     *  @return  the area of this two-dimensional interval
     */
     public   double  area ()   {
         return  x . length ()   *  y . length ();
     }
        
     /**
     * Returns a string representation of this two-dimensional interval.
     *  @return  a string representation of this two-dimensional interval
     *    in the form [xmin, xmax] x [ymin, ymax]
     */
     public   String  toString ()   {
         return  x  +   " x "   +  y ;
     }

     /**
     * Does this interval equal the other interval?
     *  @param  other the other interval
     *  @return  true if this interval equals the other interval; false otherwise
     */
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Interval2D  that  =   ( Interval2D )  other ;
         return   this . x . equals ( that . x )   &&   this . y . equals ( that . y );
     }

 
     /**
     * Returns an integer hash code for this interval.  
     *  @return  an integer hash code for this interval 
     */
     public   int  hashCode ()   {
         int  hash1  =  x . hashCode ();
         int  hash2  =  y . hashCode ();
         return   31 * hash1  +  hash2 ;
     }

     /**
     * Draws this two-dimensional interval to standard draw.
     */
     public   void  draw ()   {
         double  xc  =   ( x . min ()   +  x . max ())   /   2.0 ;
         double  yc  =   ( y . min ()   +  y . max ())   /   2.0 ;
         StdDraw . rectangle ( xc ,  yc ,  x . length ()   /   2.0 ,  y . length ()   /   2.0 );
     }

     /**
     * Unit tests the { @code  Interval2D} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         double  xmin  =   Double . parseDouble ( args [ 0 ]);
         double  xmax  =   Double . parseDouble ( args [ 1 ]);
         double  ymin  =   Double . parseDouble ( args [ 2 ]);
         double  ymax  =   Double . parseDouble ( args [ 3 ]);
         int  trials  =   Integer . parseInt ( args [ 4 ]);

         Interval1D  xInterval  =   new   Interval1D ( xmin ,  xmax );
         Interval1D  yInterval  =   new   Interval1D ( ymin ,  ymax );
         Interval2D  box  =   new   Interval2D ( xInterval ,  yInterval );
        box . draw ();

         Counter  counter  =   new   Counter ( "hits" );
         for   ( int  t  =   0 ;  t  <  trials ;  t ++ )   {
             double  x  =   StdRandom . uniform ( 0.0 ,   1.0 );
             double  y  =   StdRandom . uniform ( 0.0 ,   1.0 );
             Point2D  point  =   new   Point2D ( x ,  y );

             if   ( box . contains ( point ))  counter . increment ();
             else                      point . draw ();
         }

         StdOut . println ( counter );
         StdOut . printf ( "box area = %.2f\n" ,  box . area ());
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Inversions.java

edu/princeton/cs/algs4/Inversions.java

/******************************************************************************
 *  Compilation:  javac Inversions.java
 *  Execution:    java Inversions < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  
 *  Read array of n integers and count number of inversions in n log n time.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Inversions} class provides static methods to count the 
 *  number of <em>inversions</em> in either an array of integers or comparables.
 *  An inversion in an array { @code  a[]} is a pair of indicies { @code  i} and
 *  { @code  j} such that { @code  i < j} and { @code  a[i] > a[j]}.
 *  <p>
 *  This implementation uses a generalization of mergesort. The <em>count</em>
 *  operation takes &Theta;(<em>n</em> log <em>n</em>) time to count the
 *  number of inversions in any array of length <em>n</em> (assuming
 *  comparisons take constant time).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/22mergesort">Section 2.2</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Inversions   {

     // do not instantiate
     private   Inversions ()   {   }

     // merge and count
     private   static   long  merge ( int []  a ,   int []  aux ,   int  lo ,   int  mid ,   int  hi )   {
         long  inversions  =   0 ;

         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  a [ k ];  
         }

         // merge back to a[]
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )            a [ k ]   =  aux [ j ++ ];
             else   if   ( >  hi )             a [ k ]   =  aux [ i ++ ];
             else   if   ( aux [ j ]   <  aux [ i ])   {  a [ k ]   =  aux [ j ++ ];  inversions  +=   ( mid  -  i  +   1 );   }
             else                         a [ k ]   =  aux [ i ++ ];
         }
         return  inversions ;
     }

     // return the number of inversions in the subarray b[lo..hi]
     // side effect b[lo..hi] is rearranged in ascending order
     private   static   long  count ( int []  a ,   int []  b ,   int []  aux ,   int  lo ,   int  hi )   {
         long  inversions  =   0 ;
         if   ( hi  <=  lo )   return   0 ;
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        inversions  +=  count ( a ,  b ,  aux ,  lo ,  mid );   
        inversions  +=  count ( a ,  b ,  aux ,  mid + 1 ,  hi );
        inversions  +=  merge ( b ,  aux ,  lo ,  mid ,  hi );
         assert  inversions  ==  brute ( a ,  lo ,  hi );
         return  inversions ;
     }


     /**
     * Returns the number of inversions in the integer array.
     * The argument array is not modified.
     *  @param   a the array
     *  @return  the number of inversions in the array. An inversion is a pair of 
     *         indicies { @code  i} and { @code  j} such that { @code  i < j}
     *         and { @code  a[i] > a[j]}.
     */
     public   static   long  count ( int []  a )   {
         int []  b    =   new   int [ a . length ];
         int []  aux  =   new   int [ a . length ];
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
            b [ i ]   =  a [ i ];
         long  inversions  =  count ( a ,  b ,  aux ,   0 ,  a . length  -   1 );
         return  inversions ;
     }



     // merge and count (Comparable version)
     private   static   < Key   extends   Comparable < Key >>   long  merge ( Key []  a ,   Key []  aux ,   int  lo ,   int  mid ,   int  hi )   {
         long  inversions  =   0 ;

         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  a [ k ];  
         }

         // merge back to a[]
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )                 a [ k ]   =  aux [ j ++ ];
             else   if   ( >  hi )                  a [ k ]   =  aux [ i ++ ];
             else   if   ( less ( aux [ j ],  aux [ i ]))   {  a [ k ]   =  aux [ j ++ ];  inversions  +=   ( mid  -  i  +   1 );   }
             else                              a [ k ]   =  aux [ i ++ ];
         }
         return  inversions ;
     }

     // return the number of inversions in the subarray b[lo..hi]
     // side effect b[lo..hi] is rearranged in ascending order
     private   static   < Key   extends   Comparable < Key >>   long  count ( Key []  a ,   Key []  b ,   Key []  aux ,   int  lo ,   int  hi )   {
         long  inversions  =   0 ;
         if   ( hi  <=  lo )   return   0 ;
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        inversions  +=  count ( a ,  b ,  aux ,  lo ,  mid );   
        inversions  +=  count ( a ,  b ,  aux ,  mid + 1 ,  hi );
        inversions  +=  merge ( b ,  aux ,  lo ,  mid ,  hi );
         assert  inversions  ==  brute ( a ,  lo ,  hi );
         return  inversions ;
     }


     /**
     * Returns the number of inversions in the comparable array.
     * The argument array is not modified.
     *  @param   a the array
     *  @param  <Key> the inferred type of the elements in the array
     *  @return  the number of inversions in the array. An inversion is a pair of 
     *         indicies { @code  i} and { @code  j} such that { @code  i < j}
     *         and { @code  a[i].compareTo(a[j]) > 0}.
     */
     public   static   < Key   extends   Comparable < Key >>   long  count ( Key []  a )   {
         Key []  b    =  a . clone ();
         Key []  aux  =  a . clone ();
         long  inversions  =  count ( a ,  b ,  aux ,   0 ,  a . length  -   1 );
         return  inversions ;
     }


     // is v < w ?
     private   static   < Key   extends   Comparable < Key >>   boolean  less ( Key  v ,   Key  w )   {
         return   ( v . compareTo ( w )   <   0 );
     }

     // count number of inversions in a[lo..hi] via brute force (for debugging only)
     private   static   < Key   extends   Comparable < Key >>   long  brute ( Key []  a ,   int  lo ,   int  hi )   {
         long  inversions  =   0 ;
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i  +   1 ;  j  <=  hi ;  j ++ )
                 if   ( less ( a [ j ],  a [ i ]))  inversions ++ ;
         return  inversions ;
     }

     // count number of inversions in a[lo..hi] via brute force (for debugging only)
     private   static   long  brute ( int []  a ,   int  lo ,   int  hi )   {
         long  inversions  =   0 ;
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i  +   1 ;  j  <=  hi ;  j ++ )
                 if   ( a [ j ]   <  a [ i ])  inversions ++ ;
         return  inversions ;
     }

     /**
     * Reads a sequence of integers from standard input and
     * prints the number of inversions to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int []  a  =   StdIn . readAllInts ();
         int  n  =  a . length ;
         Integer []  b  =   new   Integer [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            b [ i ]   =  a [ i ];
         StdOut . println ( Inversions . count ( a ));
         StdOut . println ( Inversions . count ( b ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/KMP.java

edu/princeton/cs/algs4/KMP.java

/******************************************************************************
 *  Compilation:  javac KMP.java
 *  Execution:    java KMP pattern text
 *  Dependencies: StdOut.java
 *
 *  Reads in two strings, the pattern and the input text, and
 *  searches for the pattern in the input text using the
 *  KMP algorithm.
 *
 *  % java KMP abracadabra abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:               abracadabra          
 *
 *  % java KMP rab abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:         rab
 *
 *  % java KMP bcara abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad 
 *  pattern:                                   bcara
 *
 *  % java KMP rabrabracad abacadabrabracabracadabrabrabracad 
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern:                        rabrabracad
 *
 *  % java KMP abacad abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern: abacad
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  KMP} class finds the first occurrence of a pattern string
 *  in a text string.
 *  <p>
 *  This implementation uses a version of the Knuth-Morris-Pratt substring search
 *  algorithm. The version takes time proportional to <em>n</em> + <em>m R</em>
 *  in the worst case, where <em>n</em> is the length of the text string,
 *  <em>m</em> is the length of the pattern, and <em>R</em> is the alphabet size.
 *  It uses extra space proportional to <em>m R</em>.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/53substring">Section 5.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class  KMP  {
     private   final   int  R ;         // the radix
     private   int [][]  dfa ;         // the KMP automoton

     private   char []  pattern ;      // either the character array for the pattern
     private   String  pat ;          // or the pattern string

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pat the pattern string
     */
     public  KMP ( String  pat )   {
         this . =   256 ;
         this . pat  =  pat ;

         // build DFA from pattern
         int  m  =  pat . length ();
        dfa  =   new   int [ R ][ m ];  
        dfa [ pat . charAt ( 0 )][ 0 ]   =   1 ;  
         for   ( int  x  =   0 ,  j  =   1 ;  j  <  m ;  j ++ )   {
             for   ( int  c  =   0 ;  c  <  R ;  c ++ )  
                dfa [ c ][ j ]   =  dfa [ c ][ x ];       // Copy mismatch cases. 
            dfa [ pat . charAt ( j )][ j ]   =  j + 1 ;     // Set match case. 
            x  =  dfa [ pat . charAt ( j )][ x ];       // Update restart state. 
         }  
     }  

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pattern the pattern string
     *  @param  R the alphabet size
     */
     public  KMP ( char []  pattern ,   int  R )   {
         this . =  R ;
         this . pattern  =   new   char [ pattern . length ];
         for   ( int  j  =   0 ;  j  <  pattern . length ;  j ++ )
             this . pattern [ j ]   =  pattern [ j ];

         // build DFA from pattern
         int  m  =  pattern . length ;
        dfa  =   new   int [ R ][ m ];  
        dfa [ pattern [ 0 ]][ 0 ]   =   1 ;  
         for   ( int  x  =   0 ,  j  =   1 ;  j  <  m ;  j ++ )   {
             for   ( int  c  =   0 ;  c  <  R ;  c ++ )  
                dfa [ c ][ j ]   =  dfa [ c ][ x ];       // Copy mismatch cases. 
            dfa [ pattern [ j ]][ j ]   =  j + 1 ;        // Set match case. 
            x  =  dfa [ pattern [ j ]][ x ];          // Update restart state. 
         }  
     }  

     /**
     * Returns the index of the first occurrrence of the pattern string
     * in the text string.
     *
     *  @param   txt the text string
     *  @return  the index of the first occurrence of the pattern string
     *         in the text string; N if no such match
     */
     public   int  search ( String  txt )   {

         // simulate operation of DFA on text
         int  m  =  pat . length ();
         int  n  =  txt . length ();
         int  i ,  j ;
         for   ( =   0 ,  j  =   0 ;  i  <  n  &&  j  <  m ;  i ++ )   {
            j  =  dfa [ txt . charAt ( i )][ j ];
         }
         if   ( ==  m )   return  i  -  m ;      // found
         return  n ;                      // not found
     }

     /**
     * Returns the index of the first occurrrence of the pattern string
     * in the text string.
     *
     *  @param   text the text string
     *  @return  the index of the first occurrence of the pattern string
     *         in the text string; N if no such match
     */
     public   int  search ( char []  text )   {

         // simulate operation of DFA on text
         int  m  =  pattern . length ;
         int  n  =  text . length ;
         int  i ,  j ;
         for   ( =   0 ,  j  =   0 ;  i  <  n  &&  j  <  m ;  i ++ )   {
            j  =  dfa [ text [ i ]][ j ];
         }
         if   ( ==  m )   return  i  -  m ;      // found
         return  n ;                      // not found
     }


     /** 
     * Takes a pattern string and an input string as command-line arguments;
     * searches for the pattern string in the text string; and prints
     * the first occurrence of the pattern string in the text string.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  pat  =  args [ 0 ];
         String  txt  =  args [ 1 ];
         char []  pattern  =  pat . toCharArray ();
         char []  text     =  txt . toCharArray ();

        KMP kmp1  =   new  KMP ( pat );
         int  offset1  =  kmp1 . search ( txt );

        KMP kmp2  =   new  KMP ( pattern ,   256 );
         int  offset2  =  kmp2 . search ( text );

         // print results
         StdOut . println ( "text:    "   +  txt );

         StdOut . print ( "pattern: " );
         for   ( int  i  =   0 ;  i  <  offset1 ;  i ++ )
             StdOut . print ( " " );
         StdOut . println ( pat );

         StdOut . print ( "pattern: " );
         for   ( int  i  =   0 ;  i  <  offset2 ;  i ++ )
             StdOut . print ( " " );
         StdOut . println ( pat );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Knuth.java

edu/princeton/cs/algs4/Knuth.java

/******************************************************************************
 *  Compilation:  javac Knuth.java
 *  Execution:    java Knuth < list.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/11model/cards.txt
 *                https://algs4.cs.princeton.edu/11model/cardsUnicode.txt
 *  
 *  Reads in a list of strings and prints them in random order.
 *  The Knuth (or Fisher-Yates) shuffling algorithm guarantees
 *  to rearrange the elements in uniformly random order, under
 *  the assumption that Math.random() generates independent and
 *  uniformly distributed numbers between 0 and 1.
 *
 *  % more cards.txt
 *  2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC AC
 *  2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD AD
 *  2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH AH
 *  2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS AS
 *
 *  % java Knuth < cards.txt
 *  6H
 *  9C
 *  8H
 *  7C
 *  JS
 *  ...
 *  KH
 *
 *  % more cardsUnicode.txt
 *  2♣ 3♣ 4♣ 5♣ 6♣ 7♣ 8♣ 9♣ 10♣ J♣ Q♣ K♣ A♣ 
 *  2♦ 3♦ 4♦ 5♦ 6♦ 7♦ 8♦ 9♦ 10♦ J♦ Q♦ K♦ A♦ 
 *  2♥ 3♥ 4♥ 5♥ 6♥ 7♥ 8♥ 9♥ 10♥ J♥ Q♥ K♥ A♥ 
 *  2♠ 3♠ 4♠ 5♠ 6♠ 7♠ 8♠ 9♠ 10♠ J♠ Q♠ K♠ A♠ 
 * 
 *  % java Knuth < cardsUnicode.txt
 *  2♠
 *  K♥
 *  6♥
 *  5♣
 *  J♣
 *  ...
 *  A♦
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Knuth} class provides a client for reading in a 
 *  sequence of strings and <em>shuffling</em> them using the Knuth (or Fisher-Yates)
 *  shuffling algorithm. This algorithm guarantees to rearrange the
 *  elements in uniformly random order, under
 *  the assumption that Math.random() generates independent and
 *  uniformly distributed numbers between 0 and 1.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  See { @link  StdRandom} for versions that shuffle arrays and
 *  subarrays of objects, doubles, and ints.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Knuth   {  

     // this class should not be instantiated
     private   Knuth ()   {   }

     /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that { @code  Math.random()} generates independent
     * and uniformly distributed numbers between 0 and 1).
     *  @param  a the array to be shuffled
     */
     public   static   void  shuffle ( Object []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             // choose index uniformly in [0, i]
             int  r  =   ( int )   ( Math . random ()   *   ( +   1 ));
             Object  swap  =  a [ r ];
            a [ r ]   =  a [ i ];
            a [ i ]   =  swap ;
         }
     }

     /**
     * Rearranges an array of objects in uniformly random order
     * (under the assumption that { @code  Math.random()} generates independent
     * and uniformly distributed numbers between 0 and 1).
     *  @param  a the array to be shuffled
     */
     public   static   void  shuffleAlternate ( Object []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             // choose index uniformly in [i, n-1]
             int  r  =  i  +   ( int )   ( Math . random ()   *   ( -  i ));
             Object  swap  =  a [ r ];
            a [ r ]   =  a [ i ];
            a [ i ]   =  swap ;
         }
     }

     /**
     * Reads in a sequence of strings from standard input, shuffles
     * them, and prints out the results.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read in the data
         String []  a  =   StdIn . readAllStrings ();

         // shuffle the array
         Knuth . shuffle ( a );

         // print results.
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/KosarajuSharirSCC.java

edu/princeton/cs/algs4/KosarajuSharirSCC.java

/******************************************************************************
 *  Compilation:  javac KosarajuSharirSCC.java
 *  Execution:    java KosarajuSharirSCC filename.txt
 *  Dependencies: Digraph.java TransitiveClosure.java StdOut.java In.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Compute the strongly-connected components of a digraph using the
 *  Kosaraju-Sharir algorithm.
 *
 *  Runs in O(E + V) time.
 *
 *  % java KosarajuSharirSCC tinyDG.txt
 *  5 strong components
 *  1 
 *  0 2 3 4 5 
 *  9 10 11 12 
 *  6 8 
 *  7
 *
 *  % java KosarajuSharirSCC mediumDG.txt 
 *  10 strong components
 *  21 
 *  2 5 6 8 9 11 12 13 15 16 18 19 22 23 25 26 28 29 30 31 32 33 34 35 37 38 39 40 42 43 44 46 47 48 49 
 *  14 
 *  3 4 17 20 24 27 36 
 *  41 
 *  7 
 *  45 
 *  1 
 *  0 
 *  10 
 *
 *  % java -Xss50m KosarajuSharirSCC mediumDG.txt 
 *  25 strong components
 *  7 11 32 36 61 84 95 116 121 128 230   ...
 *  28 73 80 104 115 143 149 164 184 185  ...
 *  38 40 200 201 207 218 286 387 418 422 ...
 *  12 14 56 78 87 103 216 269 271 272    ...
 *  42 48 112 135 160 217 243 246 273 346 ...
 *  46 76 96 97 224 237 297 303 308 309   ...
 *  9 15 21 22 27 90 167 214 220 225 227  ...
 *  74 99 133 146 161 166 202 205 245 262 ...
 *  43 83 94 120 125 183 195 206 244 254  ...
 *  1 13 54 91 92 93 106 140 156 194 208  ...
 *  10 39 67 69 131 144 145 154 168 258   ...
 *  6 52 66 113 118 122 139 147 212 213   ...
 *  8 127 150 182 203 204 249 367 400 432 ...
 *  63 65 101 107 108 136 169 170 171 173 ...
 *  55 71 102 155 159 198 228 252 325 419 ...
 *  4 25 34 58 70 152 172 196 199 210 226 ...
 *  2 44 50 88 109 138 141 178 197 211    ...
 *  57 89 129 162 174 179 188 209 238 276 ...
 *  33 41 49 119 126 132 148 181 215 221  ...
 *  3 18 23 26 35 64 105 124 157 186 251  ...
 *  5 16 17 20 31 47 81 98 158 180 187    ...
 *  24 29 51 59 75 82 100 114 117 134 151 ...
 *  30 45 53 60 72 85 111 130 137 142 163 ...
 *  19 37 62 77 79 110 153 352 353 361    ...
 *  0 68 86 123 165 176 193 239 289 336   ...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  KosarajuSharirSCC} class represents a data type for 
 *  determining the strong components in a digraph.
 *  The <em>id</em> operation determines in which strong component
 *  a given vertex lies; the <em>areStronglyConnected</em> operation
 *  determines whether two vertices are in the same strong component;
 *  and the <em>count</em> operation determines the number of strong
 *  components.
 *  <p>
 *  The <em>component identifier</em> of a component is one of the
 *  vertices in the strong component: two vertices have the same component
 *  identifier if and only if they are in the same strong component.
 *  <p>
 *  This implementation uses the Kosaraju-Sharir algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  For alternative implementations of the same API, see
 *  { @link  TarjanSCC} and { @link  GabowSCC}.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   KosarajuSharirSCC   {
     private   boolean []  marked ;       // marked[v] = has vertex v been visited?
     private   int []  id ;               // id[v] = id of strong component containing v
     private   int  count ;              // number of strongly-connected components

     /**
     * Computes the strong components of the digraph { @code  G}.
     *  @param  G the digraph
     */
     public   KosarajuSharirSCC ( Digraph  G )   {

         // compute reverse postorder of reverse graph
         DepthFirstOrder  dfs  =   new   DepthFirstOrder ( G . reverse ());

         // run DFS on G, using reverse postorder to guide calculation
        marked  =   new   boolean [ G . V ()];
        id  =   new   int [ G . V ()];
         for   ( int  v  :  dfs . reversePost ())   {
             if   ( ! marked [ v ])   {
                dfs ( G ,  v );
                count ++ ;
             }
         }

         // check that id[] gives strong components
         assert  check ( G );
     }

     // DFS on graph G
     private   void  dfs ( Digraph  G ,   int  v )   {  
        marked [ v ]   =   true ;
        id [ v ]   =  count ;
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])  dfs ( G ,  w );
         }
     }

     /**
     * Returns the number of strong components.
     *  @return  the number of strong components
     */
     public   int  count ()   {
         return  count ;
     }

     /**
     * Are vertices { @code  v} and { @code  w} in the same strong component?
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same
     *         strong component, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     */
     public   boolean  stronglyConnected ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  id [ v ]   ==  id [ w ];
     }

     /**
     * Returns the component id of the strong component containing vertex { @code  v}.
     *  @param   v the vertex
     *  @return  the component id of the strong component containing vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   int  id ( int  v )   {
        validateVertex ( v );
         return  id [ v ];
     }

     // does the id[] array contain the strongly connected components?
     private   boolean  check ( Digraph  G )   {
         TransitiveClosure  tc  =   new   TransitiveClosure ( G );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))
                     return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  KosarajuSharirSCC} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         KosarajuSharirSCC  scc  =   new   KosarajuSharirSCC ( G );

         // number of connected components
         int  m  =  scc . count ();
         StdOut . println ( +   " strong components" );

         // compute list of vertices in each strong component
         Queue < Integer > []  components  =   ( Queue < Integer > [])   new   Queue [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
            components [ i ]   =   new   Queue < Integer > ();
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            components [ scc . id ( v )]. enqueue ( v );
         }

         // print results
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  v  :  components [ i ])   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/KruskalMST.java

edu/princeton/cs/algs4/KruskalMST.java

/******************************************************************************
 *  Compilation:  javac KruskalMST.java
 *  Execution:    java  KruskalMST filename.txt
 *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java MinPQ.java
 *                UF.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  Compute a minimum spanning forest using Kruskal's algorithm.
 *
 *  %  java KruskalMST tinyEWG.txt 
 *  0-7 0.16000
 *  2-3 0.17000
 *  1-7 0.19000
 *  0-2 0.26000
 *  5-7 0.28000
 *  4-5 0.35000
 *  6-2 0.40000
 *  1.81000
 *
 *  % java KruskalMST mediumEWG.txt
 *  168-231 0.00268
 *  151-208 0.00391
 *  7-157   0.00516
 *  122-205 0.00647
 *  8-152   0.00702
 *  156-219 0.00745
 *  28-198  0.00775
 *  38-126  0.00845
 *  10-123  0.00886
 *  ...
 *  10.46351
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  KruskalMST} class represents a data type for computing a
 *  <em>minimum spanning tree</em> in an edge-weighted graph.
 *  The edge weights can be positive, zero, or negative and need not
 *  be distinct. If the graph is not connected, it computes a <em>minimum
 *  spanning forest</em>, which is the union of minimum spanning trees
 *  in each connected component. The { @code  weight()} method returns the 
 *  weight of a minimum spanning tree and the { @code  edges()} method
 *  returns its edges.
 *  <p>
 *  This implementation uses <em>Krusal's algorithm</em> and the
 *  union-find data type.
 *  The constructor takes &Theta;(<em>E</em> log <em>E</em>) time in
 *  the worst case.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>E</em>) extra space (not including the graph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For alternate implementations, see { @link  LazyPrimMST}, { @link  PrimMST},
 *  and { @link  BoruvkaMST}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   KruskalMST   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-12 ;

     private   double  weight ;                          // weight of MST
     private   Queue < Edge >  mst  =   new   Queue < Edge > ();    // edges in MST

     /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     *  @param  G the edge-weighted graph
     */
     public   KruskalMST ( EdgeWeightedGraph  G )   {
         // more efficient to build heap by passing array of edges
         MinPQ < Edge >  pq  =   new   MinPQ < Edge > ();
         for   ( Edge  e  :  G . edges ())   {
            pq . insert ( e );
         }

         // run greedy algorithm
        UF uf  =   new  UF ( G . V ());
         while   ( ! pq . isEmpty ()   &&  mst . size ()   <  G . V ()   -   1 )   {
             Edge  e  =  pq . delMin ();
             int  v  =  e . either ();
             int  w  =  e . other ( v );
             if   ( uf . find ( v )   !=  uf . find ( w ))   {   // v-w does not create a cycle
                uf . union ( v ,  w );    // merge v and w components
                mst . enqueue ( e );    // add edge e to mst
                weight  +=  e . weight ();
             }
         }

         // check optimality conditions
         assert  check ( G );
     }

     /**
     * Returns the edges in a minimum spanning tree (or forest).
     *  @return  the edges in a minimum spanning tree (or forest) as
     *    an iterable of edges
     */
     public   Iterable < Edge >  edges ()   {
         return  mst ;
     }

     /**
     * Returns the sum of the edge weights in a minimum spanning tree (or forest).
     *  @return  the sum of the edge weights in a minimum spanning tree (or forest)
     */
     public   double  weight ()   {
         return  weight ;
     }
    
     // check optimality conditions (takes time proportional to E V lg* V)
     private   boolean  check ( EdgeWeightedGraph  G )   {

         // check total weight
         double  total  =   0.0 ;
         for   ( Edge  e  :  edges ())   {
            total  +=  e . weight ();
         }
         if   ( Math . abs ( total  -  weight ())   >  FLOATING_POINT_EPSILON )   {
             System . err . printf ( "Weight of edges does not equal weight(): %f vs. %f\n" ,  total ,  weight ());
             return   false ;
         }

         // check that it is acyclic
        UF uf  =   new  UF ( G . V ());
         for   ( Edge  e  :  edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   ==  uf . find ( w ))   {
                 System . err . println ( "Not a forest" );
                 return   false ;
             }
            uf . union ( v ,  w );
         }

         // check that it is a spanning forest
         for   ( Edge  e  :  G . edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   !=  uf . find ( w ))   {
                 System . err . println ( "Not a spanning forest" );
                 return   false ;
             }
         }

         // check that it is a minimal spanning forest (cut optimality conditions)
         for   ( Edge  e  :  edges ())   {

             // all edges in MST except e
            uf  =   new  UF ( G . V ());
             for   ( Edge  f  :  mst )   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( !=  e )  uf . union ( x ,  y );
             }
            
             // check that e is min weight edge in crossing cut
             for   ( Edge  f  :  G . edges ())   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( uf . find ( x )   !=  uf . find ( y ))   {
                     if   ( f . weight ()   <  e . weight ())   {
                         System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );
                         return   false ;
                     }
                 }
             }

         }

         return   true ;
     }


     /**
     * Unit tests the { @code  KruskalMST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         KruskalMST  mst  =   new   KruskalMST ( G );
         for   ( Edge  e  :  mst . edges ())   {
             StdOut . println ( e );
         }
         StdOut . printf ( "%.5f\n" ,  mst . weight ());
     }

}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/KWIK.java

edu/princeton/cs/algs4/KWIK.java

/******************************************************************************
 *  Compilation:  javac KWIK.java
 *  Execution:    java KWIK file.txt
 *  Dependencies: StdIn.java StdOut.java In.java SuffixArray.java
 *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt
 *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt 
 *
 *  Keyword-in-context search.
 *
 *  %  java KWIK tale.txt 15
 *  majesty
 *   most gracious majesty king george th
 *  rnkeys and the majesty of the law fir
 *  on against the majesty of the people 
 *  se them to his majestys chief secreta
 *  h lists of his majestys forces and of
 *
 *  the worst
 *  w the best and the worst are known to y
 *  f them give me the worst first there th
 *  for in case of the worst is a friend in
 *  e roomdoor and the worst is over then a
 *  pect mr darnay the worst its the wisest
 *  is his brother the worst of a bad race 
 *  ss in them for the worst of health for 
 *   you have seen the worst of her agitati
 *  cumwented into the worst of luck buuust
 *  n your brother the worst of the bad rac
 *   full share in the worst of the day pla
 *  mes to himself the worst of the strife 
 *  f times it was the worst of times it wa
 *  ould hope that the worst was over well 
 *  urage business the worst will be over i
 *  clesiastics of the worst world worldly 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  KWIK} class provides a { @link  SuffixArray} client for computing
 *  all occurrences of a keyword in a given string, with surrounding context.
 *  This is known as <em>keyword-in-context search</em>.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/63suffix">Section 6.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  KWIK  {

     // Do not instantiate.
     private  KWIK ()   {   }

     /**
     * Reads a string from a file specified as the first
     * command-line argument; read an integer k specified as the
     * second command line argument; then repeatedly processes
     * use queries, printing all occurrences of the given query
     * string in the text string with k characters of surrounding
     * context on either side.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         int  context  =   Integer . parseInt ( args [ 1 ]);

         // read in text
         String  text  =  in . readAll (). replaceAll ( "\\s+" ,   " " );
         int  n  =  text . length ();

         // build suffix array
         SuffixArray  sa  =   new   SuffixArray ( text );

         // find all occurrences of queries and give context
         while   ( StdIn . hasNextLine ())   {
             String  query  =   StdIn . readLine ();
             for   ( int  i  =  sa . rank ( query );  i  <  n ;  i ++ )   {
                 int  from1  =  sa . index ( i );
                 int  to1    =   Math . min ( n ,  from1  +  query . length ());
                 if   ( ! query . equals ( text . substring ( from1 ,  to1 )))   break ;
                 int  from2  =   Math . max ( 0 ,  sa . index ( i )   -  context );
                 int  to2    =   Math . min ( n ,  sa . index ( i )   +  context  +  query . length ());
                 StdOut . println ( text . substring ( from2 ,  to2 ));
             }
             StdOut . println ();
         }
     }  
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LazyPrimMST.java

edu/princeton/cs/algs4/LazyPrimMST.java

/******************************************************************************
 *  Compilation:  javac LazyPrimMST.java
 *  Execution:    java LazyPrimMST filename.txt
 *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java
 *                MinPQ.java UF.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  Compute a minimum spanning forest using a lazy version of Prim's 
 *  algorithm.
 *
 *  %  java LazyPrimMST tinyEWG.txt 
 *  0-7 0.16000
 *  1-7 0.19000
 *  0-2 0.26000
 *  2-3 0.17000
 *  5-7 0.28000
 *  4-5 0.35000
 *  6-2 0.40000
 *  1.81000
 *
 *  % java LazyPrimMST mediumEWG.txt
 *  0-225   0.02383
 *  49-225  0.03314
 *  44-49   0.02107
 *  44-204  0.01774
 *  49-97   0.03121
 *  202-204 0.04207
 *  176-202 0.04299
 *  176-191 0.02089
 *  68-176  0.04396
 *  58-68   0.04795
 *  10.46351
 *
 *  % java LazyPrimMST largeEWG.txt
 *  ...
 *  647.66307
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LazyPrimMST} class represents a data type for computing a
 *  <em>minimum spanning tree</em> in an edge-weighted graph.
 *  The edge weights can be positive, zero, or negative and need not
 *  be distinct. If the graph is not connected, it computes a <em>minimum
 *  spanning forest</em>, which is the union of minimum spanning trees
 *  in each connected component. The { @code  weight()} method returns the 
 *  weight of a minimum spanning tree and the { @code  edges()} method
 *  returns its edges.
 *  <p>
 *  This implementation uses a lazy version of <em>Prim's algorithm</em>
 *  with a binary heap of edges.
 *  The constructor takes &Theta;(<em>E</em> log <em>E</em>) time in
 *  the worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>E</em>) extra space in the worst case
 *  (not including the edge-weighted graph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For alternate implementations, see { @link  PrimMST}, { @link  KruskalMST},
 *  and { @link  BoruvkaMST}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LazyPrimMST   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-12 ;

     private   double  weight ;         // total weight of MST
     private   Queue < Edge >  mst ;       // edges in the MST
     private   boolean []  marked ;      // marked[v] = true iff v on tree
     private   MinPQ < Edge >  pq ;        // edges with one endpoint in tree

     /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     *  @param  G the edge-weighted graph
     */
     public   LazyPrimMST ( EdgeWeightedGraph  G )   {
        mst  =   new   Queue < Edge > ();
        pq  =   new   MinPQ < Edge > ();
        marked  =   new   boolean [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )       // run Prim from all vertices to
             if   ( ! marked [ v ])  prim ( G ,  v );       // get a minimum spanning forest

         // check optimality conditions
         assert  check ( G );
     }

     // run Prim's algorithm
     private   void  prim ( EdgeWeightedGraph  G ,   int  s )   {
        scan ( G ,  s );
         while   ( ! pq . isEmpty ())   {                          // better to stop when mst has V-1 edges
             Edge  e  =  pq . delMin ();                        // smallest edge on pq
             int  v  =  e . either (),  w  =  e . other ( v );          // two endpoints
             assert  marked [ v ]   ||  marked [ w ];
             if   ( marked [ v ]   &&  marked [ w ])   continue ;        // lazy, both v and w already scanned
            mst . enqueue ( e );                              // add e to MST
            weight  +=  e . weight ();
             if   ( ! marked [ v ])  scan ( G ,  v );                 // v becomes part of tree
             if   ( ! marked [ w ])  scan ( G ,  w );                 // w becomes part of tree
         }
     }

     // add all edges e incident to v onto pq if the other endpoint has not yet been scanned
     private   void  scan ( EdgeWeightedGraph  G ,   int  v )   {
         assert   ! marked [ v ];
        marked [ v ]   =   true ;
         for   ( Edge  e  :  G . adj ( v ))
             if   ( ! marked [ e . other ( v )])  pq . insert ( e );
     }
        
     /**
     * Returns the edges in a minimum spanning tree (or forest).
     *  @return  the edges in a minimum spanning tree (or forest) as
     *    an iterable of edges
     */
     public   Iterable < Edge >  edges ()   {
         return  mst ;
     }

     /**
     * Returns the sum of the edge weights in a minimum spanning tree (or forest).
     *  @return  the sum of the edge weights in a minimum spanning tree (or forest)
     */
     public   double  weight ()   {
         return  weight ;
     }

     // check optimality conditions (takes time proportional to E V lg* V)
     private   boolean  check ( EdgeWeightedGraph  G )   {

         // check weight
         double  totalWeight  =   0.0 ;
         for   ( Edge  e  :  edges ())   {
            totalWeight  +=  e . weight ();
         }
         if   ( Math . abs ( totalWeight  -  weight ())   >  FLOATING_POINT_EPSILON )   {
             System . err . printf ( "Weight of edges does not equal weight(): %f vs. %f\n" ,  totalWeight ,  weight ());
             return   false ;
         }

         // check that it is acyclic
        UF uf  =   new  UF ( G . V ());
         for   ( Edge  e  :  edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   ==  uf . find ( w ))   {
                 System . err . println ( "Not a forest" );
                 return   false ;
             }
            uf . union ( v ,  w );
         }

         // check that it is a spanning forest
         for   ( Edge  e  :  G . edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   !=  uf . find ( w ))   {
                 System . err . println ( "Not a spanning forest" );
                 return   false ;
             }
         }

         // check that it is a minimal spanning forest (cut optimality conditions)
         for   ( Edge  e  :  edges ())   {

             // all edges in MST except e
            uf  =   new  UF ( G . V ());
             for   ( Edge  f  :  mst )   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( !=  e )  uf . union ( x ,  y );
             }

             // check that e is min weight edge in crossing cut
             for   ( Edge  f  :  G . edges ())   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( uf . find ( x )   !=  uf . find ( y ))   {
                     if   ( f . weight ()   <  e . weight ())   {
                         System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );
                         return   false ;
                     }
                 }
             }

         }

         return   true ;
     }
    
    
     /**
     * Unit tests the { @code  LazyPrimMST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         LazyPrimMST  mst  =   new   LazyPrimMST ( G );
         for   ( Edge  e  :  mst . edges ())   {
             StdOut . println ( e );
         }
         StdOut . printf ( "%.5f\n" ,  mst . weight ());
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinearProbingHashST.java

edu/princeton/cs/algs4/LinearProbingHashST.java

/******************************************************************************
 *  Compilation:  javac LinearProbingHashST.java
 *  Execution:    java LinearProbingHashST < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/34hash/tinyST.txt
 *  
 *  Symbol-table implementation with linear-probing hash table.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LinearProbingHashST} class represents a symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This implementation uses a linear probing hash table. It requires that
 *  the key type overrides the { @code  equals()} and { @code  hashCode()} methods.
 *  The expected time per <em>put</em>, <em>contains</em>, or <em>remove</em>
 *  operation is constant, subject to the uniform hashing assumption.
 *  The <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction takes constant time.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/34hash">Section 3.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For other implementations, see { @link  ST}, { @link  BinarySearchST},
 *  { @link  SequentialSearchST}, { @link  BST}, { @link  RedBlackBST}, and
 *  { @link  SeparateChainingHashST},
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinearProbingHashST < Key ,   Value >   {
     private   static   final   int  INIT_CAPACITY  =   4 ;

     private   int  n ;             // number of key-value pairs in the symbol table
     private   int  m ;             // size of linear probing table
     private   Key []  keys ;        // the keys
     private   Value []  vals ;      // the values


     /**
     * Initializes an empty symbol table.
     */
     public   LinearProbingHashST ()   {
         this ( INIT_CAPACITY );
     }

     /**
     * Initializes an empty symbol table with the specified initial capacity.
     *
     *  @param  capacity the initial capacity
     */
     public   LinearProbingHashST ( int  capacity )   {
        m  =  capacity ;
        n  =   0 ;
        keys  =   ( Key [])     new   Object [ m ];
        vals  =   ( Value [])   new   Object [ m ];
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns true if this symbol table is empty.
     *
     *  @return  { @code  true} if this symbol table is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns true if this symbol table contains the specified key.
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key};
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }

     // hash function for keys - returns value between 0 and M-1
     private   int  hash ( Key  key )   {
         return   ( key . hashCode ()   &   0x7fffffff )   %  m ;
     }

     // resizes the hash table to the given capacity by re-hashing all of the keys
     private   void  resize ( int  capacity )   {
         LinearProbingHashST < Key ,   Value >  temp  =   new   LinearProbingHashST < Key ,   Value > ( capacity );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             if   ( keys [ i ]   !=   null )   {
                temp . put ( keys [ i ],  vals [ i ]);
             }
         }
        keys  =  temp . keys ;
        vals  =  temp . vals ;
        m     =  temp . m ;
     }

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );

         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }

         // double table size if 50% full
         if   ( >=  m / 2 )  resize ( 2 * m );

         int  i ;
         for   ( =  hash ( key );  keys [ i ]   !=   null ;  i  =   ( +   1 )   %  m )   {
             if   ( keys [ i ]. equals ( key ))   {
                vals [ i ]   =  val ;
                 return ;
             }
         }
        keys [ i ]   =  key ;
        vals [ i ]   =  val ;
        n ++ ;
     }

     /**
     * Returns the value associated with the specified key.
     *  @param  key the key
     *  @return  the value associated with { @code  key};
     *         { @code  null} if no such value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         for   ( int  i  =  hash ( key );  keys [ i ]   !=   null ;  i  =   ( +   1 )   %  m )
             if   ( keys [ i ]. equals ( key ))
                 return  vals [ i ];
         return   null ;
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).    
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );
         if   ( ! contains ( key ))   return ;

         // find position i of key
         int  i  =  hash ( key );
         while   ( ! key . equals ( keys [ i ]))   {
            i  =   ( +   1 )   %  m ;
         }

         // delete key and associated value
        keys [ i ]   =   null ;
        vals [ i ]   =   null ;

         // rehash all keys in same cluster
        i  =   ( +   1 )   %  m ;
         while   ( keys [ i ]   !=   null )   {
             // delete keys[i] an vals[i] and reinsert
             Key    keyToRehash  =  keys [ i ];
             Value  valToRehash  =  vals [ i ];
            keys [ i ]   =   null ;
            vals [ i ]   =   null ;
            n -- ;
            put ( keyToRehash ,  valToRehash );
            i  =   ( +   1 )   %  m ;
         }

        n -- ;

         // halves size of array if it's 12.5% full or less
         if   ( >   0   &&  n  <=  m / 8 )  resize ( m / 2 );

         assert  check ();
     }

     /**
     * Returns all keys in this symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *
     *  @return  all keys in this symbol table
     */
     public   Iterable < Key >  keys ()   {
         Queue < Key >  queue  =   new   Queue < Key > ();
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             if   ( keys [ i ]   !=   null )  queue . enqueue ( keys [ i ]);
         return  queue ;
     }

     // integrity check - don't check after each put() because
     // integrity not maintained during a delete()
     private   boolean  check ()   {

         // check that hash table is at most 50% full
         if   ( <   2 * n )   {
             System . err . println ( "Hash table size m = "   +  m  +   "; array size n = "   +  n );
             return   false ;
         }

         // check that each key in table can be found by get()
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             if   ( keys [ i ]   ==   null )   continue ;
             else   if   ( get ( keys [ i ])   !=  vals [ i ])   {
                 System . err . println ( "get["   +  keys [ i ]   +   "] = "   +  get ( keys [ i ])   +   "; vals[i] = "   +  vals [ i ]);
                 return   false ;
             }
         }
         return   true ;
     }


     /**
     * Unit tests the { @code  LinearProbingHashST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         LinearProbingHashST < String ,   Integer >  st  =   new   LinearProbingHashST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }

         // print keys
         for   ( String  s  :  st . keys ())  
             StdOut . println ( +   " "   +  st . get ( s ));  
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinearProgramming.java

edu/princeton/cs/algs4/LinearProgramming.java

/******************************************************************************
 *  Compilation:  javac LinearProgramming.java
 *  Execution:    java LinearProgramming m n
 *  Dependencies: StdOut.java
 *
 *  Given an m-by-n matrix A, an m-length vector b, and an
 *  n-length vector c, solve the  LP { max cx : Ax <= b, x >= 0 }.
 *  Assumes that b >= 0 so that x = 0 is a basic feasible solution.
 *
 *  Creates an (m+1)-by-(n+m+1) simplex tableaux with the 
 *  RHS in column m+n, the objective function in row m, and
 *  slack variables in columns m through m+n-1.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LinearProgramming} class represents a data type for solving a
 *  linear program of the form { max cx : Ax &le; b, x &ge; 0 }, where A is a m-by-n
 *  matrix, b is an m-length vector, and c is an n-length vector. For simplicity,
 *  we assume that A is of full rank and that b &ge; 0 so that x = 0 is a basic
 *  feasible soution.
 *  <p>
 *  The data type supplies methods for determining the optimal primal and
 *  dual solutions.
 *  <p>
 *  This is a bare-bones implementation of the <em>simplex algorithm</em>.
 *  It uses Bland's rule to determing the entering and leaving variables.
 *  It is not suitable for use on large inputs. It is also not robust
 *  in the presence of floating-point roundoff error.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/65reductions">Section 6.5</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinearProgramming   {
     private   static   final   double  EPSILON  =   1.0E-10 ;
     private   double [][]  a ;     // tableaux
     private   int  m ;            // number of constraints
     private   int  n ;            // number of original variables

     private   int []  basis ;      // basis[i] = basic variable corresponding to row i
                             // only needed to print out solution, not book

     /**
     * Determines an optimal solution to the linear program
     * { max cx : Ax &le; b, x &ge; 0 }, where A is a m-by-n
     * matrix, b is an m-length vector, and c is an n-length vector.
     *
     *  @param   A the <em>m</em>-by-<em>b</em> matrix
     *  @param   b the <em>m</em>-length RHS vector
     *  @param   c the <em>n</em>-length cost vector
     *  @throws  IllegalArgumentException unless { @code  b[i] >= 0} for each { @code  i}
     *  @throws  ArithmeticException if the linear program is unbounded
     */  
     public   LinearProgramming ( double [][]  A ,   double []  b ,   double []  c )   {
        m  =  b . length ;
        n  =  c . length ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             if   ( ! ( b [ i ]   >=   0 ))   throw   new   IllegalArgumentException ( "RHS must be nonnegative" );

        a  =   new   double [ m + 1 ][ n + m + 1 ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                a [ i ][ j ]   =  A [ i ][ j ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            a [ i ][ n + i ]   =   1.0 ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            a [ m ][ j ]   =  c [ j ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            a [ i ][ m + n ]   =  b [ i ];

        basis  =   new   int [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            basis [ i ]   =  n  +  i ;

        solve ();

         // check optimality conditions
         assert  check ( A ,  b ,  c );
     }

     // run simplex algorithm starting from initial BFS
     private   void  solve ()   {
         while   ( true )   {

             // find entering column q
             int  q  =  bland ();
             if   ( ==   - 1 )   break ;    // optimal

             // find leaving row p
             int  p  =  minRatioRule ( q );
             if   ( ==   - 1 )   throw   new   ArithmeticException ( "Linear program is unbounded" );

             // pivot
            pivot ( p ,  q );

             // update basis
            basis [ p ]   =  q ;
         }
     }

     // lowest index of a non-basic column with a positive cost
     private   int  bland ()   {
         for   ( int  j  =   0 ;  j  <  m + n ;  j ++ )
             if   ( a [ m ][ j ]   >   0 )   return  j ;
         return   - 1 ;    // optimal
     }

    // index of a non-basic column with most positive cost
     private   int  dantzig ()   {
         int  q  =   0 ;
         for   ( int  j  =   1 ;  j  <  m + n ;  j ++ )
             if   ( a [ m ][ j ]   >  a [ m ][ q ])  q  =  j ;

         if   ( a [ m ][ q ]   <=   0 )   return   - 1 ;    // optimal
         else   return  q ;
     }

     // find row p using min ratio rule (-1 if no such row)
     // (smallest such index if there is a tie)
     private   int  minRatioRule ( int  q )   {
         int  p  =   - 1 ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             // if (a[i][q] <= 0) continue;
             if   ( a [ i ][ q ]   <=  EPSILON )   continue ;
             else   if   ( ==   - 1 )  p  =  i ;
             else   if   (( a [ i ][ m + n ]   /  a [ i ][ q ])   <   ( a [ p ][ m + n ]   /  a [ p ][ q ]))  p  =  i ;
         }
         return  p ;
     }

     // pivot on entry (p, q) using Gauss-Jordan elimination
     private   void  pivot ( int  p ,   int  q )   {

         // everything but row p and column q
         for   ( int  i  =   0 ;  i  <=  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )
                 if   ( !=  p  &&  j  !=  q )  a [ i ][ j ]   -=  a [ p ][ j ]   *  a [ i ][ q ]   /  a [ p ][ q ];

         // zero out column q
         for   ( int  i  =   0 ;  i  <=  m ;  i ++ )
             if   ( !=  p )  a [ i ][ q ]   =   0.0 ;

         // scale row p
         for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )
             if   ( !=  q )  a [ p ][ j ]   /=  a [ p ][ q ];
        a [ p ][ q ]   =   1.0 ;
     }

     /**
     * Returns the optimal value of this linear program.
     *
     *  @return  the optimal value of this linear program
     *
     */
     public   double  value ()   {
         return   - a [ m ][ m + n ];
     }

     /**
     * Returns the optimal primal solution to this linear program.
     *
     *  @return  the optimal primal solution to this linear program
     */
     public   double []  primal ()   {
         double []  x  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             if   ( basis [ i ]   <  n )  x [ basis [ i ]]   =  a [ i ][ m + n ];
         return  x ;
     }

     /**
     * Returns the optimal dual solution to this linear program
     *
     *  @return  the optimal dual solution to this linear program
     */
     public   double []  dual ()   {
         double []  y  =   new   double [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            y [ i ]   =   - a [ m ][ n + i ];
         return  y ;
     }


     // is the solution primal feasible?
     private   boolean  isPrimalFeasible ( double [][]  A ,   double []  b )   {
         double []  x  =  primal ();

         // check that x >= 0
         for   ( int  j  =   0 ;  j  <  x . length ;  j ++ )   {
             if   ( x [ j ]   <   0.0 )   {
                 StdOut . println ( "x["   +  j  +   "] = "   +  x [ j ]   +   " is negative" );
                 return   false ;
             }
         }

         // check that Ax <= b
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             double  sum  =   0.0 ;
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                sum  +=  A [ i ][ j ]   *  x [ j ];
             }
             if   ( sum  >  b [ i ]   +  EPSILON )   {
                 StdOut . println ( "not primal feasible" );
                 StdOut . println ( "b["   +  i  +   "] = "   +  b [ i ]   +   ", sum = "   +  sum );
                 return   false ;
             }
         }
         return   true ;
     }

     // is the solution dual feasible?
     private   boolean  isDualFeasible ( double [][]  A ,   double []  c )   {
         double []  y  =  dual ();

         // check that y >= 0
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )   {
             if   ( y [ i ]   <   0.0 )   {
                 StdOut . println ( "y["   +  i  +   "] = "   +  y [ i ]   +   " is negative" );
                 return   false ;
             }
         }

         // check that yA >= c
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
             double  sum  =   0.0 ;
             for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
                sum  +=  A [ i ][ j ]   *  y [ i ];
             }
             if   ( sum  <  c [ j ]   -  EPSILON )   {
                 StdOut . println ( "not dual feasible" );
                 StdOut . println ( "c["   +  j  +   "] = "   +  c [ j ]   +   ", sum = "   +  sum );
                 return   false ;
             }
         }
         return   true ;
     }

     // check that optimal value = cx = yb
     private   boolean  isOptimal ( double []  b ,   double []  c )   {
         double []  x  =  primal ();
         double []  y  =  dual ();
         double  value  =  value ();

         // check that value = cx = yb
         double  value1  =   0.0 ;
         for   ( int  j  =   0 ;  j  <  x . length ;  j ++ )
            value1  +=  c [ j ]   *  x [ j ];
         double  value2  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )
            value2  +=  y [ i ]   *  b [ i ];
         if   ( Math . abs ( value  -  value1 )   >  EPSILON  ||   Math . abs ( value  -  value2 )   >  EPSILON )   {
             StdOut . println ( "value = "   +  value  +   ", cx = "   +  value1  +   ", yb = "   +  value2 );
             return   false ;
         }

         return   true ;
     }

     private   boolean  check ( double [][] A ,   double []  b ,   double []  c )   {
         return  isPrimalFeasible ( A ,  b )   &&  isDualFeasible ( A ,  c )   &&  isOptimal ( b ,  c );
     }

     // print tableaux
     private   void  show ()   {
         StdOut . println ( "m = "   +  m );
         StdOut . println ( "n = "   +  n );
         for   ( int  i  =   0 ;  i  <=  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <=  m + n ;  j ++ )   {
                 StdOut . printf ( "%7.2f " ,  a [ i ][ j ]);
                 // StdOut.printf("%10.7f ", a[i][j]);
             }
             StdOut . println ();
         }
         StdOut . println ( "value = "   +  value ());
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             if   ( basis [ i ]   <  n )   StdOut . println ( "x_"   +  basis [ i ]   +   " = "   +  a [ i ][ m + n ]);
         StdOut . println ();
     }


     private   static   void  test ( double [][]  A ,   double []  b ,   double []  c )   {
         LinearProgramming  lp ;
         try   {
            lp  =   new   LinearProgramming ( A ,  b ,  c );
         }
         catch   ( ArithmeticException  e )   {
             System . out . println ( e );
             return ;
         }

         StdOut . println ( "value = "   +  lp . value ());
         double []  x  =  lp . primal ();
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )
             StdOut . println ( "x["   +  i  +   "] = "   +  x [ i ]);
         double []  y  =  lp . dual ();
         for   ( int  j  =   0 ;  j  <  y . length ;  j ++ )
             StdOut . println ( "y["   +  j  +   "] = "   +  y [ j ]);
     }

     private   static   void  test1 ()   {
         double [][]  A  =   {
             {   - 1 ,    1 ,    0   },
             {    1 ,    4 ,    0   },
             {    2 ,    1 ,    0   },
             {    3 ,   - 4 ,    0   },
             {    0 ,    0 ,    1   },
         };
         double []  c  =   {   1 ,   1 ,   1   };
         double []  b  =   {   5 ,   45 ,   27 ,   24 ,   4   };
        test ( A ,  b ,  c );
     }


     // x0 = 12, x1 = 28, opt = 800
     private   static   void  test2 ()   {
         double []  c  =   {    13.0 ,    23.0   };
         double []  b  =   {   480.0 ,   160.0 ,   1190.0   };
         double [][]  A  =   {
             {    5.0 ,   15.0   },
             {    4.0 ,    4.0   },
             {   35.0 ,   20.0   },
         };
        test ( A ,  b ,  c );
     }

     // unbounded
     private   static   void  test3 ()   {
         double []  c  =   {   2.0 ,   3.0 ,   - 1.0 ,   - 12.0   };
         double []  b  =   {    3.0 ,     2.0   };
         double [][]  A  =   {
             {   - 2.0 ,   - 9.0 ,    1.0 ,    9.0   },
             {    1.0 ,    1.0 ,   - 1.0 ,   - 2.0   },
         };
        test ( A ,  b ,  c );
     }

     // degenerate - cycles if you choose most positive objective function coefficient
     private   static   void  test4 ()   {
         double []  c  =   {   10.0 ,   - 57.0 ,   - 9.0 ,   - 24.0   };
         double []  b  =   {    0.0 ,     0.0 ,    1.0   };
         double [][]  A  =   {
             {   0.5 ,   - 5.5 ,   - 2.5 ,   9.0   },
             {   0.5 ,   - 1.5 ,   - 0.5 ,   1.0   },
             {   1.0 ,    0.0 ,    0.0 ,   0.0   },
         };
        test ( A ,  b ,  c );
     }


     /**
     * Unit tests the { @code  LinearProgramming} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         StdOut . println ( "----- test 1 --------------------" );
        test1 ();
         StdOut . println ();

         StdOut . println ( "----- test 2 --------------------" );
        test2 ();
         StdOut . println ();

         StdOut . println ( "----- test 3 --------------------" );
        test3 ();
         StdOut . println ();

         StdOut . println ( "----- test 4 --------------------" );
        test4 ();
         StdOut . println ();

         StdOut . println ( "----- test random ---------------" );
         int  m  =   Integer . parseInt ( args [ 0 ]);
         int  n  =   Integer . parseInt ( args [ 1 ]);
         double []  c  =   new   double [ n ];
         double []  b  =   new   double [ m ];
         double [][]  A  =   new   double [ m ][ n ];
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            c [ j ]   =   StdRandom . uniform ( 1000 );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            b [ i ]   =   StdRandom . uniform ( 1000 );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                A [ i ][ j ]   =   StdRandom . uniform ( 100 );
         LinearProgramming  lp  =   new   LinearProgramming ( A ,  b ,  c );
        test ( A ,  b ,  c );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinearRegression.java

edu/princeton/cs/algs4/LinearRegression.java

/******************************************************************************
 *  Compilation:  javac LinearRegression.java
 *  Execution:    java  LinearRegression
 *  Dependencies: none
 *  
 *  Compute least squares solution to y = beta * x + alpha.
 *  Simple linear regression.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  LinearRegression} class performs a simple linear regression
 *  on an set of <em>n</em> data points (<em>y<sub>i</sub></em>, <em>x<sub>i</sub></em>).
 *  That is, it fits a straight line <em>y</em> = &alpha; + &beta; <em>x</em>,
 *  (where <em>y</em> is the response variable, <em>x</em> is the predictor variable,
 *  &alpha; is the <em>y-intercept</em>, and &beta; is the <em>slope</em>)
 *  that minimizes the sum of squared residuals of the linear regression model.
 *  It also computes associated statistics, including the coefficient of
 *  determination <em>R</em><sup>2</sup> and the standard deviation of the
 *  estimates for the slope and <em>y</em>-intercept.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinearRegression   {
     private   final   double  intercept ,  slope ;
     private   final   double  r2 ;
     private   final   double  svar0 ,  svar1 ;

    /**
     * Performs a linear regression on the data points { @code  (y[i], x[i])}.
     *
     *  @param   x the values of the predictor variable
     *  @param   y the corresponding values of the response variable
     *  @throws  IllegalArgumentException if the lengths of the two arrays are not equal
     */
     public   LinearRegression ( double []  x ,   double []  y )   {
         if   ( x . length  !=  y . length )   {
             throw   new   IllegalArgumentException ( "array lengths are not equal" );
         }
         int  n  =  x . length ;

         // first pass
         double  sumx  =   0.0 ,  sumy  =   0.0 ,  sumx2  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            sumx   +=  x [ i ];
            sumx2  +=  x [ i ] * x [ i ];
            sumy   +=  y [ i ];
         }
         double  xbar  =  sumx  /  n ;
         double  ybar  =  sumy  /  n ;

         // second pass: compute summary statistics
         double  xxbar  =   0.0 ,  yybar  =   0.0 ,  xybar  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            xxbar  +=   ( x [ i ]   -  xbar )   *   ( x [ i ]   -  xbar );
            yybar  +=   ( y [ i ]   -  ybar )   *   ( y [ i ]   -  ybar );
            xybar  +=   ( x [ i ]   -  xbar )   *   ( y [ i ]   -  ybar );
         }
        slope   =  xybar  /  xxbar ;
        intercept  =  ybar  -  slope  *  xbar ;

         // more statistical analysis
         double  rss  =   0.0 ;        // residual sum of squares
         double  ssr  =   0.0 ;        // regression sum of squares
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             double  fit  =  slope * x [ i ]   +  intercept ;
            rss  +=   ( fit  -  y [ i ])   *   ( fit  -  y [ i ]);
            ssr  +=   ( fit  -  ybar )   *   ( fit  -  ybar );
         }

         int  degreesOfFreedom  =  n - 2 ;
        r2     =  ssr  /  yybar ;
         double  svar   =  rss  /  degreesOfFreedom ;
        svar1  =  svar  /  xxbar ;
        svar0  =  svar / +  xbar * xbar * svar1 ;
     }

    /**
     * Returns the <em>y</em>-intercept &alpha; of the best of the best-fit line <em>y</em> = &alpha; + &beta; <em>x</em>.
     *
     *  @return  the <em>y</em>-intercept &alpha; of the best-fit line <em>y = &alpha; + &beta; x</em>
     */
     public   double  intercept ()   {
         return  intercept ;
     }

    /**
     * Returns the slope &beta; of the best of the best-fit line <em>y</em> = &alpha; + &beta; <em>x</em>.
     *
     *  @return  the slope &beta; of the best-fit line <em>y</em> = &alpha; + &beta; <em>x</em>
     */
     public   double  slope ()   {
         return  slope ;
     }

    /**
     * Returns the coefficient of determination <em>R</em><sup>2</sup>.
     *
     *  @return  the coefficient of determination <em>R</em><sup>2</sup>,
     *         which is a real number between 0 and 1
     */
     public   double  R2 ()   {
         return  r2 ;
     }

    /**
     * Returns the standard error of the estimate for the intercept.
     *
     *  @return  the standard error of the estimate for the intercept
     */
     public   double  interceptStdErr ()   {
         return   Math . sqrt ( svar0 );
     }

    /**
     * Returns the standard error of the estimate for the slope.
     *
     *  @return  the standard error of the estimate for the slope
     */
     public   double  slopeStdErr ()   {
         return   Math . sqrt ( svar1 );
     }

    /**
     * Returns the expected response { @code  y} given the value of the predictor
     * variable { @code  x}.
     *
     *  @param   x the value of the predictor variable
     *  @return  the expected response { @code  y} given the value of the predictor
     *         variable { @code  x}
     */
     public   double  predict ( double  x )   {
         return  slope * +  intercept ;
     }

    /**
     * Returns a string representation of the simple linear regression model.
     *
     *  @return  a string representation of the simple linear regression model,
     *         including the best-fit line and the coefficient of determination
     *         <em>R</em><sup>2</sup>
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
        s . append ( String . format ( "%.2f n + %.2f" ,  slope (),  intercept ()));
        s . append ( "  (R^2 = "   +   String . format ( "%.3f" ,  R2 ())   +   ")" );
         return  s . toString ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinkedBag.java

edu/princeton/cs/algs4/LinkedBag.java

/******************************************************************************
 *  Compilation:  javac LinkedBag.java
 *  Execution:    java LinkedBag < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *
 *  A generic bag or multiset, implemented using a singly linked list.
 *
 *  % more tobe.txt 
 *  to be or not to - be - - that - - - is
 *
 *  % java LinkedBag < tobe.txt
 *  size of bag = 14
 *  is
 *  -
 *  -
 *  -
 *  that
 *  -
 *  -
 *  be
 *  -
 *  to
 *  not
 *  or
 *  be
 *  to
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  LinkedBag} class represents a bag (or multiset) of 
 *  generic items. It supports insertion and iterating over the 
 *  items in arbitrary order.
 *  <p>
 *  This implementation uses a singly linked list with a non-static nested class Node.
 *  See { @link  Bag} for a version that uses a static nested class.
 *  The <em>add</em>, <em>isEmpty</em>, and <em>size</em> operations
 *  take constant time. Iteration takes time proportional to the number of items.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinkedBag < Item >   implements   Iterable < Item >   {
     private   Node  first ;      // beginning of bag
     private   int  n ;           // number of elements in bag

     // helper linked list class
     private   class   Node   {
         private   Item  item ;
         private   Node  next ;
     }

     /**
     * Initializes an empty bag.
     */
     public   LinkedBag ()   {
        first  =   null ;
        n  =   0 ;
     }

     /**
     * Is this bag empty?
     *  @return  true if this bag is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in this bag.
     *  @return  the number of items in this bag
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Adds the item to this bag.
     *  @param  item the item to add to this bag
     */
     public   void  add ( Item  item )   {
         Node  oldfirst  =  first ;
        first  =   new   Node ();
        first . item  =  item ;
        first . next  =  oldfirst ;
        n ++ ;
     }


     /**
     * Returns an iterator that iterates over the items in the bag.
     */
     public   Iterator < Item >  iterator ()    {
         return   new   ListIterator ();   
     }

     // an iterator over a linked list
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node  current ;

         // creates a new iterator
         public   ListIterator ()   {
            current  =  first ;
         }

         // is there a next item in the iterator?
         public   boolean  hasNext ()   {
             return  current  !=   null ;
         }

         // this method is optional in Iterator interface
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }

         // returns the next item in the iterator (and advances the iterator)
         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }

     /**
     * Unit tests the { @code  LinkedBag} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         LinkedBag < String >  bag  =   new   LinkedBag < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
            bag . add ( item );
         }

         StdOut . println ( "size of bag = "   +  bag . size ());
         for   ( String  s  :  bag )   {
             StdOut . println ( s );
         }
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinkedQueue.java

edu/princeton/cs/algs4/LinkedQueue.java

/******************************************************************************
 *  Compilation:  javac LinkedQueue.java
 *  Execution:    java LinkedQueue < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  
 *
 *  A generic queue, implemented using a singly linked list.
 *
 *  % java Queue < tobe.txt 
 *  to be or not to be (2 left on queue)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  LinkedQueue} class represents a first-in-first-out (FIFO)
 *  queue of generic items.
 *  It supports the usual <em>enqueue</em> and <em>dequeue</em>
 *  operations, along with methods for peeking at the first item,
 *  testing if the queue is empty, and iterating through
 *  the items in FIFO order.
 *  <p>
 *  This implementation uses a singly linked list with a non-static nested class 
 *  for linked-list nodes.  See { @link  Queue} for a version that uses a static nested class.
 *  The <em>enqueue</em>, <em>dequeue</em>, <em>peek</em>, <em>size</em>, and <em>is-empty</em>
 *  operations all take constant time in the worst case.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinkedQueue < Item >   implements   Iterable < Item >   {
     private   int  n ;           // number of elements on queue
     private   Node  first ;      // beginning of queue
     private   Node  last ;       // end of queue

     // helper linked list class
     private   class   Node   {
         private   Item  item ;
         private   Node  next ;
     }

     /**
     * Initializes an empty queue.
     */
     public   LinkedQueue ()   {
        first  =   null ;
        last   =   null ;
        n  =   0 ;
         assert  check ();
     }

     /**
     * Is this queue empty?
     *  @return  true if this queue is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in this queue.
     *  @return  the number of items in this queue
     */
     public   int  size ()   {
         return  n ;      
     }

     /**
     * Returns the item least recently added to this queue.
     *  @return  the item least recently added to this queue
     *  @throws  java.util.NoSuchElementException if this queue is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         return  first . item ;
     }

     /**
     * Adds the item to this queue.
     *  @param  item the item to add
     */
     public   void  enqueue ( Item  item )   {
         Node  oldlast  =  last ;
        last  =   new   Node ();
        last . item  =  item ;
        last . next  =   null ;
         if   ( isEmpty ())  first  =  last ;
         else            oldlast . next  =  last ;
        n ++ ;
         assert  check ();
     }

     /**
     * Removes and returns the item on this queue that was least recently added.
     *  @return  the item on this queue that was least recently added
     *  @throws  java.util.NoSuchElementException if this queue is empty
     */
     public   Item  dequeue ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         Item  item  =  first . item ;
        first  =  first . next ;
        n -- ;
         if   ( isEmpty ())  last  =   null ;     // to avoid loitering
         assert  check ();
         return  item ;
     }

     /**
     * Returns a string representation of this queue.
     *  @return  the sequence of items in FIFO order, separated by spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( Item  item  :   this )
            s . append ( item  +   " " );
         return  s . toString ();
     }  

     // check internal invariants
     private   boolean  check ()   {
         if   ( <   0 )   {
             return   false ;
         }
         else   if   ( ==   0 )   {
             if   ( first  !=   null )   return   false ;
             if   ( last   !=   null )   return   false ;
         }
         else   if   ( ==   1 )   {
             if   ( first  ==   null   ||  last  ==   null )   return   false ;
             if   ( first  !=  last )                   return   false ;
             if   ( first . next  !=   null )              return   false ;
         }
         else   {
             if   ( first  ==   null   ||  last  ==   null )   return   false ;
             if   ( first  ==  last )        return   false ;
             if   ( first . next  ==   null )   return   false ;
             if   ( last . next   !=   null )   return   false ;

             // check internal consistency of instance variable n
             int  numberOfNodes  =   0 ;
             for   ( Node  x  =  first ;  x  !=   null   &&  numberOfNodes  <=  n ;  x  =  x . next )   {
                numberOfNodes ++ ;
             }
             if   ( numberOfNodes  !=  n )   return   false ;

             // check internal consistency of instance variable last
             Node  lastNode  =  first ;
             while   ( lastNode . next  !=   null )   {
                lastNode  =  lastNode . next ;
             }
             if   ( last  !=  lastNode )   return   false ;
         }

         return   true ;
     }  
 

     /**
     * Returns an iterator that iterates over the items in this queue in FIFO order.
     *  @return  an iterator that iterates over the items in this queue in FIFO order
     */
     public   Iterator < Item >  iterator ()    {
         return   new   ListIterator ();   
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node  current  =  first ;

         public   boolean  hasNext ()    {   return  current  !=   null ;                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }


     /**
     * Unit tests the { @code  LinkedQueue} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         LinkedQueue < String >  queue  =   new   LinkedQueue < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))
                queue . enqueue ( item );
             else   if   ( ! queue . isEmpty ())
                 StdOut . print ( queue . dequeue ()   +   " " );
         }
         StdOut . println ( "("   +  queue . size ()   +   " left on queue)" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LinkedStack.java

edu/princeton/cs/algs4/LinkedStack.java

/******************************************************************************
 *  Compilation:  javac LinkedStack.java
 *  Execution:    java LinkedStack < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt
 *
 *  A generic stack, implemented using a linked list. Each stack
 *  element is of type Item.
 *  
 *  % more tobe.txt 
 *  to be or not to - be - - that - - - is
 *
 *  % java LinkedStack < tobe.txt
 *  to be not that or be (2 left on stack)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;


/**
 *  The { @code  LinkedStack} class represents a last-in-first-out (LIFO) stack of
 *  generic items.
 *  It supports the usual <em>push</em> and <em>pop</em> operations, along with methods
 *  for peeking at the top item, testing if the stack is empty, and iterating through
 *  the items in LIFO order.
 *  <p>
 *  This implementation uses a singly linked list with a non-static nested class for 
 *  linked-list nodes. See { @link  Stack} for a version that uses a static nested class.
 *  The <em>push</em>, <em>pop</em>, <em>peek</em>, <em>size</em>, and <em>is-empty</em>
 *  operations all take constant time in the worst case.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LinkedStack < Item >   implements   Iterable < Item >   {
     private   int  n ;            // size of the stack
     private   Node  first ;       // top of stack

     // helper linked list class
     private   class   Node   {
         private   Item  item ;
         private   Node  next ;
     }

     /**
     * Initializes an empty stack.
     */
     public   LinkedStack ()   {
        first  =   null ;
        n  =   0 ;
         assert  check ();
     }

     /**
     * Is this stack empty?
     *  @return  true if this stack is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in the stack.
     *  @return  the number of items in the stack
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Adds the item to this stack.
     *  @param  item the item to add
     */
     public   void  push ( Item  item )   {
         Node  oldfirst  =  first ;
        first  =   new   Node ();
        first . item  =  item ;
        first . next  =  oldfirst ;
        n ++ ;
         assert  check ();
     }

     /**
     * Removes and returns the item most recently added to this stack.
     *  @return  the item most recently added
     *  @throws  java.util.NoSuchElementException if this stack is empty
     */
     public   Item  pop ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         Item  item  =  first . item ;          // save item to return
        first  =  first . next ;              // delete first node
        n -- ;
         assert  check ();
         return  item ;                     // return the saved item
     }


     /**
     * Returns (but does not remove) the item most recently added to this stack.
     *  @return  the item most recently added to this stack
     *  @throws  java.util.NoSuchElementException if this stack is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         return  first . item ;
     }

     /**
     * Returns a string representation of this stack.
     *  @return  the sequence of items in the stack in LIFO order, separated by spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( Item  item  :   this )
            s . append ( item  +   " " );
         return  s . toString ();
     }
       
     /**
     * Returns an iterator to this stack that iterates through the items in LIFO order.
     *  @return  an iterator to this stack that iterates through the items in LIFO order.
     */
     public   Iterator < Item >  iterator ()   {
         return   new   ListIterator ();
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node  current  =  first ;
         public   boolean  hasNext ()    {   return  current  !=   null ;                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }


     // check internal invariants
     private   boolean  check ()   {

         // check a few properties of instance variable 'first'
         if   ( <   0 )   {
             return   false ;
         }
         if   ( ==   0 )   {
             if   ( first  !=   null )   return   false ;
         }
         else   if   ( ==   1 )   {
             if   ( first  ==   null )        return   false ;
             if   ( first . next  !=   null )   return   false ;
         }
         else   {
             if   ( first  ==   null )        return   false ;
             if   ( first . next  ==   null )   return   false ;
         }

         // check internal consistency of instance variable n
         int  numberOfNodes  =   0 ;
         for   ( Node  x  =  first ;  x  !=   null   &&  numberOfNodes  <=  n ;  x  =  x . next )   {
            numberOfNodes ++ ;
         }
         if   ( numberOfNodes  !=  n )   return   false ;

         return   true ;
     }

     /**
     * Unit tests the { @code  LinkedStack} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         LinkedStack < String >  stack  =   new   LinkedStack < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))
                stack . push ( item );
             else   if   ( ! stack . isEmpty ())
                 StdOut . print ( stack . pop ()   +   " " );
         }
         StdOut . println ( "("   +  stack . size ()   +   " left on stack)" );
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LongestCommonSubstring.java

edu/princeton/cs/algs4/LongestCommonSubstring.java

/******************************************************************************
 *  Compilation:  javac LongestCommonSubstring.java
 *  Execution:    java  LongestCommonSubstring file1.txt file2.txt
 *  Dependencies: SuffixArray.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt
 *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt
 *  
 *  Read in two text files and find the longest substring that
 *  appears in both texts.
 * 
 *  % java LongestCommonSubstring tale.txt mobydick.txt
 *  ' seemed on the point of being '
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LongestCommonSubstring} class provides a { @link  SuffixArray}
 *  client for computing the longest common substring that appears in two
 *  given strings.
 *  <p>
 *  This implementation computes the suffix array of each string and applies a
 *  merging operation to determine the longest common substring.
 *  For an alternate implementation, see
 *  <a href = "https://algs4.cs.princeton.edu/63suffix/LongestCommonSubstringConcatenate.java.html">LongestCommonSubstringConcatenate.java</a>.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/63suffix">Section 6.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *     
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LongestCommonSubstring   {

     // Do not instantiate.
     private   LongestCommonSubstring ()   {   }

     // return the longest common prefix of suffix s[p..] and suffix t[q..]
     private   static   String  lcp ( String  s ,   int  p ,   String  t ,   int  q )   {
         int  n  =   Math . min ( s . length ()   -  p ,  t . length ()   -  q );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( s . charAt ( +  i )   !=  t . charAt ( +  i ))
                 return  s . substring ( p ,  p  +  i );
         }
         return  s . substring ( p ,  p  +  n );
     }

     // compare suffix s[p..] and suffix t[q..]
     private   static   int  compare ( String  s ,   int  p ,   String  t ,   int  q )   {
         int  n  =   Math . min ( s . length ()   -  p ,  t . length ()   -  q );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( s . charAt ( +  i )   !=  t . charAt ( +  i ))
                 return  s . charAt ( p + i )   -  t . charAt ( q + i );
         }
         if        ( s . length ()   -  p  <  t . length ()   -  q )   return   - 1 ;
         else   if   ( s . length ()   -  p  >  t . length ()   -  q )   return   + 1 ;
         else                                        return    0 ;
     }

     /**
     * Returns the longest common string of the two specified strings.
     *
     *  @param   s one string
     *  @param   t the other string
     *  @return  the longest common string that appears as a substring
     *         in both { @code  s} and { @code  t}; the empty string
     *         if no such string
     */
     public   static   String  lcs ( String  s ,   String  t )   {
         SuffixArray  suffix1  =   new   SuffixArray ( s );
         SuffixArray  suffix2  =   new   SuffixArray ( t );

         // find longest common substring by "merging" sorted suffixes 
         String  lcs  =   "" ;
         int  i  =   0 ,  j  =   0 ;
         while   ( <  s . length ()   &&  j  <  t . length ())   {
             int  p  =  suffix1 . index ( i );
             int  q  =  suffix2 . index ( j );
             String  x  =  lcp ( s ,  p ,  t ,  q );
             if   ( x . length ()   >  lcs . length ())  lcs  =  x ;
             if   ( compare ( s ,  p ,  t ,  q )   <   0 )  i ++ ;
             else                          j ++ ;
         }
         return  lcs ;
     }

     /**
     * Unit tests the { @code  lcs()} method.
     * Reads in two strings from files specified as command-line arguments;
     * computes the longest common substring; and prints the results to
     * standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in1  =   new   In ( args [ 0 ]);
         In  in2  =   new   In ( args [ 1 ]);
         String  s  =  in1 . readAll (). trim (). replaceAll ( "\\s+" ,   " " );
         String  t  =  in2 . readAll (). trim (). replaceAll ( "\\s+" ,   " " );
         StdOut . println ( "'"   +  lcs ( s ,  t )   +   "'" );
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LongestRepeatedSubstring.java

edu/princeton/cs/algs4/LongestRepeatedSubstring.java

/******************************************************************************
 *  Compilation:  javac LongestRepeatedSubstring.java
 *  Execution:    java LongestRepeatedSubstring < file.txt
 *  Dependencies: StdIn.java SuffixArray.java
 *  Data files:   https://algs4.cs.princeton.edu/63suffix/tale.txt
 *                https://algs4.cs.princeton.edu/63suffix/tinyTale.txt
 *                https://algs4.cs.princeton.edu/63suffix/mobydick.txt
 *  
 *  Reads a text string from stdin, replaces all consecutive blocks of
 *  whitespace with a single space, and then computes the longest
 *  repeated substring in that text using a suffix array.
 * 
 *  % java LongestRepeatedSubstring < tinyTale.txt 
 *  'st of times it was the '
 *
 *  % java LongestRepeatedSubstring < mobydick.txt
 *  ',- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! Th'
 * 
 *  % java LongestRepeatedSubstring
 *  aaaaaaaaa
 *  'aaaaaaaa'
 *
 *  % java LongestRepeatedSubstring
 *  abcdefg
 *  ''
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LongestRepeatedSubstring} class provides a { @link  SuffixArray}
 *  client for computing the longest repeated substring of a string that
 *  appears at least twice. The repeated substrings may overlap (but must
 *  be distinct).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/63suffix">Section 6.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  See also { @link  LongestCommonSubstring}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LongestRepeatedSubstring   {

     // Do not instantiate.
     private   LongestRepeatedSubstring ()   {   }

     /**
     * Returns the longest common string of the two specified strings.
     *
     *  @param   s one string
     *  @param   t the other string
     *  @return  the longest common string that appears as a substring
     */

     /**
     * Returns the longest repeated substring of the specified string.
     *
     *  @param   text the string
     *  @return  the longest repeated substring that appears in { @code  text};
     *         the empty string if no such string
     */
     public   static   String  lrs ( String  text )   {
         int  n  =  text . length ();
         SuffixArray  sa  =   new   SuffixArray ( text );
         String  lrs  =   "" ;
         for   ( int  i  =   1 ;  i  <  n ;  i ++ )   {
             int  length  =  sa . lcp ( i );
             if   ( length  >  lrs . length ())   {
                 // lrs = sa.select(i).substring(0, length);
                lrs  =  text . substring ( sa . index ( i ),  sa . index ( i )   +  length );
             }
         }
         return  lrs ;
     }

     /**
     * Unit tests the { @code  lrs()} method.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  text  =   StdIn . readAll (). replaceAll ( "\\s+" ,   " " );
         StdOut . println ( "'"   +  lrs ( text )   +   "'" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LookupCSV.java

edu/princeton/cs/algs4/LookupCSV.java

/******************************************************************************
 *  Compilation:  javac LookupCSV.java
 *  Execution:    java LookupCSV file.csv keyField valField
 *  Dependencies: ST.java In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/DJIA.csv
 *                https://algs4.cs.princeton.edu/35applications/UPC.csv
 *                https://algs4.cs.princeton.edu/35applications/amino.csv
 *                https://algs4.cs.princeton.edu/35applications/elements.csv
 *                https://algs4.cs.princeton.edu/35applications/ip.csv
 *                https://algs4.cs.princeton.edu/35applications/morse.csv
 *  
 *  Reads in a set of key-value pairs from a two-column CSV file
 *  specified on the command line; then, reads in keys from standard
 *  input and prints out corresponding values.
 * 
 *  % java LookupCSV amino.csv 0 3     % java LookupCSV ip.csv 0 1 
 *  TTA                                www.google.com 
 *  Leucine                            216.239.41.99 
 *  ABC                               
 *  Not found                          % java LookupCSV ip.csv 1 0 
 *  TCT                                216.239.41.99 
 *  Serine                             www.google.com 
 *                                 
 *  % java LookupCSV amino.csv 3 0     % java LookupCSV DJIA.csv 0 1 
 *  Glycine                            29-Oct-29 
 *  GGG                                252.38 
 *                                     20-Oct-87 
 *                                     1738.74
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LookupCSV} class provides a data-driven client for reading in a
 *  key-value pairs from a file; then, printing the values corresponding to the
 *  keys found on standard input. Both keys and values are strings.
 *  The fields to serve as the key and value are taken as command-line arguments.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LookupCSV   {

     // Do not instantiate.
     private   LookupCSV ()   {   }

     public   static   void  main ( String []  args )   {
         int  keyField  =   Integer . parseInt ( args [ 1 ]);
         int  valField  =   Integer . parseInt ( args [ 2 ]);

         // symbol table
        ST < String ,   String >  st  =   new  ST < String ,   String > ();

         // read in the data from csv file
         In  in  =   new   In ( args [ 0 ]);
         while   ( in . hasNextLine ())   {
             String  line  =  in . readLine ();
             String []  tokens  =  line . split ( "," );
             String  key  =  tokens [ keyField ];
             String  val  =  tokens [ valField ];
            st . put ( key ,  val );
         }

         while   ( ! StdIn . isEmpty ())   {
             String  s  =   StdIn . readString ();
             if   ( st . contains ( s ))   StdOut . println ( st . get ( s ));
             else                  StdOut . println ( "Not found" );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LookupIndex.java

edu/princeton/cs/algs4/LookupIndex.java

/******************************************************************************
 *  Compilation:  javac LookupIndex.java
 *  Execution:    java LookupIndex movies.txt "/"
 *  Dependencies: ST.java Queue.java In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/aminoI.csv
 *                https://algs4.cs.princeton.edu/35applications/movies.txt
 *
 *  % java LookupIndex aminoI.csv ","
 *  Serine
 *    TCT
 *    TCA
 *    TCG
 *    AGT
 *    AGC
 *  TCG
 *    Serine
 *
 *  % java LookupIndex movies.txt "/"
 *  Bacon, Kevin
 *    Animal House (1978)
 *    Apollo 13 (1995)
 *    Beauty Shop (2005)
 *    Diner (1982)
 *    Few Good Men, A (1992)
 *    Flatliners (1990)
 *    Footloose (1984)
 *    Friday the 13th (1980)
 *    ...
 *  Tin Men (1987)
 *    DeBoy, David
 *    Blumenfeld, Alan
 *    ...
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LookupIndex} class provides a data-driven client for reading in a
 *  key-value pairs from a file; then, printing the values corresponding to the
 *  keys found on standard input. Keys are strings; values are lists of strings.
 *  The separating delimiter is taken as a command-line argument. This client
 *  is sometimes known as an <em>inverted index</em>.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   LookupIndex   {  

     // Do not instantiate.
     private   LookupIndex ()   {   }

     public   static   void  main ( String []  args )   {
         String  filename   =  args [ 0 ];
         String  separator  =  args [ 1 ];
         In  in  =   new   In ( filename );

        ST < String ,   Queue < String >>  st  =   new  ST < String ,   Queue < String >> ();
        ST < String ,   Queue < String >>  ts  =   new  ST < String ,   Queue < String >> ();

         while   ( in . hasNextLine ())   {
             String  line  =  in . readLine ();
             String []  fields  =  line . split ( separator );
             String  key  =  fields [ 0 ];
             for   ( int  i  =   1 ;  i  <  fields . length ;  i ++ )   {
                 String  val  =  fields [ i ];
                 if   ( ! st . contains ( key ))  st . put ( key ,   new   Queue < String > ());
                 if   ( ! ts . contains ( val ))  ts . put ( val ,   new   Queue < String > ());
                st . get ( key ). enqueue ( val );
                ts . get ( val ). enqueue ( key );
             }
         }

         StdOut . println ( "Done indexing" );

         // read queries from standard input, one per line
         while   ( ! StdIn . isEmpty ())   {
             String  query  =   StdIn . readLine ();
             if   ( st . contains ( query ))  
                 for   ( String  vals  :  st . get ( query ))
                     StdOut . println ( "  "   +  vals );
             if   ( ts . contains ( query ))  
                 for   ( String  keys  :  ts . get ( query ))
                     StdOut . println ( "  "   +  keys );
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LSD.java

edu/princeton/cs/algs4/LSD.java

/******************************************************************************
 *  Compilation:  javac LSD.java
 *  Execution:    java LSD < input.txt
 *  Dependencies: StdIn.java StdOut.java 
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *
 *  LSD radix sort
 *
 *    - Sort a String[] array of n extended ASCII strings (R = 256), each of length w.
 *
 *    - Sort an int[] array of n 32-bit integers, treating each integer as 
 *      a sequence of w = 4 bytes (R = 256).
 *
 *  Uses extra space proportional to n + R.
 *
 *
 *  % java LSD < words3.txt
 *  all
 *  bad
 *  bed
 *  bug
 *  dad
 *  ...
 *  yes
 *  yet
 *  zoo
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LSD} class provides static methods for sorting an
 *  array of <em>w</em>-character strings or 32-bit integers using LSD radix sort.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  LSD  {
     private   static   final   int  BITS_PER_BYTE  =   8 ;

     // do not instantiate
     private  LSD ()   {   }

    /**  
     * Rearranges the array of w-character strings in ascending order.
     *
     *  @param  a the array to be sorted
     *  @param  w the number of characters per string
     */
     public   static   void  sort ( String []  a ,   int  w )   {
         int  n  =  a . length ;
         int  R  =   256 ;     // extend ASCII alphabet size
         String []  aux  =   new   String [ n ];

         for   ( int  d  =  w - 1 ;  d  >=   0 ;  d -- )   {
             // sort by key-indexed counting on dth character

             // compute frequency counts
             int []  count  =   new   int [ R + 1 ];
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )
                count [ a [ i ]. charAt ( d )   +   1 ] ++ ;

             // compute cumulates
             for   ( int  r  =   0 ;  r  <  R ;  r ++ )
                count [ r + 1 ]   +=  count [ r ];

             // move data
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )
                aux [ count [ a [ i ]. charAt ( d )] ++ ]   =  a [ i ];

             // copy back
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )
                a [ i ]   =  aux [ i ];
         }
     }

    /**
     * Rearranges the array of 32-bit integers in ascending order.
     * This is about 2-3x faster than Arrays.sort().
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( int []  a )   {
         final   int  BITS  =   32 ;                   // each int is 32 bits 
         final   int  R  =   1   <<  BITS_PER_BYTE ;      // each bytes is between 0 and 255
         final   int  MASK  =  R  -   1 ;                // 0xFF
         final   int  w  =  BITS  /  BITS_PER_BYTE ;    // each int is 4 bytes

         int  n  =  a . length ;
         int []  aux  =   new   int [ n ];

         for   ( int  d  =   0 ;  d  <  w ;  d ++ )   {          

             // compute frequency counts
             int []  count  =   new   int [ R + 1 ];
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {            
                 int  c  =   ( a [ i ]   >>  BITS_PER_BYTE * d )   &  MASK ;
                count [ +   1 ] ++ ;
             }

             // compute cumulates
             for   ( int  r  =   0 ;  r  <  R ;  r ++ )
                count [ r + 1 ]   +=  count [ r ];

             // for most significant byte, 0x80-0xFF comes before 0x00-0x7F
             if   ( ==  w - 1 )   {
                 int  shift1  =  count [ R ]   -  count [ R / 2 ];
                 int  shift2  =  count [ R / 2 ];
                 for   ( int  r  =   0 ;  r  <  R / 2 ;  r ++ )
                    count [ r ]   +=  shift1 ;
                 for   ( int  r  =  R / 2 ;  r  <  R ;  r ++ )
                    count [ r ]   -=  shift2 ;
             }

             // move data
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 int  c  =   ( a [ i ]   >>  BITS_PER_BYTE * d )   &  MASK ;
                aux [ count [ c ] ++ ]   =  a [ i ];
             }

             // copy back
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )
                a [ i ]   =  aux [ i ];
         }
     }

     /**
     * Reads in a sequence of fixed-length strings from standard input;
     * LSD radix sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         int  n  =  a . length ;

         // check that strings have fixed length
         int  w  =  a [ 0 ]. length ();
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             assert  a [ i ]. length ()   ==  w  :   "Strings must have fixed length" ;

         // sort the strings
        sort ( a ,  w );

         // print results
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/LZW.java

edu/princeton/cs/algs4/LZW.java

/******************************************************************************
 *  Compilation:  javac LZW.java
 *  Execution:    java LZW - < input.txt   (compress)
 *  Execution:    java LZW + < input.txt   (expand)
 *  Dependencies: BinaryIn.java BinaryOut.java
 *  Data files:   https://algs4.cs.princeton.edu/55compression/abraLZW.txt
 *                https://algs4.cs.princeton.edu/55compression/ababLZW.txt
 *
 *  Compress or expand binary input from standard input using LZW.
 *
 *  WARNING: STARTING WITH ORACLE JAVA 6, UPDATE 7 the SUBSTRING
 *  METHOD TAKES TIME AND SPACE LINEAR IN THE SIZE OF THE EXTRACTED
 *  SUBSTRING (INSTEAD OF CONSTANT SPACE AND TIME AS IN EARLIER
 *  IMPLEMENTATIONS).
 *
 *  See <a href = "http://java-performance.info/changes-to-string-java-1-7-0_06/">this article</a>
 *  for more details.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  LZW} class provides static methods for compressing
 *  and expanding a binary input using LZW compression over the 8-bit extended
 *  ASCII alphabet with 12-bit codewords.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick  
 *   @author  Kevin Wayne
 */
public   class  LZW  {
     private   static   final   int  R  =   256 ;          // number of input chars
     private   static   final   int  L  =   4096 ;         // number of codewords = 2^W
     private   static   final   int  W  =   12 ;           // codeword width

     // Do not instantiate.
     private  LZW ()   {   }

     /**
     * Reads a sequence of 8-bit bytes from standard input; compresses
     * them using LZW compression with 12-bit codewords; and writes the results
     * to standard output.
     */
     public   static   void  compress ()   {  
         String  input  =   BinaryStdIn . readString ();
        TST < Integer >  st  =   new  TST < Integer > ();
         for   ( int  i  =   0 ;  i  <  R ;  i ++ )
            st . put ( ""   +   ( char )  i ,  i );
         int  code  =  R + 1 ;    // R is codeword for EOF

         while   ( input . length ()   >   0 )   {
             String  s  =  st . longestPrefixOf ( input );    // Find max prefix match s.
             BinaryStdOut . write ( st . get ( s ),  W );        // Print s's encoding.
             int  t  =  s . length ();
             if   ( <  input . length ()   &&  code  <  L )      // Add s to symbol table.
                st . put ( input . substring ( 0 ,  t  +   1 ),  code ++ );
            input  =  input . substring ( t );              // Scan past s in input.
         }
         BinaryStdOut . write ( R ,  W );
         BinaryStdOut . close ();
     }  

     /**
     * Reads a sequence of bit encoded using LZW compression with
     * 12-bit codewords from standard input; expands them; and writes
     * the results to standard output.
     */
     public   static   void  expand ()   {
         String []  st  =   new   String [ L ];
         int  i ;   // next available codeword value

         // initialize symbol table with all 1-character strings
         for   ( =   0 ;  i  <  R ;  i ++ )
            st [ i ]   =   ""   +   ( char )  i ;
        st [ i ++ ]   =   "" ;                          // (unused) lookahead for EOF

         int  codeword  =   BinaryStdIn . readInt ( W );
         if   ( codeword  ==  R )   return ;             // expanded message is empty string
         String  val  =  st [ codeword ];

         while   ( true )   {
             BinaryStdOut . write ( val );
            codeword  =   BinaryStdIn . readInt ( W );
             if   ( codeword  ==  R )   break ;
             String  s  =  st [ codeword ];
             if   ( ==  codeword )  s  =  val  +  val . charAt ( 0 );     // special case hack
             if   ( <  L )  st [ i ++ ]   =  val  +  s . charAt ( 0 );
            val  =  s ;
         }
         BinaryStdOut . close ();
     }

     /**
     * Sample client that calls { @code  compress()} if the command-line
     * argument is "-" an { @code  expand()} if it is "+".
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         if        ( args [ 0 ]. equals ( "-" ))  compress ();
         else   if   ( args [ 0 ]. equals ( "+" ))  expand ();
         else   throw   new   IllegalArgumentException ( "Illegal command line argument" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MaxPQ.java

edu/princeton/cs/algs4/MaxPQ.java

/******************************************************************************
 *  Compilation:  javac MaxPQ.java
 *  Execution:    java MaxPQ < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyPQ.txt
 *  
 *  Generic max priority queue implementation with a binary heap.
 *  Can be used with a comparator instead of the natural order,
 *  but the generic Key type must still be Comparable.
 *
 *  % java MaxPQ < tinyPQ.txt 
 *  Q X P (6 left on pq)
 *
 *  We use a one-based array to simplify parent and child calculations.
 *
 *  Can be optimized by replacing full exchanges with half exchanges
 *  (ala insertion sort).
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;
import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  MaxPQ} class represents a priority queue of generic keys.
 *  It supports the usual <em>insert</em> and <em>delete-the-maximum</em>
 *  operations, along with methods for peeking at the maximum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  <p>
 *  This implementation uses a <em>binary heap</em>.
 *  The <em>insert</em> and <em>delete-the-maximum</em> operations take
 *  &Theta;(log <em>n</em>) amortized time, where <em>n</em> is the number
 *  of elements in the priority queue. This is an amortized bound 
 *  (and not a worst-case bound) because of array resizing operations.
 *  The <em>min</em>, <em>size</em>, and <em>is-empty</em> operations take 
 *  &Theta;(1) time in the worst case.
 *  Construction takes time proportional to the specified capacity or the
 *  number of items used to initialize the data structure.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of key on this priority queue
 */

public   class   MaxPQ < Key >   implements   Iterable < Key >   {
     private   Key []  pq ;                      // store items at indices 1 to n
     private   int  n ;                         // number of items on priority queue
     private   Comparator < Key >  comparator ;    // optional comparator

     /**
     * Initializes an empty priority queue with the given initial capacity.
     *
     *  @param   initCapacity the initial capacity of this priority queue
     */
     public   MaxPQ ( int  initCapacity )   {
        pq  =   ( Key [])   new   Object [ initCapacity  +   1 ];
        n  =   0 ;
     }

     /**
     * Initializes an empty priority queue.
     */
     public   MaxPQ ()   {
         this ( 1 );
     }

     /**
     * Initializes an empty priority queue with the given initial capacity,
     * using the given comparator.
     *
     *  @param   initCapacity the initial capacity of this priority queue
     *  @param   comparator the order in which to compare the keys
     */
     public   MaxPQ ( int  initCapacity ,   Comparator < Key >  comparator )   {
         this . comparator  =  comparator ;
        pq  =   ( Key [])   new   Object [ initCapacity  +   1 ];
        n  =   0 ;
     }

     /**
     * Initializes an empty priority queue using the given comparator.
     *
     *  @param   comparator the order in which to compare the keys
     */
     public   MaxPQ ( Comparator < Key >  comparator )   {
         this ( 1 ,  comparator );
     }

     /**
     * Initializes a priority queue from the array of keys.
     * Takes time proportional to the number of keys, using sink-based heap construction.
     *
     *  @param   keys the array of keys
     */
     public   MaxPQ ( Key []  keys )   {
        n  =  keys . length ;
        pq  =   ( Key [])   new   Object [ keys . length  +   1 ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            pq [ i + 1 ]   =  keys [ i ];
         for   ( int  k  =  n / 2 ;  k  >=   1 ;  k -- )
            sink ( k );
         assert  isMaxHeap ();
     }
      


     /**
     * Returns true if this priority queue is empty.
     *
     *  @return  { @code  true} if this priority queue is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Returns the number of keys on this priority queue.
     *
     *  @return  the number of keys on this priority queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns a largest key on this priority queue.
     *
     *  @return  a largest key on this priority queue
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  pq [ 1 ];
     }

     // helper function to double the size of the heap array
     private   void  resize ( int  capacity )   {
         assert  capacity  >  n ;
         Key []  temp  =   ( Key [])   new   Object [ capacity ];
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            temp [ i ]   =  pq [ i ];
         }
        pq  =  temp ;
     }


     /**
     * Adds a new key to this priority queue.
     *
     *  @param   x the new key to add to this priority queue
     */
     public   void  insert ( Key  x )   {

         // double size of array if necessary
         if   ( ==  pq . length  -   1 )  resize ( 2   *  pq . length );

         // add x, and percolate it up to maintain heap invariant
        pq [ ++ n ]   =  x ;
        swim ( n );
         assert  isMaxHeap ();
     }

     /**
     * Removes and returns a largest key on this priority queue.
     *
     *  @return  a largest key on this priority queue
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  delMax ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );
         Key  max  =  pq [ 1 ];
        exch ( 1 ,  n -- );
        sink ( 1 );
        pq [ n + 1 ]   =   null ;       // to avoid loitering and help with garbage collection
         if   (( >   0 )   &&   ( ==   ( pq . length  -   1 )   /   4 ))  resize ( pq . length  /   2 );
         assert  isMaxHeap ();
         return  max ;
     }


    /***************************************************************************
    * Helper functions to restore the heap invariant.
    ***************************************************************************/

     private   void  swim ( int  k )   {
         while   ( >   1   &&  less ( k / 2 ,  k ))   {
            exch ( k ,  k / 2 );
            k  =  k / 2 ;
         }
     }

     private   void  sink ( int  k )   {
         while   ( 2 * <=  n )   {
             int  j  =   2 * k ;
             if   ( <  n  &&  less ( j ,  j + 1 ))  j ++ ;
             if   ( ! less ( k ,  j ))   break ;
            exch ( k ,  j );
            k  =  j ;
         }
     }

    /***************************************************************************
    * Helper functions for compares and swaps.
    ***************************************************************************/
     private   boolean  less ( int  i ,   int  j )   {
         if   ( comparator  ==   null )   {
             return   (( Comparable < Key > )  pq [ i ]). compareTo ( pq [ j ])   <   0 ;
         }
         else   {
             return  comparator . compare ( pq [ i ],  pq [ j ])   <   0 ;
         }
     }

     private   void  exch ( int  i ,   int  j )   {
         Key  swap  =  pq [ i ];
        pq [ i ]   =  pq [ j ];
        pq [ j ]   =  swap ;
     }

     // is pq[1..n] a max heap?
     private   boolean  isMaxHeap ()   {
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
             if   ( pq [ i ]   ==   null )   return   false ;
         }
         for   ( int  i  =  n + 1 ;  i  <  pq . length ;  i ++ )   {
             if   ( pq [ i ]   !=   null )   return   false ;
         }
         if   ( pq [ 0 ]   !=   null )   return   false ;
         return  isMaxHeapOrdered ( 1 );
     }

     // is subtree of pq[1..n] rooted at k a max heap?
     private   boolean  isMaxHeapOrdered ( int  k )   {
         if   ( >  n )   return   true ;
         int  left  =   2 * k ;
         int  right  =   2 * +   1 ;
         if   ( left   <=  n  &&  less ( k ,  left ))    return   false ;
         if   ( right  <=  n  &&  less ( k ,  right ))   return   false ;
         return  isMaxHeapOrdered ( left )   &&  isMaxHeapOrdered ( right );
     }


    /***************************************************************************
    * Iterator.
    ***************************************************************************/

     /**
     * Returns an iterator that iterates over the keys on this priority queue
     * in descending order.
     * The iterator doesn't implement { @code  remove()} since it's optional.
     *
     *  @return  an iterator that iterates over the keys in descending order
     */
     public   Iterator < Key >  iterator ()   {
         return   new   HeapIterator ();
     }

     private   class   HeapIterator   implements   Iterator < Key >   {

         // create a new pq
         private   MaxPQ < Key >  copy ;

         // add all items to copy of heap
         // takes linear time since already in heap order so no keys move
         public   HeapIterator ()   {
             if   ( comparator  ==   null )  copy  =   new   MaxPQ < Key > ( size ());
             else                     copy  =   new   MaxPQ < Key > ( size (),  comparator );
             for   ( int  i  =   1 ;  i  <=  n ;  i ++ )
                copy . insert ( pq [ i ]);
         }

         public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Key  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMax ();
         }
     }

     /**
     * Unit tests the { @code  MaxPQ} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         MaxPQ < String >  pq  =   new   MaxPQ < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))  pq . insert ( item );
             else   if   ( ! pq . isEmpty ())   StdOut . print ( pq . delMax ()   +   " " );
         }
         StdOut . println ( "("   +  pq . size ()   +   " left on pq)" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MergeBU.java

edu/princeton/cs/algs4/MergeBU.java

/******************************************************************************
 *  Compilation:  javac MergeBU.java
 *  Execution:    java MergeBU < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt
 *                https://algs4.cs.princeton.edu/22mergesort/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using
 *  bottom-up mergesort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java MergeBU < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java MergeBU < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  MergeBU} class provides static methods for sorting an
 *  array using <em>bottom-up mergesort</em>. It is non-recursive.
 *  <p>
 *  This implementation takes &Theta;(<em>n</em> log <em>n</em>) time
 *  to sort any array of length <em>n</em> (assuming comparisons
 *  take constant time). It makes between
 *  ~ &frac12; <em>n</em> log<sub>2</sub> <em>n</em> and
 *  ~ 1 <em>n</em> log<sub>2</sub> <em>n</em> compares.
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(<em>n</em>) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   MergeBU   {

     // This class should not be instantiated.
     private   MergeBU ()   {   }

     // stably merge a[lo..mid] with a[mid+1..hi] using aux[lo..hi]
     private   static   void  merge ( Comparable []  a ,   Comparable []  aux ,   int  lo ,   int  mid ,   int  hi )   {

         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  a [ k ];  
         }

         // merge back to a[]
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )               a [ k ]   =  aux [ j ++ ];    // this copying is unneccessary
             else   if   ( >  hi )                a [ k ]   =  aux [ i ++ ];
             else   if   ( less ( aux [ j ],  aux [ i ]))  a [ k ]   =  aux [ j ++ ];
             else                            a [ k ]   =  aux [ i ++ ];
         }

     }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;
         Comparable []  aux  =   new   Comparable [ n ];
         for   ( int  len  =   1 ;  len  <  n ;  len  *=   2 )   {
             for   ( int  lo  =   0 ;  lo  <  n - len ;  lo  +=  len + len )   {
                 int  mid   =  lo + len - 1 ;
                 int  hi  =   Math . min ( lo + len + len - 1 ,  n - 1 );
                merge ( a ,  aux ,  lo ,  mid ,  hi );
             }
         }
         assert  isSorted ( a );
     }

   /***********************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; bottom-up
     * mergesorts them; and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         MergeBU . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Merge.java

edu/princeton/cs/algs4/Merge.java

/******************************************************************************
 *  Compilation:  javac Merge.java
 *  Execution:    java Merge < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt
 *                https://algs4.cs.princeton.edu/22mergesort/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using mergesort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Merge < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java Merge < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Merge} class provides static methods for sorting an
 *  array using a top-down, recursive version of <em>mergesort</em>.
 *  <p>
 *  This implementation takes &Theta;(<em>n</em> log <em>n</em>) time
 *  to sort any array of length <em>n</em> (assuming comparisons
 *  take constant time). It makes between
 *  ~ &frac12; <em>n</em> log<sub>2</sub> <em>n</em> and
 *  ~ 1 <em>n</em> log<sub>2</sub> <em>n</em> compares.
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(<em>n</em>) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/22mergesort">Section 2.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For an optimized version, see { @link  MergeX}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Merge   {

     // This class should not be instantiated.
     private   Merge ()   {   }

     // stably merge a[lo .. mid] with a[mid+1 ..hi] using aux[lo .. hi]
     private   static   void  merge ( Comparable []  a ,   Comparable []  aux ,   int  lo ,   int  mid ,   int  hi )   {
         // precondition: a[lo .. mid] and a[mid+1 .. hi] are sorted subarrays
         assert  isSorted ( a ,  lo ,  mid );
         assert  isSorted ( a ,  mid + 1 ,  hi );

         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  a [ k ];  
         }

         // merge back to a[]
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )               a [ k ]   =  aux [ j ++ ];
             else   if   ( >  hi )                a [ k ]   =  aux [ i ++ ];
             else   if   ( less ( aux [ j ],  aux [ i ]))  a [ k ]   =  aux [ j ++ ];
             else                            a [ k ]   =  aux [ i ++ ];
         }

         // postcondition: a[lo .. hi] is sorted
         assert  isSorted ( a ,  lo ,  hi );
     }

     // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
     private   static   void  sort ( Comparable []  a ,   Comparable []  aux ,   int  lo ,   int  hi )   {
         if   ( hi  <=  lo )   return ;
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        sort ( a ,  aux ,  lo ,  mid );
        sort ( a ,  aux ,  mid  +   1 ,  hi );
        merge ( a ,  aux ,  lo ,  mid ,  hi );
     }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         Comparable []  aux  =   new   Comparable [ a . length ];
        sort ( a ,  aux ,   0 ,  a . length - 1 );
         assert  isSorted ( a );
     }


    /***************************************************************************
    *  Helper sorting function.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }
        
    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }

     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }


    /***************************************************************************
    *  Index mergesort.
    ***************************************************************************/
     // stably merge a[lo .. mid] with a[mid+1 .. hi] using aux[lo .. hi]
     private   static   void  merge ( Comparable []  a ,   int []  index ,   int []  aux ,   int  lo ,   int  mid ,   int  hi )   {

         // copy to aux[]
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
            aux [ k ]   =  index [ k ];  
         }

         // merge back to a[]
         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )                     index [ k ]   =  aux [ j ++ ];
             else   if   ( >  hi )                      index [ k ]   =  aux [ i ++ ];
             else   if   ( less ( a [ aux [ j ]],  a [ aux [ i ]]))  index [ k ]   =  aux [ j ++ ];
             else                                  index [ k ]   =  aux [ i ++ ];
         }
     }

     /**
     * Returns a permutation that gives the elements in the array in ascending order.
     *  @param  a the array
     *  @return  a permutation { @code  p[]} such that { @code  a[p[0]]}, { @code  a[p[1]]},
     *    ..., { @code  a[p[N-1]]} are in ascending order
     */
     public   static   int []  indexSort ( Comparable []  a )   {
         int  n  =  a . length ;
         int []  index  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            index [ i ]   =  i ;

         int []  aux  =   new   int [ n ];
        sort ( a ,  index ,  aux ,   0 ,  n - 1 );
         return  index ;
     }

     // mergesort a[lo..hi] using auxiliary array aux[lo..hi]
     private   static   void  sort ( Comparable []  a ,   int []  index ,   int []  aux ,   int  lo ,   int  hi )   {
         if   ( hi  <=  lo )   return ;
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        sort ( a ,  index ,  aux ,  lo ,  mid );
        sort ( a ,  index ,  aux ,  mid  +   1 ,  hi );
        merge ( a ,  index ,  aux ,  lo ,  mid ,  hi );
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; mergesorts them; 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Merge . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MergeX.java

edu/princeton/cs/algs4/MergeX.java

/******************************************************************************
 *  Compilation:  javac MergeX.java
 *  Execution:    java MergeX < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/22mergesort/tiny.txt
 *                https://algs4.cs.princeton.edu/22mergesort/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using an
 *  optimized version of mergesort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java MergeX < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java MergeX < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;

/**
 *  The { @code  MergeX} class provides static methods for sorting an
 *  array using an optimized version of mergesort.
 *  <p>
 *  In the worst case, this implementation takes
 *  &Theta;(<em>n</em> log <em>n</em>) time to sort an array of
 *  length <em>n</em> (assuming comparisons take constant time).
 *  <p>
 *  This sorting algorithm is stable.
 *  It uses &Theta;(<em>n</em>) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/22mergesort">Section 2.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   MergeX   {
     private   static   final   int  CUTOFF  =   7 ;    // cutoff to insertion sort

     // This class should not be instantiated.
     private   MergeX ()   {   }

     private   static   void  merge ( Comparable []  src ,   Comparable []  dst ,   int  lo ,   int  mid ,   int  hi )   {

         // precondition: src[lo .. mid] and src[mid+1 .. hi] are sorted subarrays
         assert  isSorted ( src ,  lo ,  mid );
         assert  isSorted ( src ,  mid + 1 ,  hi );

         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )               dst [ k ]   =  src [ j ++ ];
             else   if   ( >  hi )                dst [ k ]   =  src [ i ++ ];
             else   if   ( less ( src [ j ],  src [ i ]))  dst [ k ]   =  src [ j ++ ];     // to ensure stability
             else                            dst [ k ]   =  src [ i ++ ];
         }

         // postcondition: dst[lo .. hi] is sorted subarray
         assert  isSorted ( dst ,  lo ,  hi );
     }

     private   static   void  sort ( Comparable []  src ,   Comparable []  dst ,   int  lo ,   int  hi )   {
         // if (hi <= lo) return;
         if   ( hi  <=  lo  +  CUTOFF )   {  
            insertionSort ( dst ,  lo ,  hi );
             return ;
         }
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        sort ( dst ,  src ,  lo ,  mid );
        sort ( dst ,  src ,  mid + 1 ,  hi );

         // if (!less(src[mid+1], src[mid])) {
         //    for (int i = lo; i <= hi; i++) dst[i] = src[i];
         //    return;
         // }

         // using System.arraycopy() is a bit faster than the above loop
         if   ( ! less ( src [ mid + 1 ],  src [ mid ]))   {
             System . arraycopy ( src ,  lo ,  dst ,  lo ,  hi  -  lo  +   1 );
             return ;
         }

        merge ( src ,  dst ,  lo ,  mid ,  hi );
     }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         Comparable []  aux  =  a . clone ();
        sort ( aux ,  a ,   0 ,  a . length - 1 );   
         assert  isSorted ( a );
     }

     // sort from a[lo] to a[hi] using insertion sort
     private   static   void  insertionSort ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ]);  j -- )
                exch ( a ,  j ,  j - 1 );
     }


     /*******************************************************************
     *  Utility methods.
     *******************************************************************/

     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }

     // is a[i] < a[j]?
     private   static   boolean  less ( Comparable  a ,   Comparable  b )   {
         return  a . compareTo ( b )   <   0 ;
     }

     // is a[i] < a[j]?
     private   static   boolean  less ( Object  a ,   Object  b ,   Comparator  comparator )   {
         return  comparator . compare ( a ,  b )   <   0 ;
     }


     /*******************************************************************
     *  Version that takes Comparator as argument.
     *******************************************************************/

     /**
     * Rearranges the array in ascending order, using the provided order.
     *
     *  @param  a the array to be sorted
     *  @param  comparator the comparator that defines the total order
     */
     public   static   void  sort ( Object []  a ,   Comparator  comparator )   {
         Object []  aux  =  a . clone ();
        sort ( aux ,  a ,   0 ,  a . length - 1 ,  comparator );
         assert  isSorted ( a ,  comparator );
     }

     private   static   void  merge ( Object []  src ,   Object []  dst ,   int  lo ,   int  mid ,   int  hi ,   Comparator  comparator )   {

         // precondition: src[lo .. mid] and src[mid+1 .. hi] are sorted subarrays
         assert  isSorted ( src ,  lo ,  mid ,  comparator );
         assert  isSorted ( src ,  mid + 1 ,  hi ,  comparator );

         int  i  =  lo ,  j  =  mid + 1 ;
         for   ( int  k  =  lo ;  k  <=  hi ;  k ++ )   {
             if        ( >  mid )                           dst [ k ]   =  src [ j ++ ];
             else   if   ( >  hi )                            dst [ k ]   =  src [ i ++ ];
             else   if   ( less ( src [ j ],  src [ i ],  comparator ))  dst [ k ]   =  src [ j ++ ];
             else                                        dst [ k ]   =  src [ i ++ ];
         }

         // postcondition: dst[lo .. hi] is sorted subarray
         assert  isSorted ( dst ,  lo ,  hi ,  comparator );
     }


     private   static   void  sort ( Object []  src ,   Object []  dst ,   int  lo ,   int  hi ,   Comparator  comparator )   {
         // if (hi <= lo) return;
         if   ( hi  <=  lo  +  CUTOFF )   {  
            insertionSort ( dst ,  lo ,  hi ,  comparator );
             return ;
         }
         int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
        sort ( dst ,  src ,  lo ,  mid ,  comparator );
        sort ( dst ,  src ,  mid + 1 ,  hi ,  comparator );

         // using System.arraycopy() is a bit faster than the above loop
         if   ( ! less ( src [ mid + 1 ],  src [ mid ],  comparator ))   {
             System . arraycopy ( src ,  lo ,  dst ,  lo ,  hi  -  lo  +   1 );
             return ;
         }

        merge ( src ,  dst ,  lo ,  mid ,  hi ,  comparator );
     }

     // sort from a[lo] to a[hi] using insertion sort
     private   static   void  insertionSort ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  comparator );  j -- )
                exch ( a ,  j ,  j - 1 );
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }

     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 ,  comparator );
     }

     private   static   boolean  isSorted ( Object []  a ,   int  lo ,   int  hi ,   Comparator  comparator )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ],  comparator ))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Object []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; mergesorts them
     * (using an optimized version of mergesort); 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         MergeX . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MinPQ.java

edu/princeton/cs/algs4/MinPQ.java

/******************************************************************************
 *  Compilation:  javac MinPQ.java
 *  Execution:    java MinPQ < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyPQ.txt
 *  
 *  Generic min priority queue implementation with a binary heap.
 *  Can be used with a comparator instead of the natural order.
 *
 *  % java MinPQ < tinyPQ.txt
 *  E A E (6 left on pq)
 *
 *  We use a one-based array to simplify parent and child calculations.
 *
 *  Can be optimized by replacing full exchanges with half exchanges
 *  (ala insertion sort).
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;
import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  MinPQ} class represents a priority queue of generic keys.
 *  It supports the usual <em>insert</em> and <em>delete-the-minimum</em>
 *  operations, along with methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  <p>
 *  This implementation uses a <em>binary heap</em>.
 *  The <em>insert</em> and <em>delete-the-minimum</em> operations take
 *  &Theta;(log <em>n</em>) amortized time, where <em>n</em> is the number
 *  of elements in the priority queue. This is an amortized bound
 *  (and not a worst-case bound) because of array resizing operations.
 *  The <em>min</em>, <em>size</em>, and <em>is-empty</em> operations take
 *  &Theta;(1) time in the worst case.
 *  Construction takes time proportional to the specified capacity or the
 *  number of items used to initialize the data structure.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of key on this priority queue
 */
public   class   MinPQ < Key >   implements   Iterable < Key >   {
     private   Key []  pq ;                      // store items at indices 1 to n
     private   int  n ;                         // number of items on priority queue
     private   Comparator < Key >  comparator ;    // optional comparator

     /**
     * Initializes an empty priority queue with the given initial capacity.
     *
     *  @param   initCapacity the initial capacity of this priority queue
     */
     public   MinPQ ( int  initCapacity )   {
        pq  =   ( Key [])   new   Object [ initCapacity  +   1 ];
        n  =   0 ;
     }

     /**
     * Initializes an empty priority queue.
     */
     public   MinPQ ()   {
         this ( 1 );
     }

     /**
     * Initializes an empty priority queue with the given initial capacity,
     * using the given comparator.
     *
     *  @param   initCapacity the initial capacity of this priority queue
     *  @param   comparator the order in which to compare the keys
     */
     public   MinPQ ( int  initCapacity ,   Comparator < Key >  comparator )   {
         this . comparator  =  comparator ;
        pq  =   ( Key [])   new   Object [ initCapacity  +   1 ];
        n  =   0 ;
     }

     /**
     * Initializes an empty priority queue using the given comparator.
     *
     *  @param   comparator the order in which to compare the keys
     */
     public   MinPQ ( Comparator < Key >  comparator )   {
         this ( 1 ,  comparator );
     }

     /**
     * Initializes a priority queue from the array of keys.
     * <p>
     * Takes time proportional to the number of keys, using sink-based heap construction.
     *
     *  @param   keys the array of keys
     */
     public   MinPQ ( Key []  keys )   {
        n  =  keys . length ;
        pq  =   ( Key [])   new   Object [ keys . length  +   1 ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            pq [ i + 1 ]   =  keys [ i ];
         for   ( int  k  =  n / 2 ;  k  >=   1 ;  k -- )
            sink ( k );
         assert  isMinHeap ();
     }

     /**
     * Returns true if this priority queue is empty.
     *
     *  @return  { @code  true} if this priority queue is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Returns the number of keys on this priority queue.
     *
     *  @return  the number of keys on this priority queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns a smallest key on this priority queue.
     *
     *  @return  a smallest key on this priority queue
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );
         return  pq [ 1 ];
     }

     // helper function to double the size of the heap array
     private   void  resize ( int  capacity )   {
         assert  capacity  >  n ;
         Key []  temp  =   ( Key [])   new   Object [ capacity ];
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            temp [ i ]   =  pq [ i ];
         }
        pq  =  temp ;
     }

     /**
     * Adds a new key to this priority queue.
     *
     *  @param   x the key to add to this priority queue
     */
     public   void  insert ( Key  x )   {
         // double size of array if necessary
         if   ( ==  pq . length  -   1 )  resize ( 2   *  pq . length );

         // add x, and percolate it up to maintain heap invariant
        pq [ ++ n ]   =  x ;
        swim ( n );
         assert  isMinHeap ();
     }

     /**
     * Removes and returns a smallest key on this priority queue.
     *
     *  @return  a smallest key on this priority queue
     *  @throws  NoSuchElementException if this priority queue is empty
     */
     public   Key  delMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue underflow" );
         Key  min  =  pq [ 1 ];
        exch ( 1 ,  n -- );
        sink ( 1 );
        pq [ n + 1 ]   =   null ;       // to avoid loiterig and help with garbage collection
         if   (( >   0 )   &&   ( ==   ( pq . length  -   1 )   /   4 ))  resize ( pq . length  /   2 );
         assert  isMinHeap ();
         return  min ;
     }


    /***************************************************************************
    * Helper functions to restore the heap invariant.
    ***************************************************************************/

     private   void  swim ( int  k )   {
         while   ( >   1   &&  greater ( k / 2 ,  k ))   {
            exch ( k ,  k / 2 );
            k  =  k / 2 ;
         }
     }

     private   void  sink ( int  k )   {
         while   ( 2 * <=  n )   {
             int  j  =   2 * k ;
             if   ( <  n  &&  greater ( j ,  j + 1 ))  j ++ ;
             if   ( ! greater ( k ,  j ))   break ;
            exch ( k ,  j );
            k  =  j ;
         }
     }

    /***************************************************************************
    * Helper functions for compares and swaps.
    ***************************************************************************/
     private   boolean  greater ( int  i ,   int  j )   {
         if   ( comparator  ==   null )   {
             return   (( Comparable < Key > )  pq [ i ]). compareTo ( pq [ j ])   >   0 ;
         }
         else   {
             return  comparator . compare ( pq [ i ],  pq [ j ])   >   0 ;
         }
     }

     private   void  exch ( int  i ,   int  j )   {
         Key  swap  =  pq [ i ];
        pq [ i ]   =  pq [ j ];
        pq [ j ]   =  swap ;
     }

     // is pq[1..n] a min heap?
     private   boolean  isMinHeap ()   {
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
             if   ( pq [ i ]   ==   null )   return   false ;
         }
         for   ( int  i  =  n + 1 ;  i  <  pq . length ;  i ++ )   {
             if   ( pq [ i ]   !=   null )   return   false ;
         }
         if   ( pq [ 0 ]   !=   null )   return   false ;
         return  isMinHeapOrdered ( 1 );
     }

     // is subtree of pq[1..n] rooted at k a min heap?
     private   boolean  isMinHeapOrdered ( int  k )   {
         if   ( >  n )   return   true ;
         int  left  =   2 * k ;
         int  right  =   2 * +   1 ;
         if   ( left   <=  n  &&  greater ( k ,  left ))    return   false ;
         if   ( right  <=  n  &&  greater ( k ,  right ))   return   false ;
         return  isMinHeapOrdered ( left )   &&  isMinHeapOrdered ( right );
     }


     /**
     * Returns an iterator that iterates over the keys on this priority queue
     * in ascending order.
     * <p>
     * The iterator doesn't implement { @code  remove()} since it's optional.
     *
     *  @return  an iterator that iterates over the keys in ascending order
     */
     public   Iterator < Key >  iterator ()   {
         return   new   HeapIterator ();
     }

     private   class   HeapIterator   implements   Iterator < Key >   {
         // create a new pq
         private   MinPQ < Key >  copy ;

         // add all items to copy of heap
         // takes linear time since already in heap order so no keys move
         public   HeapIterator ()   {
             if   ( comparator  ==   null )  copy  =   new   MinPQ < Key > ( size ());
             else                     copy  =   new   MinPQ < Key > ( size (),  comparator );
             for   ( int  i  =   1 ;  i  <=  n ;  i ++ )
                copy . insert ( pq [ i ]);
         }

         public   boolean  hasNext ()    {   return   ! copy . isEmpty ();                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Key  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  copy . delMin ();
         }
     }

     /**
     * Unit tests the { @code  MinPQ} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         MinPQ < String >  pq  =   new   MinPQ < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))  pq . insert ( item );
             else   if   ( ! pq . isEmpty ())   StdOut . print ( pq . delMin ()   +   " " );
         }
         StdOut . println ( "("   +  pq . size ()   +   " left on pq)" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MSD.java

edu/princeton/cs/algs4/MSD.java

/******************************************************************************
 *  Compilation: javac MSD.java
 *  Execution:   java MSD < input.txt
 *  Dependencies: StdIn.java StdOut.java 
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *                https://algs4.cs.princeton.edu/51radix/shells.txt
 *
 *  Sort an array of strings or integers using MSD radix sort.
 *
 *  % java MSD < shells.txt 
 *  are
 *  by
 *  sea
 *  seashells
 *  seashells
 *  sells
 *  sells
 *  she
 *  she
 *  shells
 *  shore
 *  surely
 *  the
 *  the
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  MSD} class provides static methods for sorting an
 *  array of extended ASCII strings or integers using MSD radix sort.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  MSD  {
     private   static   final   int  BITS_PER_BYTE  =     8 ;
     private   static   final   int  BITS_PER_INT   =    32 ;     // each Java int is 32 bits 
     private   static   final   int  R              =   256 ;     // extended ASCII alphabet size
     private   static   final   int  CUTOFF         =    15 ;     // cutoff to insertion sort

     // do not instantiate
     private  MSD ()   {   }  

    /**
     * Rearranges the array of extended ASCII strings in ascending order.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( String []  a )   {
         int  n  =  a . length ;
         String []  aux  =   new   String [ n ];
        sort ( a ,   0 ,  n - 1 ,   0 ,  aux );
     }

     // return dth character of s, -1 if d = length of string
     private   static   int  charAt ( String  s ,   int  d )   {
         assert  d  >=   0   &&  d  <=  s . length ();
         if   ( ==  s . length ())   return   - 1 ;
         return  s . charAt ( d );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d ,   String []  aux )   {

         // cutoff to insertion sort for small subarrays
         if   ( hi  <=  lo  +  CUTOFF )   {
            insertion ( a ,  lo ,  hi ,  d );
             return ;
         }

         // compute frequency counts
         int []  count  =   new   int [ R + 2 ];
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             int  c  =  charAt ( a [ i ],  d );
            count [ c + 2 ] ++ ;
         }

         // transform counts to indicies
         for   ( int  r  =   0 ;  r  <  R + 1 ;  r ++ )
            count [ r + 1 ]   +=  count [ r ];

         // distribute
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             int  c  =  charAt ( a [ i ],  d );
            aux [ count [ c + 1 ] ++ ]   =  a [ i ];
         }

         // copy back
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )  
            a [ i ]   =  aux [ -  lo ];


         // recursively sort for each character (excludes sentinel -1)
         for   ( int  r  =   0 ;  r  <  R ;  r ++ )
            sort ( a ,  lo  +  count [ r ],  lo  +  count [ r + 1 ]   -   1 ,  d + 1 ,  aux );
     }


     // insertion sort a[lo..hi], starting at dth character
     private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( String []  a ,   int  i ,   int  j )   {
         String  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }

     // is v less than w, starting at character d
     private   static   boolean  less ( String  v ,   String  w ,   int  d )   {
         // assert v.substring(0, d).equals(w.substring(0, d));
         for   ( int  i  =  d ;  i  <   Math . min ( v . length (),  w . length ());  i ++ )   {
             if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;
             if   ( v . charAt ( i )   >  w . charAt ( i ))   return   false ;
         }
         return  v . length ()   <  w . length ();
     }


    /**
     * Rearranges the array of 32-bit integers in ascending order.
     * Currently assumes that the integers are nonnegative.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( int []  a )   {
         int  n  =  a . length ;
         int []  aux  =   new   int [ n ];
        sort ( a ,   0 ,  n - 1 ,   0 ,  aux );
     }

     // MSD sort from a[lo] to a[hi], starting at the dth byte
     private   static   void  sort ( int []  a ,   int  lo ,   int  hi ,   int  d ,   int []  aux )   {

         // cutoff to insertion sort for small subarrays
         if   ( hi  <=  lo  +  CUTOFF )   {
            insertion ( a ,  lo ,  hi ,  d );
             return ;
         }

         // compute frequency counts (need R = 256)
         int []  count  =   new   int [ R + 1 ];
         int  mask  =  R  -   1 ;     // 0xFF;
         int  shift  =  BITS_PER_INT  -  BITS_PER_BYTE * -  BITS_PER_BYTE ;
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             int  c  =   ( a [ i ]   >>  shift )   &  mask ;
            count [ +   1 ] ++ ;
         }

         // transform counts to indicies
         for   ( int  r  =   0 ;  r  <  R ;  r ++ )
            count [ r + 1 ]   +=  count [ r ];

/************* BUGGGY CODE.
        // for most significant byte, 0x80-0xFF comes before 0x00-0x7F
        if (d == 0) {
            int shift1 = count[R] - count[R/2];
            int shift2 = count[R/2];
            for (int r = 0; r < R/2; r++)
                count[r] += shift1;
            for (int r = R/2; r < R; r++)
                count[r] -= shift2;
        }
************************************/
         // distribute
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )   {
             int  c  =   ( a [ i ]   >>  shift )   &  mask ;
            aux [ count [ c ] ++ ]   =  a [ i ];
         }

         // copy back
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )  
            a [ i ]   =  aux [ -  lo ];

         // no more bits
         if   ( ==   4 )   return ;

         // recursively sort for each character
         if   ( count [ 0 ]   >   0 )
            sort ( a ,  lo ,  lo  +  count [ 0 ]   -   1 ,  d + 1 ,  aux );
         for   ( int  r  =   0 ;  r  <  R ;  r ++ )
             if   ( count [ r + 1 ]   >  count [ r ])
                sort ( a ,  lo  +  count [ r ],  lo  +  count [ r + 1 ]   -   1 ,  d + 1 ,  aux );
     }

     // TODO: insertion sort a[lo..hi], starting at dth character
     private   static   void  insertion ( int []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  a [ j ]   <  a [ j - 1 ];  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( int []  a ,   int  i ,   int  j )   {
         int  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }


     /**
     * Reads in a sequence of extended ASCII strings from standard input;
     * MSD radix sorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         int  n  =  a . length ;
        sort ( a );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Multiway.java

edu/princeton/cs/algs4/Multiway.java

/******************************************************************************
 *  Compilation:  javac Multiway.java
 *  Execution:    java Multiway input1.txt input2.txt input3.txt ...
 *  Dependencies: IndexMinPQ.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/24pq/m1.txt
 *                https://algs4.cs.princeton.edu/24pq/m2.txt
 *                https://algs4.cs.princeton.edu/24pq/m3.txt
 * 
 *  Merges together the sorted input stream given as command-line arguments
 *  into a single sorted output stream on standard output.
 *
 *  % more m1.txt 
 *  A B C F G I I Z
 *
 *  % more m2.txt 
 *  B D H P Q Q
 * 
 *  % more m3.txt 
 *  A B E F J N
 *
 *  % java Multiway m1.txt m2.txt m3.txt 
 *  A A B B B C D E F F G H I I J N P Q Q Z 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Multiway} class provides a client for reading in several
 *  sorted text files and merging them together into a single sorted
 *  text stream.
 *  This implementation uses a { @link  IndexMinPQ} to perform the multiway
 *  merge. 
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   Multiway   {  

     // This class should not be instantiated.
     private   Multiway ()   {   }

     // merge together the sorted input streams and write the sorted result to standard output
     private   static   void  merge ( In []  streams )   {
         int  n  =  streams . length ;
         IndexMinPQ < String >  pq  =   new   IndexMinPQ < String > ( n );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             if   ( ! streams [ i ]. isEmpty ())
                pq . insert ( i ,  streams [ i ]. readString ());

         // Extract and print min and read next from its stream. 
         while   ( ! pq . isEmpty ())   {
             StdOut . print ( pq . minKey ()   +   " " );
             int  i  =  pq . delMin ();
             if   ( ! streams [ i ]. isEmpty ())
                pq . insert ( i ,  streams [ i ]. readString ());
         }
         StdOut . println ();
     }


     /**
     *  Reads sorted text files specified as command-line arguments;
     *  merges them together into a sorted output; and writes
     *  the results to standard output.
     *  Note: this client does not check that the input files are sorted.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =  args . length ;
         In []  streams  =   new   In [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            streams [ i ]   =   new   In ( args [ i ]);
        merge ( streams );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/MultiwayMinPQ.java

edu/princeton/cs/algs4/MultiwayMinPQ.java

/******************************************************************************
 *  Compilation: javac MultiwayMinPQ.java   
 *  Execution:
 *  
 *  A multiway heap.
 *  
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . Comparator ;
import  java . util . NoSuchElementException ;

/**
 *  The MultiwayMinPQ class represents a priority queue of generic keys.
 *  It supports the usual insert and delete-the-minimum operations.
 *  It also supports methods for peeking at the minimum key,
 *  testing if the priority queue is empty, and iterating through
 *  the keys.
 *  It is possible to build the priority queue using a Comparator.
 *  If not, the natural order relation between the keys will be used.
 *  
 *  This implementation uses a multiway heap.
 *  For simplified notations, logarithm in base d will be referred as log-d
 *  The delete-the-minimum operation takes time proportional to d*log-d(n)
 *  The insert takes time proportional to log-d(n)
 *  The is-empty, min-key and size operations take constant time.
 *  Constructor takes time proportional to the specified capacity.
 *
 *   @author  Tristan Claverie
 */
public   class   MultiwayMinPQ < Key >   implements   Iterable < Key >   {
     private   final   int  d ;                  //Dimension of the heap
     private   int  n ;                        //Number of keys currently in the heap
     private   int  order ;                    //Number of levels of the tree
     private   Key []  keys ;                   //Array of keys
     private   final   Comparator < Key >  comp ;   //Comparator over the keys
    
    
     /**
     * Initializes an empty priority queue
     * Worst case is O(d)
     *
     *  @param   d dimension of the heap
     *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}
     */
     public   MultiwayMinPQ ( int  d )   {
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  d ;
        order  =   1 ;
        keys  =   ( Key [])   new   Comparable [ <<   1 ];
        comp  =   new   MyComparator ();
     }
    
     /**
     * Initializes an empty priority queue
     * Worst case is O(d)
     *
     *  @param   d dimension of the heap
     *  @param   comparator a Comparator over the keys
     *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}
     */
     public   MultiwayMinPQ ( Comparator < Key >  comparator ,   int  d )   {
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  d ;
        order  =   1 ;
        keys  =   ( Key [])   new   Comparable [ <<   1 ];
        comp  =  comparator ;
     }
    
     /**
     * Initializes a priority queue with given indexes
     * Worst case is O(n*log-d(n))
     *
     *  @param   d dimension of the heap
     *  @param   a an array of keys
     *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}
     */
     public   MultiwayMinPQ ( Key []  a ,   int  d )   {
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  d ;
        order  =   1 ;
        keys  =   ( Key [])   new   Comparable [ <<   1 ];
        comp  =   new   MyComparator ();
         for   ( Key  key  :  a )  insert ( key );
     }
    
     /**
     * Initializes a priority queue with given indexes
     * Worst case is O(a*log-d(n))
     *
     *  @param   d dimension of the heap
     *  @param   comparator a Comparator over the keys
     *  @param   a an array of keys
     *  @throws  java.lang.IllegalArgumentException if { @code  d < 2}
     */
     public   MultiwayMinPQ ( Comparator < Key >  comparator ,   Key []  a ,   int  d )   {
         if   ( <   2 )   throw   new   IllegalArgumentException ( "Dimension should be 2 or over" );
         this . =  d ;
        order  =   1 ;
        keys  =   ( Key [])   new   Comparable [ <<   1 ];
        comp  =  comparator ;
         for   ( Key  key  :  a )  insert ( key );
     }

         /**
     * Whether the priority queue is empty
     * Worst case is O(1)
     *  @return  true if the priority queue is empty, false if not
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Number of elements currently on the priority queue
     * Worst case is O(1)
     *  @return  the number of elements on the priority queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Puts a Key on the priority queue
     * Worst case is O(log-d(n))
     *  @param  key a Key
     */
     public   void  insert ( Key  key )   {
        keys [ n + d ]   =  key ;
        swim ( n ++ );
         if   ( ==  keys . length - d )   {
            resize ( getN ( order + 1 ) + d );
            order ++ ;
         }
     }

     /**
     * Gets the minimum key currently in the queue
     * Worst case is O(1)
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key currently in the priority queue
     */
     public   Key  minKey ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
         return  keys [ d ];
     }

     /**
     * Deletes the minimum key
     * Worst case is O(d*log-d(n))
     *  @throws  java.util.NoSuchElementException if the priority queue is empty
     *  @return  the minimum key
     */
     public   Key  delMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Priority queue is empty" );
        exch ( 0 ,   -- n );
        sink ( 0 );
         Key  min  =  keys [ n + d ];
        keys [ n + d ]   =   null ;
         int  number  =  getN ( order - 2 );
         if ( order  >   1   &&  n  ==  number )    {
            resize ( number + ( int ) Math . pow ( d ,  order - 1 ) + d );
            order -- ;
         }
         return  min ;
     }
    
     /***************************
     * General helper functions
     **************************/
    
     //Compares two keys
     private   boolean  greater ( int  x ,   int  y )   {
         int  i  =  x + d ,  j  =  y + d ;
         if   ( keys [ i ]   ==   null )   return   false ;
         if   ( keys [ j ]   ==   null )   return   true ;
         return  comp . compare ( keys [ i ],  keys [ j ])   >   0 ;
     }
    
     //Exchanges the position of two keys
     private   void  exch ( int  x ,   int  y )   {
         int  i  =  x + d ,  j  =  y + d ;
         Key  swap  =  keys [ i ];
        keys [ i ]   =  keys [ j ];
        keys [ j ]   =  swap ;
     }
    
     //Gets the maximum number of keys in the heap, given the number of levels of the tree
     private   int  getN ( int  order )   {
         return   ( 1 - (( int ) Math . pow ( d ,  order + 1 ))) / ( 1 - d );
     }
    
     /***************************
     * Functions for moving upward or downward
     **************************/
    
     //Moves upward
     private   void  swim ( int  i )   {
         if   ( >   0   &&  greater (( i - 1 ) / d ,  i ))   {
            exch ( i ,   ( i - 1 ) / d );
            swim (( i - 1 ) / d );
         }
     }
    
     //Moves downward
     private   void  sink ( int  i )   {
         int  child  =  d * i + 1 ;
         if   ( child  >=  n )   return ;
         int  min  =  minChild ( i );
         while   ( min  <  n  &&  greater ( i ,  min ))   {
            exch ( i ,  min );
            i  =  min ;
            min  =  minChild ( i );
         }
     }
    
     /***************************
     * Deletes the minimum child
     **************************/
    
     //Return the minimum child of i
     private   int  minChild ( int  i )   {
         int  loBound  =  d * i + 1 ,  hiBound  =  d * i + d ;
         int  min  =  loBound ;
         for   ( int  cur  =  loBound ;  cur  <=  hiBound ;  cur ++ )   {
             if   ( cur  <  n  &&  greater ( min ,  cur ))  min  =  cur ;
         }
         return  min ;
     }
    
     /***************************
     * Resize the priority queue
     **************************/
    
     //Resizes the array containing the keys
     //If the heap is full, it adds one floor
     //If the heap has two floors empty, it removes one
     private   void  resize ( int  N )   {
         Key []  array  =   ( Key [])   new   Comparable [ N ];
         for   ( int  i  =   0 ;  i  <   Math . min ( keys . length ,  array . length );  i ++ )   {
            array [ i ]   =  keys [ i ];
            keys [ i ]   =   null ;
         }
        keys  =  array ;
     }
    
     /***************************
     * Iterator
     **************************/
    
     /**
     * Gets an Iterator over the keys in the priority queue in ascending order
     * The Iterator does not implement the remove() method
     * iterator() : Worst case is O(n)
     * next() :     Worst case is O(d*log-d(n))
     * hasNext() :  Worst case is O(1)
     *  @return  an Iterator over the keys in the priority queue in ascending order
     */
    
     public   Iterator < Key >  iterator ()   {
         return   new   MyIterator ();
     }
    
     //Constructs an Iterator over the keys in linear time
     private   class   MyIterator   implements   Iterator < Key >   {
         MultiwayMinPQ < Key >  data ;
        
         public   MyIterator ()   {
            data  =   new   MultiwayMinPQ < Key > ( comp ,  d );
            data . keys  =   ( Key [])   new   Comparable [ keys . length ];
            data . =  n ;
             for   ( int  i  =   0 ;  i  <  keys . length ;  i ++ )   {
                data . keys [ i ]   =  keys [ i ];
             }
         }

         public   boolean  hasNext ()   {
             return   ! data . isEmpty ();
         }
        
         public   Key  next ()   {
                         if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  data . delMin ();
         }
        
         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }
     }
    
     /***************************
     * Comparator
     **************************/
    
     //default Comparator
     private   class   MyComparator   implements   Comparator < Key >   {
        @ Override
         public   int  compare ( Key  key1 ,   Key  key2 )   {
             return   (( Comparable < Key > )  key1 ). compareTo ( key2 );
         }
     }
    
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/NFA.java

edu/princeton/cs/algs4/NFA.java

/******************************************************************************
 *  Compilation:  javac NFA.java
 *  Execution:    java NFA regexp text
 *  Dependencies: Stack.java Bag.java Digraph.java DirectedDFS.java
 *
 *  % java NFA "(A*B|AC)D" AAAABD
 *  true
 *
 *  % java NFA "(A*B|AC)D" AAAAC
 *  false
 *
 *  % java NFA "(a|(bc)*d)*" abcbcd
 *  true
 *
 *  % java NFA "(a|(bc)*d)*" abcbcbcdaaaabcbcdaaaddd
 *  true
 *
 *  Remarks
 *  -----------
 *  The following features are not supported:
 *    - The + operator
 *    - Multiway or
 *    - Metacharacters in the text
 *    - Character classes.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  NFA} class provides a data type for creating a
 *  <em>nondeterministic finite state automaton</em> (NFA) from a regular
 *  expression and testing whether a given string is matched by that regular
 *  expression.
 *  It supports the following operations: <em>concatenation</em>,
 *  <em>closure</em>, <em>binary or</em>, and <em>parentheses</em>.
 *  It does not support <em>mutiway or</em>, <em>character classes</em>,
 *  <em>metacharacters</em> (either in the text or pattern),
 *  <em>capturing capabilities</em>, <em>greedy</em> or <em>relucantant</em>
 *  modifiers, and other features in industrial-strength implementations
 *  such as { @link  java.util.regex.Pattern} and { @link  java.util.regex.Matcher}.
 *  <p>
 *  This implementation builds the NFA using a digraph and a stack
 *  and simulates the NFA using digraph search (see the textbook for details).
 *  The constructor takes time proportional to <em>m</em>, where <em>m</em>
 *  is the number of characters in the regular expression.
 *  The <em>recognizes</em> method takes time proportional to <em>m n</em>,
 *  where <em>n</em> is the number of characters in the text.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/54regexp">Section 5.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class  NFA  {  

     private   Digraph  graph ;       // digraph of epsilon transitions
     private   String  regexp ;       // regular expression
     private   final   int  m ;         // number of characters in regular expression

     /**
     * Initializes the NFA from the specified regular expression.
     *
     *  @param   regexp the regular expression
     */
     public  NFA ( String  regexp )   {
         this . regexp  =  regexp ;
        m  =  regexp . length ();
         Stack < Integer >  ops  =   new   Stack < Integer > ();  
        graph  =   new   Digraph ( m + 1 );  
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {  
             int  lp  =  i ;  
             if   ( regexp . charAt ( i )   ==   '('   ||  regexp . charAt ( i )   ==   '|' )  
                ops . push ( i );  
             else   if   ( regexp . charAt ( i )   ==   ')' )   {
                 int  or  =  ops . pop ();  

                 // 2-way or operator
                 if   ( regexp . charAt ( or )   ==   '|' )   {  
                    lp  =  ops . pop ();
                    graph . addEdge ( lp ,  or + 1 );
                    graph . addEdge ( or ,  i );
                 }
                 else   if   ( regexp . charAt ( or )   ==   '(' )
                    lp  =  or ;
                 else   assert   false ;
             }  

             // closure operator (uses 1-character lookahead)
             if   ( <  m - 1   &&  regexp . charAt ( i + 1 )   ==   '*' )   {  
                graph . addEdge ( lp ,  i + 1 );  
                graph . addEdge ( i + 1 ,  lp );  
             }  
             if   ( regexp . charAt ( i )   ==   '('   ||  regexp . charAt ( i )   ==   '*'   ||  regexp . charAt ( i )   ==   ')' )  
                graph . addEdge ( i ,  i + 1 );
         }
         if   ( ops . size ()   !=   0 )
             throw   new   IllegalArgumentException ( "Invalid regular expression" );
     }  

     /**
     * Returns true if the text is matched by the regular expression.
     * 
     *  @param   txt the text
     *  @return  { @code  true} if the text is matched by the regular expression,
     *         { @code  false} otherwise
     */
     public   boolean  recognizes ( String  txt )   {
         DirectedDFS  dfs  =   new   DirectedDFS ( graph ,   0 );
         Bag < Integer >  pc  =   new   Bag < Integer > ();
         for   ( int  v  =   0 ;  v  <  graph . V ();  v ++ )
             if   ( dfs . marked ( v ))  pc . add ( v );

         // Compute possible NFA states for txt[i+1]
         for   ( int  i  =   0 ;  i  <  txt . length ();  i ++ )   {
             if   ( txt . charAt ( i )   ==   '*'   ||  txt . charAt ( i )   ==   '|'   ||  txt . charAt ( i )   ==   '('   ||  txt . charAt ( i )   ==   ')' )
                 throw   new   IllegalArgumentException ( "text contains the metacharacter '"   +  txt . charAt ( i )   +   "'" );

             Bag < Integer >  match  =   new   Bag < Integer > ();
             for   ( int  v  :  pc )   {
                 if   ( ==  m )   continue ;
                 if   (( regexp . charAt ( v )   ==  txt . charAt ( i ))   ||  regexp . charAt ( v )   ==   '.' )
                    match . add ( v + 1 );  
             }
            dfs  =   new   DirectedDFS ( graph ,  match );  
            pc  =   new   Bag < Integer > ();
             for   ( int  v  =   0 ;  v  <  graph . V ();  v ++ )
                 if   ( dfs . marked ( v ))  pc . add ( v );

             // optimization if no states reachable
             if   ( pc . size ()   ==   0 )   return   false ;
         }

         // check for accept state
         for   ( int  v  :  pc )
             if   ( ==  m )   return   true ;
         return   false ;
     }

     /**
     * Unit tests the { @code  NFA} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  regexp  =   "("   +  args [ 0 ]   +   ")" ;
         String  txt  =  args [ 1 ];
        NFA nfa  =   new  NFA ( regexp );
         StdOut . println ( nfa . recognizes ( txt ));
     }

}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/NonrecursiveDFS.java

edu/princeton/cs/algs4/NonrecursiveDFS.java

/******************************************************************************
 *  Compilation:  javac NonrecursiveDFS.java
 *  Execution:    java NonrecursiveDFS graph.txt s
 *  Dependencies: Graph.java Queue.java Stack.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/tinyCG.txt
 *                https://algs4.cs.princeton.edu/41graph/tinyG.txt
 *                https://algs4.cs.princeton.edu/41graph/mediumG.txt
 *
 *  Run nonrecurisve depth-first search on an undirected graph.
 *  Runs in O(E + V) time using O(V) extra space.
 *
 *  Explores the vertices in exactly the same order as DepthFirstSearch.java.
 *
 *  %  java Graph tinyG.txt
 *  13 vertices, 13 edges 
 *  0: 6 2 1 5 
 *  1: 0 
 *  2: 0 
 *  3: 5 4 
 *  4: 5 6 3 
 *  5: 3 4 0 
 *  6: 0 4 
 *  7: 8 
 *  8: 7 
 *  9: 11 10 12 
 *  10: 9 
 *  11: 9 12 
 *  12: 11 9 
 *
 *  % java NonrecursiveDFS tinyG.txt 0
 *  0 1 2 3 4 5 6 
 *
 * % java NonrecursiveDFS tinyG.txt 9
 * 9 10 11 12 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  NonrecursiveDFS} class represents a data type for finding
 *  the vertices connected to a source vertex <em>s</em> in the undirected
 *  graph.
 *  <p>
 *  This implementation uses a nonrecursive version of depth-first search
 *  with an explicit stack.
 *  See { @link  DepthFirstSearch} for the classic recursive version.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the worst
 *  case, where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges.
 *  The { @link  #marked(int)} instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the graph). 
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a>   
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   NonrecursiveDFS   {
     private   boolean []  marked ;    // marked[v] = is there an s-v path?
     /**
     * Computes the vertices connected to the source vertex { @code  s} in the graph { @code  G}.
     *  @param  G the graph
     *  @param  s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   NonrecursiveDFS ( Graph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];

        validateVertex ( s );

         // to be able to iterate over each adjacency list, keeping track of which
         // vertex in each adjacency list needs to be explored next
         Iterator < Integer > []  adj  =   ( Iterator < Integer > [])   new   Iterator [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =  G . adj ( v ). iterator ();

         // depth-first search using an explicit stack
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        marked [ s ]   =   true ;
        stack . push ( s );
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . peek ();
             if   ( adj [ v ]. hasNext ())   {
                 int  w  =  adj [ v ]. next ();
                 // StdOut.printf("check %d\n", w);
                 if   ( ! marked [ w ])   {
                     // discovered vertex w for the first time
                    marked [ w ]   =   true ;
                     // edgeTo[w] = v;
                    stack . push ( w );
                     // StdOut.printf("dfs(%d)\n", w);
                 }
             }
             else   {
                 // StdOut.printf("%d done\n", v);
                stack . pop ();
             }
         }
     }

     /**
     * Is vertex { @code  v} connected to the source vertex { @code  s}?
     *  @param  v the vertex
     *  @return  { @code  true} if vertex { @code  v} is connected to the source vertex { @code  s},
     *    and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  marked ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  NonrecursiveDFS} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Graph  G  =   new   Graph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);
         NonrecursiveDFS  dfs  =   new   NonrecursiveDFS ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( dfs . marked ( v ))
                 StdOut . print ( +   " " );
         StdOut . println ();
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java

edu/princeton/cs/algs4/NonrecursiveDirectedDFS.java

/******************************************************************************
 *  Compilation:  javac NonrecursiveDirectedDFS.java
 *  Execution:    java NonrecursiveDirectedDFS digraph.txt s
 *  Dependencies: Digraph.java Queue.java Stack.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Run nonrecurisve depth-first search on an directed graph.
 *  Runs in O(E + V) time.
 *
 *  Explores the vertices in exactly the same order as DirectedDFS.java.
 *
 *
 *  % java NonrecursiveDirectedDFS tinyDG.txt 1
 *  1
 *
 *  % java NonrecursiveDirectedDFS tinyDG.txt 2
 *  0 1 2 3 4 5
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  NonrecursiveDirectedDFS} class represents a data type for finding
 *  the vertices reachable from a source vertex <em>s</em> in the digraph.
 *  <p>
 *  This implementation uses a nonrecursive version of depth-first search
 *  with an explicit stack.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   NonrecursiveDirectedDFS   {
     private   boolean []  marked ;    // marked[v] = is there an s->v path?
     /**
     * Computes the vertices reachable from the source vertex { @code  s} in the digraph { @code  G}.
     *  @param   G the digraph
     *  @param   s the source vertex
     *  @throws  IllegalArgumentException unless { @code  0 <= s < V}
     */
     public   NonrecursiveDirectedDFS ( Digraph  G ,   int  s )   {
        marked  =   new   boolean [ G . V ()];
        validateVertex ( s );

         // to be able to iterate over each adjacency list, keeping track of which
         // vertex in each adjacency list needs to be explored next
         Iterator < Integer > []  adj  =   ( Iterator < Integer > [])   new   Iterator [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            adj [ v ]   =  G . adj ( v ). iterator ();

         // depth-first search using an explicit stack
         Stack < Integer >  stack  =   new   Stack < Integer > ();
        marked [ s ]   =   true ;
        stack . push ( s );
         while   ( ! stack . isEmpty ())   {
             int  v  =  stack . peek ();
             if   ( adj [ v ]. hasNext ())   {
                 int  w  =  adj [ v ]. next ();
                 // StdOut.printf("check %d\n", w);
                 if   ( ! marked [ w ])   {
                     // discovered vertex w for the first time
                    marked [ w ]   =   true ;
                     // edgeTo[w] = v;
                    stack . push ( w );
                     // StdOut.printf("dfs(%d)\n", w);
                 }
             }
             else   {
                 // StdOut.printf("%d done\n", v);
                stack . pop ();
             }
         }
     }

     /**
     * Is vertex { @code  v} reachable from the source vertex { @code  s}?
     *  @param   v the vertex
     *  @return  { @code  true} if vertex { @code  v} is reachable from the source vertex { @code  s},
     *         and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   boolean  marked ( int  v )   {
        validateVertex ( v );
         return  marked [ v ];
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  NonrecursiveDirectedDFS} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         int  s  =   Integer . parseInt ( args [ 1 ]);
         NonrecursiveDirectedDFS  dfs  =   new   NonrecursiveDirectedDFS ( G ,  s );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( dfs . marked ( v ))
                 StdOut . print ( +   " " );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Out.java

edu/princeton/cs/algs4/Out.java

/******************************************************************************
 *  Compilation:  javac Out.java
 *  Execution:    java Out
 *  Dependencies: none
 *
 *  Writes data of various types to: stdout, file, or socket.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


import  java . io . FileOutputStream ;
import  java . io . IOException ;
import  java . io . OutputStream ;
import  java . io . OutputStreamWriter ;
import  java . io . PrintWriter ;
import  java . net . Socket ;
import  java . util . Locale ;

/**
 *  This class provides methods for writing strings and numbers to
 *  various output streams, including standard output, file, and sockets.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Out   {

     // force Unicode UTF-8 encoding; otherwise it's system dependent
     private   static   final   String  CHARSET_NAME  =   "UTF-8" ;

     // assume language = English, country = US for consistency with In
     private   static   final   Locale  LOCALE  =   Locale . US ;

     private   PrintWriter  out ;

    /**
     * Initializes an output stream from a { @link  OutputStream}.
     *
     *  @param   os the { @code  OutputStream}
     */
     public   Out ( OutputStream  os )   {
         try   {
             OutputStreamWriter  osw  =   new   OutputStreamWriter ( os ,  CHARSET_NAME );
            out  =   new   PrintWriter ( osw ,   true );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Initializes an output stream from standard output.
     */
     public   Out ()   {
         this ( System . out );
     }

    /**
     * Initializes an output stream from a socket.
     *
     *  @param   socket the socket
     */
     public   Out ( Socket  socket )   {
         try   {
             OutputStream  os  =  socket . getOutputStream ();
             OutputStreamWriter  osw  =   new   OutputStreamWriter ( os ,  CHARSET_NAME );
            out  =   new   PrintWriter ( osw ,   true );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Initializes an output stream from a file.
     *
     *  @param   filename the name of the file
     */
     public   Out ( String  filename )   {
         try   {
             OutputStream  os  =   new   FileOutputStream ( filename );
             OutputStreamWriter  osw  =   new   OutputStreamWriter ( os ,  CHARSET_NAME );
            out  =   new   PrintWriter ( osw ,   true );
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
     }

    /**
     * Closes the output stream.
     */
     public   void  close ()   {
        out . close ();
     }

    /**
     * Terminates the current line by printing the line-separator string.
     */
     public   void  println ()   {
        out . println ();
     }

    /**
     * Prints an object to this output stream and then terminates the line.
     *
     *  @param  x the object to print
     */
     public   void  println ( Object  x )   {
        out . println ( x );
     }

    /**
     * Prints a boolean to this output stream and then terminates the line.
     *
     *  @param  x the boolean to print
     */
     public   void  println ( boolean  x )   {
        out . println ( x );
     }

    /**
     * Prints a character to this output stream and then terminates the line.
     *
     *  @param  x the character to print
     */
     public   void  println ( char  x )   {
        out . println ( x );
     }

    /**
     * Prints a double to this output stream and then terminates the line.
     *
     *  @param  x the double to print
     */
     public   void  println ( double  x )   {
        out . println ( x );
     }

    /**
     * Prints a float to this output stream and then terminates the line.
     *
     *  @param  x the float to print
     */
     public   void  println ( float  x )   {
        out . println ( x );
     }

    /**
     * Prints an integer to this output stream and then terminates the line.
     *
     *  @param  x the integer to print
     */
     public   void  println ( int  x )   {
        out . println ( x );
     }

    /**
     * Prints a long to this output stream and then terminates the line.
     *
     *  @param  x the long to print
     */
     public   void  println ( long  x )   {
        out . println ( x );
     }

    /**
     * Prints a byte to this output stream and then terminates the line.
     * <p>
     * To write binary data, see { @link  BinaryOut}.
     *
     *  @param  x the byte to print
     */
     public   void  println ( byte  x )   {
        out . println ( x );
     }



    /**
     * Flushes this output stream.
     */
     public   void  print ()   {
        out . flush ();
     }

    /**
     * Prints an object to this output stream and flushes this output stream.
     * 
     *  @param  x the object to print
     */
     public   void  print ( Object  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a boolean to this output stream and flushes this output stream.
     * 
     *  @param  x the boolean to print
     */
     public   void  print ( boolean  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a character to this output stream and flushes this output stream.
     * 
     *  @param  x the character to print
     */
     public   void  print ( char  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a double to this output stream and flushes this output stream.
     * 
     *  @param  x the double to print
     */
     public   void  print ( double  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a float to this output stream and flushes this output stream.
     * 
     *  @param  x the float to print
     */
     public   void  print ( float  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints an integer to this output stream and flushes this output stream.
     * 
     *  @param  x the integer to print
     */
     public   void  print ( int  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a long integer to this output stream and flushes this output stream.
     * 
     *  @param  x the long integer to print
     */
     public   void  print ( long  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a byte to this output stream and flushes this output stream.
     * 
     *  @param  x the byte to print
     */
     public   void  print ( byte  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a formatted string to this output stream, using the specified format
     * string and arguments, and then flushes this output stream.
     *
     *  @param  format the format string
     *  @param  args   the arguments accompanying the format string
     */
     public   void  printf ( String  format ,   Object ...  args )   {
        out . printf ( LOCALE ,  format ,  args );
        out . flush ();
     }

    /**
     * Prints a formatted string to this output stream, using the specified
     * locale, format string, and arguments, and then flushes this output stream.
     *
     *  @param  locale the locale
     *  @param  format the format string
     *  @param  args   the arguments accompanying the format string
     */
     public   void  printf ( Locale  locale ,   String  format ,   Object ...  args )   {
        out . printf ( locale ,  format ,  args );
        out . flush ();
     }


    /**
     * A test client.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Out  out ;

         // write to stdout
        out  =   new   Out ();
        out . println ( "Test 1" );
        out . close ();

         // write to a file
        out  =   new   Out ( "test.txt" );
        out . println ( "Test 2" );
        out . close ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Particle.java

edu/princeton/cs/algs4/Particle.java

/******************************************************************************
 *  Compilation:  javac Particle.java
 *  Execution:    none
 *  Dependencies: StdDraw.java
 *      
 *  A particle moving in the unit box with a given position, velocity,
 *  radius, and mass.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . Color ;

/**
 *  The { @code  Particle} class represents a particle moving in the unit box,
 *  with a given position, velocity, radius, and mass. Methods are provided
 *  for moving the particle and for predicting and resolvling elastic
 *  collisions with vertical walls, horizontal walls, and other particles.
 *  This data type is mutable because the position and velocity change.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/61event">Section 6.1</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Particle   {
     private   static   final   double  INFINITY  =   Double . POSITIVE_INFINITY ;

     private   double  rx ,  ry ;          // position
     private   double  vx ,  vy ;          // velocity
     private   int  count ;              // number of collisions so far
     private   final   double  radius ;    // radius
     private   final   double  mass ;      // mass
     private   final   Color  color ;      // color


     /**
     * Initializes a particle with the specified position, velocity, radius, mass, and color.
     *
     *  @param   rx <em>x</em>-coordinate of position
     *  @param   ry <em>y</em>-coordinate of position
     *  @param   vx <em>x</em>-coordinate of velocity
     *  @param   vy <em>y</em>-coordinate of velocity
     *  @param   radius the radius
     *  @param   mass the mass
     *  @param   color the color
     */
     public   Particle ( double  rx ,   double  ry ,   double  vx ,   double  vy ,   double  radius ,   double  mass ,   Color  color )   {
         this . vx  =  vx ;
         this . vy  =  vy ;
         this . rx  =  rx ;
         this . ry  =  ry ;
         this . radius  =  radius ;
         this . mass    =  mass ;
         this . color   =  color ;
     }
         
     /**
     * Initializes a particle with a random position and velocity.
     * The position is uniform in the unit box; the velocity in
     * either direciton is chosen uniformly at random.
     */
     public   Particle ()   {
        rx      =   StdRandom . uniform ( 0.0 ,   1.0 );
        ry      =   StdRandom . uniform ( 0.0 ,   1.0 );
        vx      =   StdRandom . uniform ( - 0.005 ,   0.005 );
        vy      =   StdRandom . uniform ( - 0.005 ,   0.005 );
        radius  =   0.02 ;
        mass    =   0.5 ;
        color   =   Color . BLACK ;
     }

     /**
     * Moves this particle in a straight line (based on its velocity)
     * for the specified amount of time.
     *
     *  @param   dt the amount of time
     */
     public   void  move ( double  dt )   {
        rx  +=  vx  *  dt ;
        ry  +=  vy  *  dt ;
     }

     /**
     * Draws this particle to standard draw.
     */
     public   void  draw ()   {
         StdDraw . setPenColor ( color );
         StdDraw . filledCircle ( rx ,  ry ,  radius );
     }

     /**
     * Returns the number of collisions involving this particle with
     * vertical walls, horizontal walls, or other particles.
     * This is equal to the number of calls to { @link  #bounceOff},
     * { @link  #bounceOffVerticalWall}, and
     * { @link  #bounceOffHorizontalWall}.
     *
     *  @return  the number of collisions involving this particle with
     *         vertical walls, horizontal walls, or other particles
     */
     public   int  count ()   {
         return  count ;
     }

     /**
     * Returns the amount of time for this particle to collide with the specified
     * particle, assuming no interening collisions.
     *
     *  @param   that the other particle
     *  @return  the amount of time for this particle to collide with the specified
     *         particle, assuming no interening collisions; 
     *         { @code  Double.POSITIVE_INFINITY} if the particles will not collide
     */
     public   double  timeToHit ( Particle  that )   {
         if   ( this   ==  that )   return  INFINITY ;
         double  dx   =  that . rx  -   this . rx ;
         double  dy   =  that . ry  -   this . ry ;
         double  dvx  =  that . vx  -   this . vx ;
         double  dvy  =  that . vy  -   this . vy ;
         double  dvdr  =  dx * dvx  +  dy * dvy ;
         if   ( dvdr  >   0 )   return  INFINITY ;
         double  dvdv  =  dvx * dvx  +  dvy * dvy ;
         if   ( dvdv  ==   0 )   return  INFINITY ;
         double  drdr  =  dx * dx  +  dy * dy ;
         double  sigma  =   this . radius  +  that . radius ;
         double  d  =   ( dvdr * dvdr )   -  dvdv  *   ( drdr  -  sigma * sigma );
         // if (drdr < sigma*sigma) StdOut.println("overlapping particles");
         if   ( <   0 )   return  INFINITY ;
         return   - ( dvdr  +   Math . sqrt ( d ))   /  dvdv ;
     }

     /**
     * Returns the amount of time for this particle to collide with a vertical
     * wall, assuming no interening collisions.
     *
     *  @return  the amount of time for this particle to collide with a vertical wall,
     *         assuming no interening collisions; 
     *         { @code  Double.POSITIVE_INFINITY} if the particle will not collide
     *         with a vertical wall
     */
     public   double  timeToHitVerticalWall ()   {
         if        ( vx  >   0 )   return   ( 1.0   -  rx  -  radius )   /  vx ;
         else   if   ( vx  <   0 )   return   ( radius  -  rx )   /  vx ;   
         else               return  INFINITY ;
     }

     /**
     * Returns the amount of time for this particle to collide with a horizontal
     * wall, assuming no interening collisions.
     *
     *  @return  the amount of time for this particle to collide with a horizontal wall,
     *         assuming no interening collisions; 
     *         { @code  Double.POSITIVE_INFINITY} if the particle will not collide
     *         with a horizontal wall
     */
     public   double  timeToHitHorizontalWall ()   {
         if        ( vy  >   0 )   return   ( 1.0   -  ry  -  radius )   /  vy ;
         else   if   ( vy  <   0 )   return   ( radius  -  ry )   /  vy ;
         else               return  INFINITY ;
     }

     /**
     * Updates the velocities of this particle and the specified particle according
     * to the laws of elastic collision. Assumes that the particles are colliding
     * at this instant.
     *
     *  @param   that the other particle
     */
     public   void  bounceOff ( Particle  that )   {
         double  dx   =  that . rx  -   this . rx ;
         double  dy   =  that . ry  -   this . ry ;
         double  dvx  =  that . vx  -   this . vx ;
         double  dvy  =  that . vy  -   this . vy ;
         double  dvdr  =  dx * dvx  +  dy * dvy ;               // dv dot dr
         double  dist  =   this . radius  +  that . radius ;     // distance between particle centers at collison

         // magnitude of normal force
         double  magnitude  =   2   *   this . mass  *  that . mass  *  dvdr  /   (( this . mass  +  that . mass )   *  dist );

         // normal force, and in x and y directions
         double  fx  =  magnitude  *  dx  /  dist ;
         double  fy  =  magnitude  *  dy  /  dist ;

         // update velocities according to normal force
         this . vx  +=  fx  /   this . mass ;
         this . vy  +=  fy  /   this . mass ;
        that . vx  -=  fx  /  that . mass ;
        that . vy  -=  fy  /  that . mass ;

         // update collision counts
         this . count ++ ;
        that . count ++ ;
     }

     /**
     * Updates the velocity of this particle upon collision with a vertical
     * wall (by reflecting the velocity in the <em>x</em>-direction).
     * Assumes that the particle is colliding with a vertical wall at this instant.
     */
     public   void  bounceOffVerticalWall ()   {
        vx  =   - vx ;
        count ++ ;
     }

     /**
     * Updates the velocity of this particle upon collision with a horizontal
     * wall (by reflecting the velocity in the <em>y</em>-direction).
     * Assumes that the particle is colliding with a horizontal wall at this instant.
     */
     public   void  bounceOffHorizontalWall ()   {
        vy  =   - vy ;
        count ++ ;
     }

     /**
     * Returns the kinetic energy of this particle.
     * The kinetic energy is given by the formula 1/2 <em>m</em> <em>v</em><sup>2</sup>,
     * where <em>m</em> is the mass of this particle and <em>v</em> is its velocity.
     *
     *  @return  the kinetic energy of this particle
     */
     public   double  kineticEnergy ()   {
         return   0.5   *  mass  *   ( vx * vx  +  vy * vy );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/PatriciaSET.java

edu/princeton/cs/algs4/PatriciaSET.java

/******************************************************************************
 *  Compilation:  javac PatriciaSET.java
 *  Execution:    java PatriciaSET
 *  Dependencies: StdOut.java StdRandom.java Queue.java
 *  Data files:   n/a
 *
 *  A set implementation based on PATRICIA.
 *
 *  % java PatriciaSET 1000000 1
 *  Creating dataset (1000000 items)...
 *  Shuffling...
 *  Adding (1000000 items)...
 *  Iterating...
 *  1000000 items iterated
 *  Shuffling...
 *  Deleting (500000 items)...
 *  Iterating...
 *  500000 items iterated
 *  Checking...
 *  500000 items found and 500000 (deleted) items missing
 *  Deleting the rest (500000 items)...
 *  PASS 1 TESTS SUCCEEDED
 *  %
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  PatriciaSET} class provides an implementation of an
 *  unordered set, with the restriction that the items (keys) are of class
 *  { @link  java.lang.String}. It supports the usual <em>add</em>,
 *  <em>contains</em>, <em>delete</em>, <em>size</em>, and <em>is-empty</em>
 *  methods. It also provides an <em>iterator</em> method for iterating over all
 *  the elements in the set.
 *  <p>
 *  This unordered set class implements PATRICIA (Practical Algorithm to
 *  Retrieve Information Coded In Alphanumeric). In spite of the acronym, string
 *  keys are not limited to alphanumeric content. A key may possess any string
 *  value, with one exception: a zero-length string is not permitted.
 *  <p>
 *  Unlike other generic set implementations that can accept a parameterized key
 *  type, this set class can only accommodate keys of class
 *  { @link  java.lang.String}. This unfortunate restriction stems from a
 *  limitation in Java. Although Java provides excellent support for generic
 *  programming, the current infrastructure somewhat limits generic collection
 *  implementations to those that employ comparison-based or hash-based methods.
 *  PATRICIA does not employ comparisons or hashing; instead, it relies on
 *  bit-test operations. Because Java does not furnish any generic abstractions
 *  (or implementations) for bit-testing the contents of an object, providing
 *  support for generic keys using PATRICIA does not seem practical.
 *  <p>
 *  PATRICIA is a variation of a trie, and it is often classified as a
 *  space-optimized trie. In a classical trie, each level represents a
 *  subsequent digit in a key. In PATRICIA, nodes only exist to identify the
 *  digits (bits) that distinguish the individual keys within the trie. Because
 *  PATRICIA uses a radix of two, each node has only two children, like a binary
 *  tree. Also like a binary tree, the number of nodes, within the trie, equals
 *  the number of keys. Consequently, some classify PATRICIA as a tree.
 *  <p>
 *  The analysis of PATRICIA is complicated. The theoretical wost-case
 *  performance for an <em>add</em>, <em>contains</em>, or <em>delete</em>
 *  operation is <strong>O(N)</strong>, when <strong>N</strong> is less than
 *  <strong>W</strong> (where <strong>W</strong> is the length in bits of the
 *  longest key), and <strong>O(W)</strong>, when <strong>N</strong> is greater
 *  than <strong>W</strong>. However, the worst case is unlikely to occur with
 *  typical use. The average (and usual) performance of PATRICIA is
 *  approximately <strong>~lg N</strong> for each <em>add</em>,
 *  <em>contains</em>, or <em>delete</em> operation. Although this appears to
 *  put PATRICIA on the same footing as binary trees, this time complexity
 *  represents the number of single-bit test operations (under PATRICIA), and
 *  not full-key comparisons (as required by binary trees). After the single-bit
 *  tests conclude, PATRICIA requires just one full-key comparison to confirm
 *  the existence (or absence) of the key (per <em>add</em>, <em>contains</em>,
 *  or <em>delete</em> operation).
 *  <p>
 *  In practice, decent implementations of PATRICIA can often outperform
 *  balanced binary trees, and even hash tables. Although this particular
 *  implementation performs well, the source code was written with an emphasis
 *  on clarity, and not performance. PATRICIA performs admirably when its
 *  bit-testing loops are well tuned. Consider using the source code as a guide,
 *  should you need to produce an optimized implementation, for anther key type,
 *  or in another programming language.
 *  <p>
 *  Other resources for PATRICIA:<br>
 *  Sedgewick, R. (1990) <i>Algorithms in C</i>, Addison-Wesley<br>
 *  Knuth, D. (1973) <i>The Art of Computer Programming</i>, Addison-Wesley<br>
 *
 *   @author  John Hentosh (based on an implementation by Robert Sedgewick)
 */
public   class   PatriciaSET   implements   Iterable < String >   {
     private   Node  head ;
     private   int  count ;

     /* An inner Node class specifies the objects that hold each key. The b
     * value indicates the relevant bit position.
     */
     private   class   Node   {
         private   Node  left ,  right ;
         private   String  key ;
         private   int  b ;

         public   Node ( String  key ,   int  b )   {
             this . key  =  key ;
             this . =  b ;
         }
     };

     /**
     * Initializes an empty PATRICIA-based set.
     */
     /* The constructor creates a head (sentinel) node that contains a
     * zero-length string.
     */
     public   PatriciaSET ()   {
        head  =   new   Node ( "" ,   0 );
        head . left  =  head ;
        head . right  =  head ;
        count  =   0 ;
     }

     /**
     * Adds the key to the set if it is not already present.
     *  @param  key the key to add
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   void  add ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called add(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         Node  p ;
         Node  x  =  head ;
         do   {
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         if   ( ! x . key . equals ( key ))   {
             int  b  =  firstDifferingBit ( x . key ,  key );
            x  =  head ;
             do   {
                p  =  x ;
                 if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
                 else                        x  =  x . left ;
             }   while   ( p . <  x . &&  x . <  b );
             Node  t  =   new   Node ( key ,  b );
             if   ( safeBitTest ( key ,  b ))   {
                t . left   =  x ;
                t . right  =  t ;
             }
             else   {
                t . left   =  t ;
                t . right  =  x ;
             }
             if   ( safeBitTest ( key ,  p . b ))  p . right  =  t ;
             else                        p . left  =  t ;
            count ++ ;
         }
     }

     /**
     * Does the set contain the given key?
     *  @param  key the key
     *  @return  { @code  true} if the set contains { @code  key} and
     * { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   boolean  contains ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called contains(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         Node  p ;
         Node  x  =  head ;
         do   {
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         return  x . key . equals ( key );
     }

     /**
     * Removes the key from the set if the key is present.
     *  @param  key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   void  delete ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called delete(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         Node  g ;               // previous previous (grandparent)
         Node  p  =  head ;        // previous (parent)
         Node  x  =  head ;        // node to delete
         do   {
            g  =  p ;
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         if   ( x . key . equals ( key ))   {
             Node  z ;
             Node  y  =  head ;
             do   {              // find the true parent (z) of x
                z  =  y ;
                 if   ( safeBitTest ( key ,  y . b ))  y  =  y . right ;
                 else                        y  =  y . left ;
             }   while   ( !=  x );
             if   ( ==  p )   {     // case 1: remove (leaf node) x
                 Node  c ;       // child of x
                 if   ( safeBitTest ( key ,  x . b ))  c  =  x . left ;
                 else                        c  =  x . right ;
                 if   ( safeBitTest ( key ,  z . b ))  z . right  =  c ;
                 else                        z . left   =  c ;
             }
             else   {            // case 2: p replaces (internal node) x
                 Node  c ;       // child of p
                 if   ( safeBitTest ( key ,  p . b ))  c  =  p . left ;
                 else                        c  =  p . right ;
                 if   ( safeBitTest ( key ,  g . b ))  g . right  =  c ;
                 else                        g . left   =  c ;
                 if   ( safeBitTest ( key ,  z . b ))  z . right  =  p ;
                 else                        z . left   =  p ;
                p . left  =  x . left ;
                p . right  =  x . right ;
                p . =  x . b ;
             }
            count -- ;
         }
     }

     /**
     * Is the set empty?
     *  @return  { @code  true} if the set is empty, and { @code  false}
     * otherwise
     */
     boolean  isEmpty ()   {
         return  count  ==   0 ;
     }

     /**
     * Returns the number of keys in the set.
     *  @return  the number of keys in the set
     */
     int  size ()   {
         return  count ;
     }

     /**
     * Returns all of the keys in the set, as an iterator.
     * To iterate over all of the keys in a set named { @code  set}, use the
     * foreach notation: { @code  for (Key key : set)}.
     *  @return  an iterator to all of the keys in the set
     */
     public   Iterator < String >  iterator ()   {
         Queue < String >  queue  =   new   Queue < String > ();
         if   ( head . left   !=  head )  collect ( head . left ,    0 ,  queue );
         if   ( head . right  !=  head )  collect ( head . right ,   0 ,  queue );
         return  queue . iterator ();
     }

     private   void  collect ( Node  x ,   int  b ,   Queue < String >  queue )   {
         if   ( x . >  b )   {
            collect ( x . left ,  x . b ,  queue );
            queue . enqueue ( x . key );
            collect ( x . right ,  x . b ,  queue );
         }
     }

     /**
     * Returns a string representation of this set.
     *  @return  a string representation of this set, with the keys separated
     * by single spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( String  key  :   this )  s . append ( key  +   " " );
         if   ( s . length ()   >   0 )  s . deleteCharAt ( s . length ()   -   1 );
         return  s . toString ();
     }

     /* The safeBitTest function logically appends a terminating sequence (when
     * required) to extend (logically) the string beyond its length.
     *
     * The inner loops of the get and put methods flow much better when they
     * are not concerned with the lengths of strings, so a trick is employed to
     * allow the get and put methods to view every string as an "infinite"
     * sequence of bits. Logically, every string gets a '\uffff' character,
     * followed by an "infinite" sequence of '\u0000' characters, appended to
     * the end.
     *
     * Note that the '\uffff' character serves to mark the end of the string,
     * and it is necessary. Simply padding with '\u0000' is insufficient to
     * make all unique Unicode strings "look" unique to the get and put methods
     * (because these methods do not regard string lengths).
     */
     private   static   boolean  safeBitTest ( String  key ,   int  b )   {
         if   ( <  key . length ()   *   16 )        return  bitTest ( key ,  b )   !=   0 ;
         if   ( >  key . length ()   *   16   +   15 )   return   false ;     // padding
         /* 16 bits of 0xffff */           return   true ;      // end marker
     }

     private   static   int  bitTest ( String  key ,   int  b )   {
         return   ( key . charAt ( >>>   4 )   >>>   ( &   0xf ))   &   1 ;
     }

     /* Like the safeBitTest function, the safeCharAt function makes every
     * string look like an "infinite" sequence of characters. Logically, every
     * string gets a '\uffff' character, followed by an "infinite" sequence of
     * '\u0000' characters, appended to the end.
     */
     private   static   int  safeCharAt ( String  key ,   int  i )   {
         if   ( <  key . length ())   return  key . charAt ( i );
         if   ( >  key . length ())   return   0x0000 ;              // padding
         else                    return   0xffff ;              // end marker
     }

     /* For efficiency's sake, the firstDifferingBit function compares entire
     * characters first, and then considers the individual bits (once it finds
     * two characters that do not match). Also, the least significant bits of
     * an individual character are examined first. There are many Unicode
     * alphabets where most (if not all) of the "action" occurs in the least
     * significant bits.
     *
     * Notice that the very first character comparison excludes the
     * least-significant bit. The firstDifferingBit function must never return
     * zero; otherwise, a node would become created as a child to the head
     * (sentinel) node that matches the bit-index value (zero) stored in the
     * head node. This would violate the invariant that bit-index values
     * increase as you descend into the trie.
     */
     private   static   int  firstDifferingBit ( String  k1 ,   String  k2 )   {
         int  i  =   0 ;
         int  c1  =  safeCharAt ( k1 ,   0 )   &   ~ 1 ;
         int  c2  =  safeCharAt ( k2 ,   0 )   &   ~ 1 ;
         if   ( c1  ==  c2 )   {
            i  =   1 ;
             while   ( safeCharAt ( k1 ,  i )   ==  safeCharAt ( k2 ,  i ))  i ++ ;
            c1  =  safeCharAt ( k1 ,  i );
            c2  =  safeCharAt ( k2 ,  i );
         }
         int  b  =   0 ;
         while   ((( c1  >>>  b )   &   1 )   ==   (( c2  >>>  b )   &   1 ))  b ++ ;
         return  i  *   16   +  b ;
     }

     /**
     * Unit tests the { @code  PatriciaSET} data type.
     * This test fixture runs a series of tests on a randomly generated dataset.
     * You may specify up to two integer parameters on the command line. The
     * first parameter indicates the size of the dataset. The second parameter
     * controls the number of passes (a new random dataset becomes generated at
     * the start of each pass).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         PatriciaSET  set  =   new   PatriciaSET ();
         int  limitItem  =   1000000 ;
         int  limitPass  =   1 ;
         int  countPass  =   0 ;
         boolean  ok  =   true ;

         if   ( args . length  >   0 )  limitItem  =   Integer . parseInt ( args [ 0 ]);
         if   ( args . length  >   1 )  limitPass  =   Integer . parseInt ( args [ 1 ]);

         do   {
             String []  a  =   new   String [ limitItem ];

             StdOut . printf ( "Creating dataset (%d items)...\n" ,  limitItem );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )
                a [ i ]   =   Integer . toString ( i ,   16 );

             StdOut . printf ( "Shuffling...\n" );
             StdRandom . shuffle ( a );

             StdOut . printf ( "Adding (%d items)...\n" ,  limitItem );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )
                set . add ( a [ i ]);

             int  countItems  =   0 ;
             StdOut . printf ( "Iterating...\n" );
             for   ( String  key  :  set )  countItems ++ ;
             StdOut . printf ( "%d items iterated\n" ,  countItems );
             if   ( countItems  !=  limitItem )   ok  =   false ;
             if   ( countItems  !=  set . size ())  ok  =   false ;

             StdOut . printf ( "Shuffling...\n" );
             StdRandom . shuffle ( a );

             int  limitDelete  =  limitItem  /   2 ;
             StdOut . printf ( "Deleting (%d items)...\n" ,  limitDelete );
             for   ( int  i  =   0 ;  i  <  limitDelete ;  i ++ )
                set . delete ( a [ i ]);

            countItems  =   0 ;
             StdOut . printf ( "Iterating...\n" );
             for   ( String  key  :  set )  countItems ++ ;
             StdOut . printf ( "%d items iterated\n" ,  countItems );
             if   ( countItems  !=  limitItem  -  limitDelete )  ok  =   false ;
             if   ( countItems  !=  set . size ())               ok  =   false ;

             int  countDelete  =   0 ;
             int  countRemain  =   0 ;
             StdOut . printf ( "Checking...\n" );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )   {
                 if   ( <  limitDelete )   {
                     if   ( ! set . contains ( a [ i ]))  countDelete ++ ;
                 }
                 else   {
                     if   ( set . contains ( a [ i ]))  countRemain ++ ;
                 }
             }
             StdOut . printf ( "%d items found and %d (deleted) items missing\n" ,
                countRemain ,  countDelete );
             if   ( countRemain  +  countDelete  !=  limitItem )   ok  =   false ;
             if   ( countRemain                !=  set . size ())  ok  =   false ;
             if   ( set . isEmpty ())                            ok  =   false ;

             StdOut . printf ( "Deleting the rest (%d items)...\n" ,
                limitItem  -  countDelete );
             for   ( int  i  =  countDelete ;  i  <  limitItem ;  i ++ )
                set . delete ( a [ i ]);
             if   ( ! set . isEmpty ())  ok  =   false ;

            countPass ++ ;
             if   ( ok )   StdOut . printf ( "PASS %d TESTS SUCCEEDED\n" ,  countPass );
             else      StdOut . printf ( "PASS %d TESTS FAILED\n" ,     countPass );
         }   while   ( ok  &&  countPass  <  limitPass );

         if   ( ! ok )   throw   new  java . lang . RuntimeException ( "TESTS FAILED" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/PatriciaST.java

edu/princeton/cs/algs4/PatriciaST.java

/******************************************************************************
 *  Compilation:  javac PatriciaST.java
 *  Execution:    java PatriciaST
 *  Dependencies: StdOut.java StdRandom.java Queue.java
 *  Data files:   n/a
 *
 *  A symbol table implementation based on PATRICIA.
 *
 *  % java PatriciaST 1000000 1
 *  Creating dataset (1000000 items)...
 *  Shuffling...
 *  Adding (1000000 items)...
 *  Iterating...
 *  1000000 items iterated
 *  Shuffling...
 *  Deleting (500000 items)...
 *  Iterating...
 *  500000 items iterated
 *  Checking...
 *  500000 items found and 500000 (deleted) items missing
 *  Deleting the rest (500000 items)...
 *  PASS 1 TESTS SUCCEEDED
 *  %
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  PatriciaST} class provides an implementation of an unordered
 *  symbol table of key-value pairs, with the restriction that the key is of
 *  class { @link  java.lang.String}. It supports the usual <em>put</em>,
 *  <em>get</em>, <em>contains</em>, <em>delete</em>, <em>size</em>, and
 *  <em>is-empty</em> methods. It also provides a <em>keys</em> method for
 *  iterating over all of the keys. A symbol table implements the
 *  <em>associative array</em> abstraction: when associating a value with a key
 *  that is already in the symbol table, the convention is to replace the old
 *  value with the new value. Unlike { @link  java.util.Map}, this class uses the
 *  convention that values cannot be { @code  null}—setting the value
 *  associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This unordered symbol table class implements PATRICIA (Practical Algorithm
 *  to Retrieve Information Coded In Alphanumeric). In spite of the acronym,
 *  string keys are not limited to alphanumeric content. A key may possess any
 *  string value, except for the string of zero length (the empty string).
 *  <p>
 *  Unlike other generic symbol table implementations that can accept a
 *  parameterized key type, this symbol table class can only accommodate keys
 *  of class { @link  java.lang.String}. This unfortunate restriction stems from a
 *  limitation in Java. Although Java provides excellent support for generic
 *  programming, the current infrastructure somewhat limits generic collection
 *  implementations to those that employ comparison-based or hash-based methods.
 *  PATRICIA does not employ comparisons or hashing; instead, it relies on
 *  bit-test operations. Because Java does not furnish any generic abstractions
 *  (or implementations) for bit-testing the contents of an object, providing
 *  support for generic keys using PATRICIA does not seem practical.
 *  <p>
 *  PATRICIA is a variation of a trie, and it is often classified as a
 *  space-optimized trie. In a classical trie, each level represents a
 *  subsequent digit in a key. In PATRICIA, nodes only exist to identify the
 *  digits (bits) that distinguish the individual keys within the trie. Because
 *  PATRICIA uses a radix of two, each node has only two children, like a binary
 *  tree. Also like a binary tree, the number of nodes, within the trie, equals
 *  the number of keys. Consequently, some classify PATRICIA as a tree.
 *  <p>
 *  The analysis of PATRICIA is complicated. The theoretical wost-case
 *  performance for a <em>get</em>, <em>put</em>, or <em>delete</em> operation
 *  is <strong>O(N)</strong>, when <strong>N</strong> is less than
 *  <strong>W</strong> (where <strong>W</strong> is the length in bits of the
 *  longest key), and <strong>O(W)</strong>, when <strong>N</strong> is greater
 *  than <strong>W</strong>. However, the worst case is unlikely to occur with
 *  typical use. The average (and usual) performance of PATRICIA is
 *  approximately <strong>~lg N</strong> for each <em>get</em>, <em>put</em>, or
 *  <em>delete</em> operation. Although this appears to put PATRICIA on the same
 *  footing as binary trees, this time complexity represents the number of
 *  single-bit test operations (under PATRICIA), and not full-key comparisons
 *  (as required by binary trees). After the single-bit tests conclude, PATRICIA
 *  requires just one full-key comparison to confirm the existence (or absence)
 *  of the key (per <em>get</em>, <em>put</em>, or <em>delete</em> operation).
 *  <p>
 *  In practice, decent implementations of PATRICIA can often outperform
 *  balanced binary trees, and even hash tables. Although this particular
 *  implementation performs well, the source code was written with an emphasis
 *  on clarity, and not performance. PATRICIA performs admirably when its
 *  bit-testing loops are well tuned. Consider using the source code as a guide,
 *  should you need to produce an optimized implementation, for anther key type,
 *  or in another programming language.
 *  <p>
 *  Other resources for PATRICIA:<br>
 *  Sedgewick, R. (1990) <i>Algorithms in C</i>, Addison-Wesley<br>
 *  Knuth, D. (1973) <i>The Art of Computer Programming</i>, Addison-Wesley<br>
 *
 *   @author  John Hentosh (based on an implementation by Robert Sedgewick)
 */
public   class   PatriciaST < Value >   {
     private   Node  head ;
     private   int  count ;

     /* An inner Node class specifies the objects that hold each key-value pair.
     * The b value indicates the relevant bit position.
     */
     private   class   Node   {
         private   Node  left ,  right ;
         private   String  key ;
         private   Value  val ;
         private   int  b ;

         public   Node ( String  key ,   Value  val ,   int  b )   {
             this . key  =  key ;
             this . val  =  val ;
             this . =  b ;
         }
     };

     /**
     * Initializes an empty PATRICIA-based symbol table.
     */
     /* The constructor creates a head (sentinel) node that contains a
     * zero-length string.
     */
     public   PatriciaST ()   {
        head  =   new   Node ( "" ,   null ,   0 );
        head . left  =  head ;
        head . right  =  head ;
        count  =   0 ;
     }

     /**
     * Places a key-value pair into the symbol table. If the table already
     * contains the specified key, then its associated value becomes updated.
     * If the value provided is { @code  null}, then the key becomes removed
     * from the symbol table.
     *  @param  key the key
     *  @param  val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   void  put ( String  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called put(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         if   ( val  ==   null )  delete ( key );
         Node  p ;
         Node  x  =  head ;
         do   {
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         if   ( ! x . key . equals ( key ))   {
             int  b  =  firstDifferingBit ( x . key ,  key );
            x  =  head ;
             do   {
                p  =  x ;
                 if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
                 else                        x  =  x . left ;
             }   while   ( p . <  x . &&  x . <  b );
             Node  t  =   new   Node ( key ,  val ,  b );
             if   ( safeBitTest ( key ,  b ))   {
                t . left   =  x ;
                t . right  =  t ;
             }
             else   {
                t . left   =  t ;
                t . right  =  x ;
             }
             if   ( safeBitTest ( key ,  p . b ))  p . right  =  t ;
             else                        p . left   =  t ;
            count ++ ;
         }
         else  x . val  =  val ;
     }

     /**
     * Retrieves the value associated with the given key.
     *  @param  key the key
     *  @return  the value associated with the given key if the key is in the
     * symbol table and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   Value  get ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called get(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         Node  p ;
         Node  x  =  head ;
         do   {
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         if   ( x . key . equals ( key ))   return  x . val ;
         else                     return   null ;
     }

     /**
     * Removes a key and its associated value from the symbol table, if it
     * exists.
     *  @param  key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   void  delete ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called delete(null)" );
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "invalid key" );
         Node  g ;               // previous previous (grandparent)
         Node  p  =  head ;        // previous (parent)
         Node  x  =  head ;        // node to delete
         do   {
            g  =  p ;
            p  =  x ;
             if   ( safeBitTest ( key ,  x . b ))  x  =  x . right ;
             else                        x  =  x . left ;
         }   while   ( p . <  x . b );
         if   ( x . key . equals ( key ))   {
             Node  z ;
             Node  y  =  head ;
             do   {              // find the true parent (z) of x
                z  =  y ;
                 if   ( safeBitTest ( key ,  y . b ))  y  =  y . right ;
                 else                        y  =  y . left ;
             }   while   ( !=  x );
             if   ( ==  p )   {     // case 1: remove (leaf node) x
                 Node  c ;       // child of x
                 if   ( safeBitTest ( key ,  x . b ))  c  =  x . left ;
                 else                        c  =  x . right ;
                 if   ( safeBitTest ( key ,  z . b ))  z . right  =  c ;
                 else                        z . left   =  c ;
             }
             else   {            // case 2: p replaces (internal node) x
                 Node  c ;       // child of p
                 if   ( safeBitTest ( key ,  p . b ))  c  =  p . left ;
                 else                        c  =  p . right ;
                 if   ( safeBitTest ( key ,  g . b ))  g . right  =  c ;
                 else                        g . left   =  c ;
                 if   ( safeBitTest ( key ,  z . b ))  z . right  =  p ;
                 else                        z . left   =  p ;
                p . left  =  x . left ;
                p . right  =  x . right ;
                p . =  x . b ;
             }
            count -- ;
         }
     }

     /**
     * Returns { @code  true} if the key-value pair, specified by the given
     * key, exists within the symbol table.
     *  @param  key the key
     *  @return  { @code  true} if this symbol table contains the given
     * { @code  key} and { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  key} is the empty string.
     */
     public   boolean  contains ( String  key )   {
         return  get ( key )   !=   null ;
     }

     /**
     * Returns { @code  true} if the symbol table is empty.
     *  @return  { @code  true} if this symbol table is empty and
     * { @code  false} otherwise
     */
     boolean  isEmpty ()   {
         return  count  ==   0 ;
     }

     /**
     * Returns the number of key-value pairs within the symbol table.
     *  @return  the number of key-value pairs within this symbol table
     */
     int  size ()   {
         return  count ;
     }

     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named
     * { @code  st}, use the foreach notation:
     * { @code  for (Key key : st.keys())}.
     *  @return  all keys in the symbol table as an { @code  Iterable}
     */
     public   Iterable < String >  keys ()   {
         Queue < String >  queue  =   new   Queue < String > ();
         if   ( head . left   !=  head )  keys ( head . left ,    0 ,  queue );
         if   ( head . right  !=  head )  keys ( head . right ,   0 ,  queue );
         return  queue ;
     }

     private   void  keys ( Node  x ,   int  b ,   Queue < String >  queue )   {
         if   ( x . >  b )   {
            keys ( x . left ,  x . b ,  queue );
            queue . enqueue ( x . key );
            keys ( x . right ,  x . b ,  queue );
         }
     }

     /* The safeBitTest function logically appends a terminating sequence (when
     * required) to extend (logically) the string beyond its length.
     *
     * The inner loops of the get and put methods flow much better when they
     * are not concerned with the lengths of strings, so a trick is employed to
     * allow the get and put methods to view every string as an "infinite"
     * sequence of bits. Logically, every string gets a '\uffff' character,
     * followed by an "infinite" sequence of '\u0000' characters, appended to
     * the end.
     *
     * Note that the '\uffff' character serves to mark the end of the string,
     * and it is necessary. Simply padding with '\u0000' is insufficient to
     * make all unique Unicode strings "look" unique to the get and put methods
     * (because these methods do not regard string lengths).
     */
     private   static   boolean  safeBitTest ( String  key ,   int  b )   {
         if   ( <  key . length ()   *   16 )        return  bitTest ( key ,  b )   !=   0 ;
         if   ( >  key . length ()   *   16   +   15 )   return   false ;     // padding
         /* 16 bits of 0xffff */           return   true ;      // end marker
     }

     private   static   int  bitTest ( String  key ,   int  b )   {
         return   ( key . charAt ( >>>   4 )   >>>   ( &   0xf ))   &   1 ;
     }

     /* Like the safeBitTest function, the safeCharAt function makes every
     * string look like an "infinite" sequence of characters. Logically, every
     * string gets a '\uffff' character, followed by an "infinite" sequence of
     * '\u0000' characters, appended to the end.
     */
     private   static   int  safeCharAt ( String  key ,   int  i )   {
         if   ( <  key . length ())   return  key . charAt ( i );
         if   ( >  key . length ())   return   0x0000 ;              // padding
         else                    return   0xffff ;              // end marker
     }

     /* For efficiency's sake, the firstDifferingBit function compares entire
     * characters first, and then considers the individual bits (once it finds
     * two characters that do not match). Also, the least significant bits of
     * an individual character are examined first. There are many Unicode
     * alphabets where most (if not all) of the "action" occurs in the least
     * significant bits.
     *
     * Notice that the very first character comparison excludes the
     * least-significant bit. The firstDifferingBit function must never return
     * zero; otherwise, a node would become created as a child to the head
     * (sentinel) node that matches the bit-index value (zero) stored in the
     * head node. This would violate the invariant that bit-index values
     * increase as you descend into the trie.
     */
     private   static   int  firstDifferingBit ( String  k1 ,   String  k2 )   {
         int  i  =   0 ;
         int  c1  =  safeCharAt ( k1 ,   0 )   &   ~ 1 ;
         int  c2  =  safeCharAt ( k2 ,   0 )   &   ~ 1 ;
         if   ( c1  ==  c2 )   {
            i  =   1 ;
             while   ( safeCharAt ( k1 ,  i )   ==  safeCharAt ( k2 ,  i ))  i ++ ;
            c1  =  safeCharAt ( k1 ,  i );
            c2  =  safeCharAt ( k2 ,  i );
         }
         int  b  =   0 ;
         while   ((( c1  >>>  b )   &   1 )   ==   (( c2  >>>  b )   &   1 ))  b ++ ;
         return  i  *   16   +  b ;
     }

     /**
     * Unit tests the { @code  PatriciaST} data type.
     * This test fixture runs a series of tests on a randomly generated dataset.
     * You may specify up to two integer parameters on the command line. The
     * first parameter indicates the size of the dataset. The second parameter
     * controls the number of passes (a new random dataset becomes generated at
     * the start of each pass).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         PatriciaST < Integer >  st  =   new   PatriciaST < Integer > ();
         int  limitItem  =   1000000 ;
         int  limitPass  =   1 ;
         int  countPass  =   0 ;
         boolean  ok  =   true ;

         if   ( args . length  >   0 )  limitItem  =   Integer . parseInt ( args [ 0 ]);
         if   ( args . length  >   1 )  limitPass  =   Integer . parseInt ( args [ 1 ]);

         do   {
             String []  a  =   new   String [ limitItem ];
             int []     v  =   new   int [ limitItem ];

             StdOut . printf ( "Creating dataset (%d items)...\n" ,  limitItem );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )   {
                a [ i ]   =   Integer . toString ( i ,   16 );
                v [ i ]   =  i ;
             }

             StdOut . printf ( "Shuffling...\n" );
             StdRandom . shuffle ( v );

             StdOut . printf ( "Adding (%d items)...\n" ,  limitItem );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )
                st . put ( a [ v [ i ]],  v [ i ]);

             int  countKeys  =   0 ;
             StdOut . printf ( "Iterating...\n" );
             for   ( String  key  :  st . keys ())  countKeys ++ ;
             StdOut . printf ( "%d items iterated\n" ,  countKeys );
             if   ( countKeys  !=  limitItem )  ok  =   false ;
             if   ( countKeys  !=  st . size ())  ok  =   false ;

             StdOut . printf ( "Shuffling...\n" );
             StdRandom . shuffle ( v );

             int  limitDelete  =  limitItem  /   2 ;
             StdOut . printf ( "Deleting (%d items)...\n" ,  limitDelete );
             for   ( int  i  =   0 ;  i  <  limitDelete ;  i ++ )
                st . delete ( a [ v [ i ]]);

            countKeys  =   0 ;
             StdOut . printf ( "Iterating...\n" );
             for   ( String  key  :  st . keys ())  countKeys ++ ;
             StdOut . printf ( "%d items iterated\n" ,  countKeys );
             if   ( countKeys  !=  limitItem  -  limitDelete )  ok  =   false ;
             if   ( countKeys  !=  st . size ())                ok  =   false ;

             int  countDelete  =   0 ;
             int  countRemain  =   0 ;
             StdOut . printf ( "Checking...\n" );
             for   ( int  i  =   0 ;  i  <  limitItem ;  i ++ )   {
                 if   ( <  limitDelete )   {
                     if   ( ! st . contains ( a [ v [ i ]]))  countDelete ++ ;
                 }
                 else   {
                     int  val  =  st . get ( a [ v [ i ]]);
                     if   ( val  ==  v [ i ])  countRemain ++ ;
                 }
             }
             StdOut . printf ( "%d items found and %d (deleted) items missing\n" ,
                countRemain ,  countDelete );
             if   ( countRemain  +  countDelete  !=  limitItem )  ok  =   false ;
             if   ( countRemain                !=  st . size ())  ok  =   false ;
             if   ( st . isEmpty ())                            ok  =   false ;

             StdOut . printf ( "Deleting the rest (%d items)...\n" ,
                limitItem  -  countDelete );
             for   ( int  i  =  countDelete ;  i  <  limitItem ;  i ++ )
                st . delete ( a [ v [ i ]]);
             if   ( ! st . isEmpty ())  ok  =   false ;

            countPass ++ ;
             if   ( ok )   StdOut . printf ( "PASS %d TESTS SUCCEEDED\n" ,  countPass );
             else      StdOut . printf ( "PASS %d TESTS FAILED\n" ,     countPass );
         }   while   ( ok  &&  countPass  <  limitPass );

         if   ( ! ok )   throw   new  java . lang . RuntimeException ( "TESTS FAILED" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/PictureDump.java

edu/princeton/cs/algs4/PictureDump.java

/******************************************************************************
 *  Compilation:  javac PictureDump.java
 *  Execution:    java PictureDump width height < file
 *  Dependencies: BinaryStdIn.java Picture.java
 *  Data file:    http://introcs.cs.princeton.edu/stdlib/abra.txt
 *  
 *  Reads in a binary file and writes out the bits as w-by-h picture,
 *  with the 1 bits in black and the 0 bits in white.
 *
 *  % more abra.txt 
 *  ABRACADABRA!
 *
 *  % java PictureDump 16 6 < abra.txt
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . Color ;


/**
 *  The { @code  PictureDump} class provides a client for displaying the contents
 *  of a binary file as a black-and-white picture.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  <p>
 *  See also { @link  BinaryDump} and { @link  HexDump}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   PictureDump   {

     // Do not instantiate.
     private   PictureDump ()   {   }

     /**
     * Reads in a sequence of bytes from standard input and draws
     * them to standard drawing output as a width-by-height picture,
     * using black for 1 and white for 0 (and red for any leftover
     * pixels).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  width  =   Integer . parseInt ( args [ 0 ]);
         int  height  =   Integer . parseInt ( args [ 1 ]);
         Picture  picture  =   new   Picture ( width ,  height );
         for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {
             for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {
                 if   ( ! BinaryStdIn . isEmpty ())   {
                     boolean  bit  =   BinaryStdIn . readBoolean ();
                     if   ( bit )  picture . set ( col ,  row ,   Color . BLACK );
                     else      picture . set ( col ,  row ,   Color . WHITE );
                 }
                 else   {
                    picture . set ( col ,  row ,   Color . RED );
                 }
             }
         }
        picture . show ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Picture.java

edu/princeton/cs/algs4/Picture.java

/******************************************************************************
 *  Compilation:  javac Picture.java
 *  Execution:    java Picture imagename
 *  Dependencies: none
 *
 *  Data type for manipulating individual pixels of an image. The original
 *  image can be read from a file in JPG, GIF, or PNG format, or the
 *  user can create a blank image of a given dimension. Includes methods for
 *  displaying the image in a window on the screen or saving to a file.
 *
 *  % java Picture mandrill.jpg
 *
 *  Remarks
 *  -------
 *   - pixel (x, y) is column x and row y, where (0, 0) is upper left
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . Color ;
import  java . awt . FileDialog ;
import  java . awt . Toolkit ;
import  java . awt . event . ActionEvent ;
import  java . awt . event . ActionListener ;
import  java . awt . event . KeyEvent ;
import  java . awt . image . BufferedImage ;
import  java . io . File ;
import  java . io . IOException ;
import  java . net . URL ;
import  javax . imageio . ImageIO ;
import  javax . swing . ImageIcon ;
import  javax . swing . JFrame ;
import  javax . swing . JLabel ;
import  javax . swing . JMenu ;
import  javax . swing . JMenuBar ;
import  javax . swing . JMenuItem ;
import  javax . swing . JPanel ;
import  javax . swing . KeyStroke ;


/**
 *  This class provides methods for manipulating individual pixels of
 *  an image using the RGB color format. The alpha component (for transparency)
 *  is not currently supported.
 *  The original image can be read from a { @code  PNG}, { @code  GIF},
 *  or { @code  JPEG} file or the user can create a blank image of a given dimension.
 *  This class includes methods for displaying the image in a window on
 *  the screen or saving it to a file.
 *  <p>
 *  Pixel (<em>col</em>, <em>row</em>) is column <em>col</em> and row <em>row</em>.
 *  By default, the origin (0, 0) is the pixel in the top-left corner,
 *  which is a common convention in image processing.
 *  The method { @link  #setOriginLowerLeft()} change the origin to the lower left.
 *  <p>
 *  The { @code  get()} and { @code  set()} methods use { @link  Color} objects to get
 *  or set the color of the specified pixel.
 *  The { @code  getRGB()} and { @code  setRGB()} methods use a 32-bit { @code  int}
 *  to encode the color, thereby avoiding the need to create temporary
 *  { @code  Color} objects. The red (R), green (G), and blue (B) components 
 *  are encoded using the least significant 24 bits.
 *  Given a 32-bit { @code  int} encoding the color, the following code extracts
 *  the RGB components:
 * <blockquote><pre>
 *  int r = (rgb &gt;&gt; 16) &amp; 0xFF;
 *  int g = (rgb &gt;&gt;  8) &amp; 0xFF;
 *  int b = (rgb &gt;&gt;  0) &amp; 0xFF;
 *  </pre></blockquote> 
 *  Given the RGB components (8-bits each) of a color,
 *  the following statement packs it into a 32-bit { @code  int}:
 * <blockquote><pre>
 *  int rgb = (r &lt;&lt; 16) + (g &lt;&lt; 8) + (b &lt;&lt; 0);
 * </pre></blockquote> 
 *  <p>
 *  A <em>W</em>-by-<em>H</em> picture uses ~ 4 <em>W H</em> bytes of memory,
 *  since the color of each pixel is encoded as a 32-bit <code>int</code>.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/31datatype">Section 3.1</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *  See { @link  GrayscalePicture} for a version that supports grayscale images.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   Picture   implements   ActionListener   {
     private   BufferedImage  image ;                 // the rasterized image
     private   JFrame  frame ;                        // on-screen view
     private   String  filename ;                     // name of file
     private   boolean  isOriginUpperLeft  =   true ;    // location of origin
     private   final   int  width ,  height ;             // width and height

    /**
     * Creates a { @code  width}-by-{ @code  height} picture, with { @code  width} columns
     * and { @code  height} rows, where each pixel is black.
     *
     *  @param  width the width of the picture
     *  @param  height the height of the picture
     *  @throws  IllegalArgumentException if { @code  width} is negative or zero
     *  @throws  IllegalArgumentException if { @code  height} is negative or zero
     */
     public   Picture ( int  width ,   int  height )   {
         if   ( width   <=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );
         if   ( height  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );
         this . width   =  width ;
         this . height  =  height ;
        image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );
         // set to TYPE_INT_ARGB here and in next constructor to support transparency
     }

    /**
     * Creates a new picture that is a deep copy of the argument picture.
     *
     *  @param   picture the picture to copy
     *  @throws  IllegalArgumentException if { @code  picture} is { @code  null}
     */
     public   Picture ( Picture  picture )   {
         if   ( picture  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );

        width   =  picture . width ();
        height  =  picture . height ();
        image  =   new   BufferedImage ( width ,  height ,   BufferedImage . TYPE_INT_RGB );
        filename  =  picture . filename ;
        isOriginUpperLeft  =  picture . isOriginUpperLeft ;
         for   ( int  col  =   0 ;  col  <  width ();  col ++ )
             for   ( int  row  =   0 ;  row  <  height ();  row ++ )
                image . setRGB ( col ,  row ,  picture . image . getRGB ( col ,  row ));
     }

    /**
     * Creates a picture by reading an image from a file or URL.
     *
     *  @param   name the name of the file (.png, .gif, or .jpg) or URL.
     *  @throws  IllegalArgumentException if cannot read image
     *  @throws  IllegalArgumentException if { @code  name} is { @code  null}
     */
     public   Picture ( String  name )   {
         if   ( name  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );

         this . filename  =  name ;
         try   {
             // try to read from file in working directory
             File  file  =   new   File ( name );
             if   ( file . isFile ())   {
                image  =   ImageIO . read ( file );
             }

             else   {

                 // resource relative to .class file
                URL url  =  getClass (). getResource ( filename );

                 // resource relative to classloader root
                 if   ( url  ==   null )   {
                    url  =  getClass (). getClassLoader (). getResource ( name );
                 }

                 // or URL from web
                 if   ( url  ==   null )   {
                    url  =   new  URL ( name );
                 }

                image  =   ImageIO . read ( url );
             }

             if   ( image  ==   null )   {
                 throw   new   IllegalArgumentException ( "could not read image: "   +  name );
             }

            width   =  image . getWidth ( null );
            height  =  image . getHeight ( null );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "could not open image: "   +  name ,  ioe );
         }
     }

    /**
     * Creates a picture by reading the image from a PNG, GIF, or JPEG file.
     *
     *  @param  file the file
     *  @throws  IllegalArgumentException if cannot read image
     *  @throws  IllegalArgumentException if { @code  file} is { @code  null}
     */
     public   Picture ( File  file )   {
         if   ( file  ==   null )   throw   new   IllegalArgumentException ( "constructor argument is null" );

         try   {
            image  =   ImageIO . read ( file );
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "could not open file: "   +  file ,  ioe );
         }
         if   ( image  ==   null )   {
             throw   new   IllegalArgumentException ( "could not read file: "   +  file );
         }
        width   =  image . getWidth ( null );
        height  =  image . getHeight ( null );
        filename  =  file . getName ();
     }

    /**
     * Returns a { @link  JLabel} containing this picture, for embedding in a { @link  JPanel},
     * { @link  JFrame} or other GUI widget.
     *
     *  @return  the { @code  JLabel}
     */
     public   JLabel  getJLabel ()   {
         if   ( image  ==   null )   return   null ;           // no image available
         ImageIcon  icon  =   new   ImageIcon ( image );
         return   new   JLabel ( icon );
     }

    /**
     * Sets the origin to be the upper left pixel. This is the default.
     */
     public   void  setOriginUpperLeft ()   {
        isOriginUpperLeft  =   true ;
     }

    /**
     * Sets the origin to be the lower left pixel.
     */
     public   void  setOriginLowerLeft ()   {
        isOriginUpperLeft  =   false ;
     }

    /**
     * Displays the picture in a window on the screen.
     */
     public   void  show ()   {

         // create the GUI for viewing the image if needed
         if   ( frame  ==   null )   {
            frame  =   new   JFrame ();

             JMenuBar  menuBar  =   new   JMenuBar ();
             JMenu  menu  =   new   JMenu ( "File" );
            menuBar . add ( menu );
             JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );
            menuItem1 . addActionListener ( this );
             // use getMenuShortcutKeyMaskEx() in Java 10 (getMenuShortcutKeyMask() deprecated)           
            menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,
                                      Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));
            menu . add ( menuItem1 );
            frame . setJMenuBar ( menuBar );



            frame . setContentPane ( getJLabel ());
             // f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame . setDefaultCloseOperation ( JFrame . DISPOSE_ON_CLOSE );
             if   ( filename  ==   null )  frame . setTitle ( width  +   "-by-"   +  height );
             else                   frame . setTitle ( filename );
            frame . setResizable ( false );
            frame . pack ();
            frame . setVisible ( true );
         }

         // draw
        frame . repaint ();
     }

    /**
     * Returns the height of the picture.
     *
     *  @return  the height of the picture (in pixels)
     */
     public   int  height ()   {
         return  height ;
     }

    /**
     * Returns the width of the picture.
     *
     *  @return  the width of the picture (in pixels)
     */
     public   int  width ()   {
         return  width ;
     }

     private   void  validateRowIndex ( int  row )   {
         if   ( row  <   0   ||  row  >=  height ())
             throw   new   IllegalArgumentException ( "row index must be between 0 and "   +   ( height ()   -   1 )   +   ": "   +  row );
     }

     private   void  validateColumnIndex ( int  col )   {
         if   ( col  <   0   ||  col  >=  width ())
             throw   new   IllegalArgumentException ( "column index must be between 0 and "   +   ( width ()   -   1 )   +   ": "   +  col );
     }

    /**
     * Returns the color of pixel ({ @code  col}, { @code  row}) as a { @link  java.awt.Color}.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @return  the color of pixel ({ @code  col}, { @code  row})
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   Color  get ( int  col ,   int  row )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         int  rgb  =  getRGB ( col ,  row );
         return   new   Color ( rgb );
     }

    /**
     * Returns the color of pixel ({ @code  col}, { @code  row}) as an { @code  int}.
     * Using this method can be more efficient than { @link  #get(int, int)} because
     * it does not create a { @code  Color} object.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @return  the integer representation of the color of pixel ({ @code  col}, { @code  row})
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   int  getRGB ( int  col ,   int  row )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         if   ( isOriginUpperLeft )   return  image . getRGB ( col ,  row );
         else                     return  image . getRGB ( col ,  height  -  row  -   1 );
     }

    /**
     * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @param  color the color
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   void  set ( int  col ,   int  row ,   Color  color )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         if   ( color  ==   null )   throw   new   IllegalArgumentException ( "color argument is null" );
         int  rgb  =  color . getRGB ();
        setRGB ( col ,  row ,  rgb );
     }

    /**
     * Sets the color of pixel ({ @code  col}, { @code  row}) to given color.
     *
     *  @param  col the column index
     *  @param  row the row index
     *  @param  rgb the integer representation of the color
     *  @throws  IllegalArgumentException unless both { @code  0 <= col < width} and { @code  0 <= row < height}
     */
     public   void  setRGB ( int  col ,   int  row ,   int  rgb )   {
        validateColumnIndex ( col );
        validateRowIndex ( row );
         if   ( isOriginUpperLeft )  image . setRGB ( col ,  row ,  rgb );
         else                    image . setRGB ( col ,  height  -  row  -   1 ,  rgb );
     }

    /**
     * Returns true if this picture is equal to the argument picture.
     *
     *  @param  other the other picture
     *  @return  { @code  true} if this picture is the same dimension as { @code  other}
     *         and if all pixels have the same color; { @code  false} otherwise
     */
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Picture  that  =   ( Picture )  other ;
         if   ( this . width ()    !=  that . width ())    return   false ;
         if   ( this . height ()   !=  that . height ())   return   false ;
         for   ( int  col  =   0 ;  col  <  width ();  col ++ )
             for   ( int  row  =   0 ;  row  <  height ();  row ++ )
                 if   ( this . getRGB ( col ,  row )   !=  that . getRGB ( col ,  row ))   return   false ;
         return   true ;
     }

    /**
     * Returns a string representation of this picture.
     * The result is a <code>width</code>-by-<code>height</code> matrix of pixels,
     * where the color of a pixel is represented using 6 hex digits to encode
     * the red, green, and blue components.
     *
     *  @return  a string representation of this picture
     */
     public   String  toString ()   {
         StringBuilder  sb  =   new   StringBuilder ();
        sb . append ( width  + "-by-"   +  height  +   " picture (RGB values given in hex)\n" );
         for   ( int  row  =   0 ;  row  <  height ;  row ++ )   {
             for   ( int  col  =   0 ;  col  <  width ;  col ++ )   {
                 int  rgb  =   0 ;
                 if   ( isOriginUpperLeft )  rgb  =  image . getRGB ( col ,  row );
                 else                    rgb  =  image . getRGB ( col ,  height  -  row  -   1 );
                sb . append ( String . format ( "#%06X " ,  rgb  &   0xFFFFFF ));
             }
            sb . append ( "\n" );
         }
         return  sb . toString (). trim ();
     }

     /**
     * This operation is not supported because pictures are mutable.
     *
     *  @return  does not return a value
     *  @throws  UnsupportedOperationException if called
     */
     public   int  hashCode ()   {
         throw   new   UnsupportedOperationException ( "hashCode() is not supported because pictures are mutable" );
     }

    /**
     * Saves the picture to a file in either PNG or JPEG format.
     * The filetype extension must be either .png or .jpg.
     *
     *  @param  name the name of the file
     *  @throws  IllegalArgumentException if { @code  name} is { @code  null}
     */
     public   void  save ( String  name )   {
         if   ( name  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );
        save ( new   File ( name ));
        filename  =  name ;
     }

    /**
     * Saves the picture to a file in a PNG or JPEG image format.
     *
     *  @param   file the file
     *  @throws  IllegalArgumentException if { @code  file} is { @code  null}
     */
     public   void  save ( File  file )   {
         if   ( file  ==   null )   throw   new   IllegalArgumentException ( "argument to save() is null" );
        filename  =  file . getName ();
         if   ( frame  !=   null )  frame . setTitle ( filename );
         String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );
         if   ( "jpg" . equalsIgnoreCase ( suffix )   ||   "png" . equalsIgnoreCase ( suffix ))   {
             try   {
                 ImageIO . write ( image ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }
         else   {
             System . out . println ( "Error: filename must end in .jpg or .png" );
         }
     }

    /**
     * Opens a save dialog box when the user selects "Save As" from the menu.
     */
    @ Override
     public   void  actionPerformed ( ActionEvent  e )   {
         FileDialog  chooser  =   new   FileDialog ( frame ,
                              "Use a .png or .jpg extension" ,   FileDialog . SAVE );
        chooser . setVisible ( true );
         if   ( chooser . getFile ()   !=   null )   {
            save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());
         }
     }

    /**
     * Unit tests this { @code  Picture} data type.
     * Reads a picture specified by the command-line argument,
     * and shows it in a window on the screen.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Picture  picture  =   new   Picture ( args [ 0 ]);
         System . out . printf ( "%d-by-%d\n" ,  picture . width (),  picture . height ());
        picture . show ();
     }

}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Point2D.java

edu/princeton/cs/algs4/Point2D.java

/******************************************************************************
 *  Compilation:  javac Point2D.java
 *  Execution:    java Point2D x0 y0 n
 *  Dependencies: StdDraw.java StdRandom.java
 *
 *  Immutable point data type for points in the plane.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;
import  java . util . Comparator ;


/**
 *  The { @code  Point} class is an immutable data type to encapsulate a
 *  two-dimensional point with real-value coordinates.
 *  <p>
 *  Note: in order to deal with the difference behavior of double and 
 *  Double with respect to -0.0 and +0.0, the Point2D constructor converts
 *  any coordinates that are -0.0 to +0.0.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   Point2D   implements   Comparable < Point2D >   {

     /**
     * Compares two points by x-coordinate.
     */
     public   static   final   Comparator < Point2D >  X_ORDER  =   new   XOrder ();

     /**
     * Compares two points by y-coordinate.
     */
     public   static   final   Comparator < Point2D >  Y_ORDER  =   new   YOrder ();

     /**
     * Compares two points by polar radius.
     */
     public   static   final   Comparator < Point2D >  R_ORDER  =   new   ROrder ();

     private   final   double  x ;      // x coordinate
     private   final   double  y ;      // y coordinate

     /**
     * Initializes a new point (x, y).
     *  @param  x the x-coordinate
     *  @param  y the y-coordinate
     *  @throws  IllegalArgumentException if either { @code  x} or { @code  y}
     *    is { @code  Double.NaN}, { @code  Double.POSITIVE_INFINITY} or
     *    { @code  Double.NEGATIVE_INFINITY}
     */
     public   Point2D ( double  x ,   double  y )   {
         if   ( Double . isInfinite ( x )   ||   Double . isInfinite ( y ))
             throw   new   IllegalArgumentException ( "Coordinates must be finite" );
         if   ( Double . isNaN ( x )   ||   Double . isNaN ( y ))
             throw   new   IllegalArgumentException ( "Coordinates cannot be NaN" );
         if   ( ==   0.0 )   this . =   0.0 ;    // convert -0.0 to +0.0
         else            this . =  x ;

         if   ( ==   0.0 )   this . =   0.0 ;    // convert -0.0 to +0.0
         else            this . =  y ;
     }

     /**
     * Returns the x-coordinate.
     *  @return  the x-coordinate
     */
     public   double  x ()   {
         return  x ;
     }

     /**
     * Returns the y-coordinate.
     *  @return  the y-coordinate
     */
     public   double  y ()   {
         return  y ;
     }

     /**
     * Returns the polar radius of this point.
     *  @return  the polar radius of this point in polar coordiantes: sqrt(x*x + y*y)
     */
     public   double  r ()   {
         return   Math . sqrt ( x * +  y * y );
     }

     /**
     * Returns the angle of this point in polar coordinates.
     *  @return  the angle (in radians) of this point in polar coordiantes (between –&pi; and &pi;)
     */
     public   double  theta ()   {
         return   Math . atan2 ( y ,  x );
     }

     /**
     * Returns the angle between this point and that point.
     *  @return  the angle in radians (between –&pi; and &pi;) between this point and that point (0 if equal)
     */
     private   double  angleTo ( Point2D  that )   {
         double  dx  =  that . -   this . x ;
         double  dy  =  that . -   this . y ;
         return   Math . atan2 ( dy ,  dx );
     }

     /**
     * Returns true if a→b→c is a counterclockwise turn.
     *  @param  a first point
     *  @param  b second point
     *  @param  c third point
     *  @return  { -1, 0, +1 } if a→b→c is a { clockwise, collinear; counterclocwise } turn.
     */
     public   static   int  ccw ( Point2D  a ,   Point2D  b ,   Point2D  c )   {
         double  area2  =   ( b . x - a . x ) * ( c . y - a . y )   -   ( b . y - a . y ) * ( c . x - a . x );
         if        ( area2  <   0 )   return   - 1 ;
         else   if   ( area2  >   0 )   return   + 1 ;
         else                  return    0 ;
     }

     /**
     * Returns twice the signed area of the triangle a-b-c.
     *  @param  a first point
     *  @param  b second point
     *  @param  c third point
     *  @return  twice the signed area of the triangle a-b-c
     */
     public   static   double  area2 ( Point2D  a ,   Point2D  b ,   Point2D  c )   {
         return   ( b . x - a . x ) * ( c . y - a . y )   -   ( b . y - a . y ) * ( c . x - a . x );
     }

     /**
     * Returns the Euclidean distance between this point and that point.
     *  @param  that the other point
     *  @return  the Euclidean distance between this point and that point
     */
     public   double  distanceTo ( Point2D  that )   {
         double  dx  =   this . -  that . x ;
         double  dy  =   this . -  that . y ;
         return   Math . sqrt ( dx * dx  +  dy * dy );
     }

     /**
     * Returns the square of the Euclidean distance between this point and that point.
     *  @param  that the other point
     *  @return  the square of the Euclidean distance between this point and that point
     */
     public   double  distanceSquaredTo ( Point2D  that )   {
         double  dx  =   this . -  that . x ;
         double  dy  =   this . -  that . y ;
         return  dx * dx  +  dy * dy ;
     }

     /**
     * Compares two points by y-coordinate, breaking ties by x-coordinate.
     * Formally, the invoking point (x0, y0) is less than the argument point (x1, y1)
     * if and only if either { @code  y0 < y1} or if { @code  y0 == y1} and { @code  x0 < x1}.
     *
     *  @param   that the other point
     *  @return  the value { @code  0} if this string is equal to the argument
     *         string (precisely when { @code  equals()} returns { @code  true});
     *         a negative integer if this point is less than the argument
     *         point; and a positive integer if this point is greater than the
     *         argument point
     */
     public   int  compareTo ( Point2D  that )   {
         if   ( this . <  that . y )   return   - 1 ;
         if   ( this . >  that . y )   return   + 1 ;
         if   ( this . <  that . x )   return   - 1 ;
         if   ( this . >  that . x )   return   + 1 ;
         return   0 ;
     }

     /**
     * Compares two points by polar angle (between 0 and 2&pi;) with respect to this point.
     *
     *  @return  the comparator
     */
     public   Comparator < Point2D >  polarOrder ()   {
         return   new   PolarOrder ();
     }

     /**
     * Compares two points by atan2() angle (between –&pi; and &pi;) with respect to this point.
     *
     *  @return  the comparator
     */
     public   Comparator < Point2D >  atan2Order ()   {
         return   new   Atan2Order ();
     }

     /**
     * Compares two points by distance to this point.
     *
     *  @return  the comparator
     */
     public   Comparator < Point2D >  distanceToOrder ()   {
         return   new   DistanceToOrder ();
     }

     // compare points according to their x-coordinate
     private   static   class   XOrder   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  p ,   Point2D  q )   {
             if   ( p . <  q . x )   return   - 1 ;
             if   ( p . >  q . x )   return   + 1 ;
             return   0 ;
         }
     }

     // compare points according to their y-coordinate
     private   static   class   YOrder   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  p ,   Point2D  q )   {
             if   ( p . <  q . y )   return   - 1 ;
             if   ( p . >  q . y )   return   + 1 ;
             return   0 ;
         }
     }

     // compare points according to their polar radius
     private   static   class   ROrder   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  p ,   Point2D  q )   {
             double  delta  =   ( p . x * p . +  p . y * p . y )   -   ( q . x * q . +  q . y * q . y );
             if   ( delta  <   0 )   return   - 1 ;
             if   ( delta  >   0 )   return   + 1 ;
             return   0 ;
         }
     }
 
     // compare other points relative to atan2 angle (bewteen -pi/2 and pi/2) they make with this Point
     private   class   Atan2Order   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  q1 ,   Point2D  q2 )   {
             double  angle1  =  angleTo ( q1 );
             double  angle2  =  angleTo ( q2 );
             if        ( angle1  <  angle2 )   return   - 1 ;
             else   if   ( angle1  >  angle2 )   return   + 1 ;
             else                        return    0 ;
         }
     }

     // compare other points relative to polar angle (between 0 and 2pi) they make with this Point
     private   class   PolarOrder   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  q1 ,   Point2D  q2 )   {
             double  dx1  =  q1 . -  x ;
             double  dy1  =  q1 . -  y ;
             double  dx2  =  q2 . -  x ;
             double  dy2  =  q2 . -  y ;

             if        ( dy1  >=   0   &&  dy2  <   0 )   return   - 1 ;      // q1 above; q2 below
             else   if   ( dy2  >=   0   &&  dy1  <   0 )   return   + 1 ;      // q1 below; q2 above
             else   if   ( dy1  ==   0   &&  dy2  ==   0 )   {              // 3-collinear and horizontal
                 if        ( dx1  >=   0   &&  dx2  <   0 )   return   - 1 ;
                 else   if   ( dx2  >=   0   &&  dx1  <   0 )   return   + 1 ;
                 else                            return    0 ;
             }
             else   return   - ccw ( Point2D . this ,  q1 ,  q2 );       // both above or below

             // Note: ccw() recomputes dx1, dy1, dx2, and dy2
         }
     }

     // compare points according to their distance to this point
     private   class   DistanceToOrder   implements   Comparator < Point2D >   {
         public   int  compare ( Point2D  p ,   Point2D  q )   {
             double  dist1  =  distanceSquaredTo ( p );
             double  dist2  =  distanceSquaredTo ( q );
             if        ( dist1  <  dist2 )   return   - 1 ;
             else   if   ( dist1  >  dist2 )   return   + 1 ;
             else                      return    0 ;
         }
     }


     /**       
     * Compares this point to the specified point.
     *       
     *  @param   other the other point
     *  @return  { @code  true} if this point equals { @code  other};
     *         { @code  false} otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Point2D  that  =   ( Point2D )  other ;
         return   this . ==  that . &&   this . ==  that . y ;
     }

     /**
     * Return a string representation of this point.
     *  @return  a string representation of this point in the format (x, y)
     */
    @ Override
     public   String  toString ()   {
         return   "("   +  x  +   ", "   +  y  +   ")" ;
     }

     /**
     * Returns an integer hash code for this point.
     *  @return  an integer hash code for this point
     */
    @ Override
     public   int  hashCode ()   {
         int  hashX  =   (( Double )  x ). hashCode ();
         int  hashY  =   (( Double )  y ). hashCode ();
         return   31 * hashX  +  hashY ;
     }

     /**
     * Plot this point using standard draw.
     */
     public   void  draw ()   {
         StdDraw . point ( x ,  y );
     }

     /**
     * Plot a line from this point to that point using standard draw.
     *  @param  that the other point
     */
     public   void  drawTo ( Point2D  that )   {
         StdDraw . line ( this . x ,   this . y ,  that . x ,  that . y );
     }


     /**
     * Unit tests the point data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  x0  =   Integer . parseInt ( args [ 0 ]);
         int  y0  =   Integer . parseInt ( args [ 1 ]);
         int  n  =   Integer . parseInt ( args [ 2 ]);

         StdDraw . setCanvasSize ( 800 ,   800 );
         StdDraw . setXscale ( 0 ,   100 );
         StdDraw . setYscale ( 0 ,   100 );
         StdDraw . setPenRadius ( 0.005 );
         StdDraw . enableDoubleBuffering ();

         Point2D []  points  =   new   Point2D [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  x  =   StdRandom . uniform ( 100 );
             int  y  =   StdRandom . uniform ( 100 );
            points [ i ]   =   new   Point2D ( x ,  y );
            points [ i ]. draw ();
         }

         // draw p = (x0, x1) in red
         Point2D  p  =   new   Point2D ( x0 ,  y0 );
         StdDraw . setPenColor ( StdDraw . RED );
         StdDraw . setPenRadius ( 0.02 );
        p . draw ();


         // draw line segments from p to each point, one at a time, in polar order
         StdDraw . setPenRadius ();
         StdDraw . setPenColor ( StdDraw . BLUE );
         Arrays . sort ( points ,  p . polarOrder ());
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            p . drawTo ( points [ i ]);
             StdDraw . show ();
             StdDraw . pause ( 100 );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Polynomial.java

edu/princeton/cs/algs4/Polynomial.java

/******************************************************************************
 *  Compilation:  javac Polynomial.java
 *  Execution:    java Polynomial
 *
 *  Polynomials with integer coefficients.
 *
 *  % java Polynomial
 *  zero(x)     = 0
 *  p(x)        = 4x^3 + 3x^2 + 2x + 1
 *  q(x)        = 3x^2 + 5
 *  p(x) + q(x) = 4x^3 + 6x^2 + 2x + 6
 *  p(x) * q(x) = 12x^5 + 9x^4 + 26x^3 + 18x^2 + 10x + 5
 *  p(q(x))     = 108x^6 + 567x^4 + 996x^2 + 586
 *  p(x) - p(x) = 0
 *  0 - p(x)    = -4x^3 - 3x^2 - 2x - 1
 *  p(3)        = 142
 *  p'(x)       = 12x^2 + 6x + 2
 *  p''(x)      = 24x + 6
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Polynomial} class represents a polynomial with integer
 *  coefficients.
 *  Polynomials are immutable: their values cannot be changed after they
 *  are created.
 *  It includes methods for addition, subtraction, multiplication, composition,
 *  differentiation, and evaluation.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/99scientific">Section 9.9</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Polynomial   {
     private   int []  coef ;     // coefficients p(x) = sum { coef[i] * x^i }
     private   int  degree ;     // degree of polynomial (-1 for the zero polynomial)

     /**
     * Initializes a new polynomial a x^b
     *  @param  a the leading coefficient
     *  @param  b the exponent
     *  @throws  IllegalArgumentException if { @code  b} is negative
     */
     public   Polynomial ( int  a ,   int  b )   {
         if   ( <   0 )   {
             throw   new   IllegalArgumentException ( "exponent cannot be negative: "   +  b );
         }
        coef  =   new   int [ b + 1 ];
        coef [ b ]   =  a ;
        reduce ();
     }

     // pre-compute the degree of the polynomial, in case of leading zero coefficients
     // (that is, the length of the array need not relate to the degree of the polynomial)
     private   void  reduce ()   {
        degree  =   - 1 ;
         for   ( int  i  =  coef . length  -   1 ;  i  >=   0 ;  i -- )   {
             if   ( coef [ i ]   !=   0 )   {
                degree  =  i ;
                 return ;
             }
         }
     }

     /**
     * Returns the degree of this polynomial.
     *  @return  the degree of this polynomial, -1 for the zero polynomial.
     */
     public   int  degree ()   {
         return  degree ;
     }

     /**
     * Returns the sum of this polynomial and the specified polynomial.
     *
     *  @param   that the other polynomial
     *  @return  the polynomial whose value is { @code  (this(x) + that(x))}
     */
     public   Polynomial  plus ( Polynomial  that )   {
         Polynomial  poly  =   new   Polynomial ( 0 ,   Math . max ( this . degree ,  that . degree ));
         for   ( int  i  =   0 ;  i  <=   this . degree ;  i ++ )  poly . coef [ i ]   +=   this . coef [ i ];
         for   ( int  i  =   0 ;  i  <=  that . degree ;  i ++ )  poly . coef [ i ]   +=  that . coef [ i ];
        poly . reduce ();
         return  poly ;
     }

     /**
     * Returns the result of subtracting the specified polynomial
     * from this polynomial.
     *
     *  @param   that the other polynomial
     *  @return  the polynomial whose value is { @code  (this(x) - that(x))}
     */
     public   Polynomial  minus ( Polynomial  that )   {
         Polynomial  poly  =   new   Polynomial ( 0 ,   Math . max ( this . degree ,  that . degree ));
         for   ( int  i  =   0 ;  i  <=   this . degree ;  i ++ )  poly . coef [ i ]   +=   this . coef [ i ];
         for   ( int  i  =   0 ;  i  <=  that . degree ;  i ++ )  poly . coef [ i ]   -=  that . coef [ i ];
        poly . reduce ();
         return  poly ;
     }

     /**
     * Returns the product of this polynomial and the specified polynomial.
     * Takes time proportional to the product of the degrees.
     * (Faster algorithms are known, e.g., via FFT.)
     *
     *  @param   that the other polynomial
     *  @return  the polynomial whose value is { @code  (this(x) * that(x))}
     */
     public   Polynomial  times ( Polynomial  that )   {
         Polynomial  poly  =   new   Polynomial ( 0 ,   this . degree  +  that . degree );
         for   ( int  i  =   0 ;  i  <=   this . degree ;  i ++ )
             for   ( int  j  =   0 ;  j  <=  that . degree ;  j ++ )
                poly . coef [ i + j ]   +=   ( this . coef [ i ]   *  that . coef [ j ]);
        poly . reduce ();
         return  poly ;
     }

     /**
     * Returns the composition of this polynomial and the specified
     * polynomial.
     * Takes time proportional to the product of the degrees.
     * (Faster algorithms are known, e.g., via FFT.)
     *
     *  @param   that the other polynomial
     *  @return  the polynomial whose value is { @code  (this(that(x)))}
     */
     public   Polynomial  compose ( Polynomial  that )   {
         Polynomial  poly  =   new   Polynomial ( 0 ,   0 );
         for   ( int  i  =   this . degree ;  i  >=   0 ;  i -- )   {
             Polynomial  term  =   new   Polynomial ( this . coef [ i ],   0 );
            poly  =  term . plus ( that . times ( poly ));
         }
         return  poly ;
     }


     /**       
     * Compares this polynomial to the specified polynomial.
     *       
     *  @param   other the other polynoimal
     *  @return  { @code  true} if this polynomial equals { @code  other};
     *         { @code  false} otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Polynomial  that  =   ( Polynomial )  other ;
         if   ( this . degree  !=  that . degree )   return   false ;
         for   ( int  i  =   this . degree ;  i  >=   0 ;  i -- )
             if   ( this . coef [ i ]   !=  that . coef [ i ])   return   false ;
         return   true ;
     }

     /**
     * Returns the result of differentiating this polynomial.
     *
     *  @return  the polynomial whose value is { @code  this'(x)}
     */
     public   Polynomial  differentiate ()   {
         if   ( degree  ==   0 )   return   new   Polynomial ( 0 ,   0 );
         Polynomial  poly  =   new   Polynomial ( 0 ,  degree  -   1 );
        poly . degree  =  degree  -   1 ;
         for   ( int  i  =   0 ;  i  <  degree ;  i ++ )
            poly . coef [ i ]   =   ( +   1 )   *  coef [ +   1 ];
         return  poly ;
     }

     /**
     * Returns the result of evaluating this polynomial at the point x.
     *
     *  @param   x the point at which to evaluate the polynomial
     *  @return  the integer whose value is { @code  (this(x))}
     */
     public   int  evaluate ( int  x )   {
         int  p  =   0 ;
         for   ( int  i  =  degree ;  i  >=   0 ;  i -- )
            p  =  coef [ i ]   +   ( *  p );
         return  p ;
     }

     /**
     * Compares two polynomials by degree, breaking ties by coefficient of leading term.
     *
     *  @param   that the other point
     *  @return  the value { @code  0} if this polynomial is equal to the argument
     *         polynomial (precisely when { @code  equals()} returns { @code  true});
     *         a negative integer if this polynomialt is less than the argument
     *         polynomial; and a positive integer if this polynomial is greater than the
     *         argument point
     */
     public   int  compareTo ( Polynomial  that )   {
         if   ( this . degree  <  that . degree )   return   - 1 ;
         if   ( this . degree  >  that . degree )   return   + 1 ;
         for   ( int  i  =   this . degree ;  i  >=   0 ;  i -- )   {
             if   ( this . coef [ i ]   <  that . coef [ i ])   return   - 1 ;
             if   ( this . coef [ i ]   >  that . coef [ i ])   return   + 1 ;
         }
         return   0 ;
     }

     /**
     * Return a string representation of this polynomial.
     *  @return  a string representation of this polynomial in the format
     *         4x^5 - 3x^2 + 11x + 5
     */
    @ Override
     public   String  toString ()   {
         if        ( degree  ==   - 1 )   return   "0" ;
         else   if   ( degree  ==    0 )   return   ""   +  coef [ 0 ];
         else   if   ( degree  ==    1 )   return  coef [ 1 ]   +   "x + "   +  coef [ 0 ];
         String  s  =  coef [ degree ]   +   "x^"   +  degree ;
         for   ( int  i  =  degree  -   1 ;  i  >=   0 ;  i -- )   {
             if        ( coef [ i ]   ==   0 )   continue ;
             else   if   ( coef [ i ]    >   0 )  s  =  s  +   " + "   +   ( coef [ i ]);
             else   if   ( coef [ i ]    <   0 )  s  =  s  +   " - "   +   ( - coef [ i ]);
             if        ( ==   1 )  s  =  s  +   "x" ;
             else   if   ( >    1 )  s  =  s  +   "x^"   +  i ;
         }
         return  s ;
     }

     /**
     * Unit tests the polynomial data type.
     *
     *  @param  args the command-line arguments (none)
     */
     public   static   void  main ( String []  args )   {  
         Polynomial  zero  =   new   Polynomial ( 0 ,   0 );

         Polynomial  p1    =   new   Polynomial ( 4 ,   3 );
         Polynomial  p2    =   new   Polynomial ( 3 ,   2 );
         Polynomial  p3    =   new   Polynomial ( 1 ,   0 );
         Polynomial  p4    =   new   Polynomial ( 2 ,   1 );
         Polynomial  p     =  p1 . plus ( p2 ). plus ( p3 ). plus ( p4 );     // 4x^3 + 3x^2 + 1

         Polynomial  q1    =   new   Polynomial ( 3 ,   2 );
         Polynomial  q2    =   new   Polynomial ( 5 ,   0 );
         Polynomial  q     =  q1 . plus ( q2 );                       // 3x^2 + 5


         Polynomial  r     =  p . plus ( q );
         Polynomial  s     =  p . times ( q );
         Polynomial  t     =  p . compose ( q );
         Polynomial  u     =  p . minus ( p );

         StdOut . println ( "zero(x)     = "   +  zero );
         StdOut . println ( "p(x)        = "   +  p );
         StdOut . println ( "q(x)        = "   +  q );
         StdOut . println ( "p(x) + q(x) = "   +  r );
         StdOut . println ( "p(x) * q(x) = "   +  s );
         StdOut . println ( "p(q(x))     = "   +  t );
         StdOut . println ( "p(x) - p(x) = "   +  u );
         StdOut . println ( "0 - p(x)    = "   +  zero . minus ( p ));
         StdOut . println ( "p(3)        = "   +  p . evaluate ( 3 ));
         StdOut . println ( "p'(x)       = "   +  p . differentiate ());
         StdOut . println ( "p''(x)      = "   +  p . differentiate (). differentiate ());
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/PrimMST.java

edu/princeton/cs/algs4/PrimMST.java

/******************************************************************************
 *  Compilation:  javac PrimMST.java
 *  Execution:    java PrimMST filename.txt
 *  Dependencies: EdgeWeightedGraph.java Edge.java Queue.java
 *                IndexMinPQ.java UF.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/43mst/tinyEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/mediumEWG.txt
 *                https://algs4.cs.princeton.edu/43mst/largeEWG.txt
 *
 *  Compute a minimum spanning forest using Prim's algorithm.
 *
 *  %  java PrimMST tinyEWG.txt 
 *  1-7 0.19000
 *  0-2 0.26000
 *  2-3 0.17000
 *  4-5 0.35000
 *  5-7 0.28000
 *  6-2 0.40000
 *  0-7 0.16000
 *  1.81000
 *
 *  % java PrimMST mediumEWG.txt
 *  1-72   0.06506
 *  2-86   0.05980
 *  3-67   0.09725
 *  4-55   0.06425
 *  5-102  0.03834
 *  6-129  0.05363
 *  7-157  0.00516
 *  ...
 *  10.46351
 *
 *  % java PrimMST largeEWG.txt
 *  ...
 *  647.66307
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  PrimMST} class represents a data type for computing a
 *  <em>minimum spanning tree</em> in an edge-weighted graph.
 *  The edge weights can be positive, zero, or negative and need not
 *  be distinct. If the graph is not connected, it computes a <em>minimum
 *  spanning forest</em>, which is the union of minimum spanning trees
 *  in each connected component. The { @code  weight()} method returns the 
 *  weight of a minimum spanning tree and the { @code  edges()} method
 *  returns its edges.
 *  <p>
 *  This implementation uses <em>Prim's algorithm</em> with an indexed
 *  binary heap.
 *  The constructor takes &Theta;(<em>E</em> log <em>V</em>) time in
 *  the worst case, where <em>V</em> is the number of
 *  vertices and <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the 
 *  edge-weighted graph).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/43mst">Section 4.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For alternate implementations, see { @link  LazyPrimMST}, { @link  KruskalMST},
 *  and { @link  BoruvkaMST}.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   PrimMST   {
     private   static   final   double  FLOATING_POINT_EPSILON  =   1E-12 ;

     private   Edge []  edgeTo ;          // edgeTo[v] = shortest edge from tree vertex to non-tree vertex
     private   double []  distTo ;        // distTo[v] = weight of shortest such edge
     private   boolean []  marked ;       // marked[v] = true if v on tree, false otherwise
     private   IndexMinPQ < Double >  pq ;

     /**
     * Compute a minimum spanning tree (or forest) of an edge-weighted graph.
     *  @param  G the edge-weighted graph
     */
     public   PrimMST ( EdgeWeightedGraph  G )   {
        edgeTo  =   new   Edge [ G . V ()];
        distTo  =   new   double [ G . V ()];
        marked  =   new   boolean [ G . V ()];
        pq  =   new   IndexMinPQ < Double > ( G . V ());
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            distTo [ v ]   =   Double . POSITIVE_INFINITY ;

         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )        // run from each vertex to find
             if   ( ! marked [ v ])  prim ( G ,  v );        // minimum spanning forest

         // check optimality conditions
         assert  check ( G );
     }

     // run Prim's algorithm in graph G, starting from vertex s
     private   void  prim ( EdgeWeightedGraph  G ,   int  s )   {
        distTo [ s ]   =   0.0 ;
        pq . insert ( s ,  distTo [ s ]);
         while   ( ! pq . isEmpty ())   {
             int  v  =  pq . delMin ();
            scan ( G ,  v );
         }
     }

     // scan vertex v
     private   void  scan ( EdgeWeightedGraph  G ,   int  v )   {
        marked [ v ]   =   true ;
         for   ( Edge  e  :  G . adj ( v ))   {
             int  w  =  e . other ( v );
             if   ( marked [ w ])   continue ;           // v-w is obsolete edge
             if   ( e . weight ()   <  distTo [ w ])   {
                distTo [ w ]   =  e . weight ();
                edgeTo [ w ]   =  e ;
                 if   ( pq . contains ( w ))  pq . decreaseKey ( w ,  distTo [ w ]);
                 else                 pq . insert ( w ,  distTo [ w ]);
             }
         }
     }

     /**
     * Returns the edges in a minimum spanning tree (or forest).
     *  @return  the edges in a minimum spanning tree (or forest) as
     *    an iterable of edges
     */
     public   Iterable < Edge >  edges ()   {
         Queue < Edge >  mst  =   new   Queue < Edge > ();
         for   ( int  v  =   0 ;  v  <  edgeTo . length ;  v ++ )   {
             Edge  e  =  edgeTo [ v ];
             if   ( !=   null )   {
                mst . enqueue ( e );
             }
         }
         return  mst ;
     }

     /**
     * Returns the sum of the edge weights in a minimum spanning tree (or forest).
     *  @return  the sum of the edge weights in a minimum spanning tree (or forest)
     */
     public   double  weight ()   {
         double  weight  =   0.0 ;
         for   ( Edge  e  :  edges ())
            weight  +=  e . weight ();
         return  weight ;
     }


     // check optimality conditions (takes time proportional to E V lg* V)
     private   boolean  check ( EdgeWeightedGraph  G )   {

         // check weight
         double  totalWeight  =   0.0 ;
         for   ( Edge  e  :  edges ())   {
            totalWeight  +=  e . weight ();
         }
         if   ( Math . abs ( totalWeight  -  weight ())   >  FLOATING_POINT_EPSILON )   {
             System . err . printf ( "Weight of edges does not equal weight(): %f vs. %f\n" ,  totalWeight ,  weight ());
             return   false ;
         }

         // check that it is acyclic
        UF uf  =   new  UF ( G . V ());
         for   ( Edge  e  :  edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   ==  uf . find ( w ))   {
                 System . err . println ( "Not a forest" );
                 return   false ;
             }
            uf . union ( v ,  w );
         }

         // check that it is a spanning forest
         for   ( Edge  e  :  G . edges ())   {
             int  v  =  e . either (),  w  =  e . other ( v );
             if   ( uf . find ( v )   !=  uf . find ( w ))   {
                 System . err . println ( "Not a spanning forest" );
                 return   false ;
             }
         }

         // check that it is a minimal spanning forest (cut optimality conditions)
         for   ( Edge  e  :  edges ())   {

             // all edges in MST except e
            uf  =   new  UF ( G . V ());
             for   ( Edge  f  :  edges ())   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( !=  e )  uf . union ( x ,  y );
             }

             // check that e is min weight edge in crossing cut
             for   ( Edge  f  :  G . edges ())   {
                 int  x  =  f . either (),  y  =  f . other ( x );
                 if   ( uf . find ( x )   !=  uf . find ( y ))   {
                     if   ( f . weight ()   <  e . weight ())   {
                         System . err . println ( "Edge "   +  f  +   " violates cut optimality conditions" );
                         return   false ;
                     }
                 }
             }

         }

         return   true ;
     }

     /**
     * Unit tests the { @code  PrimMST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         EdgeWeightedGraph  G  =   new   EdgeWeightedGraph ( in );
         PrimMST  mst  =   new   PrimMST ( G );
         for   ( Edge  e  :  mst . edges ())   {
             StdOut . println ( e );
         }
         StdOut . printf ( "%.5f\n" ,  mst . weight ());
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Queue.java

edu/princeton/cs/algs4/Queue.java

/******************************************************************************
 *  Compilation:  javac Queue.java
 *  Execution:    java Queue < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  
 *
 *  A generic queue, implemented using a linked list.
 *
 *  % java Queue < tobe.txt 
 *  to be or not to be (2 left on queue)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  Queue} class represents a first-in-first-out (FIFO)
 *  queue of generic items.
 *  It supports the usual <em>enqueue</em> and <em>dequeue</em>
 *  operations, along with methods for peeking at the first item,
 *  testing if the queue is empty, and iterating through
 *  the items in FIFO order.
 *  <p>
 *  This implementation uses a singly linked list with a static nested class for
 *  linked-list nodes. See { @link  LinkedQueue} for the version from the
 *  textbook that uses a non-static nested class.
 *  See { @link  ResizingArrayQueue} for a version that uses a resizing array.
 *  The <em>enqueue</em>, <em>dequeue</em>, <em>peek</em>, <em>size</em>, and <em>is-empty</em>
 *  operations all take constant time in the worst case.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Item> the generic type of an item in this queue
 */
public   class   Queue < Item >   implements   Iterable < Item >   {
     private   Node < Item >  first ;      // beginning of queue
     private   Node < Item >  last ;       // end of queue
     private   int  n ;                 // number of elements on queue

     // helper linked list class
     private   static   class   Node < Item >   {
         private   Item  item ;
         private   Node < Item >  next ;
     }

     /**
     * Initializes an empty queue.
     */
     public   Queue ()   {
        first  =   null ;
        last   =   null ;
        n  =   0 ;
     }

     /**
     * Returns true if this queue is empty.
     *
     *  @return  { @code  true} if this queue is empty; { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in this queue.
     *
     *  @return  the number of items in this queue
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns the item least recently added to this queue.
     *
     *  @return  the item least recently added to this queue
     *  @throws  NoSuchElementException if this queue is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         return  first . item ;
     }

     /**
     * Adds the item to this queue.
     *
     *  @param   item the item to add
     */
     public   void  enqueue ( Item  item )   {
         Node < Item >  oldlast  =  last ;
        last  =   new   Node < Item > ();
        last . item  =  item ;
        last . next  =   null ;
         if   ( isEmpty ())  first  =  last ;
         else            oldlast . next  =  last ;
        n ++ ;
     }

     /**
     * Removes and returns the item on this queue that was least recently added.
     *
     *  @return  the item on this queue that was least recently added
     *  @throws  NoSuchElementException if this queue is empty
     */
     public   Item  dequeue ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         Item  item  =  first . item ;
        first  =  first . next ;
        n -- ;
         if   ( isEmpty ())  last  =   null ;     // to avoid loitering
         return  item ;
     }

     /**
     * Returns a string representation of this queue.
     *
     *  @return  the sequence of items in FIFO order, separated by spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( Item  item  :   this )   {
            s . append ( item );
            s . append ( ' ' );
         }
         return  s . toString ();
     }  

     /**
     * Returns an iterator that iterates over the items in this queue in FIFO order.
     *
     *  @return  an iterator that iterates over the items in this queue in FIFO order
     */
     public   Iterator < Item >  iterator ()    {
         return   new   ListIterator ( first );   
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node < Item >  current ;

         public   ListIterator ( Node < Item >  first )   {
            current  =  first ;
         }

         public   boolean  hasNext ()    {   return  current  !=   null ;                       }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }


     /**
     * Unit tests the { @code  Queue} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Queue < String >  queue  =   new   Queue < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))
                queue . enqueue ( item );
             else   if   ( ! queue . isEmpty ())
                 StdOut . print ( queue . dequeue ()   +   " " );
         }
         StdOut . println ( "("   +  queue . size ()   +   " left on queue)" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Quick3string.java

edu/princeton/cs/algs4/Quick3string.java

/******************************************************************************
 *  Compilation:  javac Quick3string.java
 *  Execution:    java Quick3string < input.txt
 *  Dependencies: StdIn.java StdOut.java 
 *  Data files:   https://algs4.cs.princeton.edu/51radix/words3.txt
 *                https://algs4.cs.princeton.edu/51radix/shells.txt
 *
 *  Reads string from standard input and 3-way string quicksort them.
 *
 *  % java Quick3string < shell.txt
 *  are
 *  by
 *  sea
 *  seashells
 *  seashells
 *  sells
 *  sells
 *  she
 *  she
 *  shells
 *  shore
 *  surely
 *  the
 *  the
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Quick3string} class provides static methods for sorting an
 *  array of strings using 3-way radix quicksort.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/51radix">Section 5.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Quick3string   {
     private   static   final   int  CUTOFF  =    15 ;     // cutoff to insertion sort

     // do not instantiate
     private   Quick3string ()   {   }  

     /**  
     * Rearranges the array of strings in ascending order.
     *
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( String []  a )   {
         StdRandom . shuffle ( a );
        sort ( a ,   0 ,  a . length - 1 ,   0 );
         assert  isSorted ( a );
     }

     // return the dth character of s, -1 if d = length of s
     private   static   int  charAt ( String  s ,   int  d )   {  
         assert  d  >=   0   &&  d  <=  s . length ();
         if   ( ==  s . length ())   return   - 1 ;
         return  s . charAt ( d );
     }


     // 3-way string quicksort a[lo..hi] starting at dth character
     private   static   void  sort ( String []  a ,   int  lo ,   int  hi ,   int  d )   {  

         // cutoff to insertion sort for small subarrays
         if   ( hi  <=  lo  +  CUTOFF )   {
            insertion ( a ,  lo ,  hi ,  d );
             return ;
         }

         int  lt  =  lo ,  gt  =  hi ;
         int  v  =  charAt ( a [ lo ],  d );
         int  i  =  lo  +   1 ;
         while   ( <=  gt )   {
             int  t  =  charAt ( a [ i ],  d );
             if        ( <  v )  exch ( a ,  lt ++ ,  i ++ );
             else   if   ( >  v )  exch ( a ,  i ,  gt -- );
             else               i ++ ;
         }

         // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]. 
        sort ( a ,  lo ,  lt - 1 ,  d );
         if   ( >=   0 )  sort ( a ,  lt ,  gt ,  d + 1 );
        sort ( a ,  gt + 1 ,  hi ,  d );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     private   static   void  insertion ( String []  a ,   int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ],  d );  j -- )
                exch ( a ,  j ,  j - 1 );
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( String []  a ,   int  i ,   int  j )   {
         String  temp  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  temp ;
     }

     // is v less than w, starting at character d
     // DEPRECATED BECAUSE OF SLOW SUBSTRING EXTRACTION IN JAVA 7
     // private static boolean less(String v, String w, int d) {
     //    assert v.substring(0, d).equals(w.substring(0, d));
     //    return v.substring(d).compareTo(w.substring(d)) < 0; 
     // }

     // is v less than w, starting at character d
     private   static   boolean  less ( String  v ,   String  w ,   int  d )   {
         assert  v . substring ( 0 ,  d ). equals ( w . substring ( 0 ,  d ));
         for   ( int  i  =  d ;  i  <   Math . min ( v . length (),  w . length ());  i ++ )   {
             if   ( v . charAt ( i )   <  w . charAt ( i ))   return   true ;
             if   ( v . charAt ( i )   >  w . charAt ( i ))   return   false ;
         }
         return  v . length ()   <  w . length ();
     }

     // is the array sorted
     private   static   boolean  isSorted ( String []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( a [ i ]. compareTo ( a [ i - 1 ])   <   0 )   return   false ;
         return   true ;
     }


     /**
     * Reads in a sequence of fixed-length strings from standard input;
     * 3-way radix quicksorts them;
     * and prints them to standard output in ascending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read in the strings from standard input
         String []  a  =   StdIn . readAllStrings ();
         int  n  =  a . length ;

         // sort the strings
        sort ( a );

         // print the results
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
             StdOut . println ( a [ i ]);
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Quick3way.java

edu/princeton/cs/algs4/Quick3way.java

/******************************************************************************
 *  Compilation:  javac Quick3way.java
 *  Execution:    java Quick3way < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt
 *                https://algs4.cs.princeton.edu/23quicksort/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using 3-way quicksort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Quick3way < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java Quick3way < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Quick3way} class provides static methods for sorting an
 *  array using quicksort with 3-way partitioning.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/23quick">Section 2.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Quick3way   {

     // This class should not be instantiated.
     private   Quick3way ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         StdRandom . shuffle ( a );
        sort ( a ,   0 ,  a . length  -   1 );
         assert  isSorted ( a );
     }

     // quicksort the subarray a[lo .. hi] using 3-way partitioning
     private   static   void  sort ( Comparable []  a ,   int  lo ,   int  hi )   {  
         if   ( hi  <=  lo )   return ;
         int  lt  =  lo ,  gt  =  hi ;
         Comparable  v  =  a [ lo ];
         int  i  =  lo  +   1 ;
         while   ( <=  gt )   {
             int  cmp  =  a [ i ]. compareTo ( v );
             if        ( cmp  <   0 )  exch ( a ,  lt ++ ,  i ++ );
             else   if   ( cmp  >   0 )  exch ( a ,  i ,  gt -- );
             else               i ++ ;
         }

         // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]. 
        sort ( a ,  lo ,  lt - 1 );
        sort ( a ,  gt + 1 ,  hi );
         assert  isSorted ( a ,  lo ,  hi );
     }



    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }

     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }



     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; 3-way
     * quicksorts them; and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Quick3way . sort ( a );
        show ( a );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/QuickBentleyMcIlroy.java

edu/princeton/cs/algs4/QuickBentleyMcIlroy.java

/******************************************************************************
 *  Compilation:  javac QuickBentleyMcIlroy.java
 *  Execution:    java QuickBentleyMcIlroy < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt
 *                https://algs4.cs.princeton.edu/23quicksort/words3.txt
 *  
 *  Uses the Bentley-McIlroy 3-way partitioning scheme,
 *  chooses the partitioning element using Tukey's ninther,
 *  and cuts off to insertion sort.
 *
 *  Reference: Engineering a Sort Function by Jon L. Bentley
 *  and M. Douglas McIlroy. Softwae-Practice and Experience,
 *  Vol. 23 (11), 1249-1265 (November 1993).
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  QuickBentleyMcIlroy} class provides static methods for sorting
 *  an array using an optimized version of quicksort (using Bentley-McIlroy
 *  3-way partitioning, Tukey's ninther, and cutoff to insertion sort).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/23quick">Section 2.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   QuickBentleyMcIlroy   {

     // cutoff to insertion sort, must be >= 1
     private   static   final   int  INSERTION_SORT_CUTOFF  =   8 ;

     // cutoff to median-of-3 partitioning
     private   static   final   int  MEDIAN_OF_3_CUTOFF  =   40 ;

     // This class should not be instantiated.
     private   QuickBentleyMcIlroy ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
        sort ( a ,   0 ,  a . length  -   1 );
     }

     private   static   void  sort ( Comparable []  a ,   int  lo ,   int  hi )   {  
         int  n  =  hi  -  lo  +   1 ;

         // cutoff to insertion sort
         if   ( <=  INSERTION_SORT_CUTOFF )   {
            insertionSort ( a ,  lo ,  hi );
             return ;
         }

         // use median-of-3 as partitioning element
         else   if   ( <=  MEDIAN_OF_3_CUTOFF )   {
             int  m  =  median3 ( a ,  lo ,  lo  +  n / 2 ,  hi );
            exch ( a ,  m ,  lo );
         }

         // use Tukey ninther as partitioning element
         else    {
             int  eps  =  n / 8 ;
             int  mid  =  lo  +  n / 2 ;
             int  m1  =  median3 ( a ,  lo ,  lo  +  eps ,  lo  +  eps  +  eps );
             int  m2  =  median3 ( a ,  mid  -  eps ,  mid ,  mid  +  eps );
             int  m3  =  median3 ( a ,  hi  -  eps  -  eps ,  hi  -  eps ,  hi );  
             int  ninther  =  median3 ( a ,  m1 ,  m2 ,  m3 );
            exch ( a ,  ninther ,  lo );
         }

         // Bentley-McIlroy 3-way partitioning
         int  i  =  lo ,  j  =  hi + 1 ;
         int  p  =  lo ,  q  =  hi + 1 ;
         Comparable  v  =  a [ lo ];
         while   ( true )   {
             while   ( less ( a [ ++ i ],  v ))
                 if   ( ==  hi )   break ;
             while   ( less ( v ,  a [ -- j ]))
                 if   ( ==  lo )   break ;

             // pointers cross
             if   ( ==  j  &&  eq ( a [ i ],  v ))
                exch ( a ,   ++ p ,  i );
             if   ( >=  j )   break ;

            exch ( a ,  i ,  j );
             if   ( eq ( a [ i ],  v ))  exch ( a ,   ++ p ,  i );
             if   ( eq ( a [ j ],  v ))  exch ( a ,   -- q ,  j );
         }


        i  =  j  +   1 ;
         for   ( int  k  =  lo ;  k  <=  p ;  k ++ )
            exch ( a ,  k ,  j -- );
         for   ( int  k  =  hi ;  k  >=  q ;  k -- )
            exch ( a ,  k ,  i ++ );

        sort ( a ,  lo ,  j );
        sort ( a ,  i ,  hi );
     }


     // sort from a[lo] to a[hi] using insertion sort
     private   static   void  insertionSort ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( a [ j ],  a [ j - 1 ]);  j -- )
                exch ( a ,  j ,  j - 1 );
     }


     // return the index of the median element among a[i], a[j], and a[k]
     private   static   int  median3 ( Comparable []  a ,   int  i ,   int  j ,   int  k )   {
         return   ( less ( a [ i ],  a [ j ])   ?
                ( less ( a [ j ],  a [ k ])   ?  j  :  less ( a [ i ],  a [ k ])   ?  k  :  i )   :
                ( less ( a [ k ],  a [ j ])   ?  j  :  less ( a [ k ],  a [ i ])   ?  k  :  i ));
     }

    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         if   ( ==  w )   return   false ;      // optimization when reference equal
         return  v . compareTo ( w )   <   0 ;
     }

     // does v == w ?
     private   static   boolean  eq ( Comparable  v ,   Comparable  w )   {
         if   ( ==  w )   return   true ;      // optimization when reference equal
         return  v . compareTo ( w )   ==   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; quicksorts them
     * (using an optimized version of quicksort); 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         QuickBentleyMcIlroy . sort ( a );
         assert  isSorted ( a );
        show ( a );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/QuickFindUF.java

edu/princeton/cs/algs4/QuickFindUF.java

/******************************************************************************
 *  Compilation:  javac QuickFindUF.java
 *  Execution:  java QuickFindUF < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt
 *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt
 *                https://algs4.cs.princeton.edu/15uf/largeUF.txt
 *
 *  Quick-find algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  QuickFindUF} class represents a <em>union–find data type</em>
 *  (also known as the <em>disjoint-sets data type</em>).
 *  It supports the classic <em>union</em> and <em>find</em> operations,
 *  along with a <em>count</em> operation that returns the total number
 *  of sets.
 *  <p>
 *  The union-find data type models a collection of sets containing
 *  <em>n</em> elements, with each element in exactly one set.
 *  The elements are named 0 through <em>n</em>–1.
 *  Initially, there are <em>n</em> sets, with each element in its
 *  own set. The <em>cannonical elemement</em> of a set
 *  (also known as the <em>root</em>, <em>identifier</em>,
 *  <em>leader</em>, or <em>set representative</em>)
 *  is one distinguished element in the set. Here is a summary of
 *  the operations:
 *  <ul>
 *  <li><em>find</em>(<em>p</em>) returns the canonical element
 *      of the set containing <em>p</em>. The <em>find</em> operation
 *      returns the same value for two elements if and only if
 *      they are in the same set.
 *  <li><em>union</em>(<em>p</em>, <em>q</em>) merges the set
 *      containing element <em>p</em> with the set containing
 *      element <em>q</em>. That is, if <em>p</em> and <em>q</em>
 *      are in different sets, replace these two sets
 *      with a new set that is the union of the two.
 *  <li><em>count</em>() returns the number of sets.
 *  </ul>
 *  <p>
 *  The canonical element of a set can change only when the set
 *  itself changes during a call to <em>union</em>&mdash;it cannot
 *  change during a call to either <em>find</em> or <em>count</em>.
 *  <p>
 *  This implementation uses <em>quick find</em>.
 *  The constructor takes &Theta;(<em>n</em>) time, where <em>n</em>
 *  is the number of sites.
 *  The <em>find</em>, <em>connected</em>, and <em>count</em>
 *  operations take &Theta;(1) time; the <em>union</em> operation
 *  takes &Theta;(<em>n</em>) time.
 *  <p>
 *  For alternative implementations of the same API, see
 *  { @link  UF}, { @link  QuickUnionUF}, and { @link  WeightedQuickUnionUF}.
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   QuickFindUF   {
     private   int []  id ;      // id[i] = component identifier of i
     private   int  count ;     // number of components

     /**
     * Initializes an empty union-find data structure with
     * { @code  n} elements { @code  0} through { @code  n-1}. 
     * Initially, each elements is in its own set.
     *
     *  @param   n the number of elements
     *  @throws  IllegalArgumentException if { @code  n < 0}
     */
     public   QuickFindUF ( int  n )   {
        count  =  n ;
        id  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            id [ i ]   =  i ;
     }

     /**
     * Returns the number of sets.
     *
     *  @return  the number of sets (between { @code  1} and { @code  n})
     */
     public   int  count ()   {
         return  count ;
     }
  
     /**
     * Returns the canonical element of the set containing element { @code  p}.
     *
     *  @param   p an element
     *  @return  the canonical element of the set containing { @code  p}
     *  @throws  IllegalArgumentException unless { @code  0 <= p < n}
     */
     public   int  find ( int  p )   {
        validate ( p );
         return  id [ p ];
     }

     // validate that p is a valid index
     private   void  validate ( int  p )   {
         int  n  =  id . length ;
         if   ( <   0   ||  p  >=  n )   {
             throw   new   IllegalArgumentException ( "index "   +  p  +   " is not between 0 and "   +   ( n - 1 ));
         }
     }

     /**
     * Returns true if the two elements are in the same set.
     * 
     *  @param   p one element
     *  @param   q the other element
     *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     *  @deprecated  Replace with two calls to { @link  #find(int)}.
     */
    @ Deprecated
     public   boolean  connected ( int  p ,   int  q )   {
        validate ( p );
        validate ( q );
         return  id [ p ]   ==  id [ q ];
     }
  
     /**
     * Merges the set containing element { @code  p} with the 
     * the set containing element { @code  q}.
     *
     *  @param   p one element
     *  @param   q the other element
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     */
     public   void  union ( int  p ,   int  q )   {
        validate ( p );
        validate ( q );
         int  pID  =  id [ p ];     // needed for correctness
         int  qID  =  id [ q ];     // to reduce the number of array accesses

         // p and q are already in the same component
         if   ( pID  ==  qID )   return ;

         for   ( int  i  =   0 ;  i  <  id . length ;  i ++ )
             if   ( id [ i ]   ==  pID )  id [ i ]   =  qID ;
        count -- ;
     }

     /**
     * Reads in a an integer { @code  n} and a sequence of pairs of integers
     * (between { @code  0} and { @code  n-1}) from standard input, where each integer
     * in the pair represents some element;
     * if the elements are in different sets, merge the two sets
     * and print the pair to standard output.
     * 
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         QuickFindUF  uf  =   new   QuickFindUF ( n );
         while   ( ! StdIn . isEmpty ())   {
             int  p  =   StdIn . readInt ();
             int  q  =   StdIn . readInt ();
             if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;
            uf . union ( p ,  q );
             StdOut . println ( +   " "   +  q );
         }
         StdOut . println ( uf . count ()   +   " components" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Quick.java

edu/princeton/cs/algs4/Quick.java

/******************************************************************************
 *  Compilation:  javac Quick.java
 *  Execution:    java Quick < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt
 *                https://algs4.cs.princeton.edu/23quicksort/words3.txt
 *
 *  Sorts a sequence of strings from standard input using quicksort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Quick < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *       
 *  % java Quick < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 *
 *  Remark: For a type-safe version that uses static generics, see
 *
 *    https://algs4.cs.princeton.edu/23quicksort/QuickPedantic.java
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Quick} class provides static methods for sorting an
 *  array and selecting the ith smallest element in an array using quicksort.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/23quick">Section 2.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Quick   {

     // This class should not be instantiated.
     private   Quick ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         StdRandom . shuffle ( a );
        sort ( a ,   0 ,  a . length  -   1 );
         assert  isSorted ( a );
     }

     // quicksort the subarray from a[lo] to a[hi]
     private   static   void  sort ( Comparable []  a ,   int  lo ,   int  hi )   {  
         if   ( hi  <=  lo )   return ;
         int  j  =  partition ( a ,  lo ,  hi );
        sort ( a ,  lo ,  j - 1 );
        sort ( a ,  j + 1 ,  hi );
         assert  isSorted ( a ,  lo ,  hi );
     }

     // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
     // and return the index j.
     private   static   int  partition ( Comparable []  a ,   int  lo ,   int  hi )   {
         int  i  =  lo ;
         int  j  =  hi  +   1 ;
         Comparable  v  =  a [ lo ];
         while   ( true )   {  

             // find item on lo to swap
             while   ( less ( a [ ++ i ],  v ))   {
                 if   ( ==  hi )   break ;
             }

             // find item on hi to swap
             while   ( less ( v ,  a [ -- j ]))   {
                 if   ( ==  lo )   break ;        // redundant since a[lo] acts as sentinel
             }

             // check if pointers cross
             if   ( >=  j )   break ;

            exch ( a ,  i ,  j );
         }

         // put partitioning item v at a[j]
        exch ( a ,  lo ,  j );

         // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
         return  j ;
     }

     /**
     * Rearranges the array so that { @code  a[k]} contains the kth smallest key;
     * { @code  a[0]} through { @code  a[k-1]} are less than (or equal to) { @code  a[k]}; and
     * { @code  a[k+1]} through { @code  a[n-1]} are greater than (or equal to) { @code  a[k]}.
     *
     *  @param   a the array
     *  @param   k the rank of the key
     *  @return  the key of rank { @code  k}
     *  @throws  IllegalArgumentException unless { @code  0 <= k < a.length}
     */
     public   static   Comparable  select ( Comparable []  a ,   int  k )   {
         if   ( <   0   ||  k  >=  a . length )   {
             throw   new   IllegalArgumentException ( "index is not between 0 and "   +  a . length  +   ": "   +  k );
         }
         StdRandom . shuffle ( a );
         int  lo  =   0 ,  hi  =  a . length  -   1 ;
         while   ( hi  >  lo )   {
             int  i  =  partition ( a ,  lo ,  hi );
             if        ( >  k )  hi  =  i  -   1 ;
             else   if   ( <  k )  lo  =  i  +   1 ;
             else   return  a [ i ];
         }
         return  a [ lo ];
     }



    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         if   ( ==  w )   return   false ;     // optimization when reference equals
         return  v . compareTo ( w )   <   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }

     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }


     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; quicksorts them; 
     * and prints them to standard output in ascending order. 
     * Shuffles the array and then prints the strings again to
     * standard output, but this time, using the select method.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Quick . sort ( a );
        show ( a );
         assert  isSorted ( a );

         // shuffle
         StdRandom . shuffle ( a );

         // display results again using select
         StdOut . println ();
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             String  ith  =   ( String )   Quick . select ( a ,  i );
             StdOut . println ( ith );
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/QuickUnionUF.java

edu/princeton/cs/algs4/QuickUnionUF.java

/******************************************************************************
 *  Compilation:  javac QuickUnionUF.java
 *  Execution:  java QuickUnionUF < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt
 *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt
 *                https://algs4.cs.princeton.edu/15uf/largeUF.txt
 *
 *  Quick-union algorithm.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  QuickUnionUF} class represents a <em>union–find data type</em>
 *  (also known as the <em>disjoint-sets data type</em>).
 *  It supports the classic <em>union</em> and <em>find</em> operations,
 *  along with a <em>count</em> operation that returns the total number
 *  of sets.
 *  <p>
 *  The union-find data type models a collection of sets containing
 *  <em>n</em> elements, with each element in exactly one set.
 *  The elements are named 0 through <em>n</em>–1.
 *  Initially, there are <em>n</em> sets, with each element in its
 *  own set. The <em>cannonical elemement</em> of a set
 *  (also known as the <em>root</em>, <em>identifier</em>,
 *  <em>leader</em>, or <em>set representative</em>)
 *  is one distinguished element in the set. Here is a summary of
 *  the operations:
 *  <ul>
 *  <li><em>find</em>(<em>p</em>) returns the canonical element
 *      of the set containing <em>p</em>. The <em>find</em> operation
 *      returns the same value for two elements if and only if
 *      they are in the same set.
 *  <li><em>union</em>(<em>p</em>, <em>q</em>) merges the set
 *      containing element <em>p</em> with the set containing
 *      element <em>q</em>. That is, if <em>p</em> and <em>q</em>
 *      are in different sets, replace these two sets
 *      with a new set that is the union of the two.
 *  <li><em>count</em>() returns the number of sets.
 *  </ul>
 *  <p>
 *  The canonical element of a set can change only when the set
 *  itself changes during a call to <em>union</em>&mdash;it cannot
 *  change during a call to either <em>find</em> or <em>count</em>.
 *  <p>
 *  This implementation uses <em>quick union</em>.
 *  The constructor takes &Theta;(<em>n</em>) time, where
 *  <em>n</em> is the number of sites.
 *  The <em>union</em> and <em>find</em> operations take
 *  &Theta;(<em>n</em>) time in the worst case.
 *  The <em>count</em> operation takes &Theta;(1) time.
 *  <p>
 *  For alternative implementations of the same API, see
 *  { @link  UF}, { @link  QuickFindUF}, and { @link  WeightedQuickUnionUF}.
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   QuickUnionUF   {
     private   int []  parent ;    // parent[i] = parent of i
     private   int  count ;       // number of components

     /**
     * Initializes an empty union-find data structure with
     * { @code  n} elements { @code  0} through { @code  n-1}. 
     * Initially, each elements is in its own set.
     *
     *  @param   n the number of elements
     *  @throws  IllegalArgumentException if { @code  n < 0}
     */
     public   QuickUnionUF ( int  n )   {
        parent  =   new   int [ n ];
        count  =  n ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            parent [ i ]   =  i ;
         }
     }

     /**
     * Returns the number of sets.
     *
     *  @return  the number of sets (between { @code  1} and { @code  n})
     */
     public   int  count ()   {
         return  count ;
     }
  
     /**
     * Returns the canonical element of the set containing element { @code  p}.
     *
     *  @param   p an element
     *  @return  the canonical element of the set containing { @code  p}
     *  @throws  IllegalArgumentException unless { @code  0 <= p < n}
     */
     public   int  find ( int  p )   {
        validate ( p );
         while   ( !=  parent [ p ])
            p  =  parent [ p ];
         return  p ;
     }

     // validate that p is a valid index
     private   void  validate ( int  p )   {
         int  n  =  parent . length ;
         if   ( <   0   ||  p  >=  n )   {
             throw   new   IllegalArgumentException ( "index "   +  p  +   " is not between 0 and "   +   ( n - 1 ));
         }
     }

     /**
     * Returns true if the two elements are in the same set.
     * 
     *  @param   p one element
     *  @param   q the other element
     *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     *  @deprecated  Replace with two calls to { @link  #find(int)}.
     */
    @ Deprecated
     public   boolean  connected ( int  p ,   int  q )   {
         return  find ( p )   ==  find ( q );
     }

     /**
     * Merges the set containing element { @code  p} with the 
     * the set containing element { @code  q}.
     *
     *  @param   p one element
     *  @param   q the other element
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     */
     public   void  union ( int  p ,   int  q )   {
         int  rootP  =  find ( p );
         int  rootQ  =  find ( q );
         if   ( rootP  ==  rootQ )   return ;
        parent [ rootP ]   =  rootQ ;  
        count -- ;
     }

     /**
     * Reads in a an integer { @code  n} and a sequence of pairs of integers
     * (between { @code  0} and { @code  n-1}) from standard input, where each integer
     * in the pair represents some element;
     * if the elements are in different sets, merge the two sets
     * and print the pair to standard output.
     * 
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         QuickUnionUF  uf  =   new   QuickUnionUF ( n );
         while   ( ! StdIn . isEmpty ())   {
             int  p  =   StdIn . readInt ();
             int  q  =   StdIn . readInt ();
             if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;
            uf . union ( p ,  q );
             StdOut . println ( +   " "   +  q );
         }
         StdOut . println ( uf . count ()   +   " components" );
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/QuickX.java

edu/princeton/cs/algs4/QuickX.java

/******************************************************************************
 *  Compilation:  javac QuickX.java
 *  Execution:    java QuickX < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/23quicksort/tiny.txt
 *                https://algs4.cs.princeton.edu/23quicksort/words3.txt
 *  
 *  Uses the Hoare's 2-way partitioning scheme, chooses the partitioning
 *  element using median-of-3, and cuts off to insertion sort.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  QuickX} class provides static methods for sorting an array
 *  using an optimized version of quicksort (using Hoare's 2-way partitioning
 *  algorithm, median-of-3 to choose the partitioning element, and cutoff
 *  to insertion sort).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/23quick">Section 2.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   QuickX   {

     // cutoff to insertion sort, must be >= 1
     private   static   final   int  INSERTION_SORT_CUTOFF  =   8 ;

     // This class should not be instantiated.
     private   QuickX ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         // StdRandom.shuffle(a);
        sort ( a ,   0 ,  a . length  -   1 );
         assert  isSorted ( a );
     }

     // quicksort the subarray from a[lo] to a[hi]
     private   static   void  sort ( Comparable []  a ,   int  lo ,   int  hi )   {  
         if   ( hi  <=  lo )   return ;

         // cutoff to insertion sort (Insertion.sort() uses half-open intervals)
         int  n  =  hi  -  lo  +   1 ;
         if   ( <=  INSERTION_SORT_CUTOFF )   {
             Insertion . sort ( a ,  lo ,  hi  +   1 );
             return ;
         }

         int  j  =  partition ( a ,  lo ,  hi );
        sort ( a ,  lo ,  j - 1 );
        sort ( a ,  j + 1 ,  hi );
     }

     // partition the subarray a[lo..hi] so that a[lo..j-1] <= a[j] <= a[j+1..hi]
     // and return the index j.
     private   static   int  partition ( Comparable []  a ,   int  lo ,   int  hi )   {
         int  n  =  hi  -  lo  +   1 ;
         int  m  =  median3 ( a ,  lo ,  lo  +  n / 2 ,  hi );
        exch ( a ,  m ,  lo );

         int  i  =  lo ;
         int  j  =  hi  +   1 ;
         Comparable  v  =  a [ lo ];

         // a[lo] is unique largest element
         while   ( less ( a [ ++ i ],  v ))   {
             if   ( ==  hi )   {  exch ( a ,  lo ,  hi );   return  hi ;   }
         }

         // a[lo] is unique smallest element
         while   ( less ( v ,  a [ -- j ]))   {
             if   ( ==  lo  +   1 )   return  lo ;
         }

         // the main loop
         while   ( <  j )   {  
            exch ( a ,  i ,  j );
             while   ( less ( a [ ++ i ],  v ))   ;
             while   ( less ( v ,  a [ -- j ]))   ;
         }

         // put partitioning item v at a[j]
        exch ( a ,  lo ,  j );

         // now, a[lo .. j-1] <= a[j] <= a[j+1 .. hi]
         return  j ;
     }

     // return the index of the median element among a[i], a[j], and a[k]
     private   static   int  median3 ( Comparable []  a ,   int  i ,   int  j ,   int  k )   {
         return   ( less ( a [ i ],  a [ j ])   ?
                ( less ( a [ j ],  a [ k ])   ?  j  :  less ( a [ i ],  a [ k ])   ?  k  :  i )   :
                ( less ( a [ k ],  a [ j ])   ?  j  :  less ( a [ k ],  a [ i ])   ?  k  :  i ));
     }

    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }

     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; quicksorts them
     * (using an optimized version of 2-way quicksort); 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         QuickX . sort ( a );
         assert  isSorted ( a );
        show ( a );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/RabinKarp.java

edu/princeton/cs/algs4/RabinKarp.java

/******************************************************************************
 *  Compilation:  javac RabinKarp.java
 *  Execution:    java RabinKarp pat txt
 *  Dependencies: StdOut.java
 *
 *  Reads in two strings, the pattern and the input text, and
 *  searches for the pattern in the input text using the
 *  Las Vegas version of the Rabin-Karp algorithm.
 *
 *  % java RabinKarp abracadabra abacadabrabracabracadabrabrabracad
 *  pattern: abracadabra
 *  text:    abacadabrabracabracadabrabrabracad 
 *  match:                 abracadabra          
 *
 *  % java RabinKarp rab abacadabrabracabracadabrabrabracad
 *  pattern: rab
 *  text:    abacadabrabracabracadabrabrabracad 
 *  match:           rab                         
 *
 *  % java RabinKarp bcara abacadabrabracabracadabrabrabracad
 *  pattern: bcara
 *  text:         abacadabrabracabracadabrabrabracad 
 *
 *  %  java RabinKarp rabrabracad abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern:                        rabrabracad
 *
 *  % java RabinKarp abacad abacadabrabracabracadabrabrabracad
 *  text:    abacadabrabracabracadabrabrabracad
 *  pattern: abacad
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . math . BigInteger ;
import  java . util . Random ;

/**
 *  The { @code  RabinKarp} class finds the first occurrence of a pattern string
 *  in a text string.
 *  <p>
 *  This implementation uses the Rabin-Karp algorithm.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/53substring">Section 5.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   RabinKarp   {
     private   String  pat ;        // the pattern  // needed only for Las Vegas
     private   long  patHash ;      // pattern hash value
     private   int  m ;             // pattern length
     private   long  q ;            // a large prime, small enough to avoid long overflow
     private   int  R ;             // radix
     private   long  RM ;           // R^(M-1) % Q

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pattern the pattern string
     *  @param  R the alphabet size
     */
     public   RabinKarp ( char []  pattern ,   int  R )   {
         this . pat  =   String . valueOf ( pattern );
         this . =  R ;         
         throw   new   UnsupportedOperationException ( "Operation not supported yet" );
     }

     /**
     * Preprocesses the pattern string.
     *
     *  @param  pat the pattern string
     */
     public   RabinKarp ( String  pat )   {
         this . pat  =  pat ;        // save pattern (needed only for Las Vegas)
        R  =   256 ;
        m  =  pat . length ();
        q  =  longRandomPrime ();

         // precompute R^(m-1) % q for use in removing leading digit
        RM  =   1 ;
         for   ( int  i  =   1 ;  i  <=  m - 1 ;  i ++ )
            RM  =   ( *  RM )   %  q ;
        patHash  =  hash ( pat ,  m );
     }  

     // Compute hash for key[0..m-1]. 
     private   long  hash ( String  key ,   int  m )   {  
         long  h  =   0 ;  
         for   ( int  j  =   0 ;  j  <  m ;  j ++ )  
            h  =   ( *  h  +  key . charAt ( j ))   %  q ;
         return  h ;
     }

     // Las Vegas version: does pat[] match txt[i..i-m+1] ?
     private   boolean  check ( String  txt ,   int  i )   {
         for   ( int  j  =   0 ;  j  <  m ;  j ++ )  
             if   ( pat . charAt ( j )   !=  txt . charAt ( +  j ))  
                 return   false ;  
         return   true ;
     }

     // Monte Carlo version: always return true
     // private boolean check(int i) {
     //    return true;
     //}
 
     /**
     * Returns the index of the first occurrrence of the pattern string
     * in the text string.
     *
     *  @param   txt the text string
     *  @return  the index of the first occurrence of the pattern string
     *         in the text string; n if no such match
     */
     public   int  search ( String  txt )   {
         int  n  =  txt . length ();  
         if   ( <  m )   return  n ;
         long  txtHash  =  hash ( txt ,  m );  

         // check for match at offset 0
         if   (( patHash  ==  txtHash )   &&  check ( txt ,   0 ))
             return   0 ;

         // check for hash match; if hash match, check for exact match
         for   ( int  i  =  m ;  i  <  n ;  i ++ )   {
             // Remove leading digit, add trailing digit, check for match. 
            txtHash  =   ( txtHash  +  q  -  RM * txt . charAt ( i - m )   %  q )   %  q ;  
            txtHash  =   ( txtHash * +  txt . charAt ( i ))   %  q ;  

             // match
             int  offset  =  i  -  m  +   1 ;
             if   (( patHash  ==  txtHash )   &&  check ( txt ,  offset ))
                 return  offset ;
         }

         // no match
         return  n ;
     }


     // a random 31-bit prime
     private   static   long  longRandomPrime ()   {
         BigInteger  prime  =   BigInteger . probablePrime ( 31 ,   new   Random ());
         return  prime . longValue ();
     }

     /** 
     * Takes a pattern string and an input string as command-line arguments;
     * searches for the pattern string in the text string; and prints
     * the first occurrence of the pattern string in the text string.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  pat  =  args [ 0 ];
         String  txt  =  args [ 1 ];

         RabinKarp  searcher  =   new   RabinKarp ( pat );
         int  offset  =  searcher . search ( txt );

         // print results
         StdOut . println ( "text:    "   +  txt );

         // from brute force search method 1
         StdOut . print ( "pattern: " );
         for   ( int  i  =   0 ;  i  <  offset ;  i ++ )
             StdOut . print ( " " );
         StdOut . println ( pat );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/RandomSeq.java

edu/princeton/cs/algs4/RandomSeq.java

/******************************************************************************
 *  Compilation:  javac RandomSeq.java
 *  Execution:    java RandomSeq n lo hi
 *  Dependencies: StdOut.java
 *
 *  Prints N numbers between lo and hi.
 *
 *  % java RandomSeq 5 100.0 200.0
 *  123.43
 *  153.13
 *  144.38
 *  155.18
 *  104.02
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  RandomSeq} class is a client that prints out a pseudorandom
 *  sequence of real numbers in a given range.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   RandomSeq   {  

     // this class should not be instantiated
     private   RandomSeq ()   {   }


     /**
     * Reads in two command-line arguments lo and hi and prints n uniformly
     * random real numbers in [lo, hi) to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // command-line arguments
         int  n  =   Integer . parseInt ( args [ 0 ]);

         // for backward compatibility with Intro to Programming in Java version of RandomSeq
         if   ( args . length  ==   1 )   {
             // generate and print n numbers between 0.0 and 1.0
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 double  x  =   StdRandom . uniform ();
                 StdOut . println ( x );
             }
         }

         else   if   ( args . length  ==   3 )   {
             double  lo  =   Double . parseDouble ( args [ 1 ]);
             double  hi  =   Double . parseDouble ( args [ 2 ]);

             // generate and print n numbers between lo and hi
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 double  x  =   StdRandom . uniform ( lo ,  hi );
                 StdOut . printf ( "%.2f\n" ,  x );
             }
         }

         else   {
             throw   new   IllegalArgumentException ( "Invalid number of arguments" );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/RectHV.java

edu/princeton/cs/algs4/RectHV.java

/******************************************************************************
 *  Compilation:  javac RectHV.java
 *  Execution:    none
 *  Dependencies: Point2D.java
 *
 *  Immutable data type for 2D axis-aligned rectangle.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  RectHV} class is an immutable data type to encapsulate a
 *  two-dimensional axis-aligned rectagle with real-value coordinates.
 *  The rectangle is <em>closed</em>—it includes the points on the boundary.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   final   class   RectHV   {
     private   final   double  xmin ,  ymin ;     // minimum x- and y-coordinates
     private   final   double  xmax ,  ymax ;     // maximum x- and y-coordinates

     /**
     * Initializes a new rectangle [<em>xmin</em>, <em>xmax</em>]
     * x [<em>ymin</em>, <em>ymax</em>].
     *
     *  @param   xmin the <em>x</em>-coordinate of the lower-left endpoint
     *  @param   xmax the <em>x</em>-coordinate of the upper-right endpoint
     *  @param   ymin the <em>y</em>-coordinate of the lower-left endpoint
     *  @param   ymax the <em>y</em>-coordinate of the upper-right endpoint
     *  @throws  IllegalArgumentException if any of { @code  xmin},
     *         { @code  xmax}, { @code  ymin}, or { @code  ymax}
     *         is { @code  Double.NaN}.
     *  @throws  IllegalArgumentException if { @code  xmax < xmin} or { @code  ymax < ymin}.
     */
     public   RectHV ( double  xmin ,   double  ymin ,   double  xmax ,   double  ymax )   {
         this . xmin  =  xmin ;
         this . ymin  =  ymin ;
         this . xmax  =  xmax ;
         this . ymax  =  ymax ;
         if   ( Double . isNaN ( xmin )   ||   Double . isNaN ( xmax ))   {
             throw   new   IllegalArgumentException ( "x-coordinate is NaN: "   +  toString ());
         }
         if   ( Double . isNaN ( ymin )   ||   Double . isNaN ( ymax ))   {
             throw   new   IllegalArgumentException ( "y-coordinate is NaN: "   +  toString ());
         }
         if   ( xmax  <  xmin )   {
             throw   new   IllegalArgumentException ( "xmax < xmin: "   +  toString ());
         }
         if   ( ymax  <  ymin )   {
             throw   new   IllegalArgumentException ( "ymax < ymin: "   +  toString ());
         }
     }

     /**
     * Returns the minimum <em>x</em>-coordinate of any point in this rectangle.
     *
     *  @return  the minimum <em>x</em>-coordinate of any point in this rectangle
     */
     public   double  xmin ()   {
         return  xmin ;
     }

     /**
     * Returns the maximum <em>x</em>-coordinate of any point in this rectangle.
     *
     *  @return  the maximum <em>x</em>-coordinate of any point in this rectangle
     */
     public   double  xmax ()   {
         return  xmax ;
     }

     /**
     * Returns the minimum <em>y</em>-coordinate of any point in this rectangle.
     *
     *  @return  the minimum <em>y</em>-coordinate of any point in this rectangle
     */
     public   double  ymin ()   {
         return  ymin ;
     }

     /**
     * Returns the maximum <em>y</em>-coordinate of any point in this rectangle.
     *
     *  @return  the maximum <em>y</em>-coordinate of any point in this rectangle
     */
     public   double  ymax ()   {
         return  ymax ;
     }

     /**
     * Returns the width of this rectangle.
     *
     *  @return  the width of this rectangle { @code  xmax - xmin}
     */
     public   double  width ()   {
         return  xmax  -  xmin ;
     }

     /**
     * Returns the height of this rectangle.
     *
     *  @return  the height of this rectangle { @code  ymax - ymin}
     */
     public   double  height ()   {
         return  ymax  -  ymin ;
     }

     /**
     * Returns true if the two rectangles intersect. This includes
     * <em>improper intersections</em> (at points on the boundary
     * of each rectangle) and <em>nested intersctions</em>
     * (when one rectangle is contained inside the other)
     *
     *  @param   that the other rectangle
     *  @return  { @code  true} if this rectangle intersect the argument
               rectangle at one or more points
     */
     public   boolean  intersects ( RectHV  that )   {
         return   this . xmax  >=  that . xmin  &&   this . ymax  >=  that . ymin
             &&  that . xmax  >=   this . xmin  &&  that . ymax  >=   this . ymin ;
     }

     /**
     * Returns true if this rectangle contain the point.
     *  @param   p the point
     *  @return  { @code  true} if this rectangle contain the point { @code  p},
               possibly at the boundary; { @code  false} otherwise
     */
     public   boolean  contains ( Point2D  p )   {
         return   ( p . x ()   >=  xmin )   &&   ( p . x ()   <=  xmax )
             &&   ( p . y ()   >=  ymin )   &&   ( p . y ()   <=  ymax );
     }

     /**
     * Returns the Euclidean distance between this rectangle and the point { @code  p}.
     *
     *  @param   p the point
     *  @return  the Euclidean distance between the point { @code  p} and the closest point
               on this rectangle; 0 if the point is contained in this rectangle
     */
     public   double  distanceTo ( Point2D  p )   {
         return   Math . sqrt ( this . distanceSquaredTo ( p ));
     }

     /**
     * Returns the square of the Euclidean distance between this rectangle and the point { @code  p}.
     *
     *  @param   p the point
     *  @return  the square of the Euclidean distance between the point { @code  p} and
     *         the closest point on this rectangle; 0 if the point is contained
     *         in this rectangle
     */
     public   double  distanceSquaredTo ( Point2D  p )   {
         double  dx  =   0.0 ,  dy  =   0.0 ;
         if        ( p . x ()   <  xmin )  dx  =  p . x ()   -  xmin ;
         else   if   ( p . x ()   >  xmax )  dx  =  p . x ()   -  xmax ;
         if        ( p . y ()   <  ymin )  dy  =  p . y ()   -  ymin ;
         else   if   ( p . y ()   >  ymax )  dy  =  p . y ()   -  ymax ;
         return  dx * dx  +  dy * dy ;
     }

     /**
     * Compares this rectangle to the specified rectangle.
     *
     *  @param   other the other rectangle
     *  @return  { @code  true} if this rectangle equals { @code  other};
     *         { @code  false} otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         RectHV  that  =   ( RectHV )  other ;
         if   ( this . xmin  !=  that . xmin )   return   false ;
         if   ( this . ymin  !=  that . ymin )   return   false ;
         if   ( this . xmax  !=  that . xmax )   return   false ;
         if   ( this . ymax  !=  that . ymax )   return   false ;
         return   true ;
     }

     /**
     * Returns an integer hash code for this rectangle.
     *  @return  an integer hash code for this rectangle
     */
    @ Override
     public   int  hashCode ()   {
         int  hash1  =   (( Double )  xmin ). hashCode ();
         int  hash2  =   (( Double )  ymin ). hashCode ();
         int  hash3  =   (( Double )  xmax ). hashCode ();
         int  hash4  =   (( Double )  ymax ). hashCode ();
         return   31 * ( 31 * ( 31 * hash1  +  hash2 )   +  hash3 )   +  hash4 ;
     }

     /**
     * Returns a string representation of this rectangle.
     *
     *  @return  a string representation of this rectangle, using the format
     *         { @code  [xmin, xmax] x [ymin, ymax]}
     */
    @ Override
     public   String  toString ()   {
         return   "["   +  xmin  +   ", "   +  xmax  +   "] x ["   +  ymin  +   ", "   +  ymax  +   "]" ;
     }

     /**
     * Draws this rectangle to standard draw.
     */
     public   void  draw ()   {
         StdDraw . line ( xmin ,  ymin ,  xmax ,  ymin );
         StdDraw . line ( xmax ,  ymin ,  xmax ,  ymax );
         StdDraw . line ( xmax ,  ymax ,  xmin ,  ymax );
         StdDraw . line ( xmin ,  ymax ,  xmin ,  ymin );
     }


}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/RedBlackBST.java

edu/princeton/cs/algs4/RedBlackBST.java

/******************************************************************************
 *  Compilation:  javac RedBlackBST.java
 *  Execution:    java RedBlackBST < input.txt
 *  Dependencies: StdIn.java StdOut.java  
 *  Data files:   https://algs4.cs.princeton.edu/33balanced/tinyST.txt  
 *    
 *  A symbol table implemented using a left-leaning red-black BST.
 *  This is the 2-3 version.
 *
 *  Note: commented out assertions because DrJava now enables assertions
 *        by default.
 *
 *  % more tinyST.txt
 *  S E A R C H E X A M P L E
 *  
 *  % java RedBlackBST < tinyST.txt
 *  A 8
 *  C 4
 *  E 12
 *  H 5
 *  L 11
 *  M 9
 *  P 10
 *  R 3
 *  S 0
 *  X 7
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . NoSuchElementException ;

/**
 *  The { @code  BST} class represents an ordered symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, and <em>ceiling</em>.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  <p>
 *  This implementation uses a <em>left-leaning red-black BST</em>. 
 *  The <em>put</em>, <em>get</em>, <em>contains</em>, <em>remove</em>,
 *  <em>minimum</em>, <em>maximum</em>, <em>ceiling</em>, <em>floor</em>,
 *  <em>rank</em>, and <em>select</em> operations each take
 *  &Theta;(log <em>n</em>) time in the worst case, where <em>n</em> is the
 *  number of key-value pairs in the symbol table.
 *  The <em>size</em>, and <em>is-empty</em> operations take &Theta;(1) time.
 *  The <em>keys</em> methods take
 *  <em>O</em>(log <em>n</em> + <em>m</em>) time, where <em>m</em> is
 *  the number of keys returned by the iterator.
 *  Construction takes &Theta;(1) time.
 *  <p>
 *  For alternative implementations of the symbol table API, see { @link  ST},
 *  { @link  BinarySearchST}, { @link  SequentialSearchST}, { @link  BST},
 *  { @link  SeparateChainingHashST}, { @link  LinearProbingHashST}, and
 *  { @link  AVLTreeST}.
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/33balanced">Section 3.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   RedBlackBST < Key   extends   Comparable < Key > ,   Value >   {

     private   static   final   boolean  RED    =   true ;
     private   static   final   boolean  BLACK  =   false ;

     private   Node  root ;       // root of the BST

     // BST helper node data type
     private   class   Node   {
         private   Key  key ;             // key
         private   Value  val ;           // associated data
         private   Node  left ,  right ;    // links to left and right subtrees
         private   boolean  color ;       // color of parent link
         private   int  size ;            // subtree count

         public   Node ( Key  key ,   Value  val ,   boolean  color ,   int  size )   {
             this . key  =  key ;
             this . val  =  val ;
             this . color  =  color ;
             this . size  =  size ;
         }
     }

     /**
     * Initializes an empty symbol table.
     */
     public   RedBlackBST ()   {
     }

    /***************************************************************************
    *  Node helper methods.
    ***************************************************************************/
     // is node x red; false if x is null ?
     private   boolean  isRed ( Node  x )   {
         if   ( ==   null )   return   false ;
         return  x . color  ==  RED ;
     }

     // number of node in subtree rooted at x; 0 if x is null
     private   int  size ( Node  x )   {
         if   ( ==   null )   return   0 ;
         return  x . size ;
     }  


     /**
     * Returns the number of key-value pairs in this symbol table.
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  size ( root );
     }

    /**
     * Is this symbol table empty?
     *  @return  { @code  true} if this symbol table is empty and { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  root  ==   null ;
     }


    /***************************************************************************
    *  Standard BST search.
    ***************************************************************************/

     /**
     * Returns the value associated with the given key.
     *  @param  key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *     and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         return  get ( root ,  key );
     }

     // value associated with the given key in subtree rooted at x; null if no such key
     private   Value  get ( Node  x ,   Key  key )   {
         while   ( !=   null )   {
             int  cmp  =  key . compareTo ( x . key );
             if        ( cmp  <   0 )  x  =  x . left ;
             else   if   ( cmp  >   0 )  x  =  x . right ;
             else                return  x . val ;
         }
         return   null ;
     }

     /**
     * Does this symbol table contain the given key?
     *  @param  key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *     { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         return  get ( key )   !=   null ;
     }

    /***************************************************************************
    *  Red-black tree insertion.
    ***************************************************************************/

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param  key the key
     *  @param  val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );
         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }

        root  =  put ( root ,  key ,  val );
        root . color  =  BLACK ;
         // assert check();
     }

     // insert the key-value pair in the subtree rooted at h
     private   Node  put ( Node  h ,   Key  key ,   Value  val )   {  
         if   ( ==   null )   return   new   Node ( key ,  val ,  RED ,   1 );

         int  cmp  =  key . compareTo ( h . key );
         if        ( cmp  <   0 )  h . left   =  put ( h . left ,   key ,  val );  
         else   if   ( cmp  >   0 )  h . right  =  put ( h . right ,  key ,  val );  
         else               h . val    =  val ;

         // fix-up any right-leaning links
         if   ( isRed ( h . right )   &&   ! isRed ( h . left ))       h  =  rotateLeft ( h );
         if   ( isRed ( h . left )    &&   isRed ( h . left . left ))  h  =  rotateRight ( h );
         if   ( isRed ( h . left )    &&   isRed ( h . right ))      flipColors ( h );
        h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;

         return  h ;
     }

    /***************************************************************************
    *  Red-black tree deletion.
    ***************************************************************************/

     /**
     * Removes the smallest key and associated value from the symbol table.
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMin ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "BST underflow" );

         // if both children of root are black, set root to red
         if   ( ! isRed ( root . left )   &&   ! isRed ( root . right ))
            root . color  =  RED ;

        root  =  deleteMin ( root );
         if   ( ! isEmpty ())  root . color  =  BLACK ;
         // assert check();
     }

     // delete the key-value pair with the minimum key rooted at h
     private   Node  deleteMin ( Node  h )   {  
         if   ( h . left  ==   null )
             return   null ;

         if   ( ! isRed ( h . left )   &&   ! isRed ( h . left . left ))
            h  =  moveRedLeft ( h );

        h . left  =  deleteMin ( h . left );
         return  balance ( h );
     }


     /**
     * Removes the largest key and associated value from the symbol table.
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   void  deleteMax ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "BST underflow" );

         // if both children of root are black, set root to red
         if   ( ! isRed ( root . left )   &&   ! isRed ( root . right ))
            root . color  =  RED ;

        root  =  deleteMax ( root );
         if   ( ! isEmpty ())  root . color  =  BLACK ;
         // assert check();
     }

     // delete the key-value pair with the maximum key rooted at h
     private   Node  deleteMax ( Node  h )   {  
         if   ( isRed ( h . left ))
            h  =  rotateRight ( h );

         if   ( h . right  ==   null )
             return   null ;

         if   ( ! isRed ( h . right )   &&   ! isRed ( h . right . left ))
            h  =  moveRedRight ( h );

        h . right  =  deleteMax ( h . right );

         return  balance ( h );
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).    
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {  
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );
         if   ( ! contains ( key ))   return ;

         // if both children of root are black, set root to red
         if   ( ! isRed ( root . left )   &&   ! isRed ( root . right ))
            root . color  =  RED ;

        root  =  delete ( root ,  key );
         if   ( ! isEmpty ())  root . color  =  BLACK ;
         // assert check();
     }

     // delete the key-value pair with the given key rooted at h
     private   Node  delete ( Node  h ,   Key  key )   {  
         // assert get(h, key) != null;

         if   ( key . compareTo ( h . key )   <   0 )    {
             if   ( ! isRed ( h . left )   &&   ! isRed ( h . left . left ))
                h  =  moveRedLeft ( h );
            h . left  =  delete ( h . left ,  key );
         }
         else   {
             if   ( isRed ( h . left ))
                h  =  rotateRight ( h );
             if   ( key . compareTo ( h . key )   ==   0   &&   ( h . right  ==   null ))
                 return   null ;
             if   ( ! isRed ( h . right )   &&   ! isRed ( h . right . left ))
                h  =  moveRedRight ( h );
             if   ( key . compareTo ( h . key )   ==   0 )   {
                 Node  x  =  min ( h . right );
                h . key  =  x . key ;
                h . val  =  x . val ;
                 // h.val = get(h.right, min(h.right).key);
                 // h.key = min(h.right).key;
                h . right  =  deleteMin ( h . right );
             }
             else  h . right  =  delete ( h . right ,  key );
         }
         return  balance ( h );
     }

    /***************************************************************************
    *  Red-black tree helper functions.
    ***************************************************************************/

     // make a left-leaning link lean to the right
     private   Node  rotateRight ( Node  h )   {
         // assert (h != null) && isRed(h.left);
         Node  x  =  h . left ;
        h . left  =  x . right ;
        x . right  =  h ;
        x . color  =  x . right . color ;
        x . right . color  =  RED ;
        x . size  =  h . size ;
        h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;
         return  x ;
     }

     // make a right-leaning link lean to the left
     private   Node  rotateLeft ( Node  h )   {
         // assert (h != null) && isRed(h.right);
         Node  x  =  h . right ;
        h . right  =  x . left ;
        x . left  =  h ;
        x . color  =  x . left . color ;
        x . left . color  =  RED ;
        x . size  =  h . size ;
        h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;
         return  x ;
     }

     // flip the colors of a node and its two children
     private   void  flipColors ( Node  h )   {
         // h must have opposite color of its two children
         // assert (h != null) && (h.left != null) && (h.right != null);
         // assert (!isRed(h) &&  isRed(h.left) &&  isRed(h.right))
         //    || (isRed(h)  && !isRed(h.left) && !isRed(h.right));
        h . color  =   ! h . color ;
        h . left . color  =   ! h . left . color ;
        h . right . color  =   ! h . right . color ;
     }

     // Assuming that h is red and both h.left and h.left.left
     // are black, make h.left or one of its children red.
     private   Node  moveRedLeft ( Node  h )   {
         // assert (h != null);
         // assert isRed(h) && !isRed(h.left) && !isRed(h.left.left);

        flipColors ( h );
         if   ( isRed ( h . right . left ))   {  
            h . right  =  rotateRight ( h . right );
            h  =  rotateLeft ( h );
            flipColors ( h );
         }
         return  h ;
     }

     // Assuming that h is red and both h.right and h.right.left
     // are black, make h.right or one of its children red.
     private   Node  moveRedRight ( Node  h )   {
         // assert (h != null);
         // assert isRed(h) && !isRed(h.right) && !isRed(h.right.left);
        flipColors ( h );
         if   ( isRed ( h . left . left ))   {  
            h  =  rotateRight ( h );
            flipColors ( h );
         }
         return  h ;
     }

     // restore red-black tree invariant
     private   Node  balance ( Node  h )   {
         // assert (h != null);

         if   ( isRed ( h . right ))                       h  =  rotateLeft ( h );
         if   ( isRed ( h . left )   &&  isRed ( h . left . left ))  h  =  rotateRight ( h );
         if   ( isRed ( h . left )   &&  isRed ( h . right ))      flipColors ( h );

        h . size  =  size ( h . left )   +  size ( h . right )   +   1 ;
         return  h ;
     }


    /***************************************************************************
    *  Utility functions.
    ***************************************************************************/

     /**
     * Returns the height of the BST (for debugging).
     *  @return  the height of the BST (a 1-node tree has height 0)
     */
     public   int  height ()   {
         return  height ( root );
     }
     private   int  height ( Node  x )   {
         if   ( ==   null )   return   - 1 ;
         return   1   +   Math . max ( height ( x . left ),  height ( x . right ));
     }

    /***************************************************************************
    *  Ordered symbol table methods.
    ***************************************************************************/

     /**
     * Returns the smallest key in the symbol table.
     *  @return  the smallest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls min() with empty symbol table" );
         return  min ( root ). key ;
     }  

     // the smallest key in subtree rooted at x; null if no such key
     private   Node  min ( Node  x )   {  
         // assert x != null;
         if   ( x . left  ==   null )   return  x ;  
         else                  return  min ( x . left );  
     }  

     /**
     * Returns the largest key in the symbol table.
     *  @return  the largest key in the symbol table
     *  @throws  NoSuchElementException if the symbol table is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls max() with empty symbol table" );
         return  max ( root ). key ;
     }  

     // the largest key in the subtree rooted at x; null if no such key
     private   Node  max ( Node  x )   {  
         // assert x != null;
         if   ( x . right  ==   null )   return  x ;  
         else                   return  max ( x . right );  
     }  


     /**
     * Returns the largest key in the symbol table less than or equal to { @code  key}.
     *  @param  key the key
     *  @return  the largest key in the symbol table less than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls floor() with empty symbol table" );
         Node  x  =  floor ( root ,  key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );
         else             return  x . key ;
     }     

     // the largest key in the subtree rooted at x less than or equal to the given key
     private   Node  floor ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  <   0 )    return  floor ( x . left ,  key );
         Node  t  =  floor ( x . right ,  key );
         if   ( !=   null )   return  t ;  
         else             return  x ;
     }

     /**
     * Returns the smallest key in the symbol table greater than or equal to { @code  key}.
     *  @param  key the key
     *  @return  the smallest key in the symbol table greater than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls ceiling() with empty symbol table" );
         Node  x  =  ceiling ( root ,  key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to ceiling() is too small" );
         else             return  x . key ;   
     }

     // the smallest key in the subtree rooted at x greater than or equal to the given key
     private   Node  ceiling ( Node  x ,   Key  key )   {   
         if   ( ==   null )   return   null ;
         int  cmp  =  key . compareTo ( x . key );
         if   ( cmp  ==   0 )   return  x ;
         if   ( cmp  >   0 )    return  ceiling ( x . right ,  key );
         Node  t  =  ceiling ( x . left ,  key );
         if   ( !=   null )   return  t ;  
         else             return  x ;
     }

     /**
     * Return the key in the symbol table whose rank is { @code  k}.
     * This is the (k+1)st smallest key in the symbol table. 
     *
     *  @param   k the order statistic
     *  @return  the key in the symbol table of rank { @code  k}
     *  @throws  IllegalArgumentException unless { @code  k} is between 0 and
     *        <em>n</em>–1
     */
     public   Key  select ( int  k )   {
         if   ( <   0   ||  k  >=  size ())   {
             throw   new   IllegalArgumentException ( "argument to select() is invalid: "   +  k );
         }
         Node  x  =  select ( root ,  k );
         return  x . key ;
     }

     // the key of rank k in the subtree rooted at x
     private   Node  select ( Node  x ,   int  k )   {
         // assert x != null;
         // assert k >= 0 && k < size(x);
         int  t  =  size ( x . left );  
         if        ( >  k )   return  select ( x . left ,   k );  
         else   if   ( <  k )   return  select ( x . right ,  k - t - 1 );  
         else              return  x ;  
     }  

     /**
     * Return the number of keys in the symbol table strictly less than { @code  key}.
     *  @param  key the key
     *  @return  the number of keys in the symbol table strictly less than { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   int  rank ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to rank() is null" );
         return  rank ( key ,  root );
     }  

     // number of keys less than key in the subtree rooted at x
     private   int  rank ( Key  key ,   Node  x )   {
         if   ( ==   null )   return   0 ;  
         int  cmp  =  key . compareTo ( x . key );  
         if        ( cmp  <   0 )   return  rank ( key ,  x . left );  
         else   if   ( cmp  >   0 )   return   1   +  size ( x . left )   +  rank ( key ,  x . right );  
         else                return  size ( x . left );  
     }  

    /***************************************************************************
    *  Range count and range search.
    ***************************************************************************/

     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *  @return  all keys in the symbol table as an { @code  Iterable}
     */
     public   Iterable < Key >  keys ()   {
         if   ( isEmpty ())   return   new   Queue < Key > ();
         return  keys ( min (),  max ());
     }

     /**
     * Returns all keys in the symbol table in the given range,
     * as an { @code  Iterable}.
     *
     *  @param   lo minimum endpoint
     *  @param   hi maximum endpoint
     *  @return  all keys in the symbol table between { @code  lo} 
     *    (inclusive) and { @code  hi} (inclusive) as an { @code  Iterable}
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *    is { @code  null}
     */
     public   Iterable < Key >  keys ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to keys() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to keys() is null" );

         Queue < Key >  queue  =   new   Queue < Key > ();
         // if (isEmpty() || lo.compareTo(hi) > 0) return queue;
        keys ( root ,  queue ,  lo ,  hi );
         return  queue ;
     }  

     // add the keys between lo and hi in the subtree rooted at x
     // to the queue
     private   void  keys ( Node  x ,   Queue < Key >  queue ,   Key  lo ,   Key  hi )   {  
         if   ( ==   null )   return ;  
         int  cmplo  =  lo . compareTo ( x . key );  
         int  cmphi  =  hi . compareTo ( x . key );  
         if   ( cmplo  <   0 )  keys ( x . left ,  queue ,  lo ,  hi );  
         if   ( cmplo  <=   0   &&  cmphi  >=   0 )  queue . enqueue ( x . key );  
         if   ( cmphi  >   0 )  keys ( x . right ,  queue ,  lo ,  hi );  
     }  

     /**
     * Returns the number of keys in the symbol table in the given range.
     *
     *  @param   lo minimum endpoint
     *  @param   hi maximum endpoint
     *  @return  the number of keys in the symbol table between { @code  lo} 
     *    (inclusive) and { @code  hi} (inclusive)
     *  @throws  IllegalArgumentException if either { @code  lo} or { @code  hi}
     *    is { @code  null}
     */
     public   int  size ( Key  lo ,   Key  hi )   {
         if   ( lo  ==   null )   throw   new   IllegalArgumentException ( "first argument to size() is null" );
         if   ( hi  ==   null )   throw   new   IllegalArgumentException ( "second argument to size() is null" );

         if   ( lo . compareTo ( hi )   >   0 )   return   0 ;
         if   ( contains ( hi ))   return  rank ( hi )   -  rank ( lo )   +   1 ;
         else                return  rank ( hi )   -  rank ( lo );
     }


    /***************************************************************************
    *  Check integrity of red-black tree data structure.
    ***************************************************************************/
     private   boolean  check ()   {
         if   ( ! isBST ())              StdOut . println ( "Not in symmetric order" );
         if   ( ! isSizeConsistent ())   StdOut . println ( "Subtree counts not consistent" );
         if   ( ! isRankConsistent ())   StdOut . println ( "Ranks not consistent" );
         if   ( ! is23 ())               StdOut . println ( "Not a 2-3 tree" );
         if   ( ! isBalanced ())         StdOut . println ( "Not balanced" );
         return  isBST ()   &&  isSizeConsistent ()   &&  isRankConsistent ()   &&  is23 ()   &&  isBalanced ();
     }

     // does this binary tree satisfy symmetric order?
     // Note: this test also ensures that data structure is a binary tree since order is strict
     private   boolean  isBST ()   {
         return  isBST ( root ,   null ,   null );
     }

     // is the tree rooted at x a BST with all keys strictly between min and max
     // (if min or max is null, treat as empty constraint)
     // Credit: Bob Dondero's elegant solution
     private   boolean  isBST ( Node  x ,   Key  min ,   Key  max )   {
         if   ( ==   null )   return   true ;
         if   ( min  !=   null   &&  x . key . compareTo ( min )   <=   0 )   return   false ;
         if   ( max  !=   null   &&  x . key . compareTo ( max )   >=   0 )   return   false ;
         return  isBST ( x . left ,  min ,  x . key )   &&  isBST ( x . right ,  x . key ,  max );
     }  

     // are the size fields correct?
     private   boolean  isSizeConsistent ()   {   return  isSizeConsistent ( root );   }
     private   boolean  isSizeConsistent ( Node  x )   {
         if   ( ==   null )   return   true ;
         if   ( x . size  !=  size ( x . left )   +  size ( x . right )   +   1 )   return   false ;
         return  isSizeConsistent ( x . left )   &&  isSizeConsistent ( x . right );
     }  

     // check that ranks are consistent
     private   boolean  isRankConsistent ()   {
         for   ( int  i  =   0 ;  i  <  size ();  i ++ )
             if   ( !=  rank ( select ( i )))   return   false ;
         for   ( Key  key  :  keys ())
             if   ( key . compareTo ( select ( rank ( key )))   !=   0 )   return   false ;
         return   true ;
     }

     // Does the tree have no red right links, and at most one (left)
     // red links in a row on any path?
     private   boolean  is23 ()   {   return  is23 ( root );   }
     private   boolean  is23 ( Node  x )   {
         if   ( ==   null )   return   true ;
         if   ( isRed ( x . right ))   return   false ;
         if   ( !=  root  &&  isRed ( x )   &&  isRed ( x . left ))
             return   false ;
         return  is23 ( x . left )   &&  is23 ( x . right );
     }  

     // do all paths from root to leaf have same number of black edges?
     private   boolean  isBalanced ()   {  
         int  black  =   0 ;       // number of black links on path from root to min
         Node  x  =  root ;
         while   ( !=   null )   {
             if   ( ! isRed ( x ))  black ++ ;
            x  =  x . left ;
         }
         return  isBalanced ( root ,  black );
     }

     // does every path from the root to a leaf have the given number of black links?
     private   boolean  isBalanced ( Node  x ,   int  black )   {
         if   ( ==   null )   return  black  ==   0 ;
         if   ( ! isRed ( x ))  black -- ;
         return  isBalanced ( x . left ,  black )   &&  isBalanced ( x . right ,  black );
     }  


     /**
     * Unit tests the { @code  RedBlackBST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         RedBlackBST < String ,   Integer >  st  =   new   RedBlackBST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }
         StdOut . println ();
         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
         StdOut . println ();
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayBag.java

edu/princeton/cs/algs4/ResizingArrayBag.java

/******************************************************************************
 *  Compilation:  javac ResizingArrayBag.java
 *  Execution:    java ResizingArrayBag
 *  Dependencies: StdIn.java StdOut.java
 *  
 *  Bag implementation with a resizing array.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  ResizingArrayBag} class represents a bag (or multiset) of 
 *  generic items. It supports insertion and iterating over the 
 *  items in arbitrary order.
 *  <p>
 *  This implementation uses a resizing array.
 *  See { @link  LinkedBag} for a version that uses a singly linked list.
 *  The <em>add</em> operation takes constant amortized time; the
 *  <em>isEmpty</em>, and <em>size</em> operations
 *  take constant time. Iteration takes time proportional to the number of items.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ResizingArrayBag < Item >   implements   Iterable < Item >   {
     private   Item []  a ;           // array of items
     private   int  n ;              // number of elements on bag

     /**
     * Initializes an empty bag.
     */
     public   ResizingArrayBag ()   {
        a  =   ( Item [])   new   Object [ 2 ];
        n  =   0 ;
     }

     /**
     * Is this bag empty?
     *  @return  true if this bag is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Returns the number of items in this bag.
     *  @return  the number of items in this bag
     */
     public   int  size ()   {
         return  n ;
     }

     // resize the underlying array holding the elements
     private   void  resize ( int  capacity )   {
         assert  capacity  >=  n ;
         Item []  temp  =   ( Item [])   new   Object [ capacity ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            temp [ i ]   =  a [ i ];
        a  =  temp ;
     }

     /**
     * Adds the item to this bag.
     *  @param  item the item to add to this bag
     */
     public   void  add ( Item  item )   {
         if   ( ==  a . length )  resize ( 2 * a . length );      // double size of array if necessary
        a [ n ++ ]   =  item ;                              // add item
     }


     /**
     * Returns an iterator that iterates over the items in the bag in arbitrary order.
     *  @return  an iterator that iterates over the items in the bag in arbitrary order
     */
     public   Iterator < Item >  iterator ()   {
         return   new   ArrayIterator ();
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ArrayIterator   implements   Iterator < Item >   {
         private   int  i  =   0 ;
         public   boolean  hasNext ()    {   return  i  <  n ;                                 }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  a [ i ++ ];
         }
     }

     /**
     * Unit tests the { @code  ResizingArrayBag} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         ResizingArrayBag < String >  bag  =   new   ResizingArrayBag < String > ();
        bag . add ( "Hello" );
        bag . add ( "World" );
        bag . add ( "how" );
        bag . add ( "are" );
        bag . add ( "you" );

         for   ( String  s  :  bag )
             StdOut . println ( s );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayQueue.java

edu/princeton/cs/algs4/ResizingArrayQueue.java

/******************************************************************************
 *  Compilation:  javac ResizingArrayQueue.java
 *  Execution:    java ResizingArrayQueue < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt  
 *  
 *  Queue implementation with a resizing array.
 *
 *  % java ResizingArrayQueue < tobe.txt 
 *  to be or not to be (2 left on queue)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  ResizingArrayQueue} class represents a first-in-first-out (FIFO)
 *  queue of generic items.
 *  It supports the usual <em>enqueue</em> and <em>dequeue</em>
 *  operations, along with methods for peeking at the first item,
 *  testing if the queue is empty, and iterating through
 *  the items in FIFO order.
 *  <p>
 *  This implementation uses a resizing array, which double the underlying array
 *  when it is full and halves the underlying array when it is one-quarter full.
 *  The <em>enqueue</em> and <em>dequeue</em> operations take constant amortized time.
 *  The <em>size</em>, <em>peek</em>, and <em>is-empty</em> operations takes
 *  constant time in the worst case. 
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ResizingArrayQueue < Item >   implements   Iterable < Item >   {
     private   Item []  q ;         // queue elements
     private   int  n ;            // number of elements on queue
     private   int  first ;        // index of first element of queue
     private   int  last ;         // index of next available slot


     /**
     * Initializes an empty queue.
     */
     public   ResizingArrayQueue ()   {
        q  =   ( Item [])   new   Object [ 2 ];
        n  =   0 ;
        first  =   0 ;
        last  =   0 ;
     }

     /**
     * Is this queue empty?
     *  @return  true if this queue is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Returns the number of items in this queue.
     *  @return  the number of items in this queue
     */
     public   int  size ()   {
         return  n ;
     }

     // resize the underlying array
     private   void  resize ( int  capacity )   {
         assert  capacity  >=  n ;
         Item []  temp  =   ( Item [])   new   Object [ capacity ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            temp [ i ]   =  q [( first  +  i )   %  q . length ];
         }
        q  =  temp ;
        first  =   0 ;
        last   =  n ;
     }

     /**
     * Adds the item to this queue.
     *  @param  item the item to add
     */
     public   void  enqueue ( Item  item )   {
         // double size of array if necessary and recopy to front of array
         if   ( ==  q . length )  resize ( 2 * q . length );     // double size of array if necessary
        q [ last ++ ]   =  item ;                          // add item
         if   ( last  ==  q . length )  last  =   0 ;            // wrap-around
        n ++ ;
     }

     /**
     * Removes and returns the item on this queue that was least recently added.
     *  @return  the item on this queue that was least recently added
     *  @throws  java.util.NoSuchElementException if this queue is empty
     */
     public   Item  dequeue ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         Item  item  =  q [ first ];
        q [ first ]   =   null ;                              // to avoid loitering
        n -- ;
        first ++ ;
         if   ( first  ==  q . length )  first  =   0 ;             // wrap-around
         // shrink size of array if necessary
         if   ( >   0   &&  n  ==  q . length / 4 )  resize ( q . length / 2 );  
         return  item ;
     }

     /**
     * Returns the item least recently added to this queue.
     *  @return  the item least recently added to this queue
     *  @throws  java.util.NoSuchElementException if this queue is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Queue underflow" );
         return  q [ first ];
     }


     /**
     * Returns an iterator that iterates over the items in this queue in FIFO order.
     *  @return  an iterator that iterates over the items in this queue in FIFO order
     */
     public   Iterator < Item >  iterator ()   {
         return   new   ArrayIterator ();
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ArrayIterator   implements   Iterator < Item >   {
         private   int  i  =   0 ;
         public   boolean  hasNext ()    {   return  i  <  n ;                                 }
         public   void  remove ()        {   throw   new   UnsupportedOperationException ();    }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  q [( +  first )   %  q . length ];
            i ++ ;
             return  item ;
         }
     }

    /**
     * Unit tests the { @code  ResizingArrayQueue} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         ResizingArrayQueue < String >  queue  =   new   ResizingArrayQueue < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))  queue . enqueue ( item );
             else   if   ( ! queue . isEmpty ())   StdOut . print ( queue . dequeue ()   +   " " );
         }
         StdOut . println ( "("   +  queue . size ()   +   " left on queue)" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ResizingArrayStack.java

edu/princeton/cs/algs4/ResizingArrayStack.java

/******************************************************************************
 *  Compilation:  javac ResizingArrayStack.java
 *  Execution:    java ResizingArrayStack < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt
 *  
 *  Stack implementation with a resizing array.
 *
 *  % more tobe.txt 
 *  to be or not to - be - - that - - - is
 *
 *  % java ResizingArrayStack < tobe.txt
 *  to be not that or be (2 left on stack)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;

/**
 *  The { @code  ResizingArrayStack} class represents a last-in-first-out (LIFO) stack
 *  of generic items.
 *  It supports the usual <em>push</em> and <em>pop</em> operations, along with methods
 *  for peeking at the top item, testing if the stack is empty, and iterating through
 *  the items in LIFO order.
 *  <p>
 *  This implementation uses a resizing array, which double the underlying array
 *  when it is full and halves the underlying array when it is one-quarter full.
 *  The <em>push</em> and <em>pop</em> operations take constant amortized time.
 *  The <em>size</em>, <em>peek</em>, and <em>is-empty</em> operations takes
 *  constant time in the worst case. 
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ResizingArrayStack < Item >   implements   Iterable < Item >   {
     private   Item []  a ;           // array of items
     private   int  n ;              // number of elements on stack


     /**
     * Initializes an empty stack.
     */
     public   ResizingArrayStack ()   {
        a  =   ( Item [])   new   Object [ 2 ];
        n  =   0 ;
     }

     /**
     * Is this stack empty?
     *  @return  true if this stack is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  n  ==   0 ;
     }

     /**
     * Returns the number of items in the stack.
     *  @return  the number of items in the stack
     */
     public   int  size ()   {
         return  n ;
     }


     // resize the underlying array holding the elements
     private   void  resize ( int  capacity )   {
         assert  capacity  >=  n ;

         // textbook implementation
         Item []  temp  =   ( Item [])   new   Object [ capacity ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            temp [ i ]   =  a [ i ];
         }
        a  =  temp ;

        // alternative implementation
        // a = java.util.Arrays.copyOf(a, capacity);
     }



     /**
     * Adds the item to this stack.
     *  @param  item the item to add
     */
     public   void  push ( Item  item )   {
         if   ( ==  a . length )  resize ( 2 * a . length );      // double size of array if necessary
        a [ n ++ ]   =  item ;                              // add item
     }

     /**
     * Removes and returns the item most recently added to this stack.
     *  @return  the item most recently added
     *  @throws  java.util.NoSuchElementException if this stack is empty
     */
     public   Item  pop ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         Item  item  =  a [ n - 1 ];
        a [ n - 1 ]   =   null ;                                // to avoid loitering
        n -- ;
         // shrink size of array if necessary
         if   ( >   0   &&  n  ==  a . length / 4 )  resize ( a . length / 2 );
         return  item ;
     }


     /**
     * Returns (but does not remove) the item most recently added to this stack.
     *  @return  the item most recently added to this stack
     *  @throws  java.util.NoSuchElementException if this stack is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         return  a [ n - 1 ];
     }

     /**
     * Returns an iterator to this stack that iterates through the items in LIFO order.
     *  @return  an iterator to this stack that iterates through the items in LIFO order.
     */
     public   Iterator < Item >  iterator ()   {
         return   new   ReverseArrayIterator ();
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ReverseArrayIterator   implements   Iterator < Item >   {
         private   int  i ;

         public   ReverseArrayIterator ()   {
            i  =  n - 1 ;
         }

         public   boolean  hasNext ()   {
             return  i  >=   0 ;
         }

         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             return  a [ i -- ];
         }
     }


     /**
     * Unit tests the { @code  Stack} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         ResizingArrayStack < String >  stack  =   new   ResizingArrayStack < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))  stack . push ( item );
             else   if   ( ! stack . isEmpty ())   StdOut . print ( stack . pop ()   +   " " );
         }
         StdOut . println ( "("   +  stack . size ()   +   " left on stack)" );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/RunLength.java

edu/princeton/cs/algs4/RunLength.java

/******************************************************************************
 *  Compilation:  javac RunLength.java
 *  Execution:    java RunLength - < input.txt   (compress)
 *  Execution:    java RunLength + < input.txt   (expand)
 *  Dependencies: BinaryIn.java BinaryOut.java
 *  Data files:   https://algs4.cs.princeton.edu/55compression/4runs.bin
 *                https://algs4.cs.princeton.edu/55compression/q32x48.bin
 *                https://algs4.cs.princeton.edu/55compression/q64x96.bin
 *
 *  Compress or expand binary input from standard input using
 *  run-length encoding.
 *
 *  % java BinaryDump 40 < 4runs.bin 
 *  0000000000000001111111000000011111111111
 *  40 bits
 *
 *  This has runs of 15 0s, 7 1s, 7 0s, and 11 1s.
 *
 *  % java RunLength - < 4runs.bin | java HexDump
 *  0f 07 07 0b
 *  4 bytes
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  RunLength} class provides static methods for compressing
 *  and expanding a binary input using run-length coding with 8-bit
 *  run lengths.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/55compression">Section 5.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   RunLength   {
     private   static   final   int  R     =   256 ;
     private   static   final   int  LG_R  =   8 ;

     // Do not instantiate.
     private   RunLength ()   {   }

     /**
     * Reads a sequence of bits from standard input (that are encoded
     * using run-length encoding with 8-bit run lengths); decodes them;
     * and writes the results to standard output.
     */
     public   static   void  expand ()   {  
         boolean  b  =   false ;  
         while   ( ! BinaryStdIn . isEmpty ())   {
             int  run  =   BinaryStdIn . readInt ( LG_R );
             for   ( int  i  =   0 ;  i  <  run ;  i ++ )
                 BinaryStdOut . write ( b );
            b  =   ! b ;
         }
         BinaryStdOut . close ();
     }

     /**
     * Reads a sequence of bits from standard input; compresses
     * them using run-length coding with 8-bit run lengths; and writes the
     * results to standard output.
     */
     public   static   void  compress ()   {  
         char  run  =   0 ;  
         boolean  old  =   false ;
         while   ( ! BinaryStdIn . isEmpty ())   {  
             boolean  b  =   BinaryStdIn . readBoolean ();
             if   ( !=  old )   {
                 BinaryStdOut . write ( run ,  LG_R );
                run  =   1 ;
                old  =   ! old ;
             }
             else   {  
                 if   ( run  ==  R - 1 )   {  
                     BinaryStdOut . write ( run ,  LG_R );
                    run  =   0 ;
                     BinaryStdOut . write ( run ,  LG_R );
                 }
                run ++ ;
             }  
         }  
         BinaryStdOut . write ( run ,  LG_R );
         BinaryStdOut . close ();
     }


     /**
     * Sample client that calls { @code  compress()} if the command-line
     * argument is "-" an { @code  expand()} if it is "+".
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         if        ( args [ 0 ]. equals ( "-" ))  compress ();
         else   if   ( args [ 0 ]. equals ( "+" ))  expand ();
         else   throw   new   IllegalArgumentException ( "Illegal command line argument" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SegmentTree.java

edu/princeton/cs/algs4/SegmentTree.java

/******************************************************************************
 *  Compilation:  javac SegmentTree.java
 *  Execution:    java SegmentTree
 *  
 *  A segment tree data structure.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 * The { @code  SegmentTree} class is an structure for efficient search of cummulative data.
 * It performs  Range Minimum Query and Range Sum Query in O(log(n)) time.
 * It can be easily customizable to support Range Max Query, Range Multiplication Query etc.
 * <p>
 * Also it has been develop with  { @code  LazyPropagation} for range updates, which means
 * when you perform update operations over a range, the update process affects the least nodes as possible
 * so that the bigger the range you want to update the less time it consumes to update it. Eventually those changes will be propagated
 * to the children and the whole array will be up to date.
 * <p>
 * Example:
 * <p>
 * SegmentTreeHeap st = new SegmentTreeHeap(new Integer[]{1,3,4,2,1, -2, 4});
 * st.update(0,3, 1)
 * In the above case only the node that represents the range [0,3] will be updated (and not their children) so in this case
 * the update task will be less than n*log(n)
 *
 * Memory usage:  O(n)
 *
 *  @author  Ricardo Pacheco 
 */
public   class   SegmentTree   {

     private   Node []  heap ;
     private   int []  array ;
     private   int  size ;

     /**
     * Time-Complexity:  O(n*log(n))
     *
     *  @param  array the Initialization array
     */
     public   SegmentTree ( int []  array )   {
         this . array  =   Arrays . copyOf ( array ,  array . length );
         //The max size of this array is about 2 * 2 ^ log2(n) + 1
        size  =   ( int )   ( 2   *   Math . pow ( 2.0 ,   Math . floor (( Math . log (( double )  array . length )   /   Math . log ( 2.0 ))   +   1 )));
        heap  =   new   Node [ size ];
        build ( 1 ,   0 ,  array . length );
     }


     public   int  size ()   {
         return  array . length ;
     }

     //Initialize the Nodes of the Segment tree
     private   void  build ( int  v ,   int  from ,   int  size )   {
        heap [ v ]   =   new   Node ();
        heap [ v ]. from  =  from ;
        heap [ v ]. to  =  from  +  size  -   1 ;

         if   ( size  ==   1 )   {
            heap [ v ]. sum  =  array [ from ];
            heap [ v ]. min  =  array [ from ];
         }   else   {
             //Build childs
            build ( 2   *  v ,  from ,  size  /   2 );
            build ( 2   *  v  +   1 ,  from  +  size  /   2 ,  size  -  size  /   2 );

            heap [ v ]. sum  =  heap [ 2   *  v ]. sum  +  heap [ 2   *  v  +   1 ]. sum ;
             //min = min of the children
            heap [ v ]. min  =   Math . min ( heap [ 2   *  v ]. min ,  heap [ 2   *  v  +   1 ]. min );
         }
     }

     /**
     * Range Sum Query
     *
     * Time-Complexity: O(log(n))
     *
     *  @param   from from index
     *  @param   to to index
     *  @return  sum
     */
     public   int  rsq ( int  from ,   int  to )   {
         return  rsq ( 1 ,  from ,  to );
     }

     private   int  rsq ( int  v ,   int  from ,   int  to )   {
         Node  n  =  heap [ v ];

         //If you did a range update that contained this node, you can infer the Sum without going down the tree
         if   ( n . pendingVal  !=   null   &&  contains ( n . from ,  n . to ,  from ,  to ))   {
             return   ( to  -  from  +   1 )   *  n . pendingVal ;
         }

         if   ( contains ( from ,  to ,  n . from ,  n . to ))   {
             return  heap [ v ]. sum ;
         }

         if   ( intersects ( from ,  to ,  n . from ,  n . to ))   {
            propagate ( v );
             int  leftSum  =  rsq ( 2   *  v ,  from ,  to );
             int  rightSum  =  rsq ( 2   *  v  +   1 ,  from ,  to );

             return  leftSum  +  rightSum ;
         }

         return   0 ;
     }

     /**
     * Range Min Query
     * 
     * Time-Complexity: O(log(n))
     *
     *  @param   from from index
     *  @param   to to index
     *  @return  min
     */
     public   int  rMinQ ( int  from ,   int  to )   {
         return  rMinQ ( 1 ,  from ,  to );
     }

     private   int  rMinQ ( int  v ,   int  from ,   int  to )   {
         Node  n  =  heap [ v ];


         //If you did a range update that contained this node, you can infer the Min value without going down the tree
         if   ( n . pendingVal  !=   null   &&  contains ( n . from ,  n . to ,  from ,  to ))   {
             return  n . pendingVal ;
         }

         if   ( contains ( from ,  to ,  n . from ,  n . to ))   {
             return  heap [ v ]. min ;
         }

         if   ( intersects ( from ,  to ,  n . from ,  n . to ))   {
            propagate ( v );
             int  leftMin  =  rMinQ ( 2   *  v ,  from ,  to );
             int  rightMin  =  rMinQ ( 2   *  v  +   1 ,  from ,  to );

             return   Math . min ( leftMin ,  rightMin );
         }

         return   Integer . MAX_VALUE ;
     }


     /**
     * Range Update Operation.
     * With this operation you can update either one position or a range of positions with a given number.
     * The update operations will update the less it can to update the whole range (Lazy Propagation).
     * The values will be propagated lazily from top to bottom of the segment tree.
     * This behavior is really useful for updates on portions of the array
     * <p>
     * Time-Complexity: O(log(n))
     *
     *  @param  from  from index
     *  @param  to    to index
     *  @param  value value
     */
     public   void  update ( int  from ,   int  to ,   int  value )   {
        update ( 1 ,  from ,  to ,  value );
     }

     private   void  update ( int  v ,   int  from ,   int  to ,   int  value )   {

         //The Node of the heap tree represents a range of the array with bounds: [n.from, n.to]
         Node  n  =  heap [ v ];

         /**
         * If the updating-range contains the portion of the current Node  We lazily update it.
         * This means We do NOT update each position of the vector, but update only some temporal
         * values into the Node; such values into the Node will be propagated down to its children only when they need to.
         */
         if   ( contains ( from ,  to ,  n . from ,  n . to ))   {
            change ( n ,  value );
         }

         if   ( n . size ()   ==   1 )   return ;

         if   ( intersects ( from ,  to ,  n . from ,  n . to ))   {
             /**
             * Before keeping going down to the tree We need to propagate the
             * the values that have been temporally/lazily saved into this Node to its children
             * So that when We visit them the values  are properly updated
             */
            propagate ( v );

            update ( 2   *  v ,  from ,  to ,  value );
            update ( 2   *  v  +   1 ,  from ,  to ,  value );

            n . sum  =  heap [ 2   *  v ]. sum  +  heap [ 2   *  v  +   1 ]. sum ;
            n . min  =   Math . min ( heap [ 2   *  v ]. min ,  heap [ 2   *  v  +   1 ]. min );
         }
     }

     //Propagate temporal values to children
     private   void  propagate ( int  v )   {
         Node  n  =  heap [ v ];

         if   ( n . pendingVal  !=   null )   {
            change ( heap [ 2   *  v ],  n . pendingVal );
            change ( heap [ 2   *  v  +   1 ],  n . pendingVal );
            n . pendingVal  =   null ;   //unset the pending propagation value
         }
     }

     //Save the temporal values that will be propagated lazily
     private   void  change ( Node  n ,   int  value )   {
        n . pendingVal  =  value ;
        n . sum  =  n . size ()   *  value ;
        n . min  =  value ;
        array [ n . from ]   =  value ;

     }

     //Test if the range1 contains range2
     private   boolean  contains ( int  from1 ,   int  to1 ,   int  from2 ,   int  to2 )   {
         return  from2  >=  from1  &&  to2  <=  to1 ;
     }

     //check inclusive intersection, test if range1[from1, to1] intersects range2[from2, to2]
     private   boolean  intersects ( int  from1 ,   int  to1 ,   int  from2 ,   int  to2 )   {
         return  from1  <=  from2  &&  to1  >=  from2    //  (.[..)..] or (.[...]..)
                 ||  from1  >=  from2  &&  from1  <=  to2 ;   // [.(..]..) or [..(..)..
     }

     //The Node class represents a partition range of the array.
     static   class   Node   {
         int  sum ;
         int  min ;
         //Here We store the value that will be propagated lazily
         Integer  pendingVal  =   null ;
         int  from ;
         int  to ;

         int  size ()   {
             return  to  -  from  +   1 ;
         }

     }

     /**
     * Read the following commands:
     * init n v     Initializes the array of size n with all v's
     * set a b c... Initializes the array  with [a, b, c ...]
     * rsq a b      Range Sum Query for the range [a, b]
     * rmq a b      Range Min Query for the range [a, b]
     * up  a b v    Update the [a,b] portion of the array with value v.
     * exit
     * <p>
     * Example:
     * init
     * set 1 2 3 4 5 6
     * rsq 1 3
     * Sum from 1 to 3 = 6
     * rmq 1 3
     * Min from 1 to 3 = 1
     * input up 1 3
     * [3,2,3,4,5,6]
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {


         SegmentTree  st  =   null ;

         String  cmd  =   "cmp" ;
         while   ( true )   {
             String []  line  =   StdIn . readLine (). split ( " " );

             if   ( line [ 0 ]. equals ( "exit" ))   break ;

             int  arg1  =   0 ,  arg2  =   0 ,  arg3  =   0 ;

             if   ( line . length  >   1 )   {
                arg1  =   Integer . parseInt ( line [ 1 ]);
             }
             if   ( line . length  >   2 )   {
                arg2  =   Integer . parseInt ( line [ 2 ]);
             }
             if   ( line . length  >   3 )   {
                arg3  =   Integer . parseInt ( line [ 3 ]);
             }

             if   (( ! line [ 0 ]. equals ( "set" )   &&   ! line [ 0 ]. equals ( "init" ))   &&  st  ==   null )   {
                 StdOut . println ( "Segment Tree not initialized" );
                 continue ;
             }
             int  array [];
             if   ( line [ 0 ]. equals ( "set" ))   {
                array  =   new   int [ line . length  -   1 ];
                 for   ( int  i  =   0 ;  i  <  line . length  -   1 ;  i ++ )   {
                    array [ i ]   =   Integer . parseInt ( line [ +   1 ]);
                 }
                st  =   new   SegmentTree ( array );
             }
             else   if   ( line [ 0 ]. equals ( "init" ))   {
                array  =   new   int [ arg1 ];
                 Arrays . fill ( array ,  arg2 );
                st  =   new   SegmentTree ( array );

                 for   ( int  i  =   0 ;  i  <  st . size ();  i ++ )   {
                     StdOut . print ( st . rsq ( i ,  i )   +   " " );
                 }
                 StdOut . println ();
             }

             else   if   ( line [ 0 ]. equals ( "up" ))   {
                st . update ( arg1 ,  arg2 ,  arg3 );
                 for   ( int  i  =   0 ;  i  <  st . size ();  i ++ )   {
                     StdOut . print ( st . rsq ( i ,  i )   +   " " );
                 }
                 StdOut . println ();
             }
             else   if   ( line [ 0 ]. equals ( "rsq" ))   {
                 StdOut . printf ( "Sum from %d to %d = %d%n" ,  arg1 ,  arg2 ,  st . rsq ( arg1 ,  arg2 ));
             }
             else   if   ( line [ 0 ]. equals ( "rmq" ))   {
                 StdOut . printf ( "Min from %d to %d = %d%n" ,  arg1 ,  arg2 ,  st . rMinQ ( arg1 ,  arg2 ));
             }
             else   {
                 StdOut . println ( "Invalid command" );
             }

         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Selection.java

edu/princeton/cs/algs4/Selection.java

/******************************************************************************
 *  Compilation:  javac Selection.java
 *  Execution:    java  Selection < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt
 *                https://algs4.cs.princeton.edu/21elementary/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using selection sort.
 *   
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Selection < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java Selection < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Comparator ;

/**
 *  The { @code  Selection} class provides static methods for sorting an
 *  array using <em>selection sort</em>.
 *  This implementation makes ~ &frac12; <em>n</em><sup>2</sup> compares to sort
 *  any array of length <em>n</em>, so it is not suitable for sorting large arrays.
 *  It performs exactly <em>n</em> exchanges.
 *  <p>
 *  This sorting algorithm is not stable. It uses &Theta;(1) extra memory
 *  (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Selection   {

     // This class should not be instantiated.
     private   Selection ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  min  =  i ;
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 if   ( less ( a [ j ],  a [ min ]))  min  =  j ;
             }
            exch ( a ,  i ,  min );
             assert  isSorted ( a ,   0 ,  i );
         }
         assert  isSorted ( a );
     }

     /**
     * Rearranges the array in ascending order, using a comparator.
     *  @param  a the array
     *  @param  comparator the comparator specifying the order
     */
     public   static   void  sort ( Object []  a ,   Comparator  comparator )   {
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  min  =  i ;
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 if   ( less ( comparator ,  a [ j ],  a [ min ]))  min  =  j ;
             }
            exch ( a ,  i ,  min );
             assert  isSorted ( a ,  comparator ,   0 ,  i );
         }
         assert  isSorted ( a ,  comparator );
     }


    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }

     // is v < w ?
     private   static   boolean  less ( Comparator  comparator ,   Object  v ,   Object  w )   {
         return  comparator . compare ( v ,  w )   <   0 ;
     }
        
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/

     // is the array a[] sorted?
     private   static   boolean  isSorted ( Comparable []  a )   {
         return  isSorted ( a ,   0 ,  a . length  -   1 );
     }
        
     // is the array sorted from a[lo] to a[hi]
     private   static   boolean  isSorted ( Comparable []  a ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // is the array a[] sorted?
     private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator )   {
         return  isSorted ( a ,  comparator ,   0 ,  a . length  -   1 );
     }

     // is the array sorted from a[lo] to a[hi]
     private   static   boolean  isSorted ( Object []  a ,   Comparator  comparator ,   int  lo ,   int  hi )   {
         for   ( int  i  =  lo  +   1 ;  i  <=  hi ;  i ++ )
             if   ( less ( comparator ,  a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }



     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; selection sorts them; 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Selection . sort ( a );
        show ( a );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SeparateChainingHashST.java

edu/princeton/cs/algs4/SeparateChainingHashST.java

/******************************************************************************
 *  Compilation:  javac SeparateChainingHashST.java
 *  Execution:    java SeparateChainingHashST < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/34hash/tinyST.txt
 *
 *  A symbol table implemented with a separate-chaining hash table.
 * 
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SeparateChainingHashST} class represents a symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This implementation uses a separate chaining hash table. It requires that
 *  the key type overrides the { @code  equals()} and { @code  hashCode()} methods.
 *  The expected time per <em>put</em>, <em>contains</em>, or <em>remove</em>
 *  operation is constant, subject to the uniform hashing assumption.
 *  The <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction takes constant time.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/34hash">Section 3.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  For other implementations, see { @link  ST}, { @link  BinarySearchST},
 *  { @link  SequentialSearchST}, { @link  BST}, { @link  RedBlackBST}, and
 *  { @link  LinearProbingHashST},
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   SeparateChainingHashST < Key ,   Value >   {
     private   static   final   int  INIT_CAPACITY  =   4 ;

     private   int  n ;                                  // number of key-value pairs
     private   int  m ;                                  // hash table size
     private   SequentialSearchST < Key ,   Value > []  st ;    // array of linked-list symbol tables


     /**
     * Initializes an empty symbol table.
     */
     public   SeparateChainingHashST ()   {
         this ( INIT_CAPACITY );
     }  

     /**
     * Initializes an empty symbol table with { @code  m} chains.
     *  @param  m the initial number of chains
     */
     public   SeparateChainingHashST ( int  m )   {
         this . =  m ;
        st  =   ( SequentialSearchST < Key ,   Value > [])   new   SequentialSearchST [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            st [ i ]   =   new   SequentialSearchST < Key ,   Value > ();
     }  

     // resize the hash table to have the given number of chains,
     // rehashing all of the keys
     private   void  resize ( int  chains )   {
         SeparateChainingHashST < Key ,   Value >  temp  =   new   SeparateChainingHashST < Key ,   Value > ( chains );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( Key  key  :  st [ i ]. keys ())   {
                temp . put ( key ,  st [ i ]. get ( key ));
             }
         }
         this . m   =  temp . m ;
         this . n   =  temp . n ;
         this . st  =  temp . st ;
     }

     // hash value between 0 and m-1
     private   int  hash ( Key  key )   {
         return   ( key . hashCode ()   &   0x7fffffff )   %  m ;
     }  

     /**
     * Returns the number of key-value pairs in this symbol table.
     *
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }  

     /**
     * Returns true if this symbol table is empty.
     *
     *  @return  { @code  true} if this symbol table is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns true if this symbol table contains the specified key.
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key};
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }  

     /**
     * Returns the value associated with the specified key in this symbol table.
     *
     *  @param   key the key
     *  @return  the value associated with { @code  key} in the symbol table;
     *         { @code  null} if no such value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         int  i  =  hash ( key );
         return  st [ i ]. get ( key );
     }  

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );
         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }

         // double table size if average length of list >= 10
         if   ( >=   10 * m )  resize ( 2 * m );

         int  i  =  hash ( key );
         if   ( ! st [ i ]. contains ( key ))  n ++ ;
        st [ i ]. put ( key ,  val );
     }  

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).    
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );

         int  i  =  hash ( key );
         if   ( st [ i ]. contains ( key ))  n -- ;
        st [ i ]. delete ( key );

         // halve table size if average length of list <= 2
         if   ( >  INIT_CAPACITY  &&  n  <=   2 * m )  resize ( m / 2 );
     }  

     // return keys in symbol table as an Iterable
     public   Iterable < Key >  keys ()   {
         Queue < Key >  queue  =   new   Queue < Key > ();
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( Key  key  :  st [ i ]. keys ())
                queue . enqueue ( key );
         }
         return  queue ;
     }  


     /**
     * Unit tests the { @code  SeparateChainingHashST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {  
         SeparateChainingHashST < String ,   Integer >  st  =   new   SeparateChainingHashST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }

         // print keys
         for   ( String  s  :  st . keys ())  
             StdOut . println ( +   " "   +  st . get ( s ));  

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SequentialSearchST.java

edu/princeton/cs/algs4/SequentialSearchST.java

/******************************************************************************
 *  Compilation:  javac SequentialSearchST.java
 *  Execution:    java SequentialSearchST
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/31elementary/tinyST.txt  
 *  
 *  Symbol table implementation with sequential search in an
 *  unordered linked list of key-value pairs.
 *
 *  % more tinyST.txt
 *  S E A R C H E X A M P L E
 *
 *  % java SequentialSearchST < tinyST.txt 
 *  L 11
 *  P 10
 *  M 9
 *  X 7
 *  H 5
 *  C 4
 *  R 3
 *  A 8
 *  E 12
 *  S 0
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SequentialSearchST} class represents an (unordered)
 *  symbol table of generic key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  The class also uses the convention that values cannot be { @code  null}. Setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  It relies on the { @code  equals()} method to test whether two keys
 *  are equal. It does not call either the { @code  compareTo()} or
 *  { @code  hashCode()} method. 
 *  <p>
 *  This implementation uses a <em>singly linked list</em> and
 *  <em>sequential search</em>.
 *  The <em>put</em> and <em>delete</em> operations take &Theta;(<em>n</em>).
 *  The <em>get</em> and <em>contains</em> operations takes &Theta;(<em>n</em>)
 *  time in the worst case.
 *  The <em>size</em>, and <em>is-empty</em> operations take &Theta;(1) time.
 *  Construction takes &Theta;(1) time.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   SequentialSearchST < Key ,   Value >   {
     private   int  n ;             // number of key-value pairs
     private   Node  first ;        // the linked list of key-value pairs

     // a helper linked list data type
     private   class   Node   {
         private   Key  key ;
         private   Value  val ;
         private   Node  next ;

         public   Node ( Key  key ,   Value  val ,   Node  next )    {
             this . key   =  key ;
             this . val   =  val ;
             this . next  =  next ;
         }
     }

     /**
     * Initializes an empty symbol table.
     */
     public   SequentialSearchST ()   {
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Returns true if this symbol table is empty.
     *
     *  @return  { @code  true} if this symbol table is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns true if this symbol table contains the specified key.
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key};
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }

     /**
     * Returns the value associated with the given key in this symbol table.
     *
     *  @param   key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *     and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );  
         for   ( Node  x  =  first ;  x  !=   null ;  x  =  x . next )   {
             if   ( key . equals ( x . key ))
                 return  x . val ;
         }
         return   null ;
     }

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );  
         if   ( val  ==   null )   {
            delete ( key );
             return ;
         }

         for   ( Node  x  =  first ;  x  !=   null ;  x  =  x . next )   {
             if   ( key . equals ( x . key ))   {
                x . val  =  val ;
                 return ;
             }
         }
        first  =   new   Node ( key ,  val ,  first );
        n ++ ;
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).    
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );  
        first  =  delete ( first ,  key );
     }

     // delete key in linked list beginning at Node x
     // warning: function call stack too large if table is large
     private   Node  delete ( Node  x ,   Key  key )   {
         if   ( ==   null )   return   null ;
         if   ( key . equals ( x . key ))   {
            n -- ;
             return  x . next ;
         }
        x . next  =  delete ( x . next ,  key );
         return  x ;
     }


     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *
     *  @return  all keys in the symbol table
     */
     public   Iterable < Key >  keys ()    {
         Queue < Key >  queue  =   new   Queue < Key > ();
         for   ( Node  x  =  first ;  x  !=   null ;  x  =  x . next )
            queue . enqueue ( x . key );
         return  queue ;
     }


     /**
     * Unit tests the { @code  SequentialSearchST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         SequentialSearchST < String ,   Integer >  st  =   new   SequentialSearchST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }
         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SET.java

edu/princeton/cs/algs4/SET.java

/******************************************************************************
 *  Compilation:  javac SET.java
 *  Execution:    java SET
 *  Dependencies: StdOut.java
 *  
 *  Set implementation using Java's TreeSet library.
 *  Does not allow duplicates.
 *
 *  % java SET
 *  128.112.136.11
 *  208.216.181.15
 *  null
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;
import  java . util . TreeSet ;

/**
 *  The { @code  SET} class represents an ordered set of comparable keys.
 *  It supports the usual <em>add</em>, <em>contains</em>, and <em>delete</em>
 *  methods. It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, and <em>ceiling</em> and set methods
 *  for <em>union</em>, <em>intersection</em>, and <em>equality</em>.
 *  <p>
 *  Even though this implementation include the method { @code  equals()}, it
 *  does not support the method { @code  hashCode()} because sets are mutable.
 *  <p>
 *  This implementation uses a balanced binary search tree. It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  The <em>add</em>, <em>contains</em>, <em>delete</em>, <em>minimum</em>,
 *  <em>maximum</em>, <em>ceiling</em>, and <em>floor</em> methods take
 *  logarithmic time in the worst case.
 *  The <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction takes constant time.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms in Java, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of a key in this set
 */

public   class  SET < Key   extends   Comparable < Key >>   implements   Iterable < Key >   {
     private   TreeSet < Key >  set ;

     /**
     * Initializes an empty set.
     */
     public  SET ()   {
        set  =   new   TreeSet < Key > ();
     }

     /**
     * Initializes a new set that is an independent copy of the specified set.
     *
     *  @param  x the set to copy
     */
     public  SET ( SET < Key >  x )   {
        set  =   new   TreeSet < Key > ( x . set );
     }

     /**
     * Adds the key to this set (if it is not already present).
     *
     *  @param   key the key to add
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  add ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called add() with a null key" );
        set . add ( key );
     }


     /**
     * Returns true if this set contains the given key.
     *
     *  @param   key the key
     *  @return  { @code  true} if this set contains { @code  key};
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called contains() with a null key" );
         return  set . contains ( key );
     }

     /**
     * Removes the specified key from this set (if the set contains the specified key).
     * This is equivalent to { @code  remove()}, but we plan to deprecate { @code  delete()}.
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called delete() with a null key" );
        set . remove ( key );
     }

     /**
     * Removes the specified key from this set (if the set contains the specified key).
     * This is equivalent to { @code  delete()}, but we plan to deprecate { @code  delete()}.
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  remove ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called remove() with a null key" );
        set . remove ( key );
     }

     /**
     * Returns the number of keys in this set.
     *
     *  @return  the number of keys in this set
     */
     public   int  size ()   {
         return  set . size ();
     }

     /**
     * Returns true if this set is empty.
     *
     *  @return  { @code  true} if this set is empty;
     *         { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }
 
     /**
     * Returns all of the keys in this set, as an iterator.
     * To iterate over all of the keys in a set named { @code  set}, use the
     * foreach notation: { @code  for (Key key : set)}.
     *
     *  @return  an iterator to all of the keys in this set
     */
     public   Iterator < Key >  iterator ()   {
         return  set . iterator ();
     }

     /**
     * Returns the largest key in this set.
     *
     *  @return  the largest key in this set
     *  @throws  NoSuchElementException if this set is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called max() with empty set" );
         return  set . last ();
     }

     /**
     * Returns the smallest key in this set.
     *
     *  @return  the smallest key in this set
     *  @throws  NoSuchElementException if this set is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "called min() with empty set" );
         return  set . first ();
     }


     /**
     * Returns the smallest key in this set greater than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the smallest key in this set greater than or equal to { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  NoSuchElementException if there is no such key
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called ceiling() with a null key" );
         Key  k  =  set . ceiling ( key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "all keys are less than "   +  key );
         return  k ;
     }

     /**
     * Returns the largest key in this set less than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the largest key in this set table less than or equal to { @code  key}
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     *  @throws  NoSuchElementException if there is no such key
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "called floor() with a null key" );
         Key  k  =  set . floor ( key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "all keys are greater than "   +  key );
         return  k ;
     }

     /**
     * Returns the union of this set and that set.
     *
     *  @param   that the other set
     *  @return  the union of this set and that set
     *  @throws  IllegalArgumentException if { @code  that} is { @code  null}
     */
     public  SET < Key >  union ( SET < Key >  that )   {
         if   ( that  ==   null )   throw   new   IllegalArgumentException ( "called union() with a null argument" );
        SET < Key >  c  =   new  SET < Key > ();
         for   ( Key  x  :   this )   {
            c . add ( x );
         }
         for   ( Key  x  :  that )   {
            c . add ( x );
         }
         return  c ;
     }

     /**
     * Returns the intersection of this set and that set.
     *
     *  @param   that the other set
     *  @return  the intersection of this set and that set
     *  @throws  IllegalArgumentException if { @code  that} is { @code  null}
     */
     public  SET < Key >  intersects ( SET < Key >  that )   {
         if   ( that  ==   null )   throw   new   IllegalArgumentException ( "called intersects() with a null argument" );
        SET < Key >  c  =   new  SET < Key > ();
         if   ( this . size ()   <  that . size ())   {
             for   ( Key  x  :   this )   {
                 if   ( that . contains ( x ))  c . add ( x );
             }
         }
         else   {
             for   ( Key  x  :  that )   {
                 if   ( this . contains ( x ))  c . add ( x );
             }
         }
         return  c ;
     }

     /**       
     * Compares this set to the specified set.
     * <p>
     * Note that this method declares two empty sets to be equal
     * even if they are parameterized by different generic types.
     * This is consistent with the behavior of { @code  equals()} 
     * within Java's Collections framework.
     *       
     *  @param   other the other set
     *  @return  { @code  true} if this set equals { @code  other};
     *         { @code  false} otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
        SET that  =   ( SET )  other ;
         return   this . set . equals ( that . set );
     }

     /**
     * This operation is not supported because sets are mutable.
     *
     *  @return  does not return a value
     *  @throws  UnsupportedOperationException if called
     */
    @ Override
     public   int  hashCode ()   {
         throw   new   UnsupportedOperationException ( "hashCode() is not supported because sets are mutable" );
     }

     /**
     * Returns a string representation of this set.
     *
     *  @return  a string representation of this set, enclosed in curly braces,
     *         with adjacent keys separated by a comma and a space
     */
    @ Override
     public   String  toString ()   {
         String  s  =  set . toString ();
         return   "{ "   +  s . substring ( 1 ,  s . length ()   -   1 )   +   " }" ;
     }

     /**
     * Unit tests the { @code  SET} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
        SET < String >  set  =   new  SET < String > ();
         StdOut . println ( "set = "   +  set );

         // insert some keys
        set . add ( "www.cs.princeton.edu" );
        set . add ( "www.cs.princeton.edu" );      // overwrite old value
        set . add ( "www.princeton.edu" );
        set . add ( "www.math.princeton.edu" );
        set . add ( "www.yale.edu" );
        set . add ( "www.amazon.com" );
        set . add ( "www.simpsons.com" );
        set . add ( "www.stanford.edu" );
        set . add ( "www.google.com" );
        set . add ( "www.ibm.com" );
        set . add ( "www.apple.com" );
        set . add ( "www.slashdot.com" );
        set . add ( "www.whitehouse.gov" );
        set . add ( "www.espn.com" );
        set . add ( "www.snopes.com" );
        set . add ( "www.movies.com" );
        set . add ( "www.cnn.com" );
        set . add ( "www.iitb.ac.in" );


         StdOut . println ( set . contains ( "www.cs.princeton.edu" ));
         StdOut . println ( ! set . contains ( "www.harvardsucks.com" ));
         StdOut . println ( set . contains ( "www.simpsons.com" ));
         StdOut . println ();

         StdOut . println ( "ceiling(www.simpsonr.com) = "   +  set . ceiling ( "www.simpsonr.com" ));
         StdOut . println ( "ceiling(www.simpsons.com) = "   +  set . ceiling ( "www.simpsons.com" ));
         StdOut . println ( "ceiling(www.simpsont.com) = "   +  set . ceiling ( "www.simpsont.com" ));
         StdOut . println ( "floor(www.simpsonr.com)   = "   +  set . floor ( "www.simpsonr.com" ));
         StdOut . println ( "floor(www.simpsons.com)   = "   +  set . floor ( "www.simpsons.com" ));
         StdOut . println ( "floor(www.simpsont.com)   = "   +  set . floor ( "www.simpsont.com" ));
         StdOut . println ();

         StdOut . println ( "set = "   +  set );
         StdOut . println ();

         // print out all keys in this set in lexicographic order
         for   ( String  s  :  set )   {
             StdOut . println ( s );
         }

         StdOut . println ();
        SET < String >  set2  =   new  SET < String > ( set );
         StdOut . println ( set . equals ( set2 ));
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Shell.java

edu/princeton/cs/algs4/Shell.java

/******************************************************************************
 *  Compilation:  javac Shell.java
 *  Execution:    java Shell < input.txt
 *  Dependencies: StdOut.java StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/21elementary/tiny.txt
 *                https://algs4.cs.princeton.edu/21elementary/words3.txt
 *   
 *  Sorts a sequence of strings from standard input using shellsort.
 *
 *  % more tiny.txt
 *  S O R T E X A M P L E
 *
 *  % java Shell < tiny.txt
 *  A E E L M O P R S T X                 [ one string per line ]
 *    
 *  % more words3.txt
 *  bed bug dad yes zoo ... all bad yet
 *  
 *  % java Shell < words3.txt
 *  all bad bed bug dad ... yes yet zoo    [ one string per line ]
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Shell} class provides static methods for sorting an
 *  array using <em>Shellsort</em> with
 *  <a href = "https://oeis.org/A003462"> Knuth's increment sequence</a>
 *  (1, 4, 13, 40, ...). In the worst case, this implementation makes
 *  &Theta;(<em>n</em><sup>3/2</sup>) compares and exchanges to sort
 *  an array of length <em>n</em>.
 *  <p>
 *  This sorting algorithm is not stable.
 *  It uses &Theta;(1) extra memory (not including the input array).
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *  
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Shell   {

     // This class should not be instantiated.
     private   Shell ()   {   }

     /**
     * Rearranges the array in ascending order, using the natural order.
     *  @param  a the array to be sorted
     */
     public   static   void  sort ( Comparable []  a )   {
         int  n  =  a . length ;

         // 3x+1 increment sequence:  1, 4, 13, 40, 121, 364, 1093, ... 
         int  h  =   1 ;
         while   ( <  n / 3 )  h  =   3 * +   1 ;  

         while   ( >=   1 )   {
             // h-sort the array
             for   ( int  i  =  h ;  i  <  n ;  i ++ )   {
                 for   ( int  j  =  i ;  j  >=  h  &&  less ( a [ j ],  a [ j - h ]);  j  -=  h )   {
                    exch ( a ,  j ,  j - h );
                 }
             }
             assert  isHsorted ( a ,  h );  
            h  /=   3 ;
         }
         assert  isSorted ( a );
     }



    /***************************************************************************
    *  Helper sorting functions.
    ***************************************************************************/
    
     // is v < w ?
     private   static   boolean  less ( Comparable  v ,   Comparable  w )   {
         return  v . compareTo ( w )   <   0 ;
     }
        
     // exchange a[i] and a[j]
     private   static   void  exch ( Object []  a ,   int  i ,   int  j )   {
         Object  swap  =  a [ i ];
        a [ i ]   =  a [ j ];
        a [ j ]   =  swap ;
     }


    /***************************************************************************
    *  Check if array is sorted - useful for debugging.
    ***************************************************************************/
     private   static   boolean  isSorted ( Comparable []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - 1 ]))   return   false ;
         return   true ;
     }

     // is the array h-sorted?
     private   static   boolean  isHsorted ( Comparable []  a ,   int  h )   {
         for   ( int  i  =  h ;  i  <  a . length ;  i ++ )
             if   ( less ( a [ i ],  a [ i - h ]))   return   false ;
         return   true ;
     }

     // print array to standard output
     private   static   void  show ( Comparable []  a )   {
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             StdOut . println ( a [ i ]);
         }
     }

     /**
     * Reads in a sequence of strings from standard input; Shellsorts them; 
     * and prints them to standard output in ascending order. 
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String []  a  =   StdIn . readAllStrings ();
         Shell . sort ( a );
        show ( a );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SparseVector.java

edu/princeton/cs/algs4/SparseVector.java

/******************************************************************************
 *  Compilation:  javac SparseVector.java
 *  Execution:    java SparseVector
 *  Dependencies: StdOut.java
 *  
 *  A sparse vector, implementing using a symbol table.
 *
 *  [Not clear we need the instance variable N except for error checking.]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SparseVector} class represents a <em>d</em>-dimensional mathematical vector.
 *  Vectors are mutable: their values can be changed after they are created.
 *  It includes methods for addition, subtraction,
 *  dot product, scalar product, unit vector, and Euclidean norm.
 *  <p>
 *  The implementation is a symbol table of indices and values for which the vector
 *  coordinates are nonzero. This makes it efficient when most of the vector coordindates
  * are zero.
 *  <p>
 *  For additional documentation,    
 *  see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *  See also { @link  Vector} for an immutable (dense) vector data type.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   SparseVector   {
     private   int  d ;                     // dimension
     private  ST < Integer ,   Double >  st ;    // the vector, represented by index-value pairs

    /**
     * Initializes a d-dimensional zero vector.
     *  @param  d the dimension of the vector
     */
     public   SparseVector ( int  d )   {
         this . d   =  d ;
         this . st  =   new  ST < Integer ,   Double > ();
     }

    /**
     * Sets the ith coordinate of this vector to the specified value.
     *
     *  @param   i the index
     *  @param   value the new value
     *  @throws  IllegalArgumentException unless i is between 0 and d-1
     */
     public   void  put ( int  i ,   double  value )   {
         if   ( <   0   ||  i  >=  d )   throw   new   IllegalArgumentException ( "Illegal index" );
         if   ( value  ==   0.0 )  st . delete ( i );
         else               st . put ( i ,  value );
     }

    /**
     * Returns the ith coordinate of this vector.
     *
     *  @param   i the index
     *  @return  the value of the ith coordinate of this vector
     *  @throws  IllegalArgumentException unless i is between 0 and d-1
     */
     public   double  get ( int  i )   {
         if   ( <   0   ||  i  >=  d )   throw   new   IllegalArgumentException ( "Illegal index" );
         if   ( st . contains ( i ))   return  st . get ( i );
         else                  return   0.0 ;
     }

    /**
     * Returns the number of nonzero entries in this vector.
     *
     *  @return  the number of nonzero entries in this vector
     */
     public   int  nnz ()   {
         return  st . size ();
     }

    /**
     * Returns the dimension of this vector.
     *
     *  @return  the dimension of this vector
     *  @deprecated  Replaced by { @link  #dimension()}.
     */
    @ Deprecated
     public   int  size ()   {
         return  d ;
     }

    /**
     * Returns the dimension of this vector.
     *
     *  @return  the dimension of this vector
     */
     public   int  dimension ()   {
         return  d ;
     }

     /**
     * Returns the inner product of this vector with the specified vector.
     *
     *  @param   that the other vector
     *  @return  the dot product between this vector and that vector
     *  @throws  IllegalArgumentException if the lengths of the two vectors are not equal
     */
     public   double  dot ( SparseVector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Vector lengths disagree" );
         double  sum  =   0.0 ;

         // iterate over the vector with the fewest nonzeros
         if   ( this . st . size ()   <=  that . st . size ())   {
             for   ( int  i  :   this . st . keys ())
                 if   ( that . st . contains ( i ))  sum  +=   this . get ( i )   *  that . get ( i );
         }
         else    {
             for   ( int  i  :  that . st . keys ())
                 if   ( this . st . contains ( i ))  sum  +=   this . get ( i )   *  that . get ( i );
         }
         return  sum ;
     }


     /**
     * Returns the inner product of this vector with the specified array.
     *
     *  @param   that the array
     *  @return  the dot product between this vector and that array
     *  @throws  IllegalArgumentException if the dimensions of the vector and the array are not equal
     */
     public   double  dot ( double []  that )   {
         double  sum  =   0.0 ;
         for   ( int  i  :  st . keys ())
            sum  +=  that [ i ]   *   this . get ( i );
         return  sum ;
     }

     /**
     * Returns the magnitude of this vector.
     * This is also known as the L2 norm or the Euclidean norm.
     * 
     *  @return  the magnitude of this vector
     */
     public   double  magnitude ()   {
         return   Math . sqrt ( this . dot ( this ));
     }


     /**
     * Returns the Euclidean norm of this vector.
     *
     *  @return  the Euclidean norm of this vector
     *  @deprecated  Replaced by { @link  #magnitude()}.
     */
    @ Deprecated
     public   double  norm ()   {
         return   Math . sqrt ( this . dot ( this ));
     }

     /**
     * Returns the scalar-vector product of this vector with the specified scalar.
     *
     *  @param   alpha the scalar
     *  @return  the scalar-vector product of this vector with the specified scalar
     */
     public   SparseVector  scale ( double  alpha )   {
         SparseVector  c  =   new   SparseVector ( d );
         for   ( int  i  :   this . st . keys ())  c . put ( i ,  alpha  *   this . get ( i ));
         return  c ;
     }

     /**
     * Returns the sum of this vector and the specified vector.
     *
     *  @param   that the vector to add to this vector
     *  @return  the sum of this vector and that vector
     *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal
     */
     public   SparseVector  plus ( SparseVector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Vector lengths disagree" );
         SparseVector  c  =   new   SparseVector ( d );
         for   ( int  i  :   this . st . keys ())  c . put ( i ,   this . get ( i ));                  // c = this
         for   ( int  i  :  that . st . keys ())  c . put ( i ,  that . get ( i )   +  c . get ( i ));       // c = c + that
         return  c ;
     }

    /**
     * Returns a string representation of this vector.
     *  @return  a string representation of this vector, which consists of the 
     *         the vector entries, separates by commas, enclosed in parentheses
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( int  i  :  st . keys ())   {
            s . append ( "("   +  i  +   ", "   +  st . get ( i )   +   ") " );
         }
         return  s . toString ();
     }


     /**
     * Unit tests the { @code  SparseVector} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         SparseVector  a  =   new   SparseVector ( 10 );
         SparseVector  b  =   new   SparseVector ( 10 );
        a . put ( 3 ,   0.50 );
        a . put ( 9 ,   0.75 );
        a . put ( 6 ,   0.11 );
        a . put ( 6 ,   0.00 );
        b . put ( 3 ,   0.60 );
        b . put ( 4 ,   0.90 );
         StdOut . println ( "a = "   +  a );
         StdOut . println ( "b = "   +  b );
         StdOut . println ( "a dot b = "   +  a . dot ( b ));
         StdOut . println ( "a + b   = "   +  a . plus ( b ));
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Stack.java

edu/princeton/cs/algs4/Stack.java

/******************************************************************************
 *  Compilation:  javac Stack.java
 *  Execution:    java Stack < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/13stacks/tobe.txt
 *
 *  A generic stack, implemented using a singly linked list.
 *  Each stack element is of type Item.
 *
 *  This version uses a static nested class Node (to save 8 bytes per
 *  Node), whereas the version in the textbook uses a non-static nested
 *  class (for simplicity).
 *  
 *  % more tobe.txt 
 *  to be or not to - be - - that - - - is
 *
 *  % java Stack < tobe.txt
 *  to be not that or be (2 left on stack)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;


/**
 *  The { @code  Stack} class represents a last-in-first-out (LIFO) stack of generic items.
 *  It supports the usual <em>push</em> and <em>pop</em> operations, along with methods
 *  for peeking at the top item, testing if the stack is empty, and iterating through
 *  the items in LIFO order.
 *  <p>
 *  This implementation uses a singly linked list with a static nested class for
 *  linked-list nodes. See { @link  LinkedStack} for the version from the
 *  textbook that uses a non-static nested class.
 *  See { @link  ResizingArrayStack} for a version that uses a resizing array.
 *  The <em>push</em>, <em>pop</em>, <em>peek</em>, <em>size</em>, and <em>is-empty</em>
 *  operations all take constant time in the worst case.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Item> the generic type of an item in this stack
 */
public   class   Stack < Item >   implements   Iterable < Item >   {
     private   Node < Item >  first ;       // top of stack
     private   int  n ;                  // size of the stack

     // helper linked list class
     private   static   class   Node < Item >   {
         private   Item  item ;
         private   Node < Item >  next ;
     }

     /**
     * Initializes an empty stack.
     */
     public   Stack ()   {
        first  =   null ;
        n  =   0 ;
     }

     /**
     * Returns true if this stack is empty.
     *
     *  @return  true if this stack is empty; false otherwise
     */
     public   boolean  isEmpty ()   {
         return  first  ==   null ;
     }

     /**
     * Returns the number of items in this stack.
     *
     *  @return  the number of items in this stack
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Adds the item to this stack.
     *
     *  @param   item the item to add
     */
     public   void  push ( Item  item )   {
         Node < Item >  oldfirst  =  first ;
        first  =   new   Node < Item > ();
        first . item  =  item ;
        first . next  =  oldfirst ;
        n ++ ;
     }

     /**
     * Removes and returns the item most recently added to this stack.
     *
     *  @return  the item most recently added
     *  @throws  NoSuchElementException if this stack is empty
     */
     public   Item  pop ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         Item  item  =  first . item ;          // save item to return
        first  =  first . next ;              // delete first node
        n -- ;
         return  item ;                     // return the saved item
     }


     /**
     * Returns (but does not remove) the item most recently added to this stack.
     *
     *  @return  the item most recently added to this stack
     *  @throws  NoSuchElementException if this stack is empty
     */
     public   Item  peek ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "Stack underflow" );
         return  first . item ;
     }

     /**
     * Returns a string representation of this stack.
     *
     *  @return  the sequence of items in this stack in LIFO order, separated by spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( Item  item  :   this )   {
            s . append ( item );
            s . append ( ' ' );
         }
         return  s . toString ();
     }
       

     /**
     * Returns an iterator to this stack that iterates through the items in LIFO order.
     *
     *  @return  an iterator to this stack that iterates through the items in LIFO order
     */
     public   Iterator < Item >  iterator ()   {
         return   new   ListIterator ( first );
     }

     // an iterator, doesn't implement remove() since it's optional
     private   class   ListIterator   implements   Iterator < Item >   {
         private   Node < Item >  current ;

         public   ListIterator ( Node < Item >  first )   {
            current  =  first ;
         }

         public   boolean  hasNext ()   {
             return  current  !=   null ;
         }

         public   void  remove ()   {
             throw   new   UnsupportedOperationException ();
         }

         public   Item  next ()   {
             if   ( ! hasNext ())   throw   new   NoSuchElementException ();
             Item  item  =  current . item ;
            current  =  current . next ;  
             return  item ;
         }
     }


     /**
     * Unit tests the { @code  Stack} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Stack < String >  stack  =   new   Stack < String > ();
         while   ( ! StdIn . isEmpty ())   {
             String  item  =   StdIn . readString ();
             if   ( ! item . equals ( "-" ))
                stack . push ( item );
             else   if   ( ! stack . isEmpty ())
                 StdOut . print ( stack . pop ()   +   " " );
         }
         StdOut . println ( "("   +  stack . size ()   +   " left on stack)" );
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StaticSETofInts.java

edu/princeton/cs/algs4/StaticSETofInts.java

/******************************************************************************
 *  Compilation:  javac StaticSetOfInts.java
 *  Execution:    none
 *  Dependencies: StdOut.java
 *  
 *  Data type to store a set of integers.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 *  The { @code  StaticSETofInts} class represents a set of integers.
 *  It supports searching for a given integer is in the set. It accomplishes
 *  this by keeping the set of integers in a sorted array and using
 *  binary search to find the given integer.
 *  <p>
 *  The <em>rank</em> and <em>contains</em> operations take
 *  logarithmic time in the worst case.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   StaticSETofInts   {
     private   int []  a ;

     /**
     * Initializes a set of integers specified by the integer array.
     *  @param  keys the array of integers
     *  @throws  IllegalArgumentException if the array contains duplicate integers
     */
     public   StaticSETofInts ( int []  keys )   {

         // defensive copy
        a  =   new   int [ keys . length ];
         for   ( int  i  =   0 ;  i  <  keys . length ;  i ++ )
            a [ i ]   =  keys [ i ];

         // sort the integers
         Arrays . sort ( a );

         // check for duplicates
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( a [ i ]   ==  a [ i - 1 ])
                 throw   new   IllegalArgumentException ( "Argument arrays contains duplicate keys." );
     }

     /**
     * Is the key in this set of integers?
     *  @param  key the search key
     *  @return  true if the set of integers contains the key; false otherwise
     */
     public   boolean  contains ( int  key )   {
         return  rank ( key )   !=   - 1 ;
     }

     /**
     * Returns either the index of the search key in the sorted array
     * (if the key is in the set) or -1 (if the key is not in the set).
     *  @param  key the search key
     *  @return  the number of keys in this set less than the key (if the key is in the set)
     * or -1 (if the key is not in the set).
     */
     public   int  rank ( int  key )   {
         int  lo  =   0 ;
         int  hi  =  a . length  -   1 ;
         while   ( lo  <=  hi )   {
             // Key is in a[lo..hi] or not present.
             int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
             if        ( key  <  a [ mid ])  hi  =  mid  -   1 ;
             else   if   ( key  >  a [ mid ])  lo  =  mid  +   1 ;
             else   return  mid ;
         }
         return   - 1 ;
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdArrayIO.java

edu/princeton/cs/algs4/StdArrayIO.java

/******************************************************************************
 *  Compilation:  javac StdArrayIO.java
 *  Execution:    java StdArrayIO < input.txt
 *  Dependencies: StdOut.java
 *  Data files:    https://introcs.cs.princeton.edu/java/22library/tinyDouble1D.txt
 *                 https://introcs.cs.princeton.edu/java/22library/tinyDouble2D.txt
 *                 https://introcs.cs.princeton.edu/java/22library/tinyBoolean2D.txt
 *
 *  A library for reading in 1D and 2D arrays of integers, doubles,
 *  and booleans from standard input and printing them out to
 *  standard output.
 *
 *  % more tinyDouble1D.txt 
 *  4
 *    .000  .246  .222  -.032
 *
 *  % more tinyDouble2D.txt 
 *  4 3 
 *    .000  .270  .000 
 *    .246  .224 -.036 
 *    .222  .176  .0893 
 *   -.032  .739  .270 
 *
 *  % more tinyBoolean2D.txt 
 *  4 3 
 *    1 1 0
 *    0 0 0
 *    0 1 1
 *    1 1 1
 *
 *  % cat tinyDouble1D.txt tinyDouble2D.txt tinyBoolean2D.txt | java StdArrayIO
 *  4
 *    0.00000   0.24600   0.22200  -0.03200 
 *  
 *  4 3
 *    0.00000   0.27000   0.00000 
 *    0.24600   0.22400  -0.03600 
 *    0.22200   0.17600   0.08930 
 *    0.03200   0.73900   0.27000 
 *
 *  4 3
 *  1 1 0 
 *  0 0 0 
 *  0 1 1 
 *  1 1 1 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  <i>Standard array IO</i>. This class provides methods for reading
 *  in 1D and 2D arrays from standard input and printing out to 
 *  standard output.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/22libary">Section 2.2</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   StdArrayIO   {

     // it doesn't make sense to instantiate this class
     private   StdArrayIO ()   {   }

     /**
     * Reads a 1D array of doubles from standard input and returns it.
     *
     *  @return  the 1D array of doubles
     */
     public   static   double []  readDouble1D ()   {
         int  n  =   StdIn . readInt ();
         double []  a  =   new   double [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            a [ i ]   =   StdIn . readDouble ();
         }
         return  a ;
     }

     /**
     * Prints an array of doubles to standard output.
     *
     *  @param  a the 1D array of doubles
     */
     public   static   void  print ( double []  a )   {
         int  n  =  a . length ;
         StdOut . println ( n );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdOut . printf ( "%9.5f " ,  a [ i ]);
         }
         StdOut . println ();
     }

        
     /**
     * Reads a 2D array of doubles from standard input and returns it.
     *
     *  @return  the 2D array of doubles
     */
     public   static   double [][]  readDouble2D ()   {
         int  m  =   StdIn . readInt ();
         int  n  =   StdIn . readInt ();
         double [][]  a  =   new   double [ m ][ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                a [ i ][ j ]   =   StdIn . readDouble ();
             }
         }
         return  a ;
     }

     /**
     * Prints the 2D array of doubles to standard output.
     *
     *  @param  a the 2D array of doubles
     */
     public   static   void  print ( double [][]  a )   {
         int  m  =  a . length ;
         int  n  =  a [ 0 ]. length ;
         StdOut . println ( +   " "   +  n );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 StdOut . printf ( "%9.5f " ,  a [ i ][ j ]);
             }
             StdOut . println ();
         }
     }


     /**
     * Reads a 1D array of integers from standard input and returns it.
     *
     *  @return  the 1D array of integers
     */
     public   static   int []  readInt1D ()   {
         int  n  =   StdIn . readInt ();
         int []  a  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            a [ i ]   =   StdIn . readInt ();
         }
         return  a ;
     }

     /**
     * Prints an array of integers to standard output.
     *
     *  @param  a the 1D array of integers
     */
     public   static   void  print ( int []  a )   {
         int  n  =  a . length ;
         StdOut . println ( n );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdOut . printf ( "%9d " ,  a [ i ]);
         }
         StdOut . println ();
     }

        
     /**
     * Reads a 2D array of integers from standard input and returns it.
     *
     *  @return  the 2D array of integers
     */
     public   static   int [][]  readInt2D ()   {
         int  m  =   StdIn . readInt ();
         int  n  =   StdIn . readInt ();
         int [][]  a  =   new   int [ m ][ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                a [ i ][ j ]   =   StdIn . readInt ();
             }
         }
         return  a ;
     }

     /**
     * Print a 2D array of integers to standard output.
     *
     *  @param  a the 2D array of integers
     */
     public   static   void  print ( int [][]  a )   {
         int  m  =  a . length ;
         int  n  =  a [ 0 ]. length ;
         StdOut . println ( +   " "   +  n );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 StdOut . printf ( "%9d " ,  a [ i ][ j ]);
             }
             StdOut . println ();
         }
     }


     /**
     * Reads a 1D array of booleans from standard input and returns it.
     *
     *  @return  the 1D array of booleans
     */
     public   static   boolean []  readBoolean1D ()   {
         int  n  =   StdIn . readInt ();
         boolean []  a  =   new   boolean [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            a [ i ]   =   StdIn . readBoolean ();
         }
         return  a ;
     }

     /**
     * Prints a 1D array of booleans to standard output.
     *
     *  @param  a the 1D array of booleans
     */
     public   static   void  print ( boolean []  a )   {
         int  n  =  a . length ;
         StdOut . println ( n );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( a [ i ])   StdOut . print ( "1 " );
             else        StdOut . print ( "0 " );
         }
         StdOut . println ();
     }

     /**
     * Reads a 2D array of booleans from standard input and returns it.
     *
     *  @return  the 2D array of booleans
     */
     public   static   boolean [][]  readBoolean2D ()   {
         int  m  =   StdIn . readInt ();
         int  n  =   StdIn . readInt ();
         boolean [][]  a  =   new   boolean [ m ][ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                a [ i ][ j ]   =   StdIn . readBoolean ();
             }
         }
         return  a ;
     }

    /**
     * Prints a 2D array of booleans to standard output.
     *
     *  @param  a the 2D array of booleans
     */
     public   static   void  print ( boolean [][]  a )   {
         int  m  =  a . length ;
         int  n  =  a [ 0 ]. length ;
         StdOut . println ( +   " "   +  n );
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                 if   ( a [ i ][ j ])   StdOut . print ( "1 " );
                 else           StdOut . print ( "0 " );
             }
             StdOut . println ();
         }
     }


    /**
     * Unit tests { @code  StdArrayIO}.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // read and print an array of doubles
         double []  a  =   StdArrayIO . readDouble1D ();
         StdArrayIO . print ( a );
         StdOut . println ();

         // read and print a matrix of doubles
         double [][]  b  =   StdArrayIO . readDouble2D ();
         StdArrayIO . print ( b );
         StdOut . println ();

         // read and print a matrix of doubles
         boolean [][]  d  =   StdArrayIO . readBoolean2D ();
         StdArrayIO . print ( d );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdAudio.java

edu/princeton/cs/algs4/StdAudio.java

/******************************************************************************
 *  Compilation:  javac StdAudio.java
 *  Execution:    java StdAudio
 *  Dependencies: none
 *  
 *  Simple library for reading, writing, and manipulating .wav files.
 *
 *
 *  Limitations
 *  -----------
 *    - Assumes the audio is monaural, little endian, with sampling rate
 *      of 44,100
 *    - check when reading .wav files from a .jar file ?
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  javax . sound . sampled . Clip ;

import  java . io . File ;
import  java . io . ByteArrayInputStream ;
import  java . io . InputStream ;
import  java . io . IOException ;

import  java . net . URL ;

import  javax . sound . sampled . AudioFileFormat ;
import  javax . sound . sampled . AudioFormat ;
import  javax . sound . sampled . AudioInputStream ;
import  javax . sound . sampled . AudioSystem ;
import  javax . sound . sampled . DataLine ;
import  javax . sound . sampled . LineUnavailableException ;
import  javax . sound . sampled . SourceDataLine ;
import  javax . sound . sampled . UnsupportedAudioFileException ;

import  javax . sound . sampled . LineListener ;
import  javax . sound . sampled . LineEvent ;

/**
 *  <i>Standard audio</i>. This class provides a basic capability for
 *  creating, reading, and saving audio. 
 *  <p>
 *  The audio format uses a sampling rate of 44,100 Hz, 16-bit, monaural.
 *
 *  <p>
 *  For additional documentation, see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   StdAudio   {

     /**
     *  The sample rate: 44,100 Hz for CD quality audio.
     */
     public   static   final   int  SAMPLE_RATE  =   44100 ;

     private   static   final   int  BYTES_PER_SAMPLE  =   2 ;         // 16-bit audio
     private   static   final   int  BITS_PER_SAMPLE  =   16 ;         // 16-bit audio
     private   static   final   double  MAX_16_BIT  =   32768 ;
     private   static   final   int  SAMPLE_BUFFER_SIZE  =   4096 ;

     private   static   final   int  MONO    =   1 ;
     private   static   final   int  STEREO  =   2 ;
     private   static   final   boolean  LITTLE_ENDIAN  =   false ;
     private   static   final   boolean  BIG_ENDIAN     =   true ;
     private   static   final   boolean  SIGNED         =   true ;
     private   static   final   boolean  UNSIGNED       =   false ;


     private   static   SourceDataLine  line ;     // to play the sound
     private   static   byte []  buffer ;           // our internal buffer
     private   static   int  bufferSize  =   0 ;      // number of samples currently in internal buffer

     private   StdAudio ()   {
         // can not instantiate
     }
   
     // static initializer
     static   {
        init ();
     }

     // open up an audio stream
     private   static   void  init ()   {
         try   {
             // 44,100 Hz, 16-bit audio, mono, signed PCM, little endian
             AudioFormat  format  =   new   AudioFormat (( float )  SAMPLE_RATE ,  BITS_PER_SAMPLE ,  MONO ,  SIGNED ,  LITTLE_ENDIAN );
             DataLine . Info  info  =   new   DataLine . Info ( SourceDataLine . class ,  format );

            line  =   ( SourceDataLine )   AudioSystem . getLine ( info );
            line . open ( format ,  SAMPLE_BUFFER_SIZE  *  BYTES_PER_SAMPLE );
            
             // the internal buffer is a fraction of the actual buffer size, this choice is arbitrary
             // it gets divided because we can't expect the buffered data to line up exactly with when
             // the sound card decides to push out its samples.
            buffer  =   new   byte [ SAMPLE_BUFFER_SIZE  *  BYTES_PER_SAMPLE / 3 ];
         }
         catch   ( LineUnavailableException  e )   {
             System . out . println ( e . getMessage ());
         }

         // no sound gets made before this call
        line . start ();
     }

     // get an AudioInputStream object from a file
     private   static   AudioInputStream  getAudioInputStreamFromFile ( String  filename )   {
         if   ( filename  ==   null )   {
             throw   new   IllegalArgumentException ( "filename is null" );
         }

         try   {
             // first try to read file from local file system
             File  file  =   new   File ( filename );
             if   ( file . exists ())   {
                 return   AudioSystem . getAudioInputStream ( file );
             }

             // resource relative to .class file
             InputStream  is1  =   StdAudio . class . getResourceAsStream ( filename );
             if   ( is1  !=   null )   {
                 return   AudioSystem . getAudioInputStream ( is1 );
             }

             // resource relative to classloader root
             InputStream  is2  =   StdAudio . class . getClassLoader (). getResourceAsStream ( filename );
             if   ( is2  !=   null )   {
                 return   AudioSystem . getAudioInputStream ( is2 );
             }

             // give up
             else   {
                 throw   new   IllegalArgumentException ( "could not read '"   +  filename  +   "'" );
             }
         }
         catch   ( IOException  e )   {
             throw   new   IllegalArgumentException ( "could not read '"   +  filename  +   "'" ,  e );
         }
         catch   ( UnsupportedAudioFileException  e )   {
             throw   new   IllegalArgumentException ( "file of unsupported audio format: '"   +  filename  +   "'" ,  e );
         }
     }

     /**
     * Closes standard audio.
     */
     public   static   void  close ()   {
        line . drain ();
        line . stop ();
     }
    
     /**
     * Writes one sample (between -1.0 and +1.0) to standard audio.
     * If the sample is outside the range, it will be clipped.
     *
     *  @param   sample the sample to play
     *  @throws  IllegalArgumentException if the sample is { @code  Double.NaN}
     */
     public   static   void  play ( double  sample )   {
         if   ( Double . isNaN ( sample ))   throw   new   IllegalArgumentException ( "sample is NaN" );

         // clip if outside [-1, +1]
         if   ( sample  <   - 1.0 )  sample  =   - 1.0 ;
         if   ( sample  >   + 1.0 )  sample  =   + 1.0 ;

         // convert to bytes
         short  s  =   ( short )   ( MAX_16_BIT  *  sample );
         if   ( sample  ==   1.0 )  s  =   Short . MAX_VALUE ;     // special case since 32768 not a short
        buffer [ bufferSize ++ ]   =   ( byte )  s ;
        buffer [ bufferSize ++ ]   =   ( byte )   ( >>   8 );     // little endian

         // send to sound card if buffer is full        
         if   ( bufferSize  >=  buffer . length )   {
            line . write ( buffer ,   0 ,  buffer . length );
            bufferSize  =   0 ;
         }
     }

     /**
     * Writes the array of samples (between -1.0 and +1.0) to standard audio.
     * If a sample is outside the range, it will be clipped.
     *
     *  @param   samples the array of samples to play
     *  @throws  IllegalArgumentException if any sample is { @code  Double.NaN}
     *  @throws  IllegalArgumentException if { @code  samples} is { @code  null}
     */
     public   static   void  play ( double []  samples )   {
         if   ( samples  ==   null )   throw   new   IllegalArgumentException ( "argument to play() is null" );
         for   ( int  i  =   0 ;  i  <  samples . length ;  i ++ )   {
            play ( samples [ i ]);
         }
     }

     /**
     * Reads audio samples from a file (in .wav or .au format) and returns
     * them as a double array with values between -1.0 and +1.0.
     * The audio file must be 16-bit with a sampling rate of 44,100.
     * It can be mono or stereo.
     *
     *  @param   filename the name of the audio file
     *  @return  the array of samples
     */
     public   static   double []  read ( String  filename )   {

         // make sure that AudioFormat is 16-bit, 44,100 Hz, little endian
         final   AudioInputStream  ais  =  getAudioInputStreamFromFile ( filename );
         AudioFormat  audioFormat  =  ais . getFormat ();

         // require sampling rate = 44,100 Hz
         if   ( audioFormat . getSampleRate ()   !=  SAMPLE_RATE )   {
             throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only a sample rate of "   +  SAMPLE_RATE  +   " Hz\n"
                                              +   "audio format: "   +  audioFormat );
         }

         // require 16-bit audio
         if   ( audioFormat . getSampleSizeInBits ()   !=  BITS_PER_SAMPLE )   {
             throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only "   +  BITS_PER_SAMPLE  +   "-bit audio\n"
                                              +   "audio format: "   +  audioFormat );
         }

         // require little endian
         if   ( audioFormat . isBigEndian ())   {
             throw   new   IllegalArgumentException ( "StdAudio.read() currently supports only audio stored using little endian\n"
                                              +   "audio format: "   +  audioFormat );
         }

         byte []  bytes  =   null ;
         try   {
             int  bytesToRead  =  ais . available ();
            bytes  =   new   byte [ bytesToRead ];
             int  bytesRead  =  ais . read ( bytes );
             if   ( bytesToRead  !=  bytesRead )   {
                 throw   new   IllegalStateException ( "read only "   +  bytesRead  +   " of "   +  bytesToRead  +   " bytes" );  
             }
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "could not read '"   +  filename  +   "'" ,  ioe );
         }

         int  n  =  bytes . length ;

         // little endian, mono
         if   ( audioFormat . getChannels ()   ==  MONO )   {
             double []  data  =   new   double [ n / 2 ];
             for   ( int  i  =   0 ;  i  <  n / 2 ;  i ++ )   {
                 // little endian, mono
                data [ i ]   =   (( short )   ((( bytes [ 2 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 2 * i ]   &   0xFF )))   /   (( double )  MAX_16_BIT );
             }
             return  data ;
         }

         // little endian, stereo
         else   if   ( audioFormat . getChannels ()   ==  STEREO )   {
             double []  data  =   new   double [ n / 4 ];
             for   ( int  i  =   0 ;  i  <  n / 4 ;  i ++ )   {
                 double  left   =   (( short )   ((( bytes [ 4 * i + 1 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * +   0 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );
                 double  right  =   (( short )   ((( bytes [ 4 * i + 3 ]   &   0xFF )   <<   8 )   |   ( bytes [ 4 * +   2 ]   &   0xFF )))   /   (( double )  MAX_16_BIT );
                data [ i ]   =   ( left  +  right )   /   2.0 ;
             }
             return  data ;
         }

         // TODO: handle big endian (or other formats)
         else   throw   new   IllegalStateException ( "audio format is neither mono or stereo" );
     }

     /**
     * Saves the double array as an audio file (using .wav or .au format).
     *
     *  @param   filename the name of the audio file
     *  @param   samples the array of samples
     *  @throws  IllegalArgumentException if unable to save { @code  filename}
     *  @throws  IllegalArgumentException if { @code  samples} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  filename} extension is not { @code  .wav}
     *         or { @code  .au}
     */
     public   static   void  save ( String  filename ,   double []  samples )   {
         if   ( filename  ==   null )   {
             throw   new   IllegalArgumentException ( "filenameis null" );
         }
         if   ( samples  ==   null )   {
             throw   new   IllegalArgumentException ( "samples[] is null" );
         }

         // assumes 16-bit samples with sample rate = 44,100 Hz
         // use 16-bit audio, mono, signed PCM, little Endian
         AudioFormat  format  =   new   AudioFormat ( SAMPLE_RATE ,   16 ,  MONO ,  SIGNED ,  LITTLE_ENDIAN );
         byte []  data  =   new   byte [ 2   *  samples . length ];
         for   ( int  i  =   0 ;  i  <  samples . length ;  i ++ )   {
             int  temp  =   ( short )   ( samples [ i ]   *  MAX_16_BIT );
             if   ( samples [ i ]   ==   1.0 )  temp  =   Short . MAX_VALUE ;     // special case since 32768 not a short
            data [ 2 * +   0 ]   =   ( byte )  temp ;
            data [ 2 * +   1 ]   =   ( byte )   ( temp  >>   8 );     // little endian
         }

         // now save the file
         try   {
             ByteArrayInputStream  bais  =   new   ByteArrayInputStream ( data );
             AudioInputStream  ais  =   new   AudioInputStream ( bais ,  format ,  samples . length );
             if   ( filename . endsWith ( ".wav" )   ||  filename . endsWith ( ".WAV" ))   {
                 AudioSystem . write ( ais ,   AudioFileFormat . Type . WAVE ,   new   File ( filename ));
             }
             else   if   ( filename . endsWith ( ".au" )   ||  filename . endsWith ( ".AU" ))   {
                 AudioSystem . write ( ais ,   AudioFileFormat . Type . AU ,   new   File ( filename ));
             }
             else   {
                 throw   new   IllegalArgumentException ( "file type for saving must be .wav or .au" );
             }
         }
         catch   ( IOException  ioe )   {
             throw   new   IllegalArgumentException ( "unable to save file '"   +  filename  +   "'" ,  ioe );
         }
     }



     /**
     * Plays an audio file (in .wav, .mid, or .au format) in a background thread.
     *
     *  @param  filename the name of the audio file
     *  @throws  IllegalArgumentException if unable to play { @code  filename}
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   static   synchronized   void  play ( final   String  filename )   {
         new   Thread ( new   Runnable ()   {
             public   void  run ()   {
                 AudioInputStream  ais  =  getAudioInputStreamFromFile ( filename );
                stream ( ais );
             }
         }). start ();
     }


     // https://www3.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html
     // play a wav or aif file
     // javax.sound.sampled.Clip fails for long clips (on some systems), perhaps because
     // JVM closes (see remedy in loop)
     private   static   void  stream ( AudioInputStream  ais )   {
         SourceDataLine  line  =   null ;
         int  BUFFER_SIZE  =   4096 ;   // 4K buffer

         try   {
             AudioFormat  audioFormat  =  ais . getFormat ();
             DataLine . Info  info  =   new   DataLine . Info ( SourceDataLine . class ,  audioFormat );
            line  =   ( SourceDataLine )   AudioSystem . getLine ( info );
            line . open ( audioFormat );
            line . start ();
             byte []  samples  =   new   byte [ BUFFER_SIZE ];
             int  count  =   0 ;
             while   (( count  =  ais . read ( samples ,   0 ,  BUFFER_SIZE ))   !=   - 1 )   {
                line . write ( samples ,   0 ,  count );
             }
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }
         catch   ( LineUnavailableException  e )   {
            e . printStackTrace ();
         }
         finally   {
             if   ( line  !=   null )   {
                line . drain ();
                line . close ();
             }
         }
     }

     /**
     * Loops an audio file (in .wav, .mid, or .au format) in a background thread.
     *
     *  @param  filename the name of the audio file
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   static   synchronized   void  loop ( String  filename )   {
         if   ( filename  ==   null )   throw   new   IllegalArgumentException ();

         final   AudioInputStream  ais  =  getAudioInputStreamFromFile ( filename );

         try   {
             Clip  clip  =   AudioSystem . getClip ();
             // Clip clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class));
            clip . open ( ais );
            clip . loop ( Clip . LOOP_CONTINUOUSLY );
         }
         catch   ( LineUnavailableException  e )   {
            e . printStackTrace ();
         }
         catch   ( IOException  e )   {
            e . printStackTrace ();
         }

         // keep JVM open
         new   Thread ( new   Runnable ()   {
             public   void  run ()   {
                 while   ( true )   {
                     try   {
                        Thread . sleep ( 1000 );
                     }
                     catch   ( InterruptedException  e )   {
                        e . printStackTrace ();
                     }
                 }
             }
         }). start ();
     }


    /***************************************************************************
    * Unit tests { @code  StdAudio}.
    ***************************************************************************/

     // create a note (sine wave) of the given frequency (Hz), for the given
     // duration (seconds) scaled to the given volume (amplitude)
     private   static   double []  note ( double  hz ,   double  duration ,   double  amplitude )   {
         int  n  =   ( int )   ( StdAudio . SAMPLE_RATE  *  duration );
         double []  a  =   new   double [ n + 1 ];
         for   ( int  i  =   0 ;  i  <=  n ;  i ++ )
            a [ i ]   =  amplitude  *   Math . sin ( 2   *   Math . PI  *  i  *  hz  /   StdAudio . SAMPLE_RATE );
         return  a ;
     }

     /**
     * Test client - play an A major scale to standard audio.
     *
     *  @param  args the command-line arguments
     */
     /**
     * Test client - play an A major scale to standard audio.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
        
         // 440 Hz for 1 sec
         double  freq  =   440.0 ;
         for   ( int  i  =   0 ;  i  <=   StdAudio . SAMPLE_RATE ;  i ++ )   {
             StdAudio . play ( 0.5   *   Math . sin ( 2 * Math . PI  *  freq  *  i  /   StdAudio . SAMPLE_RATE ));
         }
        
         // scale increments
         int []  steps  =   {   0 ,   2 ,   4 ,   5 ,   7 ,   9 ,   11 ,   12   };
         for   ( int  i  =   0 ;  i  <  steps . length ;  i ++ )   {
             double  hz  =   440.0   *   Math . pow ( 2 ,  steps [ i ]   /   12.0 );
             StdAudio . play ( note ( hz ,   1.0 ,   0.5 ));
         }


         // need to call this in non-interactive stuff so the program doesn't terminate
         // until all the sound leaves the speaker.
         StdAudio . close ();  
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdDraw.java

edu/princeton/cs/algs4/StdDraw.java

/******************************************************************************
 *  Compilation:  javac StdDraw.java
 *  Execution:    java StdDraw
 *  Dependencies: none
 *
 *  Standard drawing library. This class provides a basic capability for
 *  creating drawings with your programs. It uses a simple graphics model that
 *  allows you to create drawings consisting of geometric shapes (e.g.,
 *  points, lines, circles, rectangles) in a window on your computer
 *  and to save the drawings to a file.
 *
 *  Todo
 *  ----
 *    -  Add support for gradient fill, etc.
 *    -  Fix setCanvasSize() so that it can be called only once.
 *    -  Should setCanvasSize() reset xScale(), yScale(), penRadius(),
 *       penColor(), and font()
 *    -  On some systems, drawing a line (or other shape) that extends way
 *       beyond canvas (e.g., to infinity) dimensions does not get drawn.
 *
 *  Remarks
 *  -------
 *    -  don't use AffineTransform for rescaling since it inverts
 *       images and strings
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . awt . BasicStroke ;
import  java . awt . Color ;
import  java . awt . Component ;
import  java . awt . FileDialog ;
import  java . awt . Font ;
import  java . awt . FontMetrics ;
import  java . awt . Graphics ;
import  java . awt . Graphics2D ;
import  java . awt . Image ;
import  java . awt . MediaTracker ;
import  java . awt . RenderingHints ;
import  java . awt . Toolkit ;

import  java . awt . event . ActionEvent ;
import  java . awt . event . ActionListener ;
import  java . awt . event . MouseEvent ;
import  java . awt . event . MouseListener ;
import  java . awt . event . MouseMotionListener ;
import  java . awt . event . KeyEvent ;
import  java . awt . event . KeyListener ;

import  java . awt . geom . Arc2D ;
import  java . awt . geom . Ellipse2D ;
import  java . awt . geom . GeneralPath ;
import  java . awt . geom . Line2D ;
import  java . awt . geom . Rectangle2D ;

import  java . awt . image . BufferedImage ;
import  java . awt . image . DirectColorModel ;
import  java . awt . image . WritableRaster ;

import  java . io . File ;
import  java . io . IOException ;

import  java . net . MalformedURLException ;
import  java . net . URL ;

import  java . util . LinkedList ;
import  java . util . TreeSet ;
import  java . util . NoSuchElementException ;
import  javax . imageio . ImageIO ;

import  javax . swing . ImageIcon ;
import  javax . swing . JFrame ;
import  javax . swing . JLabel ;
import  javax . swing . JMenu ;
import  javax . swing . JMenuBar ;
import  javax . swing . JMenuItem ;
import  javax . swing . KeyStroke ;

/**
 *  The { @code  StdDraw} class provides a basic capability for
 *  creating drawings with your programs. It uses a simple graphics model that
 *  allows you to create drawings consisting of points, lines, squares, 
 *  circles, and other geometric shapes in a window on your computer and
 *  to save the drawings to a file. Standard drawing also includes
 *  facilities for text, color, pictures, and animation, along with
 *  user interaction via the keyboard and mouse.
 *  <p>
 *  <b>Getting started.</b>
 *  To use this class, you must have { @code  StdDraw.class} in your
 *  Java classpath. If you used our autoinstaller, you should be all set.
 *  Otherwise, either download
 *  <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a>
 *  and add to your Java classpath or download
 *  <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdDraw.java">StdDraw.java</a>
 *  and put a copy in your working directory.
 *  <p>
 *  Now, type the following short program into your editor:
 *  <pre>
 *   public class TestStdDraw {
 *       public static void main(String[] args) {
 *           StdDraw.setPenRadius(0.05);
 *           StdDraw.setPenColor(StdDraw.BLUE);
 *           StdDraw.point(0.5, 0.5);
 *           StdDraw.setPenColor(StdDraw.MAGENTA);
 *           StdDraw.line(0.2, 0.2, 0.8, 0.2);
 *       }
 *   }
 *  </pre>
 *  If you compile and execute the program, you should see a window
 *  appear with a thick magenta line and a blue point.
 *  This program illustrates the two main types of methods in standard
 *  drawing—methods that draw geometric shapes and methods that
 *  control drawing parameters.
 *  The methods { @code  StdDraw.line()} and { @code  StdDraw.point()}
 *  draw lines and points; the methods { @code  StdDraw.setPenRadius()}
 *  and { @code  StdDraw.setPenColor()} control the line thickness and color.
 *  <p>
 *  <b>Points and lines.</b>
 *  You can draw points and line segments with the following methods:
 *  <ul>
 *  <li> { @link  #point(double x, double y)}
 *  <li> { @link  #line(double x1, double y1, double x2, double y2)}
 *  </ul>
 *  <p>
 *  The <em>x</em>- and <em>y</em>-coordinates must be in the drawing area
 *  (between 0 and 1 and by default) or the points and lines will not be visible.
 *  <p>
 *  <b>Squares, circles, rectangles, and ellipses.</b>
 *  You can draw squares, circles, rectangles, and ellipses using
 *  the following methods:
 *  <ul>
 *  <li> { @link  #circle(double x, double y, double radius)}
 *  <li> { @link  #ellipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}
 *  <li> { @link  #square(double x, double y, double halfLength)}
 *  <li> { @link  #rectangle(double x, double y, double halfWidth, double halfHeight)}
 *  </ul>
 *  <p>
 *  All of these methods take as arguments the location and size of the shape.
 *  The location is always specified by the <em>x</em>- and <em>y</em>-coordinates
 *  of its <em>center</em>.
 *  The size of a circle is specified by its radius and the size of an ellipse is
 *  specified by the lengths of its semi-major and semi-minor axes.
 *  The size of a square or rectangle is specified by its half-width or half-height.
 *  The convention for drawing squares and rectangles is parallel to those for
 *  drawing circles and ellipses, but may be unexpected to the uninitiated.
 *  <p>
 *  The methods above trace outlines of the given shapes. The following methods
 *  draw filled versions:
 *  <ul>
 *  <li> { @link  #filledCircle(double x, double y, double radius)}
 *  <li> { @link  #filledEllipse(double x, double y, double semiMajorAxis, double semiMinorAxis)}
 *  <li> { @link  #filledSquare(double x, double y, double radius)}
 *  <li> { @link  #filledRectangle(double x, double y, double halfWidth, double halfHeight)}
 *  </ul>
 *  <p>
 *  <b>Circular arcs.</b>
 *  You can draw circular arcs with the following method:
 *  <ul>
 *  <li> { @link  #arc(double x, double y, double radius, double angle1, double angle2)}
 *  </ul>
 *  <p>
 *  The arc is from the circle centered at (<em>x</em>, <em>y</em>) of the specified radius.
 *  The arc extends from angle1 to angle2. By convention, the angles are
 *  <em>polar</em> (counterclockwise angle from the <em>x</em>-axis)
 *  and represented in degrees. For example, { @code  StdDraw.arc(0.0, 0.0, 1.0, 0, 90)}
 *  draws the arc of the unit circle from 3 o'clock (0 degrees) to 12 o'clock (90 degrees).
 *  <p>
 *  <b>Polygons.</b>
 *  You can draw polygons with the following methods:
 *  <ul>
 *  <li> { @link  #polygon(double[] x, double[] y)}
 *  <li> { @link  #filledPolygon(double[] x, double[] y)}
 *  </ul>
 *  <p>
 *  The points in the polygon are ({ @code  x[i]}, { @code  y[i]}).
 *  For example, the following code fragment draws a filled diamond
 *  with vertices (0.1, 0.2), (0.2, 0.3), (0.3, 0.2), and (0.2, 0.1):
 *  <pre>
 *   double[] x = { 0.1, 0.2, 0.3, 0.2 };
 *   double[] y = { 0.2, 0.3, 0.2, 0.1 };
 *   StdDraw.filledPolygon(x, y);
 *  </pre>
 *  <p>
 *  <b>Pen size.</b>
 *  The pen is circular, so that when you set the pen radius to <em>r</em>
 *  and draw a point, you get a circle of radius <em>r</em>. Also, lines are
 *  of thickness 2<em>r</em> and have rounded ends. The default pen radius
 *  is 0.005 and is not affected by coordinate scaling. This default pen
 *  radius is about 1/200 the width of the default canvas, so that if
 *  you draw 100 points equally spaced along a horizontal or vertical line,
 *  you will be able to see individual circles, but if you draw 200 such
 *  points, the result will look like a line.
 *  <ul>
 *  <li> { @link  #setPenRadius(double radius)}
 *  </ul>
 *  <p>
 *  For example, { @code  StdDraw.setPenRadius(0.025)} makes
 *  the thickness of the lines and the size of the points to be five times
 *  the 0.005 default.
 *  To draw points with the minimum possible radius (one pixel on typical
 *  displays), set the pen radius to 0.0.
 *  <p>
 *  <b>Pen color.</b>
 *  All geometric shapes (such as points, lines, and circles) are drawn using
 *  the current pen color. By default, it is black.
 *  You can change the pen color with the following methods:
 *  <ul>
 *  <li> { @link  #setPenColor(int red, int green, int blue)}
 *  <li> { @link  #setPenColor(Color color)}
 *  </ul>
 *  <p>
 *  The first method allows you to specify colors using the RGB color system.
 *  This <a href = "http://johndyer.name/lab/colorpicker/">color picker</a>
 *  is a convenient way to find a desired color.
 *  The second method allows you to specify colors using the
 *  { @link  Color} data type that is discussed in Chapter 3. Until then,
 *  you can use this method with one of these predefined colors in standard drawing:
 *  { @link  #BLACK}, { @link  #BLUE}, { @link  #CYAN}, { @link  #DARK_GRAY}, { @link  #GRAY},
 *  { @link  #GREEN}, { @link  #LIGHT_GRAY}, { @link  #MAGENTA}, { @link  #ORANGE},
 *  { @link  #PINK}, { @link  #RED}, { @link  #WHITE}, { @link  #YELLOW},
 *  { @link  #BOOK_BLUE}, { @link  #BOOK_LIGHT_BLUE}, { @link  #BOOK_RED}, and
 *  { @link  #PRINCETON_ORANGE}.
 *  For example, { @code  StdDraw.setPenColor(StdDraw.MAGENTA)} sets the
 *  pen color to magenta.
 *  <p>
 *  <b>Canvas size.</b>
 *  By default, all drawing takes places in a 512-by-512 canvas.
 *  The canvas does not include the window title or window border.
 *  You can change the size of the canvas with the following method:
 *  <ul>
 *  <li> { @link  #setCanvasSize(int width, int height)}
 *  </ul>
 *  <p>
 *  This sets the canvas size to be <em>width</em>-by-<em>height</em> pixels.
 *  It also erases the current drawing and resets the coordinate system,
 *  pen radius, pen color, and font back to their default values.
 *  Ordinarly, this method is called once, at the very beginning of a program.
 *  For example, { @code  StdDraw.setCanvasSize(800, 800)}
 *  sets the canvas size to be 800-by-800 pixels.
 *  <p>
 *  <b>Canvas scale and coordinate system.</b>
 *  By default, all drawing takes places in the unit square, with (0, 0) at
 *  lower left and (1, 1) at upper right. You can change the default
 *  coordinate system with the following methods:
 *  <ul>
 *  <li> { @link  #setXscale(double xmin, double xmax)}
 *  <li> { @link  #setYscale(double ymin, double ymax)}
 *  <li> { @link  #setScale(double min, double max)}
 *  </ul>
 *  <p>
 *  The arguments are the coordinates of the minimum and maximum 
 *  <em>x</em>- or <em>y</em>-coordinates that will appear in the canvas.
 *  For example, if you  wish to use the default coordinate system but
 *  leave a small margin, you can call { @code  StdDraw.setScale(-.05, 1.05)}.
 *  <p>
 *  These methods change the coordinate system for subsequent drawing
 *  commands; they do not affect previous drawings.
 *  These methods do not change the canvas size; so, if the <em>x</em>-
 *  and <em>y</em>-scales are different, squares will become rectangles
 *  and circles will become ellipses.
 *  <p>
 *  <b>Text.</b>
 *  You can use the following methods to annotate your drawings with text:
 *  <ul>
 *  <li> { @link  #text(double x, double y, String text)}
 *  <li> { @link  #text(double x, double y, String text, double degrees)}
 *  <li> { @link  #textLeft(double x, double y, String text)}
 *  <li> { @link  #textRight(double x, double y, String text)}
 *  </ul>
 *  <p>
 *  The first two methods write the specified text in the current font,
 *  centered at (<em>x</em>, <em>y</em>).
 *  The second method allows you to rotate the text.
 *  The last two methods either left- or right-align the text at (<em>x</em>, <em>y</em>).
 *  <p>
 *  The default font is a Sans Serif font with point size 16.
 *  You can use the following method to change the font:
 *  <ul>
 *  <li> { @link  #setFont(Font font)}
 *  </ul>
 *  <p>
 *  You use the { @link  Font} data type to specify the font. This allows you to
 *  choose the face, size, and style of the font. For example, the following
 *  code fragment sets the font to Arial Bold, 60 point.
 *  <pre>
 *   Font font = new Font("Arial", Font.BOLD, 60);
 *   StdDraw.setFont(font);
 *   StdDraw.text(0.5, 0.5, "Hello, World");
 *  </pre>
 *  <p>
 *  <b>Images.</b>
 *  You can use the following methods to add images to your drawings:
 *  <ul>
 *  <li> { @link  #picture(double x, double y, String filename)}
 *  <li> { @link  #picture(double x, double y, String filename, double degrees)}
 *  <li> { @link  #picture(double x, double y, String filename, double scaledWidth, double scaledHeight)}
 *  <li> { @link  #picture(double x, double y, String filename, double scaledWidth, double scaledHeight, double degrees)}
 *  </ul>
 *  <p>
 *  These methods draw the specified image, centered at (<em>x</em>, <em>y</em>).
 *  The supported image formats are JPEG, PNG, and GIF.
 *  The image will display at its native size, independent of the coordinate system.
 *  Optionally, you can rotate the image a specified number of degrees counterclockwise
 *  or rescale it to fit snugly inside a width-by-height bounding box.
 *  <p>
 *  <b>Saving to a file.</b>
 *  You save your image to a file using the <em>File → Save</em> menu option.
 *  You can also save a file programatically using the following method:
 *  <ul>
 *  <li> { @link  #save(String filename)}
 *  </ul>
 *  <p>
 *  The supported image formats are JPEG and PNG. The filename must have either the
 *  extension .jpg or .png.
 *  We recommend using PNG for drawing that consist solely of geometric shapes and JPEG 
 *  for drawings that contains pictures.
 *  <p>
 *  <b>Clearing the canvas.</b>
 *  To clear the entire drawing canvas, you can use the following methods:
 *  <ul>
 *  <li> { @link  #clear()}
 *  <li> { @link  #clear(Color color)}
 *  </ul>
 *  <p>
 *  The first method clears the canvas to white; the second method
 *  allows you to specify a color of your choice. For example,
 *  { @code  StdDraw.clear(StdDraw.LIGHT_GRAY)} clears the canvas to a shade
 *  of gray.
 *  <p>
 *  <b>Computer animations and double buffering.</b>
 *  Double buffering is one of the most powerful features of standard drawing,
 *  enabling computer animations.
 *  The following methods control the way in which objects are drawn:
 *  <ul>
 *  <li> { @link  #enableDoubleBuffering()}
 *  <li> { @link  #disableDoubleBuffering()}
 *  <li> { @link  #show()}
 *  <li> { @link  #pause(int t)}
 *  </ul>
 *  <p>
 *  By default, double buffering is disabled, which means that as soon as you
 *  call a drawing
 *  method—such as { @code  point()} or { @code  line()}—the
 *  results appear on the screen.
 *  <p>
 *  When double buffering is enabled by calling { @link  #enableDoubleBuffering()},
 *  all drawing takes place on the <em>offscreen canvas</em>. The offscreen canvas
 *  is not displayed. Only when you call
 *  { @link  #show()} does your drawing get copied from the offscreen canvas to
 *  the onscreen canvas, where it is displayed in the standard drawing window. You 
 *  can think of double buffering as collecting all of the lines, points, shapes,
 *  and text that you tell it to draw, and then drawing them all
 *  <em>simultaneously</em>, upon request.
 *  <p>
 *  The most important use of double buffering is to produce computer
 *  animations, creating the illusion of motion by rapidly
 *  displaying static drawings. To produce an animation, repeat
 *  the following four steps:
 *  <ul>
 *  <li> Clear the offscreen canvas.
 *  <li> Draw objects on the offscreen canvas.
 *  <li> Copy the offscreen canvas to the onscreen canvas.
 *  <li> Wait for a short while.
 *  </ul>
 *  <p>
 *  The { @link  #clear()}, { @link  #show()}, and { @link  #pause(int t)} methods
 *  support the first, third, and fourth of these steps, respectively.
 *  <p>
 *  For example, this code fragment animates two balls moving in a circle.
 *  <pre>
 *   StdDraw.setScale(-2, +2);
 *   StdDraw.enableDoubleBuffering();
 *
 *   for (double t = 0.0; true; t += 0.02) {
 *       double x = Math.sin(t);
 *       double y = Math.cos(t);
 *       StdDraw.clear();
 *       StdDraw.filledCircle(x, y, 0.05);
 *       StdDraw.filledCircle(-x, -y, 0.05);
 *       StdDraw.show();
 *       StdDraw.pause(20);
 *   }
 *  </pre>
 *  <p>
 *  <b>Keyboard and mouse inputs.</b>
 *  Standard drawing has very basic support for keyboard and mouse input.
 *  It is much less powerful than most user interface libraries provide, but also much simpler.
 *  You can use the following methods to intercept mouse events:
 *  <ul>
 *  <li> { @link  #isMousePressed()}
 *  <li> { @link  #mouseX()}
 *  <li> { @link  #mouseY()}
 *  </ul>
 *  <p>
 *  The first method tells you whether a mouse button is currently being pressed.
 *  The last two methods tells you the <em>x</em>- and <em>y</em>-coordinates of the mouse's
 *  current position, using the same coordinate system as the canvas (the unit square, by default).
 *  You should use these methods in an animation loop that waits a short while before trying
 *  to poll the mouse for its current state.
 *  You can use the following methods to intercept keyboard events:
 *  <ul>
 *  <li> { @link  #hasNextKeyTyped()}
 *  <li> { @link  #nextKeyTyped()}
 *  <li> { @link  #isKeyPressed(int keycode)}
 *  </ul>
 *  <p>
 *  If the user types lots of keys, they will be saved in a list until you process them.
 *  The first method tells you whether the user has typed a key (that your program has
 *  not yet processed).
 *  The second method returns the next key that the user typed (that your program has
 *  not yet processed) and removes it from the list of saved keystrokes.
 *  The third method tells you whether a key is currently being pressed.
 *  <p>
 *  <b>Accessing control parameters.</b>
 *  You can use the following methods to access the current pen color, pen radius,
 *  and font:
 *  <ul>
 *  <li> { @link  #getPenColor()}
 *  <li> { @link  #getPenRadius()}
 *  <li> { @link  #getFont()}
 *  </ul>
 *  <p>
 *  These methods are useful when you want to temporarily change a
 *  control parameter and reset it back to its original value.
 *  <p>
 *  <b>Corner cases.</b>
 *  Here are some corner cases.
 *  <ul>
 *  <li> Drawing an object outside (or partly outside) the canvas is permitted.
 *       However, only the part of the object that appears inside the canvas
 *       will be visible.
 *  <li> Any method that is passed a { @code  null} argument will throw an
 *       { @link  IllegalArgumentException}.
 *  <li> Any method that is passed a { @link  Double#NaN},
 *       { @link  Double#POSITIVE_INFINITY}, or { @link  Double#NEGATIVE_INFINITY}
 *       argument will throw an { @link  IllegalArgumentException}.
 *  <li> Due to floating-point issues, an object drawn with an <em>x</em>- or
 *       <em>y</em>-coordinate that is way outside the canvas (such as the line segment
 *       from (0.5, –10^308) to (0.5, 10^308) may not be visible even in the
 *       part of the canvas where it should be.
 *  </ul>
 *  <p>
 *  <b>Performance tricks.</b>
 *  Standard drawing is capable of drawing large amounts of data.
 *  Here are a few tricks and tips:
 *  <ul>
 *  <li> Use <em>double buffering</em> for static drawing with a large
 *       number of objects.
 *       That is, call { @link  #enableDoubleBuffering()} before
 *       the sequence of drawing commands and call { @link  #show()} afterwards.
 *       Incrementally displaying a complex drawing while it is being
 *       created can be intolerably inefficient on many computer systems.
 *  <li> When drawing computer animations, call { @code  show()}
 *       only once per frame, not after drawing each individual object.
 *  <li> If you call { @code  picture()} multiple times with the same filename,
 *       Java will cache the image, so you do not incur the cost of reading
 *       from a file each time.
 *  </ul>
 *  <p>
 *  <b>Known bugs and issues.</b>
 *  <ul>
 *  <li> The { @code  picture()} methods may not draw the portion of the image that is
 *       inside the canvas if the center point (<em>x</em>, <em>y</em>) is outside the
 *       canvas.
 *       This bug appears only on some systems.
 *  </ul>
 *  <p>
 *  <b>Reference.</b>
 *  For additional documentation,
 *  see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of
 *  <em>Computer Science: An Interdisciplinary Approach</em>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   StdDraw   implements   ActionListener ,   MouseListener ,   MouseMotionListener ,   KeyListener   {

     /**
     *  The color black.
     */
     public   static   final   Color  BLACK  =   Color . BLACK ;

     /**
     *  The color blue.
     */
     public   static   final   Color  BLUE  =   Color . BLUE ;

     /**
     *  The color cyan.
     */
     public   static   final   Color  CYAN  =   Color . CYAN ;

     /**
     *  The color dark gray.
     */
     public   static   final   Color  DARK_GRAY  =   Color . DARK_GRAY ;

     /**
     *  The color gray.
     */
     public   static   final   Color  GRAY  =   Color . GRAY ;

     /**
     *  The color green.
     */
     public   static   final   Color  GREEN   =   Color . GREEN ;

     /**
     *  The color light gray.
     */
     public   static   final   Color  LIGHT_GRAY  =   Color . LIGHT_GRAY ;

     /**
     *  The color magenta.
     */
     public   static   final   Color  MAGENTA  =   Color . MAGENTA ;

     /**
     *  The color orange.
     */
     public   static   final   Color  ORANGE  =   Color . ORANGE ;

     /**
     *  The color pink.
     */
     public   static   final   Color  PINK  =   Color . PINK ;

     /**
     *  The color red.
     */
     public   static   final   Color  RED  =   Color . RED ;

     /**
     *  The color white.
     */
     public   static   final   Color  WHITE  =   Color . WHITE ;

     /**
     *  The color yellow.
     */
     public   static   final   Color  YELLOW  =   Color . YELLOW ;

     /**
     * Shade of blue used in <em>Introduction to Programming in Java</em>.
     * It is Pantone 300U. The RGB values are approximately (9, 90, 166).
     */
     public   static   final   Color  BOOK_BLUE  =   new   Color ( 9 ,   90 ,   166 );

     /**
     * Shade of light blue used in <em>Introduction to Programming in Java</em>.
     * The RGB values are approximately (103, 198, 243).
     */
     public   static   final   Color  BOOK_LIGHT_BLUE  =   new   Color ( 103 ,   198 ,   243 );

     /**
     * Shade of red used in <em>Algorithms, 4th edition</em>.
     * It is Pantone 1805U. The RGB values are approximately (150, 35, 31).
     */
     public   static   final   Color  BOOK_RED  =   new   Color ( 150 ,   35 ,   31 );

     /**
     * Shade of orange used in Princeton University's identity.
     * It is PMS 158. The RGB values are approximately (245, 128, 37).
     */
     public   static   final   Color  PRINCETON_ORANGE  =   new   Color ( 245 ,   128 ,   37 );

     // default colors
     private   static   final   Color  DEFAULT_PEN_COLOR    =  BLACK ;
     private   static   final   Color  DEFAULT_CLEAR_COLOR  =  WHITE ;

     // current pen color
     private   static   Color  penColor ;

     // default canvas size is DEFAULT_SIZE-by-DEFAULT_SIZE
     private   static   final   int  DEFAULT_SIZE  =   512 ;
     private   static   int  width   =  DEFAULT_SIZE ;
     private   static   int  height  =  DEFAULT_SIZE ;

     // default pen radius
     private   static   final   double  DEFAULT_PEN_RADIUS  =   0.002 ;

     // current pen radius
     private   static   double  penRadius ;

     // show we draw immediately or wait until next show?
     private   static   boolean  defer  =   false ;

     // boundary of drawing canvas, 0% border
     // private static final double BORDER = 0.05;
     private   static   final   double  BORDER  =   0.00 ;
     private   static   final   double  DEFAULT_XMIN  =   0.0 ;
     private   static   final   double  DEFAULT_XMAX  =   1.0 ;
     private   static   final   double  DEFAULT_YMIN  =   0.0 ;
     private   static   final   double  DEFAULT_YMAX  =   1.0 ;
     private   static   double  xmin ,  ymin ,  xmax ,  ymax ;

     // for synchronization
     private   static   Object  mouseLock  =   new   Object ();
     private   static   Object  keyLock  =   new   Object ();

     // default font
     private   static   final   Font  DEFAULT_FONT  =   new   Font ( "SansSerif" ,   Font . PLAIN ,   16 );

     // current font
     private   static   Font  font ;

     // double buffered graphics
     private   static   BufferedImage  offscreenImage ,  onscreenImage ;
     private   static   Graphics2D  offscreen ,  onscreen ;

     // singleton for callbacks: avoids generation of extra .class files
     private   static   StdDraw  std  =   new   StdDraw ();

     // the frame for drawing to the screen
     private   static   JFrame  frame ;

     // mouse state
     private   static   boolean  isMousePressed  =   false ;
     private   static   double  mouseX  =   0 ;
     private   static   double  mouseY  =   0 ;

     // queue of typed key characters
     private   static   LinkedList < Character >  keysTyped  =   new   LinkedList < Character > ();

     // set of key codes currently pressed down
     private   static   TreeSet < Integer >  keysDown  =   new   TreeSet < Integer > ();

     // singleton pattern: client can't instantiate
     private   StdDraw ()   {   }


     // static initializer
     static   {
        init ();
     }

     /**
     * Sets the canvas (drawing area) to be 512-by-512 pixels.
     * This also erases the current drawing and resets the coordinate system,
     * pen radius, pen color, and font back to their default values.
     * Ordinarly, this method is called once, at the very beginning
     * of a program.
     */
     public   static   void  setCanvasSize ()   {
        setCanvasSize ( DEFAULT_SIZE ,  DEFAULT_SIZE );
     }

     /**
     * Sets the canvas (drawing area) to be <em>width</em>-by-<em>height</em> pixels.
     * This also erases the current drawing and resets the coordinate system,
     * pen radius, pen color, and font back to their default values.
     * Ordinarly, this method is called once, at the very beginning
     * of a program.
     *
     *  @param   canvasWidth the width as a number of pixels
     *  @param   canvasHeight the height as a number of pixels
     *  @throws  IllegalArgumentException unless both { @code  canvasWidth} and
     *         { @code  canvasHeight} are positive
     */
     public   static   void  setCanvasSize ( int  canvasWidth ,   int  canvasHeight )   {
         if   ( canvasWidth  <=   0 )   throw   new   IllegalArgumentException ( "width must be positive" );
         if   ( canvasHeight  <=   0 )   throw   new   IllegalArgumentException ( "height must be positive" );
        width  =  canvasWidth ;
        height  =  canvasHeight ;
        init ();
     }

     // init
     private   static   void  init ()   {
         if   ( frame  !=   null )  frame . setVisible ( false );
        frame  =   new   JFrame ();
        offscreenImage  =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );
        onscreenImage   =   new   BufferedImage ( 2 * width ,   2 * height ,   BufferedImage . TYPE_INT_ARGB );
        offscreen  =  offscreenImage . createGraphics ();
        onscreen   =  onscreenImage . createGraphics ();
        offscreen . scale ( 2.0 ,   2.0 );    // since we made it 2x as big

        setXscale ();
        setYscale ();
        offscreen . setColor ( DEFAULT_CLEAR_COLOR );
        offscreen . fillRect ( 0 ,   0 ,  width ,  height );
        setPenColor ();
        setPenRadius ();
        setFont ();
        clear ();

         // add antialiasing
         RenderingHints  hints  =   new   RenderingHints ( RenderingHints . KEY_ANTIALIASING ,
                                                   RenderingHints . VALUE_ANTIALIAS_ON );
        hints . put ( RenderingHints . KEY_RENDERING ,   RenderingHints . VALUE_RENDER_QUALITY );
        offscreen . addRenderingHints ( hints );

         // frame stuff
         RetinaImageIcon  icon  =   new   RetinaImageIcon ( onscreenImage );
         JLabel  draw  =   new   JLabel ( icon );

        draw . addMouseListener ( std );
        draw . addMouseMotionListener ( std );

        frame . setContentPane ( draw );
        frame . addKeyListener ( std );      // JLabel cannot get keyboard focus
        frame . setFocusTraversalKeysEnabled ( false );    // allow VK_TAB with isKeyPressed()
        frame . setResizable ( false );
        frame . setDefaultCloseOperation ( JFrame . EXIT_ON_CLOSE );              // closes all windows
         // frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);      // closes only current window
        frame . setTitle ( "Standard Draw" );
        frame . setJMenuBar ( createMenuBar ());
        frame . pack ();
        frame . requestFocusInWindow ();
        frame . setVisible ( true );
     }

     // create the menu bar (changed to private)
     private   static   JMenuBar  createMenuBar ()   {
         JMenuBar  menuBar  =   new   JMenuBar ();
         JMenu  menu  =   new   JMenu ( "File" );
        menuBar . add ( menu );
         JMenuItem  menuItem1  =   new   JMenuItem ( " Save...   " );
        menuItem1 . addActionListener ( std );
         // Java 10+: replace getMenuShortcutKeyMask() with getMenuShortcutKeyMaskEx()
        menuItem1 . setAccelerator ( KeyStroke . getKeyStroke ( KeyEvent . VK_S ,
                                 Toolkit . getDefaultToolkit (). getMenuShortcutKeyMask ()));
        menu . add ( menuItem1 );
         return  menuBar ;
     }

    /***************************************************************************
    *  User and screen coordinate systems.
    ***************************************************************************/

     // throw an IllegalArgumentException if x is NaN or infinite
     private   static   void  validate ( double  x ,   String  name )   {
         if   ( Double . isNaN ( x ))   throw   new   IllegalArgumentException ( name  +   " is NaN" );
         if   ( Double . isInfinite ( x ))   throw   new   IllegalArgumentException ( name  +   " is infinite" );
     }

     // throw an IllegalArgumentException if s is null
     private   static   void  validateNonnegative ( double  x ,   String  name )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( name  +   " negative" );
     }

     // throw an IllegalArgumentException if s is null
     private   static   void  validateNotNull ( Object  x ,   String  name )   {
         if   ( ==   null )   throw   new   IllegalArgumentException ( name  +   " is null" );
     }


     /**
     * Sets the <em>x</em>-scale to be the default (between 0.0 and 1.0).
     */
     public   static   void  setXscale ()   {
        setXscale ( DEFAULT_XMIN ,  DEFAULT_XMAX );
     }

     /**
     * Sets the <em>y</em>-scale to be the default (between 0.0 and 1.0).
     */
     public   static   void  setYscale ()   {
        setYscale ( DEFAULT_YMIN ,  DEFAULT_YMAX );
     }

     /**
     * Sets the <em>x</em>-scale and <em>y</em>-scale to be the default
     * (between 0.0 and 1.0).
     */
     public   static   void  setScale ()   {
        setXscale ();
        setYscale ();
     }

     /**
     * Sets the <em>x</em>-scale to the specified range.
     *
     *  @param   min the minimum value of the <em>x</em>-scale
     *  @param   max the maximum value of the <em>x</em>-scale
     *  @throws  IllegalArgumentException if { @code  (max == min)}
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite
     */
     public   static   void  setXscale ( double  min ,   double  max )   {
        validate ( min ,   "min" );
        validate ( max ,   "max" );
         double  size  =  max  -  min ;
         if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );
         synchronized   ( mouseLock )   {
            xmin  =  min  -  BORDER  *  size ;
            xmax  =  max  +  BORDER  *  size ;
         }
     }

     /**
     * Sets the <em>y</em>-scale to the specified range.
     *
     *  @param   min the minimum value of the <em>y</em>-scale
     *  @param   max the maximum value of the <em>y</em>-scale
     *  @throws  IllegalArgumentException if { @code  (max == min)}
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite
     */
     public   static   void  setYscale ( double  min ,   double  max )   {
        validate ( min ,   "min" );
        validate ( max ,   "max" );
         double  size  =  max  -  min ;
         if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );
         synchronized   ( mouseLock )   {
            ymin  =  min  -  BORDER  *  size ;
            ymax  =  max  +  BORDER  *  size ;
         }
     }

     /**
     * Sets both the <em>x</em>-scale and <em>y</em>-scale to the (same) specified range.
     *
     *  @param   min the minimum value of the <em>x</em>- and <em>y</em>-scales
     *  @param   max the maximum value of the <em>x</em>- and <em>y</em>-scales
     *  @throws  IllegalArgumentException if { @code  (max == min)}
     *  @throws  IllegalArgumentException if either { @code  min} or { @code  max} is either NaN or infinite
     */
     public   static   void  setScale ( double  min ,   double  max )   {
        validate ( min ,   "min" );
        validate ( max ,   "max" );
         double  size  =  max  -  min ;
         if   ( size  ==   0.0 )   throw   new   IllegalArgumentException ( "the min and max are the same" );
         synchronized   ( mouseLock )   {
            xmin  =  min  -  BORDER  *  size ;
            xmax  =  max  +  BORDER  *  size ;
            ymin  =  min  -  BORDER  *  size ;
            ymax  =  max  +  BORDER  *  size ;
         }
     }

     // helper functions that scale from user coordinates to screen coordinates and back
     private   static   double   scaleX ( double  x )   {   return  width   *   ( -  xmin )   /   ( xmax  -  xmin );   }
     private   static   double   scaleY ( double  y )   {   return  height  *   ( ymax  -  y )   /   ( ymax  -  ymin );   }
     private   static   double  factorX ( double  w )   {   return  w  *  width   /   Math . abs ( xmax  -  xmin );    }
     private   static   double  factorY ( double  h )   {   return  h  *  height  /   Math . abs ( ymax  -  ymin );    }
     private   static   double    userX ( double  x )   {   return  xmin  +  x  *   ( xmax  -  xmin )   /  width ;      }
     private   static   double    userY ( double  y )   {   return  ymax  -  y  *   ( ymax  -  ymin )   /  height ;     }


     /**
     * Clears the screen to the default color (white).
     */
     public   static   void  clear ()   {
        clear ( DEFAULT_CLEAR_COLOR );
     }

     /**
     * Clears the screen to the specified color.
     *
     *  @param  color the color to make the background
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   static   void  clear ( Color  color )   {
        validateNotNull ( color ,   "color" );
        offscreen . setColor ( color );
        offscreen . fillRect ( 0 ,   0 ,  width ,  height );
        offscreen . setColor ( penColor );
        draw ();
     }

     /**
     * Returns the current pen radius.
     *
     *  @return  the current value of the pen radius
     */
     public   static   double  getPenRadius ()   {
         return  penRadius ;
     }

     /**
     * Sets the pen size to the default size (0.002).
     * The pen is circular, so that lines have rounded ends, and when you set the
     * pen radius and draw a point, you get a circle of the specified radius.
     * The pen radius is not affected by coordinate scaling.
     */
     public   static   void  setPenRadius ()   {
        setPenRadius ( DEFAULT_PEN_RADIUS );
     }

     /**
     * Sets the radius of the pen to the specified size.
     * The pen is circular, so that lines have rounded ends, and when you set the
     * pen radius and draw a point, you get a circle of the specified radius.
     * The pen radius is not affected by coordinate scaling.
     *
     *  @param   radius the radius of the pen
     *  @throws  IllegalArgumentException if { @code  radius} is negative, NaN, or infinite
     */
     public   static   void  setPenRadius ( double  radius )   {
        validate ( radius ,   "pen radius" );
        validateNonnegative ( radius ,   "pen radius" );

        penRadius  =  radius ;
         float  scaledPenRadius  =   ( float )   ( radius  *  DEFAULT_SIZE );
         BasicStroke  stroke  =   new   BasicStroke ( scaledPenRadius ,   BasicStroke . CAP_ROUND ,   BasicStroke . JOIN_ROUND );
         // BasicStroke stroke = new BasicStroke(scaledPenRadius);
        offscreen . setStroke ( stroke );
     }

     /**
     * Returns the current pen color.
     *
     *  @return  the current pen color
     */
     public   static   Color  getPenColor ()   {
         return  penColor ;
     }

     /**
     * Sets the pen color to the default color (black).
     */
     public   static   void  setPenColor ()   {
        setPenColor ( DEFAULT_PEN_COLOR );
     }

     /**
     * Sets the pen color to the specified color.
     * <p>
     * The predefined pen colors are
     * { @code  StdDraw.BLACK}, { @code  StdDraw.BLUE}, { @code  StdDraw.CYAN},
     * { @code  StdDraw.DARK_GRAY}, { @code  StdDraw.GRAY}, { @code  StdDraw.GREEN},
     * { @code  StdDraw.LIGHT_GRAY}, { @code  StdDraw.MAGENTA}, { @code  StdDraw.ORANGE},
     * { @code  StdDraw.PINK}, { @code  StdDraw.RED}, { @code  StdDraw.WHITE}, and
     * { @code  StdDraw.YELLOW}.
     *
     *  @param  color the color to make the pen
     *  @throws  IllegalArgumentException if { @code  color} is { @code  null}
     */
     public   static   void  setPenColor ( Color  color )   {
        validateNotNull ( color ,   "color" );
        penColor  =  color ;
        offscreen . setColor ( penColor );
     }

     /**
     * Sets the pen color to the specified RGB color.
     *
     *  @param   red the amount of red (between 0 and 255)
     *  @param   green the amount of green (between 0 and 255)
     *  @param   blue the amount of blue (between 0 and 255)
     *  @throws  IllegalArgumentException if { @code  red}, { @code  green},
     *         or { @code  blue} is outside its prescribed range
     */
     public   static   void  setPenColor ( int  red ,   int  green ,   int  blue )   {
         if   ( red    <   0   ||  red    >=   256 )   throw   new   IllegalArgumentException ( "red must be between 0 and 255" );
         if   ( green  <   0   ||  green  >=   256 )   throw   new   IllegalArgumentException ( "green must be between 0 and 255" );
         if   ( blue   <   0   ||  blue   >=   256 )   throw   new   IllegalArgumentException ( "blue must be between 0 and 255" );
        setPenColor ( new   Color ( red ,  green ,  blue ));
     }

     /**
     * Returns the current font.
     *
     *  @return  the current font
     */
     public   static   Font  getFont ()   {
         return  font ;
     }

     /**
     * Sets the font to the default font (sans serif, 16 point).
     */
     public   static   void  setFont ()   {
        setFont ( DEFAULT_FONT );
     }

     /**
     * Sets the font to the specified value.
     *
     *  @param  font the font
     *  @throws  IllegalArgumentException if { @code  font} is { @code  null}
     */
     public   static   void  setFont ( Font  font )   {
        validateNotNull ( font ,   "font" );
         StdDraw . font  =  font ;
     }


    /***************************************************************************
    *  Drawing geometric shapes.
    ***************************************************************************/

     /**
     * Draws a line segment between (<em>x</em><sub>0</sub>, <em>y</em><sub>0</sub>) and
     * (<em>x</em><sub>1</sub>, <em>y</em><sub>1</sub>).
     *
     *  @param   x0 the <em>x</em>-coordinate of one endpoint
     *  @param   y0 the <em>y</em>-coordinate of one endpoint
     *  @param   x1 the <em>x</em>-coordinate of the other endpoint
     *  @param   y1 the <em>y</em>-coordinate of the other endpoint
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     */
     public   static   void  line ( double  x0 ,   double  y0 ,   double  x1 ,   double  y1 )   {
        validate ( x0 ,   "x0" );
        validate ( y0 ,   "y0" );
        validate ( x1 ,   "x1" );
        validate ( y1 ,   "y1" );
        offscreen . draw ( new   Line2D . Double ( scaleX ( x0 ),  scaleY ( y0 ),  scaleX ( x1 ),  scaleY ( y1 )));
        draw ();
     }

     /**
     * Draws one pixel at (<em>x</em>, <em>y</em>).
     * This method is private because pixels depend on the display.
     * To achieve the same effect, set the pen radius to 0 and call { @code  point()}.
     *
     *  @param   x the <em>x</em>-coordinate of the pixel
     *  @param   y the <em>y</em>-coordinate of the pixel
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     private   static   void  pixel ( double  x ,   double  y )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        offscreen . fillRect (( int )   Math . round ( scaleX ( x )),   ( int )   Math . round ( scaleY ( y )),   1 ,   1 );
     }

     /**
     * Draws a point centered at (<em>x</em>, <em>y</em>).
     * The point is a filled circle whose radius is equal to the pen radius.
     * To draw a single-pixel point, first set the pen radius to 0.
     *
     *  @param  x the <em>x</em>-coordinate of the point
     *  @param  y the <em>y</em>-coordinate of the point
     *  @throws  IllegalArgumentException if either { @code  x} or { @code  y} is either NaN or infinite
     */
     public   static   void  point ( double  x ,   double  y )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  r  =  penRadius ;
         float  scaledPenRadius  =   ( float )   ( *  DEFAULT_SIZE );

         // double ws = factorX(2*r);
         // double hs = factorY(2*r);
         // if (ws <= 1 && hs <= 1) pixel(x, y);
         if   ( scaledPenRadius  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  scaledPenRadius / 2 ,  ys  -  scaledPenRadius / 2 ,
                                                 scaledPenRadius ,  scaledPenRadius ));
        draw ();
     }

     /**
     * Draws a circle of the specified radius, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the circle
     *  @param   y the <em>y</em>-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  circle ( double  x ,   double  y ,   double  radius )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "radius" );
        validateNonnegative ( radius ,   "radius" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled circle of the specified radius, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the circle
     *  @param   y the <em>y</em>-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  filledCircle ( double  x ,   double  y ,   double  radius )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "radius" );
        validateNonnegative ( radius ,   "radius" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws an ellipse with the specified semimajor and semiminor axes,
     * centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the ellipse
     *  @param   y the <em>y</em>-coordinate of the center of the ellipse
     *  @param   semiMajorAxis is the semimajor axis of the ellipse
     *  @param   semiMinorAxis is the semiminor axis of the ellipse
     *  @throws  IllegalArgumentException if either { @code  semiMajorAxis}
     *         or { @code  semiMinorAxis} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  ellipse ( double  x ,   double  y ,   double  semiMajorAxis ,   double  semiMinorAxis )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( semiMajorAxis ,   "semimajor axis" );
        validate ( semiMinorAxis ,   "semiminor axis" );
        validateNonnegative ( semiMajorAxis ,   "semimajor axis" );
        validateNonnegative ( semiMinorAxis ,   "semiminor axis" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * semiMajorAxis );
         double  hs  =  factorY ( 2 * semiMinorAxis );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled ellipse with the specified semimajor and semiminor axes,
     * centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the ellipse
     *  @param   y the <em>y</em>-coordinate of the center of the ellipse
     *  @param   semiMajorAxis is the semimajor axis of the ellipse
     *  @param   semiMinorAxis is the semiminor axis of the ellipse
     *  @throws  IllegalArgumentException if either { @code  semiMajorAxis}
     *         or { @code  semiMinorAxis} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  filledEllipse ( double  x ,   double  y ,   double  semiMajorAxis ,   double  semiMinorAxis )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( semiMajorAxis ,   "semimajor axis" );
        validate ( semiMinorAxis ,   "semiminor axis" );
        validateNonnegative ( semiMajorAxis ,   "semimajor axis" );
        validateNonnegative ( semiMinorAxis ,   "semiminor axis" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * semiMajorAxis );
         double  hs  =  factorY ( 2 * semiMinorAxis );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Ellipse2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws a circular arc of the specified radius,
     * centered at (<em>x</em>, <em>y</em>), from angle1 to angle2 (in degrees).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the circle
     *  @param   y the <em>y</em>-coordinate of the center of the circle
     *  @param   radius the radius of the circle
     *  @param   angle1 the starting angle. 0 would mean an arc beginning at 3 o'clock.
     *  @param   angle2 the angle at the end of the arc. For example, if
     *         you want a 90 degree arc, then angle2 should be angle1 + 90.
     *  @throws  IllegalArgumentException if { @code  radius} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  arc ( double  x ,   double  y ,   double  radius ,   double  angle1 ,   double  angle2 )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( radius ,   "arc radius" );
        validate ( angle1 ,   "angle1" );
        validate ( angle2 ,   "angle2" );
        validateNonnegative ( radius ,   "arc radius" );

         while   ( angle2  <  angle1 )  angle2  +=   360 ;
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * radius );
         double  hs  =  factorY ( 2 * radius );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Arc2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ,  angle1 ,  angle2  -  angle1 ,   Arc2D . OPEN ));
        draw ();
     }

     /**
     * Draws a square of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the square
     *  @param   y the <em>y</em>-coordinate of the center of the square
     *  @param   halfLength one half the length of any side of the square
     *  @throws  IllegalArgumentException if { @code  halfLength} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  square ( double  x ,   double  y ,   double  halfLength )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfLength ,   "halfLength" );
        validateNonnegative ( halfLength ,   "half length" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfLength );
         double  hs  =  factorY ( 2 * halfLength );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled square of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the square
     *  @param   y the <em>y</em>-coordinate of the center of the square
     *  @param   halfLength one half the length of any side of the square
     *  @throws  IllegalArgumentException if { @code  halfLength} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  filledSquare ( double  x ,   double  y ,   double  halfLength )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfLength ,   "halfLength" );
        validateNonnegative ( halfLength ,   "half length" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfLength );
         double  hs  =  factorY ( 2 * halfLength );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws a rectangle of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the rectangle
     *  @param   y the <em>y</em>-coordinate of the center of the rectangle
     *  @param   halfWidth one half the width of the rectangle
     *  @param   halfHeight one half the height of the rectangle
     *  @throws  IllegalArgumentException if either { @code  halfWidth} or { @code  halfHeight} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  rectangle ( double  x ,   double  y ,   double  halfWidth ,   double  halfHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfWidth ,   "halfWidth" );
        validate ( halfHeight ,   "halfHeight" );
        validateNonnegative ( halfWidth ,   "half width" );
        validateNonnegative ( halfHeight ,   "half height" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfWidth );
         double  hs  =  factorY ( 2 * halfHeight );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . draw ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }

     /**
     * Draws a filled rectangle of the specified size, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the center of the rectangle
     *  @param   y the <em>y</em>-coordinate of the center of the rectangle
     *  @param   halfWidth one half the width of the rectangle
     *  @param   halfHeight one half the height of the rectangle
     *  @throws  IllegalArgumentException if either { @code  halfWidth} or { @code  halfHeight} is negative
     *  @throws  IllegalArgumentException if any argument is either NaN or infinite
     */
     public   static   void  filledRectangle ( double  x ,   double  y ,   double  halfWidth ,   double  halfHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( halfWidth ,   "halfWidth" );
        validate ( halfHeight ,   "halfHeight" );
        validateNonnegative ( halfWidth ,   "half width" );
        validateNonnegative ( halfHeight ,   "half height" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( 2 * halfWidth );
         double  hs  =  factorY ( 2 * halfHeight );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else  offscreen . fill ( new   Rectangle2D . Double ( xs  -  ws / 2 ,  ys  -  hs / 2 ,  ws ,  hs ));
        draw ();
     }


     /**
     * Draws a polygon with the vertices 
     * (<em>x</em><sub>0</sub>, <em>y</em><sub>0</sub>),
     * (<em>x</em><sub>1</sub>, <em>y</em><sub>1</sub>), ...,
     * (<em>x</em><sub><em>n</em>–1</sub>, <em>y</em><sub><em>n</em>–1</sub>).
     *
     *  @param   x an array of all the <em>x</em>-coordinates of the polygon
     *  @param   y an array of all the <em>y</em>-coordinates of the polygon
     *  @throws  IllegalArgumentException unless { @code  x[]} and { @code  y[]}
     *         are of the same length
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     *  @throws  IllegalArgumentException if either { @code  x[]} or { @code  y[]} is { @code  null}
     */
     public   static   void  polygon ( double []  x ,   double []  y )   {
        validateNotNull ( x ,   "x-coordinate array" );
        validateNotNull ( y ,   "y-coordinate array" );
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )  validate ( x [ i ],   "x["   +  i  +   "]" );
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )  validate ( y [ i ],   "y["   +  i  +   "]" );

         int  n1  =  x . length ;
         int  n2  =  y . length ;
         if   ( n1  !=  n2 )   throw   new   IllegalArgumentException ( "arrays must be of the same length" );
         int  n  =  n1 ;
         if   ( ==   0 )   return ;

         GeneralPath  path  =   new   GeneralPath ();
        path . moveTo (( float )  scaleX ( x [ 0 ]),   ( float )  scaleY ( y [ 0 ]));
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            path . lineTo (( float )  scaleX ( x [ i ]),   ( float )  scaleY ( y [ i ]));
        path . closePath ();
        offscreen . draw ( path );
        draw ();
     }

     /**
     * Draws a filled polygon with the vertices 
     * (<em>x</em><sub>0</sub>, <em>y</em><sub>0</sub>),
     * (<em>x</em><sub>1</sub>, <em>y</em><sub>1</sub>), ...,
     * (<em>x</em><sub><em>n</em>–1</sub>, <em>y</em><sub><em>n</em>–1</sub>).
     *
     *  @param   x an array of all the <em>x</em>-coordinates of the polygon
     *  @param   y an array of all the <em>y</em>-coordinates of the polygon
     *  @throws  IllegalArgumentException unless { @code  x[]} and { @code  y[]}
     *         are of the same length
     *  @throws  IllegalArgumentException if any coordinate is either NaN or infinite
     *  @throws  IllegalArgumentException if either { @code  x[]} or { @code  y[]} is { @code  null}
     */
     public   static   void  filledPolygon ( double []  x ,   double []  y )   {
        validateNotNull ( x ,   "x-coordinate array" );
        validateNotNull ( y ,   "y-coordinate array" );
         for   ( int  i  =   0 ;  i  <  x . length ;  i ++ )  validate ( x [ i ],   "x["   +  i  +   "]" );
         for   ( int  i  =   0 ;  i  <  y . length ;  i ++ )  validate ( y [ i ],   "y["   +  i  +   "]" );

         int  n1  =  x . length ;
         int  n2  =  y . length ;
         if   ( n1  !=  n2 )   throw   new   IllegalArgumentException ( "arrays must be of the same length" );
         int  n  =  n1 ;
         if   ( ==   0 )   return ;

         GeneralPath  path  =   new   GeneralPath ();
        path . moveTo (( float )  scaleX ( x [ 0 ]),   ( float )  scaleY ( y [ 0 ]));
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            path . lineTo (( float )  scaleX ( x [ i ]),   ( float )  scaleY ( y [ i ]));
        path . closePath ();
        offscreen . fill ( path );
        draw ();
     }


    /***************************************************************************
    *  Drawing images.
    ***************************************************************************/
     // get an image from the given filename
     private   static   Image  getImage ( String  filename )   {
         if   ( filename  ==   null )   throw   new   IllegalArgumentException ();

         // to read from file
         ImageIcon  icon  =   new   ImageIcon ( filename );

         // try to read from URL
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
             try   {
                URL url  =   new  URL ( filename );
                icon  =   new   ImageIcon ( url );
             }
             catch   ( MalformedURLException  e )   {
                 /* not a url */
             }
         }

         // in case file is inside a .jar (classpath relative to StdDraw)
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
            URL url  =   StdDraw . class . getResource ( filename );
             if   ( url  !=   null )
                icon  =   new   ImageIcon ( url );
         }

         // in case file is inside a .jar (classpath relative to root of jar)
         if   (( icon  ==   null )   ||   ( icon . getImageLoadStatus ()   !=   MediaTracker . COMPLETE ))   {
            URL url  =   StdDraw . class . getResource ( "/"   +  filename );
             if   ( url  ==   null )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " not found" );
            icon  =   new   ImageIcon ( url );
         }

         return  icon . getImage ();
     }

    /***************************************************************************
    * [Summer 2016] Should we update to use ImageIO instead of ImageIcon()?
    *               Seems to have some issues loading images on some systems
    *               and slows things down on other systems.
    *               especially if you don't call ImageIO.setUseCache(false)
    *               One advantage is that it returns a BufferedImage.
    ***************************************************************************/
/*
    private static BufferedImage getImage(String filename) {
        if (filename == null) throw new IllegalArgumentException();

        // from a file or URL
        try {
            URL url = new URL(filename);
            BufferedImage image = ImageIO.read(url);
            return image;
        } 
        catch (IOException e) {
            // ignore
        }

        // in case file is inside a .jar (classpath relative to StdDraw)
        try {
            URL url = StdDraw.class.getResource(filename);
            BufferedImage image = ImageIO.read(url);
            return image;
        } 
        catch (IOException e) {
            // ignore
        }

        // in case file is inside a .jar (classpath relative to root of jar)
        try {
            URL url = StdDraw.class.getResource("/" + filename);
            BufferedImage image = ImageIO.read(url);
            return image;
        } 
        catch (IOException e) {
            // ignore
        }
        throw new IllegalArgumentException("image " + filename + " not found");
    }
*/
     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>).
     * The supported image formats are JPEG, PNG, and GIF.
     * As an optimization, the picture is cached, so there is no performance
     * penalty for redrawing the same image multiple times (e.g., in an animation).
     * However, if you change the picture file after drawing it, subsequent
     * calls will draw the original picture.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if either { @code  x} or { @code  y} is either NaN or infinite
     */
     public   static   void  picture ( double  x ,   double  y ,   String  filename )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( filename ,   "filename" );

         // BufferedImage image = getImage(filename);
         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         // int ws = image.getWidth();    // can call only if image is a BufferedImage
         // int hs = image.getHeight();
         int  ws  =  image . getWidth ( null );
         int  hs  =  image . getHeight ( null );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );

        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),   ( int )   Math . round ( ys  -  hs / 2.0 ),   null );
        draw ();
     }

     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>),
     * rotated given number of degrees.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if { @code  x}, { @code  y}, { @code  degrees} is NaN or infinite
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   static   void  picture ( double  x ,   double  y ,   String  filename ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( filename ,   "filename" );

         // BufferedImage image = getImage(filename);
         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         // int ws = image.getWidth();    // can call only if image is a BufferedImage
         // int hs = image.getHeight();
         int  ws  =  image . getWidth ( null );
         int  hs  =  image . getHeight ( null );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );

        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),   ( int )   Math . round ( ys  -  hs / 2.0 ),   null );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );

        draw ();
     }

     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>),
     * rescaled to the specified bounding box.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   scaledWidth the width of the scaled image (in screen coordinates)
     *  @param   scaledHeight the height of the scaled image (in screen coordinates)
     *  @throws  IllegalArgumentException if either { @code  scaledWidth}
     *         or { @code  scaledHeight} is negative
     *  @throws  IllegalArgumentException if the image filename is invalid
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   static   void  picture ( double  x ,   double  y ,   String  filename ,   double  scaledWidth ,   double  scaledHeight )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( scaledWidth ,   "scaled width" );
        validate ( scaledHeight ,   "scaled height" );
        validateNotNull ( filename ,   "filename" );
        validateNonnegative ( scaledWidth ,   "scaled width" );
        validateNonnegative ( scaledHeight ,   "scaled height" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( scaledWidth );
         double  hs  =  factorY ( scaledHeight );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );
         else   {
            offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),
                                        ( int )   Math . round ( ys  -  hs / 2.0 ),
                                        ( int )   Math . round ( ws ),
                                        ( int )   Math . round ( hs ),   null );
         }
        draw ();
     }


     /**
     * Draws the specified image centered at (<em>x</em>, <em>y</em>), rotated
     * given number of degrees, and rescaled to the specified bounding box.
     * The supported image formats are JPEG, PNG, and GIF.
     *
     *  @param   x the center <em>x</em>-coordinate of the image
     *  @param   y the center <em>y</em>-coordinate of the image
     *  @param   filename the name of the image/picture, e.g., "ball.gif"
     *  @param   scaledWidth the width of the scaled image (in screen coordinates)
     *  @param   scaledHeight the height of the scaled image (in screen coordinates)
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if either { @code  scaledWidth}
     *         or { @code  scaledHeight} is negative
     *  @throws  IllegalArgumentException if the image filename is invalid
     */
     public   static   void  picture ( double  x ,   double  y ,   String  filename ,   double  scaledWidth ,   double  scaledHeight ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( scaledWidth ,   "scaled width" );
        validate ( scaledHeight ,   "scaled height" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( filename ,   "filename" );
        validateNonnegative ( scaledWidth ,   "scaled width" );
        validateNonnegative ( scaledHeight ,   "scaled height" );

         Image  image  =  getImage ( filename );
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         double  ws  =  factorX ( scaledWidth );
         double  hs  =  factorY ( scaledHeight );
         if   ( ws  <   0   ||  hs  <   0 )   throw   new   IllegalArgumentException ( "image "   +  filename  +   " is corrupt" );
         if   ( ws  <=   1   &&  hs  <=   1 )  pixel ( x ,  y );

        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        offscreen . drawImage ( image ,   ( int )   Math . round ( xs  -  ws / 2.0 ),
                                    ( int )   Math . round ( ys  -  hs / 2.0 ),
                                    ( int )   Math . round ( ws ),
                                    ( int )   Math . round ( hs ),   null );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );

        draw ();
     }

    /***************************************************************************
    *  Drawing text.
    ***************************************************************************/

     /**
     * Writes the given text string in the current font, centered at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the center <em>x</em>-coordinate of the text
     *  @param   y the center <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   static   void  text ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  metrics . stringWidth ( text );
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )   ( xs  -  ws / 2.0 ),   ( float )   ( ys  +  hs ));
        draw ();
     }

     /**
     * Writes the given text string in the current font, centered at (<em>x</em>, <em>y</em>) and
     * rotated by the specified number of degrees.
     *  @param   x the center <em>x</em>-coordinate of the text
     *  @param   y the center <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @param   degrees is the number of degrees to rotate counterclockwise
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x}, { @code  y}, or { @code  degrees} is either NaN or infinite
     */
     public   static   void  text ( double  x ,   double  y ,   String  text ,   double  degrees )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validate ( degrees ,   "degrees" );
        validateNotNull ( text ,   "text" );

         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
        offscreen . rotate ( Math . toRadians ( - degrees ),  xs ,  ys );
        text ( x ,  y ,  text );
        offscreen . rotate ( Math . toRadians ( + degrees ),  xs ,  ys );
     }


     /**
     * Writes the given text string in the current font, left-aligned at (<em>x</em>, <em>y</em>).
     *  @param   x the <em>x</em>-coordinate of the text
     *  @param   y the <em>y</em>-coordinate of the text
     *  @param   text the text
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   static   void  textLeft ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )  xs ,   ( float )   ( ys  +  hs ));
        draw ();
     }

     /**
     * Writes the given text string in the current font, right-aligned at (<em>x</em>, <em>y</em>).
     *
     *  @param   x the <em>x</em>-coordinate of the text
     *  @param   y the <em>y</em>-coordinate of the text
     *  @param   text the text to write
     *  @throws  IllegalArgumentException if { @code  text} is { @code  null}
     *  @throws  IllegalArgumentException if { @code  x} or { @code  y} is either NaN or infinite
     */
     public   static   void  textRight ( double  x ,   double  y ,   String  text )   {
        validate ( x ,   "x" );
        validate ( y ,   "y" );
        validateNotNull ( text ,   "text" );

        offscreen . setFont ( font );
         FontMetrics  metrics  =  offscreen . getFontMetrics ();
         double  xs  =  scaleX ( x );
         double  ys  =  scaleY ( y );
         int  ws  =  metrics . stringWidth ( text );
         int  hs  =  metrics . getDescent ();
        offscreen . drawString ( text ,   ( float )   ( xs  -  ws ),   ( float )   ( ys  +  hs ));
        draw ();
     }


     /**
     * Copies the offscreen buffer to the onscreen buffer, pauses for t milliseconds
     * and enables double buffering.
     *  @param  t number of milliseconds
     *  @deprecated  replaced by { @link  #enableDoubleBuffering()}, { @link  #show()}, and { @link  #pause(int t)}
     */
    @ Deprecated
     public   static   void  show ( int  t )   {
        validateNonnegative ( t ,   "t" );
        show ();
        pause ( t );
        enableDoubleBuffering ();
     }

     /**
     * Pauses for t milliseconds. This method is intended to support computer animations.
     *  @param  t number of milliseconds
     */
     public   static   void  pause ( int  t )   {
        validateNonnegative ( t ,   "t" );
         try   {
             Thread . sleep ( t );
         }
         catch   ( InterruptedException  e )   {
             System . out . println ( "Error sleeping" );
         }
     }

     /**
     * Copies offscreen buffer to onscreen buffer. There is no reason to call
     * this method unless double buffering is enabled.
     */
     public   static   void  show ()   {
        onscreen . drawImage ( offscreenImage ,   0 ,   0 ,   null );
        frame . repaint ();
     }

     // draw onscreen if defer is false
     private   static   void  draw ()   {
         if   ( ! defer )  show ();
     }

     /**
     * Enables double buffering. All subsequent calls to 
     * drawing methods such as { @code  line()}, { @code  circle()},
     * and { @code  square()} will be deferred until the next call
     * to show(). Useful for animations.
     */
     public   static   void  enableDoubleBuffering ()   {
        defer  =   true ;
     }

     /**
     * Disables double buffering. All subsequent calls to 
     * drawing methods such as { @code  line()}, { @code  circle()},
     * and { @code  square()} will be displayed on screen when called.
     * This is the default.
     */
     public   static   void  disableDoubleBuffering ()   {
        defer  =   false ;
     }


    /***************************************************************************
    *  Save drawing to a file.
    ***************************************************************************/

     /**
     * Saves the drawing to using the specified filename.
     * The supported image formats are JPEG and PNG;
     * the filename suffix must be { @code  .jpg} or { @code  .png}.
     *
     *  @param   filename the name of the file with one of the required suffixes
     *  @throws  IllegalArgumentException if { @code  filename} is { @code  null}
     */
     public   static   void  save ( String  filename )   {
        validateNotNull ( filename ,   "filename" );
         File  file  =   new   File ( filename );
         String  suffix  =  filename . substring ( filename . lastIndexOf ( '.' )   +   1 );

         // png files
         if   ( "png" . equalsIgnoreCase ( suffix ))   {
             try   {
                 ImageIO . write ( onscreenImage ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }

         // need to change from ARGB to RGB for JPEG
         // reference: http://archives.java.sun.com/cgi-bin/wa?A2=ind0404&L=java2d-interest&D=0&P=2727
         else   if   ( "jpg" . equalsIgnoreCase ( suffix ))   {
             WritableRaster  raster  =  onscreenImage . getRaster ();
             WritableRaster  newRaster ;
            newRaster  =  raster . createWritableChild ( 0 ,   0 ,  width ,  height ,   0 ,   0 ,   new   int []   { 0 ,   1 ,   2 });
             DirectColorModel  cm  =   ( DirectColorModel )  onscreenImage . getColorModel ();
             DirectColorModel  newCM  =   new   DirectColorModel ( cm . getPixelSize (),
                                                          cm . getRedMask (),
                                                          cm . getGreenMask (),
                                                          cm . getBlueMask ());
             BufferedImage  rgbBuffer  =   new   BufferedImage ( newCM ,  newRaster ,   false ,    null );
             try   {
                 ImageIO . write ( rgbBuffer ,  suffix ,  file );
             }
             catch   ( IOException  e )   {
                e . printStackTrace ();
             }
         }

         else   {
             System . out . println ( "Invalid image file type: "   +  suffix );
         }
     }


     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  actionPerformed ( ActionEvent  e )   {
         FileDialog  chooser  =   new   FileDialog ( StdDraw . frame ,   "Use a .png or .jpg extension" ,   FileDialog . SAVE );
        chooser . setVisible ( true );
         String  filename  =  chooser . getFile ();
         if   ( filename  !=   null )   {
             StdDraw . save ( chooser . getDirectory ()   +   File . separator  +  chooser . getFile ());
         }
     }


    /***************************************************************************
    *  Mouse interactions.
    ***************************************************************************/

     /**
     * Returns true if the mouse is being pressed.
     *
     *  @return  { @code  true} if the mouse is being pressed; { @code  false} otherwise
     */
     public   static   boolean  isMousePressed ()   {
         synchronized   ( mouseLock )   {
             return  isMousePressed ;
         }
     }

     /**
     * Returns true if the mouse is being pressed.
     *
     *  @return  { @code  true} if the mouse is being pressed; { @code  false} otherwise
     *  @deprecated  replaced by { @link  #isMousePressed()}
     */
    @ Deprecated
     public   static   boolean  mousePressed ()   {
         synchronized   ( mouseLock )   {
             return  isMousePressed ;
         }
     }

     /**
     * Returns the <em>x</em>-coordinate of the mouse.
     *
     *  @return  the <em>x</em>-coordinate of the mouse
     */
     public   static   double  mouseX ()   {
         synchronized   ( mouseLock )   {
             return  mouseX ;
         }
     }

     /**
     * Returns the <em>y</em>-coordinate of the mouse.
     *
     *  @return  <em>y</em>-coordinate of the mouse
     */
     public   static   double  mouseY ()   {
         synchronized   ( mouseLock )   {
             return  mouseY ;
         }
     }


     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseClicked ( MouseEvent  e )   {
         // this body is intentionally left empty
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseEntered ( MouseEvent  e )   {
         // this body is intentionally left empty
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseExited ( MouseEvent  e )   {
         // this body is intentionally left empty
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mousePressed ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            mouseX  =   StdDraw . userX ( e . getX ());
            mouseY  =   StdDraw . userY ( e . getY ());
            isMousePressed  =   true ;
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseReleased ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            isMousePressed  =   false ;
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseDragged ( MouseEvent  e )    {
         synchronized   ( mouseLock )   {
            mouseX  =   StdDraw . userX ( e . getX ());
            mouseY  =   StdDraw . userY ( e . getY ());
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  mouseMoved ( MouseEvent  e )   {
         synchronized   ( mouseLock )   {
            mouseX  =   StdDraw . userX ( e . getX ());
            mouseY  =   StdDraw . userY ( e . getY ());
         }
     }


    /***************************************************************************
    *  Keyboard interactions.
    ***************************************************************************/

     /**
     * Returns true if the user has typed a key (that has not yet been processed).
     *
     *  @return  { @code  true} if the user has typed a key (that has not yet been processed
     *         by { @link  #nextKeyTyped()}; { @code  false} otherwise
     */
     public   static   boolean  hasNextKeyTyped ()   {
         synchronized   ( keyLock )   {
             return   ! keysTyped . isEmpty ();
         }
     }

     /**
     * Returns the next key that was typed by the user (that your program has not already processed).
     * This method should be preceded by a call to { @link  #hasNextKeyTyped()} to ensure
     * that there is a next key to process.
     * This method returns a Unicode character corresponding to the key
     * typed (such as { @code  'a'} or { @code  'A'}).
     * It cannot identify action keys (such as F1 and arrow keys)
     * or modifier keys (such as control).
     *
     *  @return  the next key typed by the user (that your program has not already processed).
     *  @throws  NoSuchElementException if there is no remaining key
     */
     public   static   char  nextKeyTyped ()   {
         synchronized   ( keyLock )   {
             if   ( keysTyped . isEmpty ())   {
                 throw   new   NoSuchElementException ( "your program has already processed all keystrokes" );
             }
             return  keysTyped . remove ( keysTyped . size ()   -   1 );
             // return keysTyped.removeLast();
         }
     }

     /**
     * Returns true if the given key is being pressed.
     * <p>
     * This method takes the keycode (corresponding to a physical key)
    *  as an argument. It can handle action keys
     * (such as F1 and arrow keys) and modifier keys (such as shift and control).
     * See { @link  KeyEvent} for a description of key codes.
     *
     *  @param   keycode the key to check if it is being pressed
     *  @return  { @code  true} if { @code  keycode} is currently being pressed;
     *         { @code  false} otherwise
     */
     public   static   boolean  isKeyPressed ( int  keycode )   {
         synchronized   ( keyLock )   {
             return  keysDown . contains ( keycode );
         }
     }


     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyTyped ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysTyped . addFirst ( e . getKeyChar ());
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyPressed ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysDown . add ( e . getKeyCode ());
         }
     }

     /**
     * This method cannot be called directly.
     */
    @ Override
     public   void  keyReleased ( KeyEvent  e )   {
         synchronized   ( keyLock )   {
            keysDown . remove ( e . getKeyCode ());
         }
     }


    /***************************************************************************
    *  For improved resolution on Mac Retina displays.
    ***************************************************************************/

     private   static   class   RetinaImageIcon   extends   ImageIcon   {
    
         public   RetinaImageIcon ( Image  image )   {
             super ( image );
         }

         public   int  getIconWidth ()   {
             return   super . getIconWidth ()   /   2 ;
         }

         /**
         * Gets the height of the icon.
         *
         *  @return  the height in pixels of this icon
         */
         public   int  getIconHeight ()   {
             return   super . getIconHeight ()   /   2 ;
         }

         public   synchronized   void  paintIcon ( Component  c ,   Graphics  g ,   int  x ,   int  y )   {
             Graphics2D  g2  =   ( Graphics2D )  g . create ();
            g2 . setRenderingHint ( RenderingHints . KEY_INTERPOLATION , RenderingHints . VALUE_INTERPOLATION_BICUBIC );
            g2 . setRenderingHint ( RenderingHints . KEY_RENDERING , RenderingHints . VALUE_RENDER_QUALITY );
            g2 . setRenderingHint ( RenderingHints . KEY_ANTIALIASING , RenderingHints . VALUE_ANTIALIAS_ON );
            g2 . scale ( 0.5 ,   0.5 );
             super . paintIcon ( c ,  g2 ,  x  *   2 ,  y  *   2 );
            g2 . dispose ();
         }
     }


     /**
     * Test client.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         StdDraw . square ( 0.2 ,   0.8 ,   0.1 );
         StdDraw . filledSquare ( 0.8 ,   0.8 ,   0.2 );
         StdDraw . circle ( 0.8 ,   0.2 ,   0.2 );

         StdDraw . setPenColor ( StdDraw . BOOK_RED );
         StdDraw . setPenRadius ( 0.02 );
         StdDraw . arc ( 0.8 ,   0.2 ,   0.1 ,   200 ,   45 );

         // draw a blue diamond
         StdDraw . setPenRadius ();
         StdDraw . setPenColor ( StdDraw . BOOK_BLUE );
         double []  x  =   {   0.1 ,   0.2 ,   0.3 ,   0.2   };
         double []  y  =   {   0.2 ,   0.3 ,   0.2 ,   0.1   };
         StdDraw . filledPolygon ( x ,  y );

         // text
         StdDraw . setPenColor ( StdDraw . BLACK );
         StdDraw . text ( 0.2 ,   0.5 ,   "black text" );
         StdDraw . setPenColor ( StdDraw . WHITE );
         StdDraw . text ( 0.8 ,   0.8 ,   "white text" );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdIn.java

edu/princeton/cs/algs4/StdIn.java

/******************************************************************************
 *  Compilation:  javac StdIn.java
 *  Execution:    java StdIn   (interactive test of basic functionality)
 *  Dependencies: none
 *
 *  Reads in data of various types from standard input.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . ArrayList ;
import  java . util . InputMismatchException ;
import  java . util . Locale ;
import  java . util . NoSuchElementException ;
import  java . util . Scanner ;
import  java . util . regex . Pattern ;

/**
 *  The { @code  StdIn} class provides static methods for reading strings
 *  and numbers from standard input.
 *  These functions fall into one of four categories:
 *  <ul>
 *  <li>those for reading individual tokens from standard input, one at a time,
 *      and converting each to a number, string, or boolean
 *  <li>those for reading characters from standard input, one at a time
 *  <li>those for reading lines from standard input, one at a time
 *  <li>those for reading a sequence of values of the same type from standard input,
 *      and returning the values in an array
 *  </ul>
 *  <p>
 *  Generally, it is best not to mix functions from the different
 *  categories in the same program.
 *  <p>
 *  <b>Getting started.</b>
 *  To use this class, you must have { @code  StdIn.class} in your
 *  Java classpath. If you used our autoinstaller, you should be all set.
 *  Otherwise, either download
 *  <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a>
 *  and add to your Java classpath or download
 *  <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdIn.java">StdIn.java</a>
 *  and put a copy in your working directory.
 *  <p>
 *  <b>Reading tokens from standard input and converting to numbers and strings.</b>
 *  You can use the following methods to read numbers, strings, and booleans
 *  from standard input one at a time:
 *  <ul>
 *  <li> { @link  #isEmpty()}
 *  <li> { @link  #readInt()}
 *  <li> { @link  #readDouble()}
 *  <li> { @link  #readString()}
 *  <li> { @link  #readShort()}
 *  <li> { @link  #readLong()}
 *  <li> { @link  #readFloat()}
 *  <li> { @link  #readByte()}
 *  <li> { @link  #readBoolean()}
 *  </ul>
 *  <p>
 *  The first method returns true if standard input has no more tokens.
 *  Each other method skips over any input that is whitespace. Then, it reads
 *  the next token and attempts to convert it into a value of the specified
 *  type. If it succeeds, it returns that value; otherwise, it
 *  throws an { @link  InputMismatchException}.
 *  <p>
 *  <em>Whitespace</em> includes spaces, tabs, and newlines; the full definition
 *  is inherited from { @link  Character#isWhitespace(char)}.
 *  A <em>token</em> is a maximal sequence of non-whitespace characters.
 *  The precise rules for describing which tokens can be converted to
 *  integers and floating-point numbers are inherited from
 *  <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#number-syntax">Scanner</a>,
 *  using the locale { @link  Locale#US}; the rules
 *  for floating-point numbers are slightly different
 *  from those in { @link  Double#valueOf(String)},
 *  but unlikely to be of concern to most programmers.
 *  <p>
 *  As an example, the following code fragment reads integers from standard input,
 *  one at a time, and prints them one per line.
 *  <pre>
 *  while (!StdIn.isEmpty()) {
 *      double value = StdIn.readDouble();
 *      StdOut.println(value);
 *  }
 *  </pre>
 *  <p>
 *  <b>Reading characters from standard input.</b>
 *  You can use the following two methods to read characters from standard input one at a time:
 *  <ul>
 *  <li> { @link  #hasNextChar()}
 *  <li> { @link  #readChar()}
 *  </ul>
 *  <p>
 *  The first method returns true if standard input has more input (including whitespace).
 *  The second method reads and returns the next character of input on standard 
 *  input (possibly a whitespace character).
 *  <p>
 *  As an example, the following code fragment reads characters from standard input,
 *  one character at a time, and prints it to standard output.
 *  <pre>
 *  while (StdIn.hasNextChar()) {
 *      char c = StdIn.readChar();
 *      StdOut.print(c);
 *  }
 *  </pre>
 *  <p>
 *  <b>Reading lines from standard input.</b>
 *  You can use the following two methods to read lines from standard input:
 *  <ul>
 *  <li> { @link  #hasNextLine()}
 *  <li> { @link  #readLine()}
 *  </ul>
 *  <p>
 *  The first method returns true if standard input has more input (including whitespace).
 *  The second method reads and returns the remaining portion of 
 *  the next line of input on standard input (possibly whitespace),
 *  discarding the trailing line separator.
 *  <p>
 *  A <em>line separator</em> is defined to be one of the following strings:
 *  { @code  \n} (Linux), { @code  \r} (old Macintosh),
 *  { @code  \r\n} (Windows),
 *  { @code  \}{ @code  u2028}, { @code  \}{ @code  u2029}, or { @code  \}{ @code  u0085}.
 *  <p>
 *  As an example, the following code fragment reads text from standard input,
 *  one line at a time, and prints it to standard output.
 *  <pre>
 *  while (StdIn.hasNextLine()) {
 *      String line = StdIn.readLine();
 *      StdOut.println(line);
 *  }
 *  </pre>
 *  <p>
 *  <b>Reading a sequence of values of the same type from standard input.</b>
 *  You can use the following methods to read a sequence numbers, strings,
 *  or booleans (all of the same type) from standard input:
 *  <ul>
 *  <li> { @link  #readAllDoubles()}
 *  <li> { @link  #readAllInts()}
 *  <li> { @link  #readAllLongs()}
 *  <li> { @link  #readAllStrings()}
 *  <li> { @link  #readAllLines()}
 *  <li> { @link  #readAll()}
 *  </ul>
 *  <p>
 *  The first three methods read of all of remaining token on standard input
 *  and converts the tokens to values of
 *  the specified type, as in the corresponding
 *  { @code  readDouble}, { @code  readInt}, and { @code  readString()} methods.
 *  The { @code  readAllLines()} method reads all remaining lines on standard
 *  input and returns them as an array of strings.
 *  The { @code  readAll()} method reads all remaining input on standard
 *  input and returns it as a string.
 *  <p>
 *  As an example, the following code fragment reads all of the remaining
 *  tokens from standard input and returns them as an array of strings.
 *  <pre>
 *  String[] words = StdIn.readAllStrings();
 *  </pre>
 *  <p>
 *  <b>Differences with Scanner.</b>
 *  { @code  StdIn} and { @link  Scanner} are both designed to parse 
 *  tokens and convert them to primitive types and strings.
 *  The main differences are summarized below:
 *  <ul>
 *  <li> { @code  StdIn} is a set of static methods and reads 
 *       reads input from only standard input. It is suitable for use before
 *       a programmer knows about objects.
 *       See { @link  In} for an object-oriented version that handles
 *       input from files, URLs,
 *       and sockets.
 *  <li> { @code  StdIn} uses whitespace as the delimiter pattern
 *       that separates tokens.
 *       { @link  Scanner} supports arbitrary delimiter patterns.
 *  <li> { @code  StdIn} coerces the character-set encoding to UTF-8,
 *       which is the most widely used character encoding for Unicode.
 *  <li> { @code  StdIn} coerces the locale to { @link  Locale#US},
 *       for consistency with { @link  StdOut}, { @link  Double#parseDouble(String)},
 *       and floating-point literals.
 *  <li> { @code  StdIn} has convenient methods for reading a single
 *       character; reading in sequences of integers, doubles, or strings;
 *       and reading in all of the remaining input.
 *  </ul>
 *  <p>
 *  Historical note: { @code  StdIn} preceded { @code  Scanner}; when
 *  { @code  Scanner} was introduced, this class was re-implemented to use { @code  Scanner}.
 *  <p>
 *  <b>Using standard input.</b>
 *  Standard input is a fundamental operating system abstraction on Mac OS X,
 *  Windows, and Linux.
 *  The methods in { @code  StdIn} are <em>blocking</em>, which means that they
 *  will wait until you enter input on standard input.
 *  If your program has a loop that repeats until standard input is empty,
 *  you must signal that the input is finished.
 *  To do so, depending on your operating system and IDE, 
 *  use either { @code  <Ctrl-d>} or { @code  <Ctrl-z>}, on its own line.
 *  If you are redirecting standard input from a file, you will not need
 *  to do anything to signal that the input is finished.
 *  <p>
 *  <b>Known bugs.</b>
 *  Java's UTF-8 encoding does not recognize the optional 
 *  <a href = "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058">byte-order mask</a>.
 *  If the input begins with the optional byte-order mask, { @code  StdIn}
 *  will have an extra character { @code  \}{ @code  uFEFF} at the beginning.
 *  <p>
 *  <b>Reference.</b> 
 *  For additional documentation,
 *  see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of   
 *  <em>Computer Science: An Interdisciplinary Approach</em>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *   @author  David Pritchard
 */
public   final   class   StdIn   {

     /*** begin: section (1 of 2) of code duplicated from In to StdIn. */
    
     // assume Unicode UTF-8 encoding
     private   static   final   String  CHARSET_NAME  =   "UTF-8" ;

     // assume language = English, country = US for consistency with System.out.
     private   static   final   Locale  LOCALE  =   Locale . US ;

     // the default token separator; we maintain the invariant that this value
     // is held by the scanner's delimiter between calls
     private   static   final   Pattern  WHITESPACE_PATTERN  =   Pattern . compile ( "\\p{javaWhitespace}+" );

     // makes whitespace significant
     private   static   final   Pattern  EMPTY_PATTERN  =   Pattern . compile ( "" );

     // used to read the entire input
     private   static   final   Pattern  EVERYTHING_PATTERN  =   Pattern . compile ( "\\A" );

     /*** end: section (1 of 2) of code duplicated from In to StdIn. */

     private   static   Scanner  scanner ;
 
     // it doesn't make sense to instantiate this class
     private   StdIn ()   {   }

     //// begin: section (2 of 2) of code duplicated from In to StdIn,
     //// with all methods changed from "public" to "public static"

    /**
     * Returns true if standard input is empty (except possibly for whitespace).
     * Use this method to know whether the next call to { @link  #readString()}, 
     * { @link  #readDouble()}, etc will succeed.
     *
     *  @return  { @code  true} if standard input is empty (except possibly
     *         for whitespace); { @code  false} otherwise
     */
     public   static   boolean  isEmpty ()   {
         return   ! scanner . hasNext ();
     }

    /**
     * Returns true if standard input has a next line.
     * Use this method to know whether the
     * next call to { @link  #readLine()} will succeed.
     * This method is functionally equivalent to { @link  #hasNextChar()}.
     *
     *  @return  { @code  true} if standard input has more input (including whitespace);
     *         { @code  false} otherwise
     */
     public   static   boolean  hasNextLine ()   {
         return  scanner . hasNextLine ();
     }

     /**
     * Returns true if standard input has more input (including whitespace).
     * Use this method to know whether the next call to { @link  #readChar()} will succeed.
     * This method is functionally equivalent to { @link  #hasNextLine()}.
     *
     *  @return  { @code  true} if standard input has more input (including whitespace);
     *         { @code  false} otherwise
     */
     public   static   boolean  hasNextChar ()   {
        scanner . useDelimiter ( EMPTY_PATTERN );
         boolean  result  =  scanner . hasNext ();
        scanner . useDelimiter ( WHITESPACE_PATTERN );
         return  result ;
     }


    /**
     * Reads and returns the next line, excluding the line separator if present.
     *
     *  @return  the next line, excluding the line separator if present;
     *         { @code  null} if no such line
     */
     public   static   String  readLine ()   {
         String  line ;
         try   {
            line  =  scanner . nextLine ();
         }
         catch   ( NoSuchElementException  e )   {
            line  =   null ;
         }
         return  line ;
     }

     /**
     * Reads and returns the next character.
     *
     *  @return  the next { @code  char}
     *  @throws  NoSuchElementException if standard input is empty
     */
     public   static   char  readChar ()   {
         try   {
            scanner . useDelimiter ( EMPTY_PATTERN );
             String  ch  =  scanner . next ();
             assert  ch . length ()   ==   1   :   "Internal (Std)In.readChar() error!"
                 +   " Please contact the authors." ;
            scanner . useDelimiter ( WHITESPACE_PATTERN );
             return  ch . charAt ( 0 );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'char' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }   


    /**
     * Reads and returns the remainder of the input, as a string.
     *
     *  @return  the remainder of the input, as a string
     *  @throws  NoSuchElementException if standard input is empty
     */
     public   static   String  readAll ()   {
         if   ( ! scanner . hasNextLine ())
             return   "" ;

         String  result  =  scanner . useDelimiter ( EVERYTHING_PATTERN ). next ();
         // not that important to reset delimeter, since now scanner is empty
        scanner . useDelimiter ( WHITESPACE_PATTERN );   // but let's do it anyway
         return  result ;
     }


    /**
     * Reads the next token  and returns the { @code  String}.
     *
     *  @return  the next { @code  String}
     *  @throws  NoSuchElementException if standard input is empty
     */
     public   static   String  readString ()   {
         try   {
             return  scanner . next ();
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'String' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from standard input, parses it as an integer, and returns the integer.
     *
     *  @return  the next integer on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as an { @code  int}
     */
     public   static   int  readInt ()   {
         try   {
             return  scanner . nextInt ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read an 'int' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attemps to read an 'int' value from standard input, "
                                            +   "but no more tokens are available" );
         }

     }

    /**
     * Reads the next token from standard input, parses it as a double, and returns the double.
     *
     *  @return  the next double on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  double}
     */
     public   static   double  readDouble ()   {
         try   {
             return  scanner . nextDouble ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'double' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'double' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from standard input, parses it as a float, and returns the float.
     *
     *  @return  the next float on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  float}
     */
     public   static   float  readFloat ()   {
         try   {
             return  scanner . nextFloat ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'float' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'float' value from standard input, "
                                            +   "but there no more tokens are available" );
         }
     }

    /**
     * Reads the next token from standard input, parses it as a long integer, and returns the long integer.
     *
     *  @return  the next long integer on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  long}
     */
     public   static   long  readLong ()   {
         try   {
             return  scanner . nextLong ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'long' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'long' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from standard input, parses it as a short integer, and returns the short integer.
     *
     *  @return  the next short integer on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  short}
     */
     public   static   short  readShort ()   {
         try   {
             return  scanner . nextShort ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'short' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'short' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }

    /**
     * Reads the next token from standard input, parses it as a byte, and returns the byte.
     *
     *  @return  the next byte on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  byte}
     */
     public   static   byte  readByte ()   {
         try   {
             return  scanner . nextByte ();
         }
         catch   ( InputMismatchException  e )   {
             String  token  =  scanner . next ();
             throw   new   InputMismatchException ( "attempts to read a 'byte' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'byte' value from standard input, "
                                            +   "but no more tokens are available" );
         }
     }

     /**
     * Reads the next token from standard input, parses it as a boolean,
     * and returns the boolean.
     *
     *  @return  the next boolean on standard input
     *  @throws  NoSuchElementException if standard input is empty
     *  @throws  InputMismatchException if the next token cannot be parsed as a { @code  boolean}:
     *    { @code  true} or { @code  1} for true, and { @code  false} or { @code  0} for false,
     *    ignoring case
     */
     public   static   boolean  readBoolean ()   {
         try   {
             String  token  =  readString ();
             if   ( "true" . equalsIgnoreCase ( token ))    return   true ;
             if   ( "false" . equalsIgnoreCase ( token ))   return   false ;
             if   ( "1" . equals ( token ))                 return   true ;
             if   ( "0" . equals ( token ))                 return   false ;
             throw   new   InputMismatchException ( "attempts to read a 'boolean' value from standard input, "
                                            +   "but the next token is \""   +  token  +   "\"" );
         }
         catch   ( NoSuchElementException  e )   {
             throw   new   NoSuchElementException ( "attempts to read a 'boolean' value from standard input, "
                                            +   "but no more tokens are available" );
         }

     }

     /**
     * Reads all remaining tokens from standard input and returns them as an array of strings.
     *
     *  @return  all remaining tokens on standard input, as an array of strings
     */
     public   static   String []  readAllStrings ()   {
         // we could use readAll.trim().split(), but that's not consistent
         // because trim() uses characters 0x00..0x20 as whitespace
         String []  tokens  =  WHITESPACE_PATTERN . split ( readAll ());
         if   ( tokens . length  ==   0   ||  tokens [ 0 ]. length ()   >   0 )
             return  tokens ;

         // don't include first token if it is leading whitespace
         String []  decapitokens  =   new   String [ tokens . length - 1 ];
         for   ( int  i  =   0 ;  i  <  tokens . length  -   1 ;  i ++ )
            decapitokens [ i ]   =  tokens [ i + 1 ];
         return  decapitokens ;
     }

     /**
     * Reads all remaining lines from standard input and returns them as an array of strings.
     *  @return  all remaining lines on standard input, as an array of strings
     */
     public   static   String []  readAllLines ()   {
         ArrayList < String >  lines  =   new   ArrayList < String > ();
         while   ( hasNextLine ())   {
            lines . add ( readLine ());
         }
         return  lines . toArray ( new   String [ lines . size ()]);
     }

     /**
     * Reads all remaining tokens from standard input, parses them as integers, and returns
     * them as an array of integers.
     *  @return  all remaining integers on standard input, as an array
     *  @throws  InputMismatchException if any token cannot be parsed as an { @code  int}
     */
     public   static   int []  readAllInts ()   {
         String []  fields  =  readAllStrings ();
         int []  vals  =   new   int [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Integer . parseInt ( fields [ i ]);
         return  vals ;
     }

     /**
     * Reads all remaining tokens from standard input, parses them as longs, and returns
     * them as an array of longs.
     *  @return  all remaining longs on standard input, as an array
     *  @throws  InputMismatchException if any token cannot be parsed as a { @code  long}
     */
     public   static   long []  readAllLongs ()   {
         String []  fields  =  readAllStrings ();
         long []  vals  =   new   long [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Long . parseLong ( fields [ i ]);
         return  vals ;
     }

     /**
     * Reads all remaining tokens from standard input, parses them as doubles, and returns
     * them as an array of doubles.
     *  @return  all remaining doubles on standard input, as an array
     *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}
     */
     public   static   double []  readAllDoubles ()   {
         String []  fields  =  readAllStrings ();
         double []  vals  =   new   double [ fields . length ];
         for   ( int  i  =   0 ;  i  <  fields . length ;  i ++ )
            vals [ i ]   =   Double . parseDouble ( fields [ i ]);
         return  vals ;
     }
    
     //// end: section (2 of 2) of code duplicated from In to StdIn
    
    
     // do this once when StdIn is initialized
     static   {
        resync ();
     }

     /**
     * If StdIn changes, use this to reinitialize the scanner.
     */
     private   static   void  resync ()   {
        setScanner ( new   Scanner ( new  java . io . BufferedInputStream ( System . in ),  CHARSET_NAME ));
     }
    
     private   static   void  setScanner ( Scanner  scanner )   {
         StdIn . scanner  =  scanner ;
         StdIn . scanner . useLocale ( LOCALE );
     }

    /**
     * Reads all remaining tokens, parses them as integers, and returns
     * them as an array of integers.
     *  @return  all remaining integers, as an array
     *  @throws  InputMismatchException if any token cannot be parsed as an { @code  int}
     *  @deprecated  Replaced by { @link  #readAllInts()}.
     */
    @ Deprecated
     public   static   int []  readInts ()   {
         return  readAllInts ();
     }

    /**
     * Reads all remaining tokens, parses them as doubles, and returns
     * them as an array of doubles.
     *  @return  all remaining doubles, as an array
     *  @throws  InputMismatchException if any token cannot be parsed as a { @code  double}
     *  @deprecated  Replaced by { @link  #readAllDoubles()}.
     */
    @ Deprecated
     public   static   double []  readDoubles ()   {
         return  readAllDoubles ();
     }

    /**
     * Reads all remaining tokens and returns them as an array of strings.
     *  @return  all remaining tokens, as an array of strings
     *  @deprecated  Replaced by { @link  #readAllStrings()}.
     */
    @ Deprecated
     public   static   String []  readStrings ()   {
         return  readAllStrings ();
     }


     /**
     * Interactive test of basic functionality.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         StdOut . print ( "Type a string: " );
         String  s  =   StdIn . readString ();
         StdOut . println ( "Your string was: "   +  s );
         StdOut . println ();

         StdOut . print ( "Type an int: " );
         int  a  =   StdIn . readInt ();
         StdOut . println ( "Your int was: "   +  a );
         StdOut . println ();

         StdOut . print ( "Type a boolean: " );
         boolean  b  =   StdIn . readBoolean ();
         StdOut . println ( "Your boolean was: "   +  b );
         StdOut . println ();

         StdOut . print ( "Type a double: " );
         double  c  =   StdIn . readDouble ();
         StdOut . println ( "Your double was: "   +  c );
         StdOut . println ();
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdOut.java

edu/princeton/cs/algs4/StdOut.java

/******************************************************************************
 *  Compilation:  javac StdOut.java
 *  Execution:    java StdOut
 *  Dependencies: none
 *
 *  Writes data of various types to standard output.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . io . OutputStreamWriter ;
import  java . io . PrintWriter ;
import  java . io . UnsupportedEncodingException ;
import  java . util . Locale ;

/**
 *  This class provides methods for printing strings and numbers to standard output.
 *  <p>
 *  <b>Getting started.</b>
 *  To use this class, you must have { @code  StdOut.class} in your
 *  Java classpath. If you used our autoinstaller, you should be all set.
 *  Otherwise, either download
 *  <a href = "https://introcs.cs.princeton.edu/java/code/stdlib.jar">stdlib.jar</a>
 *  and add to your Java classpath or download
 *  <a href = "https://introcs.cs.princeton.edu/java/stdlib/StdOut.java">StdOut.java</a>
 *  and put a copy in your working directory.
 *  <p>
 *  Here is an example program that uses { @code  StdOut}:
 *  <pre>
 *   public class TestStdOut {
 *       public static void main(String[] args) {
 *           int a = 17;
 *           int b = 23;
 *           int sum = a + b;
 *           StdOut.println("Hello, World");
 *           StdOut.printf("%d + %d = %d\n", a, b, sum);
 *       }
 *   }
 *  </pre>
 *  <p>
 *  <b>Differences with System.out.</b>
 *  The behavior of { @code  StdOut} is similar to that of { @link  System#out},
 *  but there are a few technical differences:
 *  <ul>
 *  <li> { @code  StdOut} coerces the character-set encoding to UTF-8,
 *       which is a standard character encoding for Unicode.
 *  <li> { @code  StdOut} coerces the locale to { @link  Locale#US},
 *       for consistency with { @link  StdIn}, { @link  Double#parseDouble(String)},
 *       and floating-point literals.
 *  <li> { @code  StdOut} <em>flushes</em> standard output after each call to
 *       { @code  print()} so that text will appear immediately in the terminal.
 *  </ul>
 *  <p>
 *  <b>Reference.</b>
 *  For additional documentation,
 *  see <a href="https://introcs.cs.princeton.edu/15inout">Section 1.5</a> of
 *  <em>Computer Science: An Interdisciplinary Approach</em>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   StdOut   {

     // force Unicode UTF-8 encoding; otherwise it's system dependent
     private   static   final   String  CHARSET_NAME  =   "UTF-8" ;

     // assume language = English, country = US for consistency with StdIn
     private   static   final   Locale  LOCALE  =   Locale . US ;

     // send output here
     private   static   PrintWriter  out ;

     // this is called before invoking any methods
     static   {
         try   {
            out  =   new   PrintWriter ( new   OutputStreamWriter ( System . out ,  CHARSET_NAME ),   true );
         }
         catch   ( UnsupportedEncodingException  e )   {
             System . out . println ( e );
         }
     }

     // don't instantiate
     private   StdOut ()   {   }

    /**
     * Terminates the current line by printing the line-separator string.
     */
     public   static   void  println ()   {
        out . println ();
     }

    /**
     * Prints an object to this output stream and then terminates the line.
     *
     *  @param  x the object to print
     */
     public   static   void  println ( Object  x )   {
        out . println ( x );
     }

    /**
     * Prints a boolean to standard output and then terminates the line.
     *
     *  @param  x the boolean to print
     */
     public   static   void  println ( boolean  x )   {
        out . println ( x );
     }

    /**
     * Prints a character to standard output and then terminates the line.
     *
     *  @param  x the character to print
     */
     public   static   void  println ( char  x )   {
        out . println ( x );
     }

    /**
     * Prints a double to standard output and then terminates the line.
     *
     *  @param  x the double to print
     */
     public   static   void  println ( double  x )   {
        out . println ( x );
     }

    /**
     * Prints an integer to standard output and then terminates the line.
     *
     *  @param  x the integer to print
     */
     public   static   void  println ( float  x )   {
        out . println ( x );
     }

    /**
     * Prints an integer to standard output and then terminates the line.
     *
     *  @param  x the integer to print
     */
     public   static   void  println ( int  x )   {
        out . println ( x );
     }

    /**
     * Prints a long to standard output and then terminates the line.
     *
     *  @param  x the long to print
     */
     public   static   void  println ( long  x )   {
        out . println ( x );
     }

    /**
     * Prints a short integer to standard output and then terminates the line.
     *
     *  @param  x the short to print
     */
     public   static   void  println ( short  x )   {
        out . println ( x );
     }

    /**
     * Prints a byte to standard output and then terminates the line.
     * <p>
     * To write binary data, see { @link  BinaryStdOut}.
     *
     *  @param  x the byte to print
     */
     public   static   void  println ( byte  x )   {
        out . println ( x );
     }

    /**
     * Flushes standard output.
     */
     public   static   void  print ()   {
        out . flush ();
     }

    /**
     * Prints an object to standard output and flushes standard output.
     * 
     *  @param  x the object to print
     */
     public   static   void  print ( Object  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a boolean to standard output and flushes standard output.
     * 
     *  @param  x the boolean to print
     */
     public   static   void  print ( boolean  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a character to standard output and flushes standard output.
     * 
     *  @param  x the character to print
     */
     public   static   void  print ( char  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a double to standard output and flushes standard output.
     * 
     *  @param  x the double to print
     */
     public   static   void  print ( double  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a float to standard output and flushes standard output.
     * 
     *  @param  x the float to print
     */
     public   static   void  print ( float  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints an integer to standard output and flushes standard output.
     * 
     *  @param  x the integer to print
     */
     public   static   void  print ( int  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a long integer to standard output and flushes standard output.
     * 
     *  @param  x the long integer to print
     */
     public   static   void  print ( long  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a short integer to standard output and flushes standard output.
     * 
     *  @param  x the short integer to print
     */
     public   static   void  print ( short  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a byte to standard output and flushes standard output.
     *
     *  @param  x the byte to print
     */
     public   static   void  print ( byte  x )   {
        out . print ( x );
        out . flush ();
     }

    /**
     * Prints a formatted string to standard output, using the specified format
     * string and arguments, and then flushes standard output.
     *
     *
     *  @param  format the <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">format string</a>
     *  @param  args   the arguments accompanying the format string
     */
     public   static   void  printf ( String  format ,   Object ...  args )   {
        out . printf ( LOCALE ,  format ,  args );
        out . flush ();
     }

    /**
     * Prints a formatted string to standard output, using the locale and
     * the specified format string and arguments; then flushes standard output.
     *
     *  @param  locale the locale
     *  @param  format the <a href = "http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html#syntax">format string</a>
     *  @param  args   the arguments accompanying the format string
     */
     public   static   void  printf ( Locale  locale ,   String  format ,   Object ...  args )   {
        out . printf ( locale ,  format ,  args );
        out . flush ();
     }

    /**
     * Unit tests some of the methods in { @code  StdOut}.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // write to stdout
         StdOut . println ( "Test" );
         StdOut . println ( 17 );
         StdOut . println ( true );
         StdOut . printf ( "%.6f\n" ,   1.0 / 7.0 );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdRandom.java

edu/princeton/cs/algs4/StdRandom.java

/******************************************************************************
 *  Compilation:  javac StdRandom.java
 *  Execution:    java StdRandom
 *  Dependencies: StdOut.java
 *
 *  A library of static methods to generate pseudo-random numbers from
 *  different distributions (bernoulli, uniform, gaussian, discrete,
 *  and exponential). Also includes a method for shuffling an array.
 *
 *
 *  %  java StdRandom 5
 *  seed = 1316600602069
 *  59 16.81826  true 8.83954  0 
 *  32 91.32098  true 9.11026  0 
 *  35 10.11874  true 8.95396  3 
 *  92 32.88401  true 8.87089  0 
 *  72 92.55791  true 9.46241  0 
 *
 *  % java StdRandom 5
 *  seed = 1316600616575
 *  96 60.17070  true 8.72821  0 
 *  79 32.01607  true 8.58159  0 
 *  81 59.49065  true 9.10423  1 
 *  96 51.65818  true 9.02102  0 
 *  99 17.55771  true 8.99762  0 
 *
 *  % java StdRandom 5 1316600616575
 *  seed = 1316600616575
 *  96 60.17070  true 8.72821  0 
 *  79 32.01607  true 8.58159  0 
 *  81 59.49065  true 9.10423  1 
 *  96 51.65818  true 9.02102  0 
 *  99 17.55771  true 8.99762  0 
 *
 *
 *  Remark
 *  ------
 *    - Relies on randomness of nextDouble() method in java.util.Random
 *      to generate pseudo-random numbers in [0, 1).
 *
 *    - This library allows you to set and get the pseudo-random number seed.
 *
 *    - See http://www.honeylocust.com/RngPack/ for an industrial
 *      strength random number generator in Java.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Random ;

/**
 *  The { @code  StdRandom} class provides static methods for generating
 *  random number from various discrete and continuous distributions, 
 *  including uniform, Bernoulli, geometric, Gaussian, exponential, Pareto,
 *  Poisson, and Cauchy. It also provides method for shuffling an
 *  array or subarray and generating random permutations.
 *  <p>
 *  By convention, all intervals are half open. For example,
 *  <code>uniform(-1.0, 1.0)</code> returns a random number between
 *  <code>-1.0</code> (inclusive) and <code>1.0</code> (exclusive).
 *  Similarly, <code>shuffle(a, lo, hi)</code> shuffles the <code>hi - lo</code>
 *  elements in the array <code>a[]</code>, starting at index <code>lo</code>
 *  (inclusive) and ending at index <code>hi</code> (exclusive).
 *  <p>
 *  For additional documentation,
 *  see <a href="https://introcs.cs.princeton.edu/22library">Section 2.2</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   StdRandom   {

     private   static   Random  random ;      // pseudo-random number generator
     private   static   long  seed ;          // pseudo-random number generator seed

     // static initializer
     static   {
         // this is how the seed was set in Java 1.4
        seed  =   System . currentTimeMillis ();
        random  =   new   Random ( seed );
     }

     // don't instantiate
     private   StdRandom ()   {   }

     /**
     * Sets the seed of the pseudo-random number generator.
     * This method enables you to produce the same sequence of "random"
     * number for each execution of the program.
     * Ordinarily, you should call this method at most once per program.
     *
     *  @param  s the seed
     */
     public   static   void  setSeed ( long  s )   {
        seed    =  s ;
        random  =   new   Random ( seed );
     }

     /**
     * Returns the seed of the pseudo-random number generator.
     *
     *  @return  the seed
     */
     public   static   long  getSeed ()   {
         return  seed ;
     }

     /**
     * Returns a random real number uniformly in [0, 1).
     *
     *  @return  a random real number uniformly in [0, 1)
     */
     public   static   double  uniform ()   {
         return  random . nextDouble ();
     }

     /**
     * Returns a random integer uniformly in [0, n).
     * 
     *  @param  n number of possible integers
     *  @return  a random integer uniformly between 0 (inclusive) and { @code  n} (exclusive)
     *  @throws  IllegalArgumentException if { @code  n <= 0}
     */
     public   static   int  uniform ( int  n )   {
         if   ( <=   0 )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );
         return  random . nextInt ( n );
     }


     /**
     * Returns a random long integer uniformly in [0, n).
     * 
     *  @param  n number of possible { @code  long} integers
     *  @return  a random long integer uniformly between 0 (inclusive) and { @code  n} (exclusive)
     *  @throws  IllegalArgumentException if { @code  n <= 0}
     */
     public   static   long  uniform ( long  n )   {
         if   ( <=   0L )   throw   new   IllegalArgumentException ( "argument must be positive: "   +  n );

         // https://docs.oracle.com/javase/8/docs/api/java/util/Random.html#longs-long-long-long-
         long  r  =  random . nextLong ();
         long  m  =  n  -   1 ;

         // power of two
         if   (( &  m )   ==   0L )   {
             return  r  &  m ;
         }

         // reject over-represented candidates
         long  u  =  r  >>>   1 ;
         while   ( +  m  -   ( =  u  %  n )   <   0L )   {
            u  =  random . nextLong ()   >>>   1 ;
         }
         return  r ;
     }

     ///////////////////////////////////////////////////////////////////////////
     //  STATIC METHODS BELOW RELY ON JAVA.UTIL.RANDOM ONLY INDIRECTLY VIA
     //  THE STATIC METHODS ABOVE.
     ///////////////////////////////////////////////////////////////////////////

     /**
     * Returns a random real number uniformly in [0, 1).
     * 
     *  @return      a random real number uniformly in [0, 1)
     *  @deprecated  Replaced by { @link  #uniform()}.
     */
    @ Deprecated
     public   static   double  random ()   {
         return  uniform ();
     }

     /**
     * Returns a random integer uniformly in [a, b).
     * 
     *  @param   a the left endpoint
     *  @param   b the right endpoint
     *  @return  a random integer uniformly in [a, b)
     *  @throws  IllegalArgumentException if { @code  b <= a}
     *  @throws  IllegalArgumentException if { @code  b - a >= Integer.MAX_VALUE}
     */
     public   static   int  uniform ( int  a ,   int  b )   {
         if   (( <=  a )   ||   (( long )  b  -  a  >=   Integer . MAX_VALUE ))   {
             throw   new   IllegalArgumentException ( "invalid range: ["   +  a  +   ", "   +  b  +   ")" );
         }
         return  a  +  uniform ( -  a );
     }

     /**
     * Returns a random real number uniformly in [a, b).
     * 
     *  @param   a the left endpoint
     *  @param   b the right endpoint
     *  @return  a random real number uniformly in [a, b)
     *  @throws  IllegalArgumentException unless { @code  a < b}
     */
     public   static   double  uniform ( double  a ,   double  b )   {
         if   ( ! ( <  b ))   {
             throw   new   IllegalArgumentException ( "invalid range: ["   +  a  +   ", "   +  b  +   ")" );
         }
         return  a  +  uniform ()   *   ( b - a );
     }

     /**
     * Returns a random boolean from a Bernoulli distribution with success
     * probability <em>p</em>.
     *
     *  @param   p the probability of returning { @code  true}
     *  @return  { @code  true} with probability { @code  p} and
     *         { @code  false} with probability { @code  1 - p}
     *  @throws  IllegalArgumentException unless { @code  0} &le; { @code  p} &le; { @code  1.0}
     */
     public   static   boolean  bernoulli ( double  p )   {
         if   ( ! ( >=   0.0   &&  p  <=   1.0 ))
             throw   new   IllegalArgumentException ( "probability p must be between 0.0 and 1.0: "   +  p );
         return  uniform ()   <  p ;
     }

     /**
     * Returns a random boolean from a Bernoulli distribution with success
     * probability 1/2.
     * 
     *  @return  { @code  true} with probability 1/2 and
     *         { @code  false} with probability 1/2
     */
     public   static   boolean  bernoulli ()   {
         return  bernoulli ( 0.5 );
     }

     /**
     * Returns a random real number from a standard Gaussian distribution.
     * 
     *  @return  a random real number from a standard Gaussian distribution
     *         (mean 0 and standard deviation 1).
     */
     public   static   double  gaussian ()   {
         // use the polar form of the Box-Muller transform
         double  r ,  x ,  y ;
         do   {
            x  =  uniform ( - 1.0 ,   1.0 );
            y  =  uniform ( - 1.0 ,   1.0 );
            r  =  x * +  y * y ;
         }   while   ( >=   1   ||  r  ==   0 );
         return  x  *   Math . sqrt ( - 2   *   Math . log ( r )   /  r );

         // Remark:  y * Math.sqrt(-2 * Math.log(r) / r)
         // is an independent random gaussian
     }

     /**
     * Returns a random real number from a Gaussian distribution with mean &mu;
     * and standard deviation &sigma;.
     * 
     *  @param   mu the mean
     *  @param   sigma the standard deviation
     *  @return  a real number distributed according to the Gaussian distribution
     *         with mean { @code  mu} and standard deviation { @code  sigma}
     */
     public   static   double  gaussian ( double  mu ,   double  sigma )   {
         return  mu  +  sigma  *  gaussian ();
     }

     /**
     * Returns a random integer from a geometric distribution with success
     * probability <em>p</em>.
     * The integer represents the number of independent trials
     * before the first success.
     * 
     *  @param   p the parameter of the geometric distribution
     *  @return  a random integer from a geometric distribution with success
     *         probability { @code  p}; or { @code  Integer.MAX_VALUE} if
     *         { @code  p} is (nearly) equal to { @code  1.0}.
     *  @throws  IllegalArgumentException unless { @code  p >= 0.0} and { @code  p <= 1.0}
     */
     public   static   int  geometric ( double  p )   {
         if   ( ! ( >=   0 ))   {
             throw   new   IllegalArgumentException ( "probability p must be greater than 0: "   +  p );
         }
         if   ( ! ( <=   1.0 ))   {
             throw   new   IllegalArgumentException ( "probability p must not be larger than 1: "   +  p );
         }
         // using algorithm given by Knuth
         return   ( int )   Math . ceil ( Math . log ( uniform ())   /   Math . log ( 1.0   -  p ));
     }

     /**
     * Returns a random integer from a Poisson distribution with mean &lambda;.
     *
     *  @param   lambda the mean of the Poisson distribution
     *  @return  a random integer from a Poisson distribution with mean { @code  lambda}
     *  @throws  IllegalArgumentException unless { @code  lambda > 0.0} and not infinite
     */
     public   static   int  poisson ( double  lambda )   {
         if   ( ! ( lambda  >   0.0 ))
             throw   new   IllegalArgumentException ( "lambda must be positive: "   +  lambda );
         if   ( Double . isInfinite ( lambda ))
             throw   new   IllegalArgumentException ( "lambda must not be infinite: "   +  lambda );
         // using algorithm given by Knuth
         // see http://en.wikipedia.org/wiki/Poisson_distribution
         int  k  =   0 ;
         double  p  =   1.0 ;
         double  expLambda  =   Math . exp ( - lambda );
         do   {
            k ++ ;
            p  *=  uniform ();
         }   while   ( >=  expLambda );
         return  k - 1 ;
     }

     /**
     * Returns a random real number from the standard Pareto distribution.
     *
     *  @return  a random real number from the standard Pareto distribution
     */
     public   static   double  pareto ()   {
         return  pareto ( 1.0 );
     }

     /**
     * Returns a random real number from a Pareto distribution with
     * shape parameter &alpha;.
     *
     *  @param   alpha shape parameter
     *  @return  a random real number from a Pareto distribution with shape
     *         parameter { @code  alpha}
     *  @throws  IllegalArgumentException unless { @code  alpha > 0.0}
     */
     public   static   double  pareto ( double  alpha )   {
         if   ( ! ( alpha  >   0.0 ))
             throw   new   IllegalArgumentException ( "alpha must be positive: "   +  alpha );
         return   Math . pow ( 1   -  uniform (),   - 1.0 / alpha )   -   1.0 ;
     }

     /**
     * Returns a random real number from the Cauchy distribution.
     *
     *  @return  a random real number from the Cauchy distribution.
     */
     public   static   double  cauchy ()   {
         return   Math . tan ( Math . PI  *   ( uniform ()   -   0.5 ));
     }

     /**
     * Returns a random integer from the specified discrete distribution.
     *
     *  @param   probabilities the probability of occurrence of each integer
     *  @return  a random integer from a discrete distribution:
     *         { @code  i} with probability { @code  probabilities[i]}
     *  @throws  IllegalArgumentException if { @code  probabilities} is { @code  null}
     *  @throws  IllegalArgumentException if sum of array entries is not (very nearly) equal to { @code  1.0}
     *  @throws  IllegalArgumentException unless { @code  probabilities[i] >= 0.0} for each index { @code  i}
     */
     public   static   int  discrete ( double []  probabilities )   {
         if   ( probabilities  ==   null )   throw   new   IllegalArgumentException ( "argument array is null" );
         double  EPSILON  =   1.0E-14 ;
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  probabilities . length ;  i ++ )   {
             if   ( ! ( probabilities [ i ]   >=   0.0 ))
                 throw   new   IllegalArgumentException ( "array entry "   +  i  +   " must be nonnegative: "   +  probabilities [ i ]);
            sum  +=  probabilities [ i ];
         }
         if   ( sum  >   1.0   +  EPSILON  ||  sum  <   1.0   -  EPSILON )
             throw   new   IllegalArgumentException ( "sum of array entries does not approximately equal 1.0: "   +  sum );

         // the for loop may not return a value when both r is (nearly) 1.0 and when the
         // cumulative sum is less than 1.0 (as a result of floating-point roundoff error)
         while   ( true )   {
             double  r  =  uniform ();
            sum  =   0.0 ;
             for   ( int  i  =   0 ;  i  <  probabilities . length ;  i ++ )   {
                sum  =  sum  +  probabilities [ i ];
                 if   ( sum  >  r )   return  i ;
             }
         }
     }

     /**
     * Returns a random integer from the specified discrete distribution.
     *
     *  @param   frequencies the frequency of occurrence of each integer
     *  @return  a random integer from a discrete distribution:
     *         { @code  i} with probability proportional to { @code  frequencies[i]}
     *  @throws  IllegalArgumentException if { @code  frequencies} is { @code  null}
     *  @throws  IllegalArgumentException if all array entries are { @code  0}
     *  @throws  IllegalArgumentException if { @code  frequencies[i]} is negative for any index { @code  i}
     *  @throws  IllegalArgumentException if sum of frequencies exceeds { @code  Integer.MAX_VALUE} (2<sup>31</sup> - 1)
     */
     public   static   int  discrete ( int []  frequencies )   {
         if   ( frequencies  ==   null )   throw   new   IllegalArgumentException ( "argument array is null" );
         long  sum  =   0 ;
         for   ( int  i  =   0 ;  i  <  frequencies . length ;  i ++ )   {
             if   ( frequencies [ i ]   <   0 )
                 throw   new   IllegalArgumentException ( "array entry "   +  i  +   " must be nonnegative: "   +  frequencies [ i ]);
            sum  +=  frequencies [ i ];
         }
         if   ( sum  ==   0 )
             throw   new   IllegalArgumentException ( "at least one array entry must be positive" );
         if   ( sum  >=   Integer . MAX_VALUE )
             throw   new   IllegalArgumentException ( "sum of frequencies overflows an int" );

         // pick index i with probabilitity proportional to frequency
         double  r  =  uniform (( int )  sum );
        sum  =   0 ;
         for   ( int  i  =   0 ;  i  <  frequencies . length ;  i ++ )   {
            sum  +=  frequencies [ i ];
             if   ( sum  >  r )   return  i ;
         }

         // can't reach here
         assert   false ;
         return   - 1 ;
     }

     /**
     * Returns a random real number from an exponential distribution
     * with rate &lambda;.
     * 
     *  @param   lambda the rate of the exponential distribution
     *  @return  a random real number from an exponential distribution with
     *         rate { @code  lambda}
     *  @throws  IllegalArgumentException unless { @code  lambda > 0.0}
     */
     public   static   double  exp ( double  lambda )   {
         if   ( ! ( lambda  >   0.0 ))
             throw   new   IllegalArgumentException ( "lambda must be positive: "   +  lambda );
         return   - Math . log ( 1   -  uniform ())   /  lambda ;
     }

     /**
     * Rearranges the elements of the specified array in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     */
     public   static   void  shuffle ( Object []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  r  =  i  +  uniform ( n - i );       // between i and n-1
             Object  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified array in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     */
     public   static   void  shuffle ( double []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  r  =  i  +  uniform ( n - i );       // between i and n-1
             double  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified array in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     */
     public   static   void  shuffle ( int []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  r  =  i  +  uniform ( n - i );       // between i and n-1
             int  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified array in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     */
     public   static   void  shuffle ( char []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             int  r  =  i  +  uniform ( n - i );       // between i and n-1
             char  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified subarray in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @param   lo the left endpoint (inclusive)
     *  @param   hi the right endpoint (exclusive)
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     * 
     */
     public   static   void  shuffle ( Object []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
             int  r  =  i  +  uniform ( hi - i );       // between i and hi-1
             Object  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified subarray in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @param   lo the left endpoint (inclusive)
     *  @param   hi the right endpoint (exclusive)
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   void  shuffle ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
             int  r  =  i  +  uniform ( hi - i );       // between i and hi-1
             double  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Rearranges the elements of the specified subarray in uniformly random order.
     *
     *  @param   a the array to shuffle
     *  @param   lo the left endpoint (inclusive)
     *  @param   hi the right endpoint (exclusive)
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   void  shuffle ( int []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
             int  r  =  i  +  uniform ( hi - i );       // between i and hi-1
             int  temp  =  a [ i ];
            a [ i ]   =  a [ r ];
            a [ r ]   =  temp ;
         }
     }

     /**
     * Returns a uniformly random permutation of <em>n</em> elements.
     *
     *  @param   n number of elements
     *  @throws  IllegalArgumentException if { @code  n} is negative
     *  @return  an array of length { @code  n} that is a uniformly random permutation
     *         of { @code  0}, { @code  1}, ..., { @code  n-1}
     */
     public   static   int []  permutation ( int  n )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "argument is negative" );
         int []  perm  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            perm [ i ]   =  i ;
        shuffle ( perm );
         return  perm ;
     }

     /**
     * Returns a uniformly random permutation of <em>k</em> of <em>n</em> elements.
     *
     *  @param   n number of elements
     *  @param   k number of elements to select
     *  @throws  IllegalArgumentException if { @code  n} is negative
     *  @throws  IllegalArgumentException unless { @code  0 <= k <= n}
     *  @return  an array of length { @code  k} that is a uniformly random permutation
     *         of { @code  k} of the elements from { @code  0}, { @code  1}, ..., { @code  n-1}
     */
     public   static   int []  permutation ( int  n ,   int  k )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ( "argument is negative" );
         if   ( <   0   ||  k  >  n )   throw   new   IllegalArgumentException ( "k must be between 0 and n" );
         int []  perm  =   new   int [ k ];
         for   ( int  i  =   0 ;  i  <  k ;  i ++ )   {
             int  r  =  uniform ( i + 1 );      // between 0 and i
            perm [ i ]   =  perm [ r ];
            perm [ r ]   =  i ;
         }
         for   ( int  i  =  k ;  i  <  n ;  i ++ )   {
             int  r  =  uniform ( i + 1 );      // between 0 and i
             if   ( <  k )  perm [ r ]   =  i ;
         }
         return  perm ;
     }

     // throw an IllegalArgumentException if x is null
     // (x can be of type Object[], double[], int[], ...)
     private   static   void  validateNotNull ( Object  x )   {
         if   ( ==   null )   {
             throw   new   IllegalArgumentException ( "argument is null" );
         }
     }

     // throw an exception unless 0 <= lo <= hi <= length
     private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {
         if   ( lo  <   0   ||  hi  >  length  ||  lo  >  hi )   {
             throw   new   IllegalArgumentException ( "subarray indices out of bounds: ["   +  lo  +   ", "   +  hi  +   ")" );
         }
     }

     /**
     * Unit tests the methods in this class.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   Integer . parseInt ( args [ 0 ]);
         if   ( args . length  ==   2 )   StdRandom . setSeed ( Long . parseLong ( args [ 1 ]));
         double []  probabilities  =   {   0.5 ,   0.3 ,   0.1 ,   0.1   };
         int []  frequencies  =   {   5 ,   3 ,   1 ,   1   };
         String []  a  =   "A B C D E F G" . split ( " " );

         StdOut . println ( "seed = "   +   StdRandom . getSeed ());
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdOut . printf ( "%2d " ,    uniform ( 100 ));
             StdOut . printf ( "%8.5f " ,  uniform ( 10.0 ,   99.0 ));
             StdOut . printf ( "%5b " ,    bernoulli ( 0.5 ));
             StdOut . printf ( "%7.5f " ,  gaussian ( 9.0 ,   0.2 ));
             StdOut . printf ( "%1d " ,    discrete ( probabilities ));
             StdOut . printf ( "%1d " ,    discrete ( frequencies ));
             StdOut . printf ( "%11d " ,   uniform ( 100000000000L ));
             StdRandom . shuffle ( a );
             for   ( String  s  :  a )
                 StdOut . print ( s );
             StdOut . println ();
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StdStats.java

edu/princeton/cs/algs4/StdStats.java

/******************************************************************************
 *  Compilation:  javac StdStats.java
 *  Execution:    java StdStats < input.txt
 *  Dependencies: StdOut.java
 *
 *  Library of statistical functions.
 *
 *  The test client reads an array of real numbers from standard
 *  input, and computes the minimum, mean, maximum, and
 *  standard deviation.
 *
 *  The functions all throw a java.lang.IllegalArgumentException
 *  if the array passed in as an argument is null.
 *
 *  The floating-point functions all return NaN if any input is NaN.
 *
 *  Unlike Math.min() and Math.max(), the min() and max() functions
 *  do not differentiate between -0.0 and 0.0.
 *
 *  % more tiny.txt
 *  5
 *  3.0 1.0 2.0 5.0 4.0
 *
 *  % java StdStats < tiny.txt
 *         min   1.000
 *        mean   3.000
 *         max   5.000
 *     std dev   1.581
 *
 *  Should these funtions use varargs instead of array arguments?
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  StdStats} class provides static methods for computing
 *  statistics such as min, max, mean, sample standard deviation, and
 *  sample variance.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://introcs.cs.princeton.edu/22library">Section 2.2</a> of
 *  <i>Computer Science: An Interdisciplinary Approach</i>
 *  by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   final   class   StdStats   {

     private   StdStats ()   {   }

     /**
     * Returns the maximum value in the specified array.
     *
     *  @param   a the array
     *  @return  the maximum value in the array { @code  a[]};
     *         { @code  Double.NEGATIVE_INFINITY} if no such value
     */
     public   static   double  max ( double []  a )   {
        validateNotNull ( a );

         double  max  =   Double . NEGATIVE_INFINITY ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;
             if   ( a [ i ]   >  max )  max  =  a [ i ];
         }
         return  max ;
     }

     /**
     * Returns the maximum value in the specified subarray.
     *
     *  @param   a the array
     *  @param   lo the left endpoint of the subarray (inclusive)
     *  @param   hi the right endpoint of the subarray (exclusive)
     *  @return  the maximum value in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NEGATIVE_INFINITY} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null}
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  max ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         double  max  =   Double . NEGATIVE_INFINITY ;
         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
             if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;
             if   ( a [ i ]   >  max )  max  =  a [ i ];
         }
         return  max ;
     }

     /**
     * Returns the maximum value in the specified array.
     *
     *  @param   a the array
     *  @return  the maximum value in the array { @code  a[]};
     *         { @code  Integer.MIN_VALUE} if no such value
     */
     public   static   int  max ( int []  a )   {
        validateNotNull ( a );

         int  max  =   Integer . MIN_VALUE ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             if   ( a [ i ]   >  max )  max  =  a [ i ];
         }
         return  max ;
     }

     /**
     * Returns the minimum value in the specified array.
     *
     *  @param   a the array
     *  @return  the minimum value in the array { @code  a[]};
     *         { @code  Double.POSITIVE_INFINITY} if no such value
     */
     public   static   double  min ( double []  a )   {
        validateNotNull ( a );

         double  min  =   Double . POSITIVE_INFINITY ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;
             if   ( a [ i ]   <  min )  min  =  a [ i ];
         }
         return  min ;
     }

     /**
     * Returns the minimum value in the specified subarray.
     *
     *  @param   a the array
     *  @param   lo the left endpoint of the subarray (inclusive)
     *  @param   hi the right endpoint of the subarray (exclusive)
     *  @return  the maximum value in the subarray { @code  a[lo..hi)};
     *         { @code  Double.POSITIVE_INFINITY} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  min ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         double  min  =   Double . POSITIVE_INFINITY ;
         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
             if   ( Double . isNaN ( a [ i ]))   return   Double . NaN ;
             if   ( a [ i ]   <  min )  min  =  a [ i ];
         }
         return  min ;
     }

     /**
     * Returns the minimum value in the specified array.
     *
     *  @param   a the array
     *  @return  the minimum value in the array { @code  a[]};
     *         { @code  Integer.MAX_VALUE} if no such value
     */
     public   static   int  min ( int []  a )   {
        validateNotNull ( a );

         int  min  =   Integer . MAX_VALUE ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
             if   ( a [ i ]   <  min )  min  =  a [ i ];
         }
         return  min ;
     }

     /**
     * Returns the average value in the specified array.
     *
     *  @param   a the array
     *  @return  the average value in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  mean ( double []  a )   {
        validateNotNull ( a );

         if   ( a . length  ==   0 )   return   Double . NaN ;
         double  sum  =  sum ( a );
         return  sum  /  a . length ;
     }

     /**
     * Returns the average value in the specified subarray.
     *
     *  @param  a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the average value in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NaN} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  mean ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         int  length  =  hi  -  lo ;
         if   ( length  ==   0 )   return   Double . NaN ;

         double  sum  =  sum ( a ,  lo ,  hi );
         return  sum  /  length ;
     }

     /**
     * Returns the average value in the specified array.
     *
     *  @param   a the array
     *  @return  the average value in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  mean ( int []  a )   {
        validateNotNull ( a );

         if   ( a . length  ==   0 )   return   Double . NaN ;
         int  sum  =  sum ( a );
         return   1.0   *  sum  /  a . length ;
     }

     /**
     * Returns the sample variance in the specified array.
     *
     *  @param   a the array
     *  @return  the sample variance in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  var ( double []  a )   {
        validateNotNull ( a );

         if   ( a . length  ==   0 )   return   Double . NaN ;
         double  avg  =  mean ( a );
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
            sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );
         }
         return  sum  /   ( a . length  -   1 );
     }

     /**
     * Returns the sample variance in the specified subarray.
     *
     *  @param   a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the sample variance in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NaN} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  var ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         int  length  =  hi  -  lo ;
         if   ( length  ==   0 )   return   Double . NaN ;

         double  avg  =  mean ( a ,  lo ,  hi );
         double  sum  =   0.0 ;
         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
            sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );
         }
         return  sum  /   ( length  -   1 );
     }

     /**
     * Returns the sample variance in the specified array.
     *
     *  @param   a the array
     *  @return  the sample variance in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  var ( int []  a )   {
        validateNotNull ( a );
         if   ( a . length  ==   0 )   return   Double . NaN ;
         double  avg  =  mean ( a );
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
            sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );
         }
         return  sum  /   ( a . length  -   1 );
     }

     /**
     * Returns the population variance in the specified array.
     *
     *  @param   a the array
     *  @return  the population variance in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  varp ( double []  a )   {
        validateNotNull ( a );
         if   ( a . length  ==   0 )   return   Double . NaN ;
         double  avg  =  mean ( a );
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
            sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );
         }
         return  sum  /  a . length ;
     }

     /**
     * Returns the population variance in the specified subarray.
     *
     *  @param   a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the population variance in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NaN} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  varp ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         int  length  =  hi  -  lo ;
         if   ( length  ==   0 )   return   Double . NaN ;

         double  avg  =  mean ( a ,  lo ,  hi );
         double  sum  =   0.0 ;
         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
            sum  +=   ( a [ i ]   -  avg )   *   ( a [ i ]   -  avg );
         }
         return  sum  /  length ;
     }

     /**
     * Returns the sample standard deviation in the specified array.
     *
     *  @param   a the array
     *  @return  the sample standard deviation in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  stddev ( double []  a )   {
        validateNotNull ( a );
         return   Math . sqrt ( var ( a ));
     }

     /**
     * Returns the sample standard deviation in the specified array.
     *
     *  @param   a the array
     *  @return  the sample standard deviation in the array { @code  a[]};
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  stddev ( int []  a )   {
        validateNotNull ( a );
         return   Math . sqrt ( var ( a ));
     }

     /**
     * Returns the sample standard deviation in the specified subarray.
     *
     *  @param   a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the sample standard deviation in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NaN} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  stddev ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         return   Math . sqrt ( var ( a ,  lo ,  hi ));
     }


     /**
     * Returns the population standard deviation in the specified array.
     *
     *  @param   a the array
     *  @return  the population standard deviation in the array;
     *         { @code  Double.NaN} if no such value
     */
     public   static   double  stddevp ( double []  a )   {
        validateNotNull ( a );
         return   Math . sqrt ( varp ( a ));
     }

     /**
     * Returns the population standard deviation in the specified subarray.
     *
     *  @param   a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the population standard deviation in the subarray { @code  a[lo..hi)};
     *         { @code  Double.NaN} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     public   static   double  stddevp ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         return   Math . sqrt ( varp ( a ,  lo ,  hi ));
     }

     /**
     * Returns the sum of all values in the specified array.
     *
     *  @param   a the array
     *  @return  the sum of all values in the array { @code  a[]};
     *         { @code  0.0} if no such value
     */
     private   static   double  sum ( double []  a )   {
        validateNotNull ( a );
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
            sum  +=  a [ i ];
         }
         return  sum ;
     }

     /**
     * Returns the sum of all values in the specified subarray.
     *
     *  @param   a the array
     *  @param  lo the left endpoint of the subarray (inclusive)
     *  @param  hi the right endpoint of the subarray (exclusive)
     *  @return  the sum of all values in the subarray { @code  a[lo..hi)};
     *         { @code  0.0} if no such value
     *  @throws  IllegalArgumentException if { @code  a} is { @code  null} 
     *  @throws  IllegalArgumentException unless { @code  (0 <= lo) && (lo < hi) && (hi <= a.length)}
     */
     private   static   double  sum ( double []  a ,   int  lo ,   int  hi )   {
        validateNotNull ( a );
        validateSubarrayIndices ( lo ,  hi ,  a . length );

         double  sum  =   0.0 ;
         for   ( int  i  =  lo ;  i  <  hi ;  i ++ )   {
            sum  +=  a [ i ];
         }
         return  sum ;
     }

     /**
     * Returns the sum of all values in the specified array.
     *
     *  @param   a the array
     *  @return  the sum of all values in the array { @code  a[]};
     *         { @code  0.0} if no such value
     */
     private   static   int  sum ( int []  a )   {
        validateNotNull ( a );
         int  sum  =   0 ;
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
            sum  +=  a [ i ];
         }
         return  sum ;
     }

    /**
     * Plots the points (0, <em>a</em><sub>0</sub>), (1, <em>a</em><sub>1</sub>), ...,
     * (<em>n</em>-1, <em>a</em><sub><em>n</em>-1</sub>) to standard draw.
     *
     *  @param  a the array of values
     */
     public   static   void  plotPoints ( double []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         StdDraw . setXscale ( - 1 ,  n );
         StdDraw . setPenRadius ( 1.0   /   ( 3.0   *  n ));
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdDraw . point ( i ,  a [ i ]);
         }
     }

    /**
     * Plots the line segments connecting 
     * (<em>i</em>, <em>a</em><sub><em>i</em></sub>) to
     * (<em>i</em>+1, <em>a</em><sub><em>i</em>+1</sub>) for 
     * each <em>i</em> to standard draw.
     *
     *  @param  a the array of values
     */
     public   static   void  plotLines ( double []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         StdDraw . setXscale ( - 1 ,  n );
         StdDraw . setPenRadius ();
         for   ( int  i  =   1 ;  i  <  n ;  i ++ )   {
             StdDraw . line ( i - 1 ,  a [ i - 1 ],  i ,  a [ i ]);
         }
     }

    /**
     * Plots bars from (0, <em>a</em><sub><em>i</em></sub>) to
     * (<em>a</em><sub><em>i</em></sub>) for each <em>i</em>
     * to standard draw.
     *
     *  @param  a the array of values
     */
     public   static   void  plotBars ( double []  a )   {
        validateNotNull ( a );
         int  n  =  a . length ;
         StdDraw . setXscale ( - 1 ,  n );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             StdDraw . filledRectangle ( i ,  a [ i ] / 2 ,   0.25 ,  a [ i ] / 2 );
         }
     }

     // throw an IllegalArgumentException if x is null
     // (x is either of type double[] or int[])
     private   static   void  validateNotNull ( Object  x )   {
         if   ( ==   null )
             throw   new   IllegalArgumentException ( "argument is null" );
     }

     // throw an exception unless 0 <= lo <= hi <= length
     private   static   void  validateSubarrayIndices ( int  lo ,   int  hi ,   int  length )   {
         if   ( lo  <   0   ||  hi  >  length  ||  lo  >  hi )
             throw   new   IllegalArgumentException ( "subarray indices out of bounds: ["   +  lo  +   ", "   +  hi  +   ")" );
     }


    /**
     * Unit tests { @code  StdStats}.
     * Convert command-line arguments to array of doubles and call various methods.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         double []  a  =   StdArrayIO . readDouble1D ();
         StdOut . printf ( "       min %10.3f\n" ,  min ( a ));
         StdOut . printf ( "      mean %10.3f\n" ,  mean ( a ));
         StdOut . printf ( "       max %10.3f\n" ,  max ( a ));
         StdOut . printf ( "    stddev %10.3f\n" ,  stddev ( a ));
         StdOut . printf ( "       var %10.3f\n" ,  var ( a ));
         StdOut . printf ( "   stddevp %10.3f\n" ,  stddevp ( a ));
         StdOut . printf ( "      varp %10.3f\n" ,  varp ( a ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ST.java

edu/princeton/cs/algs4/ST.java

/******************************************************************************
 *  Compilation:  javac ST.java
 *  Execution:    java ST < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyST.txt
 *  
 *  Sorted symbol table implementation using a java.util.TreeMap.
 *  Does not allow duplicates.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;
import  java . util . NoSuchElementException ;
import  java . util . TreeMap ;

/**
 *  The { @code  ST} class represents an ordered symbol table of generic
 *  key-value pairs.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides ordered methods for finding the <em>minimum</em>,
 *  <em>maximum</em>, <em>floor</em>, and <em>ceiling</em>.
 *  It also provides a <em>keys</em> method for iterating over all of the keys.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  It requires that
 *  the key type implements the { @code  Comparable} interface and calls the
 *  { @code  compareTo()} and method to compare two keys. It does not call either
 *  { @code  equals()} or { @code  hashCode()}.
 *  <p>
 *  This implementation uses a <em>red-black BST</em>.
 *  The <em>put</em>, <em>get</em>, <em>contains</em>, <em>remove</em>,
 *  <em>minimum</em>, <em>maximum</em>, <em>ceiling</em>, and <em>floor</em>
 *  operations each take &Theta;(log <em>n</em>) time in the worst case,
 *  where <em>n</em> is the number of key-value pairs in the symbol table.
 *  The <em>size</em> and <em>is-empty</em> operations take &Theta;(1) time.
 *  Construction takes &Theta;(1) time.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 *
 *   @param  <Key> the generic type of keys in this symbol table
 *   @param  <Value> the generic type of values in this symbol table
 */
public   class  ST < Key   extends   Comparable < Key > ,   Value >   implements   Iterable < Key >   {

     private   TreeMap < Key ,   Value >  st ;

     /**
     * Initializes an empty symbol table.
     */
     public  ST ()   {
        st  =   new   TreeMap < Key ,   Value > ();
     }


     /**
     * Returns the value associated with the given key in this symbol table.
     *
     *  @param   key the key
     *  @return  the value associated with the given key if the key is in this symbol table;
     *         { @code  null} if the key is not in this symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls get() with null key" );
         return  st . get ( key );
     }

     /**
     * Inserts the specified key-value pair into the symbol table, overwriting the old 
     * value with the new value if the symbol table already contains the specified key.
     * Deletes the specified key (and its associated value) from this symbol table
     * if the specified value is { @code  null}.
     *
     *  @param   key the key
     *  @param   val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( Key  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls put() with null key" );
         if   ( val  ==   null )  st . remove ( key );
         else              st . put ( key ,  val );
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).
     * This is equivalent to { @code  remove()}, but we plan to deprecate { @code  delete()}.
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls delete() with null key" );
        st . remove ( key );
     }

     /**
     * Removes the specified key and its associated value from this symbol table     
     * (if the key is in this symbol table).
     * This is equivalent to { @code  delete()}, but we plan to deprecate { @code  delete()}.
     *
     *  @param   key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  remove ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls remove() with null key" );
        st . remove ( key );
     }

     /**
     * Returns true if this symbol table contain the given key.
     *
     *  @param   key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "calls contains() with null key" );
         return  st . containsKey ( key );
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  st . size ();
     }

     /**
     * Returns true if this symbol table is empty.
     *
     *  @return  { @code  true} if this symbol table is empty and { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns all keys in this symbol table.
     * <p>
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *
     *  @return  all keys in this symbol table
     */
     public   Iterable < Key >  keys ()   {
         return  st . keySet ();
     }

     /**
     * Returns all of the keys in this symbol table.
     * To iterate over all of the keys in a symbol table named { @code  st}, use the
     * foreach notation: { @code  for (Key key : st)}.
     * <p>
     * This method is provided for backward compatibility with the version from
     * <em>Introduction to Programming in Java: An Interdisciplinary Approach.</em>
     *
     *  @return      an iterator to all of the keys in this symbol table
     *  @deprecated  Replaced by { @link  #keys()}.
     */
    @ Deprecated
     public   Iterator < Key >  iterator ()   {
         return  st . keySet (). iterator ();
     }

     /**
     * Returns the smallest key in this symbol table.
     *
     *  @return  the smallest key in this symbol table
     *  @throws  NoSuchElementException if this symbol table is empty
     */
     public   Key  min ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls min() with empty symbol table" );
         return  st . firstKey ();
     }

     /**
     * Returns the largest key in this symbol table.
     *
     *  @return  the largest key in this symbol table
     *  @throws  NoSuchElementException if this symbol table is empty
     */
     public   Key  max ()   {
         if   ( isEmpty ())   throw   new   NoSuchElementException ( "calls max() with empty symbol table" );
         return  st . lastKey ();
     }

     /**
     * Returns the smallest key in this symbol table greater than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the smallest key in this symbol table greater than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  ceiling ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to ceiling() is null" );
         Key  k  =  st . ceilingKey ( key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to ceiling() is too large" );
         return  k ;
     }

     /**
     * Returns the largest key in this symbol table less than or equal to { @code  key}.
     *
     *  @param   key the key
     *  @return  the largest key in this symbol table less than or equal to { @code  key}
     *  @throws  NoSuchElementException if there is no such key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Key  floor ( Key  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to floor() is null" );
         Key  k  =  st . floorKey ( key );
         if   ( ==   null )   throw   new   NoSuchElementException ( "argument to floor() is too small" );
         return  k ;
     }

     /**
     * Unit tests the { @code  ST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
        ST < String ,   Integer >  st  =   new  ST < String ,   Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }
         for   ( String  s  :  st . keys ())
             StdOut . println ( +   " "   +  st . get ( s ));
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/StopwatchCPU.java

edu/princeton/cs/algs4/StopwatchCPU.java

/******************************************************************************
 *  Compilation:  javac StopwatchCPU.java
 *  Execution:    java StopwtachCPU n
 *  Dependencies: none
 *
 *  A version of Stopwatch.java that measures CPU time on a single
 *  core or processor (instead of wall clock time).
 *
 *  % java8 StopwatchCPU 100000000
 *  6.666667e+11 (1.05 seconds)
 *  6.666667e+11 (7.50 seconds)
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . lang . management . ThreadMXBean ;
import  java . lang . management . ManagementFactory ;

/**
 *  The { @code  StopwatchCPU} data type is for measuring
 *  the CPU time used during a programming task.
 *
 *  See { @link  Stopwatch} for a version that measures wall-clock time
 *  (the real time that elapses).
 *
 *   @author  Josh Hug
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class   StopwatchCPU   {
     private   static   final   double  NANOSECONDS_PER_SECOND  =   1000000000 ;

     private   final   ThreadMXBean  threadTimer ;
     private   final   long  start ;
            
     /**
     * Initializes a new stopwatch.
     */
     public   StopwatchCPU ()   {   
        threadTimer  =   ManagementFactory . getThreadMXBean ();
        start  =  threadTimer . getCurrentThreadCpuTime ();
     }    
        
     /**
     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.
     *
     *  @return  elapsed CPU time (in seconds) since the stopwatch was created
     */
     public   double  elapsedTime ()   {
         long  now  =  threadTimer . getCurrentThreadCpuTime ();
         return   ( now  -  start )   /  NANOSECONDS_PER_SECOND ;
     }

     /**
     * Unit tests the { @code  StopwatchCPU} data type.
     * Takes a command-line argument { @code  n} and computes the 
     * sum of the square roots of the first { @code  n} positive integers,
     * first using { @code  Math.sqrt()}, then using { @code  Math.pow()}.
     * It prints to standard output the sum and the amount of time to
     * compute the sum. Note that the discrete sum can be approximated by
     * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   Integer . parseInt ( args [ 0 ]);

         // sum of square roots of integers from 1 to n using Math.sqrt(x).
         StopwatchCPU  timer1  =   new   StopwatchCPU ();
         double  sum1  =   0.0 ;
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            sum1  +=   Math . sqrt ( i );
         }
         double  time1  =  timer1 . elapsedTime ();
         StdOut . printf ( "%e (%.2f seconds)\n" ,  sum1 ,  time1 );

         // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).
         StopwatchCPU  timer2  =   new   StopwatchCPU ();
         double  sum2  =   0.0 ;
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            sum2  +=   Math . pow ( i ,   0.5 );
         }
         double  time2  =  timer2 . elapsedTime ();
         StdOut . printf ( "%e (%.2f seconds)\n" ,  sum2 ,  time2 );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Stopwatch.java

edu/princeton/cs/algs4/Stopwatch.java

/******************************************************************************
 *  Compilation:  javac Stopwatch.java
 *  Execution:    java Stopwatch n
 *  Dependencies: none
 *
 *  A utility class to measure the running time (wall clock) of a program.
 *
 *  % java8 Stopwatch 100000000
 *  6.666667e+11  0.5820 seconds
 *  6.666667e+11  8.4530 seconds
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Stopwatch} data type is for measuring
 *  the time that elapses between the start and end of a
 *  programming task (wall-clock time).
 *
 *  See { @link  StopwatchCPU} for a version that measures CPU time.
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/14analysis">Section 1.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */


public   class   Stopwatch   {  

     private   final   long  start ;

     /**
     * Initializes a new stopwatch.
     */
     public   Stopwatch ()   {
        start  =   System . currentTimeMillis ();
     }  


     /**
     * Returns the elapsed CPU time (in seconds) since the stopwatch was created.
     *
     *  @return  elapsed CPU time (in seconds) since the stopwatch was created
     */
     public   double  elapsedTime ()   {
         long  now  =   System . currentTimeMillis ();
         return   ( now  -  start )   /   1000.0 ;
     }

    
     /**
     * Unit tests the { @code  Stopwatch} data type.
     * Takes a command-line argument { @code  n} and computes the 
     * sum of the square roots of the first { @code  n} positive integers,
     * first using { @code  Math.sqrt()}, then using { @code  Math.pow()}.
     * It prints to standard output the sum and the amount of time to
     * compute the sum. Note that the discrete sum can be approximated by
     * an integral - the sum should be approximately 2/3 * (n^(3/2) - 1).
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   Integer . parseInt ( args [ 0 ]);

         // sum of square roots of integers from 1 to n using Math.sqrt(x).
         Stopwatch  timer1  =   new   Stopwatch ();
         double  sum1  =   0.0 ;
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            sum1  +=   Math . sqrt ( i );
         }
         double  time1  =  timer1 . elapsedTime ();
         StdOut . printf ( "%e (%.2f seconds)\n" ,  sum1 ,  time1 );

         // sum of square roots of integers from 1 to n using Math.pow(x, 0.5).
         Stopwatch  timer2  =   new   Stopwatch ();
         double  sum2  =   0.0 ;
         for   ( int  i  =   1 ;  i  <=  n ;  i ++ )   {
            sum2  +=   Math . pow ( i ,   0.5 );
         }
         double  time2  =  timer2 . elapsedTime ();
         StdOut . printf ( "%e (%.2f seconds)\n" ,  sum2 ,  time2 );
     }
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SuffixArray.java

edu/princeton/cs/algs4/SuffixArray.java

/******************************************************************************
 *  Compilation:  javac SuffixArray.java
 *  Execution:    java SuffixArray < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/63suffix/abra.txt
 *
 *  A data type that computes the suffix array of a string.
 *
 *   % java SuffixArray < abra.txt
 *    i ind lcp rnk  select
 *   ---------------------------
 *    0  11   -   0  "!"
 *    1  10   0   1  "A!"
 *    2   7   1   2  "ABRA!"
 *    3   0   4   3  "ABRACADABRA!"
 *    4   3   1   4  "ACADABRA!"
 *    5   5   1   5  "ADABRA!"
 *    6   8   0   6  "BRA!"
 *    7   1   3   7  "BRACADABRA!"
 *    8   4   0   8  "CADABRA!"
 *    9   6   0   9  "DABRA!"
 *   10   9   0  10  "RA!"
 *   11   2   2  11  "RACADABRA!"
 *
 *  See SuffixArrayX.java for an optimized version that uses 3-way
 *  radix quicksort and does not use the nested class Suffix.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 *  The { @code  SuffixArray} class represents a suffix array of a string of
 *  length <em>n</em>.
 *  It supports the <em>selecting</em> the <em>i</em>th smallest suffix,
 *  getting the <em>index</em> of the <em>i</em>th smallest suffix,
 *  computing the length of the <em>longest common prefix</em> between the
 *  <em>i</em>th smallest suffix and the <em>i</em>-1st smallest suffix,
 *  and determining the <em>rank</em> of a query string (which is the number
 *  of suffixes strictly less than the query string).
 *  <p>
 *  This implementation uses a nested class { @code  Suffix} to represent
 *  a suffix of a string (using constant time and space) and
 *  { @code  Arrays.sort()} to sort the array of suffixes.
 *  The <em>index</em> and <em>length</em> operations takes constant time 
 *  in the worst case. The <em>lcp</em> operation takes time proportional to the
 *  length of the longest common prefix.
 *  The <em>select</em> operation takes time proportional
 *  to the length of the suffix and should be used primarily for debugging.
 *  <p>
 *  For alternate implementations of the same API, see
 *  { @link  SuffixArrayX}, which is faster in practice (uses 3-way radix quicksort)
 *  and uses less memory (does not create { @code  Suffix} objects)
 *  and <a href = "https://algs4.cs.princeton.edu/63suffix/SuffixArrayJava6.java.html">SuffixArrayJava6.java</a>,
 *  which relies on the constant-time substring extraction method that existed
 *  in Java 6.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/63suffix">Section 6.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   SuffixArray   {
     private   Suffix []  suffixes ;

     /**
     * Initializes a suffix array for the given { @code  text} string.
     *  @param  text the input string
     */
     public   SuffixArray ( String  text )   {
         int  n  =  text . length ();
         this . suffixes  =   new   Suffix [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            suffixes [ i ]   =   new   Suffix ( text ,  i );
         Arrays . sort ( suffixes );
     }

     private   static   class   Suffix   implements   Comparable < Suffix >   {
         private   final   String  text ;
         private   final   int  index ;

         private   Suffix ( String  text ,   int  index )   {
             this . text  =  text ;
             this . index  =  index ;
         }
         private   int  length ()   {
             return  text . length ()   -  index ;
         }
         private   char  charAt ( int  i )   {
             return  text . charAt ( index  +  i );
         }

         public   int  compareTo ( Suffix  that )   {
             if   ( this   ==  that )   return   0 ;    // optimization
             int  n  =   Math . min ( this . length (),  that . length ());
             for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
                 if   ( this . charAt ( i )   <  that . charAt ( i ))   return   - 1 ;
                 if   ( this . charAt ( i )   >  that . charAt ( i ))   return   + 1 ;
             }
             return   this . length ()   -  that . length ();
         }

         public   String  toString ()   {
             return  text . substring ( index );
         }
     }

     /**
     * Returns the length of the input string.
     *  @return  the length of the input string
     */
     public   int  length ()   {
         return  suffixes . length ;
     }


     /**
     * Returns the index into the original string of the <em>i</em>th smallest suffix.
     * That is, { @code  text.substring(sa.index(i))} is the <em>i</em>th smallest suffix.
     *  @param  i an integer between 0 and <em>n</em>-1
     *  @return  the index into the original string of the <em>i</em>th smallest suffix
     *  @throws  java.lang.IllegalArgumentException unless { @code  0 <= i < n}
     */
     public   int  index ( int  i )   {
         if   ( <   0   ||  i  >=  suffixes . length )   throw   new   IllegalArgumentException ();
         return  suffixes [ i ]. index ;
     }


     /**
     * Returns the length of the longest common prefix of the <em>i</em>th
     * smallest suffix and the <em>i</em>-1st smallest suffix.
     *  @param  i an integer between 1 and <em>n</em>-1
     *  @return  the length of the longest common prefix of the <em>i</em>th
     * smallest suffix and the <em>i</em>-1st smallest suffix.
     *  @throws  java.lang.IllegalArgumentException unless { @code  1 <= i < n}
     */
     public   int  lcp ( int  i )   {
         if   ( <   1   ||  i  >=  suffixes . length )   throw   new   IllegalArgumentException ();
         return  lcpSuffix ( suffixes [ i ],  suffixes [ i - 1 ]);
     }

     // longest common prefix of s and t
     private   static   int  lcpSuffix ( Suffix  s ,   Suffix  t )   {
         int  n  =   Math . min ( s . length (),  t . length ());
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( s . charAt ( i )   !=  t . charAt ( i ))   return  i ;
         }
         return  n ;
     }

     /**
     * Returns the <em>i</em>th smallest suffix as a string.
     *  @param  i the index
     *  @return  the <em>i</em> smallest suffix as a string
     *  @throws  java.lang.IllegalArgumentException unless { @code  0 <= i < n}
     */
     public   String  select ( int  i )   {
         if   ( <   0   ||  i  >=  suffixes . length )   throw   new   IllegalArgumentException ();
         return  suffixes [ i ]. toString ();
     }

     /**
     * Returns the number of suffixes strictly less than the { @code  query} string.
     * We note that { @code  rank(select(i))} equals { @code  i} for each { @code  i}
     * between 0 and <em>n</em>-1.
     *  @param  query the query string
     *  @return  the number of suffixes strictly less than { @code  query}
     */
     public   int  rank ( String  query )   {
         int  lo  =   0 ,  hi  =  suffixes . length  -   1 ;
         while   ( lo  <=  hi )   {
             int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
             int  cmp  =  compare ( query ,  suffixes [ mid ]);
             if   ( cmp  <   0 )  hi  =  mid  -   1 ;
             else   if   ( cmp  >   0 )  lo  =  mid  +   1 ;
             else   return  mid ;
         }
         return  lo ;
     }

     // compare query string to suffix
     private   static   int  compare ( String  query ,   Suffix  suffix )   {
         int  n  =   Math . min ( query . length (),  suffix . length ());
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             if   ( query . charAt ( i )   <  suffix . charAt ( i ))   return   - 1 ;
             if   ( query . charAt ( i )   >  suffix . charAt ( i ))   return   + 1 ;
         }
         return  query . length ()   -  suffix . length ();
     }

     /**
     * Unit tests the { @code  SuffixArray} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  s  =   StdIn . readAll (). replaceAll ( "\\s+" ,   " " ). trim ();
         SuffixArray  suffix  =   new   SuffixArray ( s );

         // StdOut.println("rank(" + args[0] + ") = " + suffix.rank(args[0]));

         StdOut . println ( "  i ind lcp rnk select" );
         StdOut . println ( "---------------------------" );

         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )   {
             int  index  =  suffix . index ( i );
             String  ith  =   "\""   +  s . substring ( index ,   Math . min ( index  +   50 ,  s . length ()))   +   "\"" ;
             assert  s . substring ( index ). equals ( suffix . select ( i ));
             int  rank  =  suffix . rank ( s . substring ( index ));
             if   ( ==   0 )   {
                 StdOut . printf ( "%3d %3d %3s %3d %s\n" ,  i ,  index ,   "-" ,  rank ,  ith );
             }
             else   {
                 int  lcp  =  suffix . lcp ( i );
                 StdOut . printf ( "%3d %3d %3d %3d %s\n" ,  i ,  index ,  lcp ,  rank ,  ith );
             }
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SuffixArrayX.java

edu/princeton/cs/algs4/SuffixArrayX.java

/******************************************************************************
 *  Compilation:  javac SuffixArrayX.java
 *  Execution:    java SuffixArrayX < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/63suffix/abra.txt
 *  
 *  A data type that computes the suffix array of a string using 3-way
 *  radix quicksort.
 *
 *  % java SuffixArrayX < abra.txt 
 *    i ind lcp rnk  select
 *  ---------------------------
 *    0  11   -   0  !
 *    1  10   0   1  A!
 *    2   7   1   2  ABRA!
 *    3   0   4   3  ABRACADABRA!
 *    4   3   1   4  ACADABRA!
 *    5   5   1   5  ADABRA!
 *    6   8   0   6  BRA!
 *    7   1   3   7  BRACADABRA!
 *    8   4   0   8  CADABRA!
 *    9   6   0   9  DABRA!
 *   10   9   0  10  RA!
 *   11   2   2  11  RACADABRA!
 *
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SuffixArrayX} class represents a suffix array of a string of
 *  length <em>n</em>.
 *  It supports the <em>selecting</em> the <em>i</em>th smallest suffix,
 *  getting the <em>index</em> of the <em>i</em>th smallest suffix,
 *  computing the length of the <em>longest common prefix</em> between the
 *  <em>i</em>th smallest suffix and the <em>i</em>-1st smallest suffix,
 *  and determining the <em>rank</em> of a query string (which is the number
 *  of suffixes strictly less than the query string).
 *  <p>
 *  This implementation uses 3-way radix quicksort to sort the array of suffixes.
 *  For a simpler (but less efficient) implementations of the same API, see
 *  { @link  SuffixArray}.
 *  The <em>index</em> and <em>length</em> operations takes constant time
 *  in the worst case. The <em>lcp</em> operation takes time proportional to the
 *  length of the longest common prefix.
 *  The <em>select</em> operation takes time proportional
 *  to the length of the suffix and should be used primarily for debugging.
 *  <p>
 *  This implementation uses '\0' as a sentinel and assumes that the charater
 *  '\0' does not appear in the text.
 *  <p>
 *  In practice, this algorithm runs very fast. However, in the worst-case
 *  it can be very poor (e.g., a string consisting of N copies of the same
 *  character. We do not shuffle the array of suffixes before sorting because
 *  shuffling is relatively expensive and a pathologial input for which 
 *  the suffixes start out in a bad order (e.g., sorted) is likely to be
 *  a bad input for this algorithm with or without the shuffle.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/63suffix">Section 6.3</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   SuffixArrayX   {
     private   static   final   int  CUTOFF  =    5 ;     // cutoff to insertion sort (any value between 0 and 12)

     private   final   char []  text ;
     private   final   int []  index ;     // index[i] = j means text.substring(j) is ith largest suffix
     private   final   int  n ;           // number of characters in text

     /**
     * Initializes a suffix array for the given { @code  text} string.
     *  @param  text the input string
     */
     public   SuffixArrayX ( String  text )   {
        n  =  text . length ();
        text  =  text  +   '\0' ;
         this . text  =  text . toCharArray ();
         this . index  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )
            index [ i ]   =  i ;

        sort ( 0 ,  n - 1 ,   0 );
     }

     // 3-way string quicksort lo..hi starting at dth character
     private   void  sort ( int  lo ,   int  hi ,   int  d )   {  

         // cutoff to insertion sort for small subarrays
         if   ( hi  <=  lo  +  CUTOFF )   {
            insertion ( lo ,  hi ,  d );
             return ;
         }

         int  lt  =  lo ,  gt  =  hi ;
         char  v  =  text [ index [ lo ]   +  d ];
         int  i  =  lo  +   1 ;
         while   ( <=  gt )   {
             char  t  =  text [ index [ i ]   +  d ];
             if        ( <  v )  exch ( lt ++ ,  i ++ );
             else   if   ( >  v )  exch ( i ,  gt -- );
             else             i ++ ;
         }

         // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]. 
        sort ( lo ,  lt - 1 ,  d );
         if   ( >   0 )  sort ( lt ,  gt ,  d + 1 );
        sort ( gt + 1 ,  hi ,  d );
     }

     // sort from a[lo] to a[hi], starting at the dth character
     private   void  insertion ( int  lo ,   int  hi ,   int  d )   {
         for   ( int  i  =  lo ;  i  <=  hi ;  i ++ )
             for   ( int  j  =  i ;  j  >  lo  &&  less ( index [ j ],  index [ j - 1 ],  d );  j -- )
                exch ( j ,  j - 1 );
     }

     // is text[i+d..n) < text[j+d..n) ?
     private   boolean  less ( int  i ,   int  j ,   int  d )   {
         if   ( ==  j )   return   false ;
        i  =  i  +  d ;
        j  =  j  +  d ;
         while   ( <  n  &&  j  <  n )   {
             if   ( text [ i ]   <  text [ j ])   return   true ;
             if   ( text [ i ]   >  text [ j ])   return   false ;
            i ++ ;
            j ++ ;
         }
         return  i  >  j ;
     }

     // exchange index[i] and index[j]
     private   void  exch ( int  i ,   int  j )   {
         int  swap  =  index [ i ];
        index [ i ]   =  index [ j ];
        index [ j ]   =  swap ;
     }

     /**
     * Returns the length of the input string.
     *  @return  the length of the input string
     */
     public   int  length ()   {
         return  n ;
     }


     /**
     * Returns the index into the original string of the <em>i</em>th smallest suffix.
     * That is, { @code  text.substring(sa.index(i))} is the <em>i</em> smallest suffix.
     *  @param  i an integer between 0 and <em>n</em>-1
     *  @return  the index into the original string of the <em>i</em>th smallest suffix
     *  @throws  java.lang.IllegalArgumentException unless { @code  0 <=i < n}
     */
     public   int  index ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         return  index [ i ];
     }

     /**
     * Returns the length of the longest common prefix of the <em>i</em>th
     * smallest suffix and the <em>i</em>-1st smallest suffix.
     *  @param  i an integer between 1 and <em>n</em>-1
     *  @return  the length of the longest common prefix of the <em>i</em>th
     * smallest suffix and the <em>i</em>-1st smallest suffix.
     *  @throws  java.lang.IllegalArgumentException unless { @code  1 <= i < n}
     */
     public   int  lcp ( int  i )   {
         if   ( <   1   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         return  lcp ( index [ i ],  index [ i - 1 ]);
     }

     // longest common prefix of text[i..n) and text[j..n)
     private   int  lcp ( int  i ,   int  j )   {
         int  length  =   0 ;
         while   ( <  n  &&  j  <  n )   {
             if   ( text [ i ]   !=  text [ j ])   return  length ;
            i ++ ;
            j ++ ;
            length ++ ;
         }
         return  length ;
     }

     /**
     * Returns the <em>i</em>th smallest suffix as a string.
     *  @param  i the index
     *  @return  the <em>i</em> smallest suffix as a string
     *  @throws  java.lang.IllegalArgumentException unless { @code  0 <= i < n}
     */
     public   String  select ( int  i )   {
         if   ( <   0   ||  i  >=  n )   throw   new   IllegalArgumentException ();
         return   new   String ( text ,  index [ i ],  n  -  index [ i ]);
     }

     /**
     * Returns the number of suffixes strictly less than the { @code  query} string.
     * We note that { @code  rank(select(i))} equals { @code  i} for each { @code  i}
     * between 0 and <em>n</em>-1. 
     *  @param  query the query string
     *  @return  the number of suffixes strictly less than { @code  query}
     */
     public   int  rank ( String  query )   {
         int  lo  =   0 ,  hi  =  n  -   1 ;
         while   ( lo  <=  hi )   {
             int  mid  =  lo  +   ( hi  -  lo )   /   2 ;
             int  cmp  =  compare ( query ,  index [ mid ]);
             if        ( cmp  <   0 )  hi  =  mid  -   1 ;
             else   if   ( cmp  >   0 )  lo  =  mid  +   1 ;
             else   return  mid ;
         }
         return  lo ;
     }  

     // is query < text[i..n) ?
     private   int  compare ( String  query ,   int  i )   {
         int  m  =  query . length ();
         int  j  =   0 ;
         while   ( <  n  &&  j  <  m )   {
             if   ( query . charAt ( j )   !=  text [ i ])   return  query . charAt ( j )   -  text [ i ];
            i ++ ;
            j ++ ;

         }
         if   ( <  n )   return   - 1 ;
         if   ( <  m )   return   + 1 ;
         return   0 ;
     }


     /**
     * Unit tests the { @code  SuffixArrayx} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  s  =   StdIn . readAll (). replaceAll ( "\n" ,   " " ). trim ();
         SuffixArrayX  suffix1  =   new   SuffixArrayX ( s );
         SuffixArray  suffix2  =   new   SuffixArray ( s );
         boolean  check  =   true ;
         for   ( int  i  =   0 ;  check  &&  i  <  s . length ();  i ++ )   {
             if   ( suffix1 . index ( i )   !=  suffix2 . index ( i ))   {
                 StdOut . println ( "suffix1("   +  i  +   ") = "   +  suffix1 . index ( i ));
                 StdOut . println ( "suffix2("   +  i  +   ") = "   +  suffix2 . index ( i ));
                 String  ith  =   "\""   +  s . substring ( suffix1 . index ( i ),   Math . min ( suffix1 . index ( i )   +   50 ,  s . length ()))   +   "\"" ;
                 String  jth  =   "\""   +  s . substring ( suffix2 . index ( i ),   Math . min ( suffix2 . index ( i )   +   50 ,  s . length ()))   +   "\"" ;
                 StdOut . println ( ith );
                 StdOut . println ( jth );
                check  =   false ;
             }
         }

         StdOut . println ( "  i ind lcp rnk  select" );
         StdOut . println ( "---------------------------" );

         for   ( int  i  =   0 ;  i  <  s . length ();  i ++ )   {
             int  index  =  suffix2 . index ( i );
             String  ith  =   "\""   +  s . substring ( index ,   Math . min ( index  +   50 ,  s . length ()))   +   "\"" ;
             int  rank  =  suffix2 . rank ( s . substring ( index ));
             assert  s . substring ( index ). equals ( suffix2 . select ( i ));
             if   ( ==   0 )   {
                 StdOut . printf ( "%3d %3d %3s %3d  %s\n" ,  i ,  index ,   "-" ,  rank ,  ith );
             }
             else   {
                 // int lcp  = suffix.lcp(suffix2.index(i), suffix2.index(i-1));
                 int  lcp   =  suffix2 . lcp ( i );
                 StdOut . printf ( "%3d %3d %3d %3d  %s\n" ,  i ,  index ,  lcp ,  rank ,  ith );
             }
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SymbolDigraph.java

edu/princeton/cs/algs4/SymbolDigraph.java

/******************************************************************************
 *  Compilation:  javac SymbolDigraph.java
 *  Execution:    java SymbolDigraph
 *  Dependencies: ST.java Digraph.java In.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/routes.txt
 *  
 *  %  java SymbolDigraph routes.txt " "
 *  JFK
 *     MCO
 *     ATL
 *     ORD
 *  ATL
 *     HOU
 *     MCO
 *  LAX
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SymbolDigraph} class represents a digraph, where the
 *  vertex names are arbitrary strings.
 *  By providing mappings between string vertex names and integers,
 *  it serves as a wrapper around the
 *  { @link  Digraph} data type, which assumes the vertex names are integers
 *  between 0 and <em>V</em> - 1.
 *  It also supports initializing a symbol digraph from a file.
 *  <p>
 *  This implementation uses an { @link  ST} to map from strings to integers,
 *  an array to map from integers to strings, and a { @link  Digraph} to store
 *  the underlying graph.
 *  The <em>indexOf</em> and <em>contains</em> operations take time 
 *  proportional to log <em>V</em>, where <em>V</em> is the number of vertices.
 *  The <em>nameOf</em> operation takes constant time.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   SymbolDigraph   {
     private  ST < String ,   Integer >  st ;    // string -> index
     private   String []  keys ;             // index  -> string
     private   Digraph  graph ;             // the underlying digraph

     /**  
     * Initializes a digraph from a file using the specified delimiter.
     * Each line in the file contains
     * the name of a vertex, followed by a list of the names
     * of the vertices adjacent to that vertex, separated by the delimiter.
     *  @param  filename the name of the file
     *  @param  delimiter the delimiter between fields
     */
     public   SymbolDigraph ( String  filename ,   String  delimiter )   {
        st  =   new  ST < String ,   Integer > ();

         // First pass builds the index by reading strings to associate
         // distinct strings with an index
         In  in  =   new   In ( filename );
         while   ( in . hasNextLine ())   {
             String []  a  =  in . readLine (). split ( delimiter );
             for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
                 if   ( ! st . contains ( a [ i ]))
                    st . put ( a [ i ],  st . size ());
             }
         }

         // inverted index to get string keys in an array
        keys  =   new   String [ st . size ()];
         for   ( String  name  :  st . keys ())   {
            keys [ st . get ( name )]   =  name ;
         }

         // second pass builds the digraph by connecting first vertex on each
         // line to all others
        graph  =   new   Digraph ( st . size ());
        in  =   new   In ( filename );
         while   ( in . hasNextLine ())   {
             String []  a  =  in . readLine (). split ( delimiter );
             int  v  =  st . get ( a [ 0 ]);
             for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )   {
                 int  w  =  st . get ( a [ i ]);
                graph . addEdge ( v ,  w );
             }
         }
     }

     /**
     * Does the digraph contain the vertex named { @code  s}?
     *  @param  s the name of a vertex
     *  @return  { @code  true} if { @code  s} is the name of a vertex, and { @code  false} otherwise
     */
     public   boolean  contains ( String  s )   {
         return  st . contains ( s );
     }

     /**
     * Returns the integer associated with the vertex named { @code  s}.
     *  @param  s the name of a vertex
     *  @return  the integer (between 0 and <em>V</em> - 1) associated with the vertex named { @code  s}
     *  @deprecated  Replaced by { @link  #indexOf(String)}.
     */
    @ Deprecated
     public   int  index ( String  s )   {
         return  st . get ( s );
     }

     /**
     * Returns the integer associated with the vertex named { @code  s}.
     *  @param  s the name of a vertex
     *  @return  the integer (between 0 and <em>V</em> - 1) associated with the vertex named { @code  s}
     */
     public   int  indexOf ( String  s )   {
         return  st . get ( s );
     }

     /**
     * Returns the name of the vertex associated with the integer { @code  v}.
     *  @param   v the integer corresponding to a vertex (between 0 and <em>V</em> - 1) 
     *  @return  the name of the vertex associated with the integer { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @deprecated  Replaced by { @link  #nameOf(int)}.
     */
    @ Deprecated
     public   String  name ( int  v )   {
        validateVertex ( v );
         return  keys [ v ];
     }

     /**
     * Returns the name of the vertex associated with the integer { @code  v}.
     *  @param   v the integer corresponding to a vertex (between 0 and <em>V</em> - 1) 
     *  @return  the name of the vertex associated with the integer { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   String  nameOf ( int  v )   {
        validateVertex ( v );
         return  keys [ v ];
     }

     /**
     * Returns the digraph assoicated with the symbol graph. It is the client's responsibility
     * not to mutate the digraph.
     *
     *  @return  the digraph associated with the symbol digraph
     *  @deprecated  Replaced by { @link  #digraph()}.
     */
    @ Deprecated
     public   Digraph  G ()   {
         return  graph ;
     }

     /**
     * Returns the digraph assoicated with the symbol graph. It is the client's responsibility
     * not to mutate the digraph.
     *
     *  @return  the digraph associated with the symbol digraph
     */
     public   Digraph  digraph ()   {
         return  graph ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  graph . V ();
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  SymbolDigraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  filename   =  args [ 0 ];
         String  delimiter  =  args [ 1 ];
         SymbolDigraph  sg  =   new   SymbolDigraph ( filename ,  delimiter );
         Digraph  graph  =  sg . digraph ();
         while   ( ! StdIn . isEmpty ())   {
             String  t  =   StdIn . readLine ();
             for   ( int  v  :  graph . adj ( sg . index ( t )))   {
                 StdOut . println ( "   "   +  sg . name ( v ));
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/SymbolGraph.java

edu/princeton/cs/algs4/SymbolGraph.java

/******************************************************************************
 *  Compilation:  javac SymbolGraph.java
 *  Execution:    java SymbolGraph filename.txt delimiter
 *  Dependencies: ST.java Graph.java In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/41graph/routes.txt
 *                https://algs4.cs.princeton.edu/41graph/movies.txt
 *                https://algs4.cs.princeton.edu/41graph/moviestiny.txt
 *                https://algs4.cs.princeton.edu/41graph/moviesG.txt
 *                https://algs4.cs.princeton.edu/41graph/moviestopGrossing.txt
 *  
 *  %  java SymbolGraph routes.txt " "
 *  JFK
 *     MCO
 *     ATL
 *     ORD
 *  LAX
 *     PHX
 *     LAS
 *
 *  % java SymbolGraph movies.txt "/"
 *  Tin Men (1987)
 *     Hershey, Barbara
 *     Geppi, Cindy
 *     Jones, Kathy (II)
 *     Herr, Marcia
 *     ...
 *     Blumenfeld, Alan
 *     DeBoy, David
 *  Bacon, Kevin
 *     Woodsman, The (2004)
 *     Wild Things (1998)
 *     Where the Truth Lies (2005)
 *     Tremors (1990)
 *     ...
 *     Apollo 13 (1995)
 *     Animal House (1978)
 *
 * 
 *  Assumes that input file is encoded using UTF-8.
 *  % iconv -f ISO-8859-1 -t UTF-8 movies-iso8859.txt > movies.txt
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  SymbolGraph} class represents an undirected graph, where the
 *  vertex names are arbitrary strings.
 *  By providing mappings between string vertex names and integers,
 *  it serves as a wrapper around the
 *  { @link  Graph} data type, which assumes the vertex names are integers
 *  between 0 and <em>V</em> - 1.
 *  It also supports initializing a symbol graph from a file.
 *  <p>
 *  This implementation uses an { @link  ST} to map from strings to integers,
 *  an array to map from integers to strings, and a { @link  Graph} to store
 *  the underlying graph.
 *  The <em>indexOf</em> and <em>contains</em> operations take time 
 *  proportional to log <em>V</em>, where <em>V</em> is the number of vertices.
 *  The <em>nameOf</em> operation takes constant time.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/41graph">Section 4.1</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   SymbolGraph   {
     private  ST < String ,   Integer >  st ;    // string -> index
     private   String []  keys ;             // index  -> string
     private   Graph  graph ;               // the underlying graph

     /**  
     * Initializes a graph from a file using the specified delimiter.
     * Each line in the file contains
     * the name of a vertex, followed by a list of the names
     * of the vertices adjacent to that vertex, separated by the delimiter.
     *  @param  filename the name of the file
     *  @param  delimiter the delimiter between fields
     */
     public   SymbolGraph ( String  filename ,   String  delimiter )   {
        st  =   new  ST < String ,   Integer > ();

         // First pass builds the index by reading strings to associate
         // distinct strings with an index
         In  in  =   new   In ( filename );
         // while (in.hasNextLine()) {
         while   ( ! in . isEmpty ())   {
             String []  a  =  in . readLine (). split ( delimiter );
             for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )   {
                 if   ( ! st . contains ( a [ i ]))
                    st . put ( a [ i ],  st . size ());
             }
         }

         // inverted index to get string keys in an array
        keys  =   new   String [ st . size ()];
         for   ( String  name  :  st . keys ())   {
            keys [ st . get ( name )]   =  name ;
         }

         // second pass builds the graph by connecting first vertex on each
         // line to all others
        graph  =   new   Graph ( st . size ());
        in  =   new   In ( filename );
         while   ( in . hasNextLine ())   {
             String []  a  =  in . readLine (). split ( delimiter );
             int  v  =  st . get ( a [ 0 ]);
             for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )   {
                 int  w  =  st . get ( a [ i ]);
                graph . addEdge ( v ,  w );
             }
         }
     }

     /**
     * Does the graph contain the vertex named { @code  s}?
     *  @param  s the name of a vertex
     *  @return  { @code  true} if { @code  s} is the name of a vertex, and { @code  false} otherwise
     */
     public   boolean  contains ( String  s )   {
         return  st . contains ( s );
     }

     /**
     * Returns the integer associated with the vertex named { @code  s}.
     *  @param  s the name of a vertex
     *  @return  the integer (between 0 and <em>V</em> - 1) associated with the vertex named { @code  s}
     *  @deprecated  Replaced by { @link  #indexOf(String)}.
     */
    @ Deprecated
     public   int  index ( String  s )   {
         return  st . get ( s );
     }


     /**
     * Returns the integer associated with the vertex named { @code  s}.
     *  @param  s the name of a vertex
     *  @return  the integer (between 0 and <em>V</em> - 1) associated with the vertex named { @code  s}
     */
     public   int  indexOf ( String  s )   {
         return  st . get ( s );
     }

     /**
     * Returns the name of the vertex associated with the integer { @code  v}.
     *  @param   v the integer corresponding to a vertex (between 0 and <em>V</em> - 1) 
     *  @return  the name of the vertex associated with the integer { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @deprecated  Replaced by { @link  #nameOf(int)}.
     */
    @ Deprecated
     public   String  name ( int  v )   {
        validateVertex ( v );
         return  keys [ v ];
     }

     /**
     * Returns the name of the vertex associated with the integer { @code  v}.
     *  @param   v the integer corresponding to a vertex (between 0 and <em>V</em> - 1) 
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @return  the name of the vertex associated with the integer { @code  v}
     */
     public   String  nameOf ( int  v )   {
        validateVertex ( v );
         return  keys [ v ];
     }

     /**
     * Returns the graph assoicated with the symbol graph. It is the client's responsibility
     * not to mutate the graph.
     *  @return  the graph associated with the symbol graph
     *  @deprecated  Replaced by { @link  #graph()}.
     */
    @ Deprecated
     public   Graph  G ()   {
         return  graph ;
     }

     /**
     * Returns the graph assoicated with the symbol graph. It is the client's responsibility
     * not to mutate the graph.
     *  @return  the graph associated with the symbol graph
     */
     public   Graph  graph ()   {
         return  graph ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  graph . V ();
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }


     /**
     * Unit tests the { @code  SymbolGraph} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  filename   =  args [ 0 ];
         String  delimiter  =  args [ 1 ];
         SymbolGraph  sg  =   new   SymbolGraph ( filename ,  delimiter );
         Graph  graph  =  sg . graph ();
         while   ( StdIn . hasNextLine ())   {
             String  source  =   StdIn . readLine ();
             if   ( sg . contains ( source ))   {
                 int  s  =  sg . index ( source );
                 for   ( int  v  :  graph . adj ( s ))   {
                     StdOut . println ( "   "   +  sg . name ( v ));
                 }
             }
             else   {
                 StdOut . println ( "input not contain '"   +  source  +   "'" );
             }
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TarjanSCC.java

edu/princeton/cs/algs4/TarjanSCC.java

/******************************************************************************
 *  Compilation:  javac TarjanSCC.java
 *  Execution:    Java TarjanSCC V E
 *  Dependencies: Digraph.java Stack.java TransitiveClosure.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/mediumDG.txt
 *                https://algs4.cs.princeton.edu/42digraph/largeDG.txt
 *
 *  Compute the strongly-connected components of a digraph using 
 *  Tarjan's algorithm.
 *
 *  Runs in O(E + V) time.
 *
 *  % java TarjanSCC tinyDG.txt
 *  5 components
 *  1 
 *  0 2 3 4 5
 *  9 10 11 12
 *  6 8
 *  7 
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TarjanSCC} class represents a data type for 
 *  determining the strong components in a digraph.
 *  The <em>id</em> operation determines in which strong component
 *  a given vertex lies; the <em>areStronglyConnected</em> operation
 *  determines whether two vertices are in the same strong component;
 *  and the <em>count</em> operation determines the number of strong
 *  components.
 *  <p>
 *  The <em>component identifier</em> of a component is one of the
 *  vertices in the strong component: two vertices have the same component
 *  identifier if and only if they are in the same strong component.
 *  <p>
 *  This implementation uses Tarjan's algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
 *  where <em>V</em> is the number of vertices and <em>E</em> is the
 *  number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  For alternative implementations of the same API, see
 *  { @link  KosarajuSharirSCC} and { @link  GabowSCC}.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TarjanSCC   {

     private   boolean []  marked ;          // marked[v] = has v been visited?
     private   int []  id ;                  // id[v] = id of strong component containing v
     private   int []  low ;                 // low[v] = low number of v
     private   int  pre ;                   // preorder number counter
     private   int  count ;                 // number of strongly-connected components
     private   Stack < Integer >  stack ;


     /**
     * Computes the strong components of the digraph { @code  G}.
     *  @param  G the digraph
     */
     public   TarjanSCC ( Digraph  G )   {
        marked  =   new   boolean [ G . V ()];
        stack  =   new   Stack < Integer > ();
        id  =   new   int [ G . V ()];  
        low  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             if   ( ! marked [ v ])  dfs ( G ,  v );
         }

         // check that id[] gives strong components
         assert  check ( G );
     }

     private   void  dfs ( Digraph  G ,   int  v )   {  
        marked [ v ]   =   true ;
        low [ v ]   =  pre ++ ;
         int  min  =  low [ v ];
        stack . push ( v );
         for   ( int  w  :  G . adj ( v ))   {
             if   ( ! marked [ w ])  dfs ( G ,  w );
             if   ( low [ w ]   <  min )  min  =  low [ w ];
         }
         if   ( min  <  low [ v ])   {
            low [ v ]   =  min ;
             return ;
         }
         int  w ;
         do   {
            w  =  stack . pop ();
            id [ w ]   =  count ;
            low [ w ]   =  G . V ();
         }   while   ( !=  v );
        count ++ ;
     }


     /**
     * Returns the number of strong components.
     *  @return  the number of strong components
     */
     public   int  count ()   {
         return  count ;
     }


     /**
     * Are vertices { @code  v} and { @code  w} in the same strong component?
     *  @param   v one vertex
     *  @param   w the other vertex
     *  @return  { @code  true} if vertices { @code  v} and { @code  w} are in the same
     *         strong component, and { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     */
     public   boolean  stronglyConnected ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  id [ v ]   ==  id [ w ];
     }

     /**
     * Returns the component id of the strong component containing vertex { @code  v}.
     *  @param   v the vertex
     *  @return  the component id of the strong component containing vertex { @code  v}
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  id ( int  v )   {
        validateVertex ( v );
         return  id [ v ];
     }

     // does the id[] array contain the strongly connected components?
     private   boolean  check ( Digraph  G )   {
         TransitiveClosure  tc  =   new   TransitiveClosure ( G );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( stronglyConnected ( v ,  w )   !=   ( tc . reachable ( v ,  w )   &&  tc . reachable ( w ,  v )))
                     return   false ;
             }
         }
         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  marked . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  TarjanSCC} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );
         TarjanSCC  scc  =   new   TarjanSCC ( G );

         // number of connected components
         int  m  =  scc . count ();
         StdOut . println ( +   " components" );

         // compute list of vertices in each strong component
         Queue < Integer > []  components  =   ( Queue < Integer > [])   new   Queue [ m ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
            components [ i ]   =   new   Queue < Integer > ();
         }
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            components [ scc . id ( v )]. enqueue ( v );
         }

         // print results
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             for   ( int  v  :  components [ i ])   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ThreeSumFast.java

edu/princeton/cs/algs4/ThreeSumFast.java

/******************************************************************************
 *  Compilation:  javac ThreeSumFast.java
 *  Execution:    java ThreeSumFast input.txt
 *  Dependencies: StdOut.java In.java Stopwatch.java
 *  Data files:   https://algs4.cs.princeton.edu/14analysis/1Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/2Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/4Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/8Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/16Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/32Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/1Mints.txt
 *
 *  A program with n^2 log n running time. Reads n integers
 *  and counts the number of triples that sum to exactly 0.
 *
 *  Limitations
 *  -----------
 *     - we ignore integer overflow
 *     - doesn't handle case when input has duplicates
 *
 *
 *  % java ThreeSumFast 1Kints.txt
 *  70
 *  
 *  % java ThreeSumFast 2Kints.txt
 *  528
 *                
 *  % java ThreeSumFast 4Kints.txt
 *  4039
 * 
 *  % java ThreeSumFast 8Kints.txt
 *  32074
 *
 *  % java ThreeSumFast 16Kints.txt
 *  255181
 *
 *  % java ThreeSumFast 32Kints.txt
 *  2052358
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;

/**
 *  The { @code  ThreeSumFast} class provides static methods for counting
 *  and printing the number of triples in an array of distinct integers that
 *  sum to 0 (ignoring integer overflow).
 *  <p>
 *  This implementation uses sorting and binary search and takes time 
 *  proportional to n^2 log n, where n is the number of integers.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/14analysis">Section 1.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ThreeSumFast   {

     // Do not instantiate.
     private   ThreeSumFast ()   {   }

     // returns true if the sorted array a[] contains any duplicated integers
     private   static   boolean  containsDuplicates ( int []  a )   {
         for   ( int  i  =   1 ;  i  <  a . length ;  i ++ )
             if   ( a [ i ]   ==  a [ i - 1 ])   return   true ;
         return   false ;
     }

     /**
     * Prints to standard output the (i, j, k) with { @code  i < j < k}
     * such that { @code  a[i] + a[j] + a[k] == 0}.
     *
     *  @param  a the array of integers
     *  @throws  IllegalArgumentException if the array contains duplicate integers
     */
     public   static   void  printAll ( int []  a )   {
         int  n  =  a . length ;
         Arrays . sort ( a );
         if   ( containsDuplicates ( a ))   throw   new   IllegalArgumentException ( "array contains duplicate integers" );
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 int  k  =   Arrays . binarySearch ( a ,   - ( a [ i ]   +  a [ j ]));
                 if   ( >  j )   StdOut . println ( a [ i ]   +   " "   +  a [ j ]   +   " "   +  a [ k ]);
             }
         }
     }  

     /**
     * Returns the number of triples (i, j, k) with { @code  i < j < k}
     * such that { @code  a[i] + a[j] + a[k] == 0}.
     *
     *  @param  a the array of integers
     *  @return  the number of triples (i, j, k) with { @code  i < j < k}
     * such that { @code  a[i] + a[j] + a[k] == 0}
     */
     public   static   int  count ( int []  a )   {
         int  n  =  a . length ;
         Arrays . sort ( a );
         if   ( containsDuplicates ( a ))   throw   new   IllegalArgumentException ( "array contains duplicate integers" );
         int  count  =   0 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 int  k  =   Arrays . binarySearch ( a ,   - ( a [ i ]   +  a [ j ]));
                 if   ( >  j )  count ++ ;
             }
         }
         return  count ;
     }  

     /**
     * Reads in a sequence of distinct integers from a file, specified as a command-line argument;
     * counts the number of triples sum to exactly zero; prints out the time to perform
     * the computation.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )    {  
         In  in  =   new   In ( args [ 0 ]);
         int []  a  =  in . readAllInts ();
         int  count  =  count ( a );
         StdOut . println ( count );
     }  
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/ThreeSum.java

edu/princeton/cs/algs4/ThreeSum.java

/******************************************************************************
 *  Compilation:  javac ThreeSum.java
 *  Execution:    java ThreeSum input.txt
 *  Dependencies: In.java StdOut.java Stopwatch.java
 *  Data files:   https://algs4.cs.princeton.edu/14analysis/1Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/2Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/4Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/8Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/16Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/32Kints.txt
 *                https://algs4.cs.princeton.edu/14analysis/1Mints.txt
 *
 *  A program with cubic running time. Reads n integers
 *  and counts the number of triples that sum to exactly 0
 *  (ignoring integer overflow).
 *
 *  % java ThreeSum 1Kints.txt 
 *  70
 *
 *  % java ThreeSum 2Kints.txt 
 *  528
 *
 *  % java ThreeSum 4Kints.txt 
 *  4039
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  ThreeSum} class provides static methods for counting
 *  and printing the number of triples in an array of integers that sum to 0
 *  (ignoring integer overflow).
 *  <p>
 *  This implementation uses a triply nested loop and takes proportional to n^3,
 *  where n is the number of integers.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/14analysis">Section 1.4</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   ThreeSum   {

     // Do not instantiate.
     private   ThreeSum ()   {   }

     /**
     * Prints to standard output the (i, j, k) with { @code  i < j < k}
     * such that { @code  a[i] + a[j] + a[k] == 0}.
     *
     *  @param  a the array of integers
     */
     public   static   void  printAll ( int []  a )   {
         int  n  =  a . length ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 for   ( int  k  =  j + 1 ;  k  <  n ;  k ++ )   {
                     if   ( a [ i ]   +  a [ j ]   +  a [ k ]   ==   0 )   {
                         StdOut . println ( a [ i ]   +   " "   +  a [ j ]   +   " "   +  a [ k ]);
                     }
                 }
             }
         }
     }  

     /**
     * Returns the number of triples (i, j, k) with { @code  i < j < k}
     * such that { @code  a[i] + a[j] + a[k] == 0}.
     *
     *  @param   a the array of integers
     *  @return  the number of triples (i, j, k) with { @code  i < j < k}
     *         such that { @code  a[i] + a[j] + a[k] == 0}
     */
     public   static   int  count ( int []  a )   {
         int  n  =  a . length ;
         int  count  =   0 ;
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
             for   ( int  j  =  i + 1 ;  j  <  n ;  j ++ )   {
                 for   ( int  k  =  j + 1 ;  k  <  n ;  k ++ )   {
                     if   ( a [ i ]   +  a [ j ]   +  a [ k ]   ==   0 )   {
                        count ++ ;
                     }
                 }
             }
         }
         return  count ;
     }  

     /**
     * Reads in a sequence of integers from a file, specified as a command-line argument;
     * counts the number of triples sum to exactly zero; prints out the time to perform
     * the computation.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )    {  
         In  in  =   new   In ( args [ 0 ]);
         int []  a  =  in . readAllInts ();

         Stopwatch  timer  =   new   Stopwatch ();
         int  count  =  count ( a );
         StdOut . println ( "elapsed time = "   +  timer . elapsedTime ());
         StdOut . println ( count );
     }  
}  

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TopM.java

edu/princeton/cs/algs4/TopM.java

/******************************************************************************
 *  Compilation:  javac TopM.java
 *  Execution:    java TopM m < input.txt
 *  Dependencies: MinPQ.java Transaction.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/24pq/tinyBatch.txt
 * 
 *  Given an integer m from the command line and an input stream where
 *  each line contains a String and a long value, this MinPQ client
 *  prints the m lines whose numbers are the highest.
 * 
 *  % java TopM 5 < tinyBatch.txt 
 *  Thompson    2/27/2000  4747.08
 *  vonNeumann  2/12/1994  4732.35
 *  vonNeumann  1/11/1999  4409.74
 *  Hoare       8/18/1992  4381.21
 *  vonNeumann  3/26/2002  4121.85
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TopM} class provides a client that reads a sequence of
 *  transactions from standard input and prints the <em>m</em> largest ones
 *  to standard output. This implementation uses a { @link  MinPQ} of size
 *  at most <em>m</em> + 1 to identify the <em>M</em> largest transactions
 *  and a { @link  Stack} to output them in the proper order.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/24pq">Section 2.4</a>
 *  of <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TopM   {    

     // This class should not be instantiated.
     private   TopM ()   {   }

     /**
     *  Reads a sequence of transactions from standard input; takes a
     *  command-line integer m; prints to standard output the m largest
     *  transactions in descending order.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  m  =   Integer . parseInt ( args [ 0 ]);  
         MinPQ < Transaction >  pq  =   new   MinPQ < Transaction > ( m + 1 );

         while   ( StdIn . hasNextLine ())   {
             // Create an entry from the next line and put on the PQ. 
             String  line  =   StdIn . readLine ();
             Transaction  transaction  =   new   Transaction ( line );
            pq . insert ( transaction );  

             // remove minimum if m+1 entries on the PQ
             if   ( pq . size ()   >  m )  
                pq . delMin ();
         }     // top m entries are on the PQ

         // print entries on PQ in reverse order
         Stack < Transaction >  stack  =   new   Stack < Transaction > ();
         for   ( Transaction  transaction  :  pq )
            stack . push ( transaction );
         for   ( Transaction  transaction  :  stack )
             StdOut . println ( transaction );
     }  
}  


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Topological.java

edu/princeton/cs/algs4/Topological.java

/******************************************************************************
 *  Compilation:  javac Topological.java
 *  Execution:    java  Topological filename.txt delimiter
 *  Dependencies: Digraph.java DepthFirstOrder.java DirectedCycle.java
 *                EdgeWeightedDigraph.java EdgeWeightedDirectedCycle.java
 *                SymbolDigraph.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/jobs.txt
 *
 *  Compute topological ordering of a DAG or edge-weighted DAG.
 *  Runs in O(E + V) time.
 *
 *  % java Topological jobs.txt "/"
 *  Calculus
 *  Linear Algebra
 *  Introduction to CS
 *  Advanced Programming
 *  Algorithms
 *  Theoretical CS
 *  Artificial Intelligence
 *  Robotics
 *  Machine Learning
 *  Neural Networks
 *  Databases
 *  Scientific Computing
 *  Computational Biology
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Topological} class represents a data type for 
 *  determining a topological order of a <em>directed acyclic graph</em> (DAG).
 *  A digraph has a topological order if and only if it is a DAG.
 *  The <em>hasOrder</em> operation determines whether the digraph has
 *  a topological order, and if so, the <em>order</em> operation
 *  returns one.
 *  <p>
 *  This implementation uses depth-first search.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the
 *  worst case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  See { @link  DirectedCycle}, { @link  DirectedCycleX}, and
 *  { @link  EdgeWeightedDirectedCycle} for computing a directed cycle
 *  if the digraph is not a DAG.
 *  See { @link  TopologicalX} for a nonrecursive queue-based algorithm
 *  for computing a topological order of a DAG.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Topological   {
     private   Iterable < Integer >  order ;    // topological order
     private   int []  rank ;                 // rank[v] = rank of vertex v in order

     /**
     * Determines whether the digraph { @code  G} has a topological order and, if so,
     * finds such a topological order.
     *  @param  G the digraph
     */
     public   Topological ( Digraph  G )   {
         DirectedCycle  finder  =   new   DirectedCycle ( G );
         if   ( ! finder . hasCycle ())   {
             DepthFirstOrder  dfs  =   new   DepthFirstOrder ( G );
            order  =  dfs . reversePost ();
            rank  =   new   int [ G . V ()];
             int  i  =   0 ;
             for   ( int  v  :  order )
                rank [ v ]   =  i ++ ;
         }
     }

     /**
     * Determines whether the edge-weighted digraph { @code  G} has a topological
     * order and, if so, finds such an order.
     *  @param  G the edge-weighted digraph
     */
     public   Topological ( EdgeWeightedDigraph  G )   {
         EdgeWeightedDirectedCycle  finder  =   new   EdgeWeightedDirectedCycle ( G );
         if   ( ! finder . hasCycle ())   {
             DepthFirstOrder  dfs  =   new   DepthFirstOrder ( G );
            order  =  dfs . reversePost ();
         }
     }

     /**
     * Returns a topological order if the digraph has a topologial order,
     * and { @code  null} otherwise.
     *  @return  a topological order of the vertices (as an interable) if the
     *    digraph has a topological order (or equivalently, if the digraph is a DAG),
     *    and { @code  null} otherwise
     */
     public   Iterable < Integer >  order ()   {
         return  order ;
     }

     /**
     * Does the digraph have a topological order?
     *  @return  { @code  true} if the digraph has a topological order (or equivalently,
     *    if the digraph is a DAG), and { @code  false} otherwise
     */
     public   boolean  hasOrder ()   {
         return  order  !=   null ;
     }

     /**
     * Does the digraph have a topological order?
     *  @return  { @code  true} if the digraph has a topological order (or equivalently,
     *    if the digraph is a DAG), and { @code  false} otherwise
     *  @deprecated  Replaced by { @link  #hasOrder()}.
     */
    @ Deprecated
     public   boolean  isDAG ()   {
         return  hasOrder ();
     }

     /**
     * The the rank of vertex { @code  v} in the topological order;
     * -1 if the digraph is not a DAG
     *
     *  @param  v the vertex
     *  @return  the position of vertex { @code  v} in a topological order
     *    of the digraph; -1 if the digraph is not a DAG
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  rank ( int  v )   {
        validateVertex ( v );
         if   ( hasOrder ())   return  rank [ v ];
         else              return   - 1 ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  rank . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  Topological} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         String  filename   =  args [ 0 ];
         String  delimiter  =  args [ 1 ];
         SymbolDigraph  sg  =   new   SymbolDigraph ( filename ,  delimiter );
         Topological  topological  =   new   Topological ( sg . digraph ());
         for   ( int  v  :  topological . order ())   {
             StdOut . println ( sg . nameOf ( v ));
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TopologicalX.java

edu/princeton/cs/algs4/TopologicalX.java

/******************************************************************************
 *  Compilation:  javac TopologicalX.java
 *  Execution:    java TopologicalX V E F
 *  Dependencies: Queue.java Digraph.java
 *
 *  Compute topological ordering of a DAG using queue-based algorithm.
 *  Runs in O(E + V) time.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TopologicalX} class represents a data type for 
 *  determining a topological order of a <em>directed acyclic graph</em> (DAG).
 *  A digraph has a topological order if and only if it is a DAG.
 *  The <em>hasOrder</em> operation determines whether the digraph has
 *  a topological order, and if so, the <em>order</em> operation
 *  returns one.
 *  <p>
 *  This implementation uses a nonrecursive, queue-based algorithm.
 *  The constructor takes &Theta;(<em>V</em> + <em>E</em>) time in the worst
 *  case, where <em>V</em> is the number of vertices and <em>E</em>
 *  is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
 *  <p>
 *  See { @link  DirectedCycle}, { @link  DirectedCycleX}, and
 *  { @link  EdgeWeightedDirectedCycle} to compute a
 *  directed cycle if the digraph is not a DAG.
 *  See { @link  Topological} for a recursive version that uses depth-first search.
 *  <p>
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TopologicalX   {
     private   Queue < Integer >  order ;       // vertices in topological order
     private   int []  ranks ;                // ranks[v] = order where vertex v appers in order

     /**
     * Determines whether the digraph { @code  G} has a topological order and, if so,
     * finds such a topological order.
     *  @param  G the digraph
     */
     public   TopologicalX ( Digraph  G )   {

         // indegrees of remaining vertices
         int []  indegree  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            indegree [ v ]   =  G . indegree ( v );
         }

         // initialize 
        ranks  =   new   int [ G . V ()];  
        order  =   new   Queue < Integer > ();
         int  count  =   0 ;

         // initialize queue to contain all vertices with indegree = 0
         Queue < Integer >  queue  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );

         while   ( ! queue . isEmpty ())   {
             int  v  =  queue . dequeue ();
            order . enqueue ( v );
            ranks [ v ]   =  count ++ ;
             for   ( int  w  :  G . adj ( v ))   {
                indegree [ w ] -- ;
                 if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );
             }
         }

         // there is a directed cycle in subgraph of vertices with indegree >= 1.
         if   ( count  !=  G . V ())   {
            order  =   null ;
         }

         assert  check ( G );
     }

     /**
     * Determines whether the edge-weighted digraph { @code  G} has a
     * topological order and, if so, finds such a topological order.
     *  @param  G the digraph
     */
     public   TopologicalX ( EdgeWeightedDigraph  G )   {

         // indegrees of remaining vertices
         int []  indegree  =   new   int [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
            indegree [ v ]   =  G . indegree ( v );
         }

         // initialize 
        ranks  =   new   int [ G . V ()];  
        order  =   new   Queue < Integer > ();
         int  count  =   0 ;

         // initialize queue to contain all vertices with indegree = 0
         Queue < Integer >  queue  =   new   Queue < Integer > ();
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             if   ( indegree [ v ]   ==   0 )  queue . enqueue ( v );

         while   ( ! queue . isEmpty ())   {
             int  v  =  queue . dequeue ();
            order . enqueue ( v );
            ranks [ v ]   =  count ++ ;
             for   ( DirectedEdge  e  :  G . adj ( v ))   {
                 int  w  =  e . to ();
                indegree [ w ] -- ;
                 if   ( indegree [ w ]   ==   0 )  queue . enqueue ( w );
             }
         }

         // there is a directed cycle in subgraph of vertices with indegree >= 1.
         if   ( count  !=  G . V ())   {
            order  =   null ;
         }

         assert  check ( G );
     }

     /**
     * Returns a topological order if the digraph has a topologial order,
     * and { @code  null} otherwise.
     *  @return  a topological order of the vertices (as an interable) if the
     *    digraph has a topological order (or equivalently, if the digraph is a DAG),
     *    and { @code  null} otherwise
     */
     public   Iterable < Integer >  order ()   {
         return  order ;
     }

     /**
     * Does the digraph have a topological order?
     *  @return  { @code  true} if the digraph has a topological order (or equivalently,
     *    if the digraph is a DAG), and { @code  false} otherwise
     */
     public   boolean  hasOrder ()   {
         return  order  !=   null ;
     }

     /**
     * The the rank of vertex { @code  v} in the topological order;
     * -1 if the digraph is not a DAG
     *
     *  @param  v vertex
     *  @return  the position of vertex { @code  v} in a topological order
     *    of the digraph; -1 if the digraph is not a DAG
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     */
     public   int  rank ( int  v )   {
        validateVertex ( v );
         if   ( hasOrder ())   return  ranks [ v ];
         else              return   - 1 ;
     }

     // certify that digraph is acyclic
     private   boolean  check ( Digraph  G )   {

         // digraph is acyclic
         if   ( hasOrder ())   {
             // check that ranks are a permutation of 0 to V-1
             boolean []  found  =   new   boolean [ G . V ()];
             for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                found [ rank ( i )]   =   true ;
             }
             for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                 if   ( ! found [ i ])   {
                     System . err . println ( "No vertex with rank "   +  i );
                     return   false ;
                 }
             }

             // check that ranks provide a valid topological order
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( int  w  :  G . adj ( v ))   {
                     if   ( rank ( v )   >  rank ( w ))   {
                         System . err . printf ( "%d-%d: rank(%d) = %d, rank(%d) = %d\n" ,
                                          v ,  w ,  v ,  rank ( v ),  w ,  rank ( w ));
                         return   false ;
                     }
                 }
             }

             // check that order() is consistent with rank()
             int  r  =   0 ;
             for   ( int  v  :  order ())   {
                 if   ( rank ( v )   !=  r )   {
                     System . err . println ( "order() and rank() inconsistent" );
                     return   false ;
                 }
                r ++ ;
             }
         }


         return   true ;
     }

     // certify that digraph is acyclic
     private   boolean  check ( EdgeWeightedDigraph  G )   {

         // digraph is acyclic
         if   ( hasOrder ())   {
             // check that ranks are a permutation of 0 to V-1
             boolean []  found  =   new   boolean [ G . V ()];
             for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                found [ rank ( i )]   =   true ;
             }
             for   ( int  i  =   0 ;  i  <  G . V ();  i ++ )   {
                 if   ( ! found [ i ])   {
                     System . err . println ( "No vertex with rank "   +  i );
                     return   false ;
                 }
             }

             // check that ranks provide a valid topological order
             for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
                 for   ( DirectedEdge  e  :  G . adj ( v ))   {
                     int  w  =  e . to ();
                     if   ( rank ( v )   >  rank ( w ))   {
                         System . err . printf ( "%d-%d: rank(%d) = %d, rank(%d) = %d\n" ,
                                          v ,  w ,  v ,  rank ( v ),  w ,  rank ( w ));
                         return   false ;
                     }
                 }
             }

             // check that order() is consistent with rank()
             int  r  =   0 ;
             for   ( int  v  :  order ())   {
                 if   ( rank ( v )   !=  r )   {
                     System . err . println ( "order() and rank() inconsistent" );
                     return   false ;
                 }
                r ++ ;
             }
         }


         return   true ;
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  ranks . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  TopologicalX} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // create random DAG with V vertices and E edges; then add F random edges
         int  V  =   Integer . parseInt ( args [ 0 ]);
         int  E  =   Integer . parseInt ( args [ 1 ]);
         int  F  =   Integer . parseInt ( args [ 2 ]);

         Digraph  G1  =   DigraphGenerator . dag ( V ,  E );

         // corresponding edge-weighted digraph
         EdgeWeightedDigraph  G2  =   new   EdgeWeightedDigraph ( V );
         for   ( int  v  =   0 ;  v  <  G1 . V ();  v ++ )
             for   ( int  w  :  G1 . adj ( v ))
                G2 . addEdge ( new   DirectedEdge ( v ,  w ,   0.0 ));

         // add F extra edges
         for   ( int  i  =   0 ;  i  <  F ;  i ++ )   {
             int  v  =   StdRandom . uniform ( V );
             int  w  =   StdRandom . uniform ( V );
            G1 . addEdge ( v ,  w );
            G2 . addEdge ( new   DirectedEdge ( v ,  w ,   0.0 ));
         }

         StdOut . println ( G1 );
         StdOut . println ();
         StdOut . println ( G2 );

         // find a directed cycle
         TopologicalX  topological1  =   new   TopologicalX ( G1 );
         if   ( ! topological1 . hasOrder ())   {
             StdOut . println ( "Not a DAG" );
         }

         // or give topologial sort
         else   {
             StdOut . print ( "Topological order: " );
             for   ( int  v  :  topological1 . order ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }

         // find a directed cycle
         TopologicalX  topological2  =   new   TopologicalX ( G2 );
         if   ( ! topological2 . hasOrder ())   {
             StdOut . println ( "Not a DAG" );
         }

         // or give topologial sort
         else   {
             StdOut . print ( "Topological order: " );
             for   ( int  v  :  topological2 . order ())   {
                 StdOut . print ( +   " " );
             }
             StdOut . println ();
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Transaction.java

edu/princeton/cs/algs4/Transaction.java

/******************************************************************************
 *  Compilation:  javac Transaction.java
 *  Execution:    java Transaction
 *  Dependencies: StdOut.java
 *  
 *  Data type for commercial transactions.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Arrays ;
import  java . util . Comparator ;

/**
 *  The { @code  Transaction} class is an immutable data type to encapsulate a
 *  commercial transaction with a customer name, date, and amount.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Transaction   implements   Comparable < Transaction >   {
     private   final   String   who ;        // customer
     private   final   Date     when ;       // date
     private   final   double   amount ;     // amount


     /**
     * Initializes a new transaction from the given arguments.
     *
     *  @param   who the person involved in this transaction
     *  @param   when the date of this transaction
     *  @param   amount the amount of this transaction
     *  @throws  IllegalArgumentException if { @code  amount} 
     *         is { @code  Double.NaN}, { @code  Double.POSITIVE_INFINITY},
     *         or { @code  Double.NEGATIVE_INFINITY}
     */
     public   Transaction ( String  who ,   Date  when ,   double  amount )   {
         if   ( Double . isNaN ( amount )   ||   Double . isInfinite ( amount ))
             throw   new   IllegalArgumentException ( "Amount cannot be NaN or infinite" );
         this . who     =  who ;
         this . when    =  when ;
         this . amount  =  amount ;
     }

     /**
     * Initializes a new transaction by parsing a string of the form NAME DATE AMOUNT.
     *
     *  @param   transaction the string to parse
     *  @throws  IllegalArgumentException if { @code  amount} 
     *         is { @code  Double.NaN}, { @code  Double.POSITIVE_INFINITY},
     *         or { @code  Double.NEGATIVE_INFINITY}
     */
     public   Transaction ( String  transaction )   {
         String []  a  =  transaction . split ( "\\s+" );
        who     =  a [ 0 ];
        when    =   new   Date ( a [ 1 ]);
        amount  =   Double . parseDouble ( a [ 2 ]);
         if   ( Double . isNaN ( amount )   ||   Double . isInfinite ( amount ))
             throw   new   IllegalArgumentException ( "Amount cannot be NaN or infinite" );
     }

     /**
     * Returns the name of the customer involved in this transaction.
     *
     *  @return  the name of the customer involved in this transaction
     */
     public   String  who ()   {
         return  who ;
     }
 
     /**
     * Returns the date of this transaction.
     *
     *  @return  the date of this transaction
     */
     public   Date  when ()   {
         return  when ;
     }
 
     /**
     * Returns the amount of this transaction.
     *
     *  @return  the amount of this transaction
     */
     public   double  amount ()   {
         return  amount ;
     }

     /**
     * Returns a string representation of this transaction.
     *
     *  @return  a string representation of this transaction
     */
    @ Override
     public   String  toString ()   {
         return   String . format ( "%-10s %10s %8.2f" ,  who ,  when ,  amount );
     }

     /**
     * Compares two transactions by amount.
     *
     *  @param   that the other transaction
     *  @return  { a negative integer, zero, a positive integer}, depending
     *         on whether the amount of this transaction is { less than,
     *         equal to, or greater than } the amount of that transaction
     */
     public   int  compareTo ( Transaction  that )   {
         return   Double . compare ( this . amount ,  that . amount );
     }     

     /**
     * Compares this transaction to the specified object.
     *
     *  @param   other the other transaction
     *  @return  true if this transaction is equal to { @code  other}; false otherwise
     */
    @ Override
     public   boolean  equals ( Object  other )   {
         if   ( other  ==   this )   return   true ;
         if   ( other  ==   null )   return   false ;
         if   ( other . getClass ()   !=   this . getClass ())   return   false ;
         Transaction  that  =   ( Transaction )  other ;
         return   ( this . amount  ==  that . amount )   &&   ( this . who . equals ( that . who ))
                                             &&   ( this . when . equals ( that . when ));
     }


     /**
     * Returns a hash code for this transaction.
     *
     *  @return  a hash code for this transaction
     */
     public   int  hashCode ()   {
         int  hash  =   1 ;
        hash  =   31 * hash  +  who . hashCode ();
        hash  =   31 * hash  +  when . hashCode ();
        hash  =   31 * hash  +   (( Double )  amount ). hashCode ();
         return  hash ;
         // return Objects.hash(who, when, amount);
     }

     /**
     * Compares two transactions by customer name.
     */
     public   static   class   WhoOrder   implements   Comparator < Transaction >   {

        @ Override
         public   int  compare ( Transaction  v ,   Transaction  w )   {
             return  v . who . compareTo ( w . who );
         }
     }

     /**
     * Compares two transactions by date.
     */
     public   static   class   WhenOrder   implements   Comparator < Transaction >   {

        @ Override
         public   int  compare ( Transaction  v ,   Transaction  w )   {
             return  v . when . compareTo ( w . when );
         }
     }

     /**
     * Compares two transactions by amount.
     */
     public   static   class   HowMuchOrder   implements   Comparator < Transaction >   {

        @ Override
         public   int  compare ( Transaction  v ,   Transaction  w )   {
             return   Double . compare ( v . amount ,  w . amount );
         }
     }


     /**
     * Unit tests the { @code  Transaction} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         Transaction []  a  =   new   Transaction [ 4 ];
        a [ 0 ]   =   new   Transaction ( "Turing   6/17/1990  644.08" );
        a [ 1 ]   =   new   Transaction ( "Tarjan   3/26/2002 4121.85" );
        a [ 2 ]   =   new   Transaction ( "Knuth    6/14/1999  288.34" );
        a [ 3 ]   =   new   Transaction ( "Dijkstra 8/22/2007 2678.40" );

         StdOut . println ( "Unsorted" );
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
         StdOut . println ();
        
         StdOut . println ( "Sort by date" );
         Arrays . sort ( a ,   new   Transaction . WhenOrder ());
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
         StdOut . println ();

         StdOut . println ( "Sort by customer" );
         Arrays . sort ( a ,   new   Transaction . WhoOrder ());
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
         StdOut . println ();

         StdOut . println ( "Sort by amount" );
         Arrays . sort ( a ,   new   Transaction . HowMuchOrder ());
         for   ( int  i  =   0 ;  i  <  a . length ;  i ++ )
             StdOut . println ( a [ i ]);
         StdOut . println ();
     }

}




/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TransitiveClosure.java

edu/princeton/cs/algs4/TransitiveClosure.java

/******************************************************************************
 *  Compilation:  javac TransitiveClosure.java
 *  Execution:    java TransitiveClosure filename.txt
 *  Dependencies: Digraph.java DepthFirstDirectedPaths.java In.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
 *
 *  Compute transitive closure of a digraph and support
 *  reachability queries.
 *
 *  Preprocessing time: O(V(E + V)) time.
 *  Query time: O(1).
 *  Space: O(V^2).
 *
 *  % java TransitiveClosure tinyDG.txt
 *         0  1  2  3  4  5  6  7  8  9 10 11 12
 *  --------------------------------------------
 *    0:   T  T  T  T  T  T                     
 *    1:      T                                 
 *    2:   T  T  T  T  T  T                     
 *    3:   T  T  T  T  T  T                     
 *    4:   T  T  T  T  T  T                     
 *    5:   T  T  T  T  T  T                     
 *    6:   T  T  T  T  T  T  T        T  T  T  T
 *    7:   T  T  T  T  T  T  T  T  T  T  T  T  T
 *    8:   T  T  T  T  T  T  T  T  T  T  T  T  T
 *    9:   T  T  T  T  T  T           T  T  T  T
 *   10:   T  T  T  T  T  T           T  T  T  T
 *   11:   T  T  T  T  T  T           T  T  T  T
 *   12:   T  T  T  T  T  T           T  T  T  T
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TransitiveClosure} class represents a data type for 
 *  computing the transitive closure of a digraph.
 *  <p>
 *  This implementation runs depth-first search from each vertex.
 *  The constructor takes &Theta;(<em>V</em>(<em>V</em> + <em>E</em>))
 *  in the worst case, where <em>V</em> is the number of vertices and
 *  <em>E</em> is the number of edges.
 *  Each instance method takes &Theta;(1) time.
 *  It uses &Theta;(<em>V</em><sup>2</sup>) extra space (not including the digraph).
 *  <p>
 *  For large digraphs, you may want to consider a more sophisticated algorithm.
 *  <a href = "http://www.cs.hut.fi/~enu/thesis.html">Nuutila</a> proposes two
 *  algorithm for the problem (based on strong components and an interval representation)
 *  that runs in &Theta;(<em>E</em> + <em>V</em>) time on typical digraphs.
 *
 *  For additional documentation,
 *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TransitiveClosure   {
     private   DirectedDFS []  tc ;    // tc[v] = reachable from v

     /**
     * Computes the transitive closure of the digraph { @code  G}.
     *  @param  G the digraph
     */
     public   TransitiveClosure ( Digraph  G )   {
        tc  =   new   DirectedDFS [ G . V ()];
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
            tc [ v ]   =   new   DirectedDFS ( G ,  v );
     }

     /**
     * Is there a directed path from vertex { @code  v} to vertex { @code  w} in the digraph?
     *  @param   v the source vertex
     *  @param   w the target vertex
     *  @return  { @code  true} if there is a directed path from { @code  v} to { @code  w},
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless { @code  0 <= v < V}
     *  @throws  IllegalArgumentException unless { @code  0 <= w < V}
     */
     public   boolean  reachable ( int  v ,   int  w )   {
        validateVertex ( v );
        validateVertex ( w );
         return  tc [ v ]. marked ( w );
     }

     // throw an IllegalArgumentException unless {@code 0 <= v < V}
     private   void  validateVertex ( int  v )   {
         int  V  =  tc . length ;
         if   ( <   0   ||  v  >=  V )
             throw   new   IllegalArgumentException ( "vertex "   +  v  +   " is not between 0 and "   +   ( V - 1 ));
     }

     /**
     * Unit tests the { @code  TransitiveClosure} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         Digraph  G  =   new   Digraph ( in );

         TransitiveClosure  tc  =   new   TransitiveClosure ( G );

         // print header
         StdOut . print ( "     " );
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )
             StdOut . printf ( "%3d" ,  v );
         StdOut . println ();
         StdOut . println ( "--------------------------------------------" );

         // print transitive closure
         for   ( int  v  =   0 ;  v  <  G . V ();  v ++ )   {
             StdOut . printf ( "%3d: " ,  v );
             for   ( int  w  =   0 ;  w  <  G . V ();  w ++ )   {
                 if   ( tc . reachable ( v ,  w ))   StdOut . printf ( "  T" );
                 else                      StdOut . printf ( "   " );
             }
             StdOut . println ();
         }
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TrieSET.java

edu/princeton/cs/algs4/TrieSET.java

/******************************************************************************
 *  Compilation:  javac TrieSET.java
 *  Execution:    java TrieSET < words.txt
 *  Dependencies: StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt
 *
 *  An set for extended ASCII strings, implemented  using a 256-way trie.
 *
 *  Sample client reads in a list of words from standard input and
 *  prints out each word, removing any duplicates.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

import  java . util . Iterator ;

/**
 *  The { @code  TrieSET} class represents an ordered set of strings over
 *  the extended ASCII alphabet.
 *  It supports the usual <em>add</em>, <em>contains</em>, and <em>delete</em>
 *  methods. It also provides character-based methods for finding the string
 *  in the set that is the <em>longest prefix</em> of a given prefix,
 *  finding all strings in the set that <em>start with</em> a given prefix,
 *  and finding all strings in the set that <em>match</em> a given pattern.
 *  <p>
 *  This implementation uses a 256-way trie.
 *  The <em>add</em>, <em>contains</em>, <em>delete</em>, and
 *  <em>longest prefix</em> methods take time proportional to the length
 *  of the key (in the worst case). Construction takes constant time.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/52trie">Section 5.2</a> of
 *  <i>Algorithms in Java, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TrieSET   implements   Iterable < String >   {
     private   static   final   int  R  =   256 ;          // extended ASCII

     private   Node  root ;        // root of trie
     private   int  n ;            // number of keys in trie

     // R-way trie node
     private   static   class   Node   {
         private   Node []  next  =   new   Node [ R ];
         private   boolean  isString ;
     }

     /**
     * Initializes an empty set of strings.
     */
     public   TrieSET ()   {
     }

     /**
     * Does the set contain the given key?
     *  @param  key the key
     *  @return  { @code  true} if the set contains { @code  key} and
     *     { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         Node  x  =  get ( root ,  key ,   0 );
         if   ( ==   null )   return   false ;
         return  x . isString ;
     }

     private   Node  get ( Node  x ,   String  key ,   int  d )   {
         if   ( ==   null )   return   null ;
         if   ( ==  key . length ())   return  x ;
         char  c  =  key . charAt ( d );
         return  get ( x . next [ c ],  key ,  d + 1 );
     }

     /**
     * Adds the key to the set if it is not already present.
     *  @param  key the key to add
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  add ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to add() is null" );
        root  =  add ( root ,  key ,   0 );
     }

     private   Node  add ( Node  x ,   String  key ,   int  d )   {
         if   ( ==   null )  x  =   new   Node ();
         if   ( ==  key . length ())   {
             if   ( ! x . isString )  n ++ ;
            x . isString  =   true ;
         }
         else   {
             char  c  =  key . charAt ( d );
            x . next [ c ]   =  add ( x . next [ c ],  key ,  d + 1 );
         }
         return  x ;
     }

     /**
     * Returns the number of strings in the set.
     *  @return  the number of strings in the set
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Is the set empty?
     *  @return  { @code  true} if the set is empty, and { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns all of the keys in the set, as an iterator.
     * To iterate over all of the keys in a set named { @code  set}, use the
     * foreach notation: { @code  for (Key key : set)}.
     *  @return  an iterator to all of the keys in the set
     */
     public   Iterator < String >  iterator ()   {
         return  keysWithPrefix ( "" ). iterator ();
     }

     /**
     * Returns all of the keys in the set that start with { @code  prefix}.
     *  @param  prefix the prefix
     *  @return  all of the keys in the set that start with { @code  prefix},
     *     as an iterable
     */
     public   Iterable < String >  keysWithPrefix ( String  prefix )   {
         Queue < String >  results  =   new   Queue < String > ();
         Node  x  =  get ( root ,  prefix ,   0 );
        collect ( x ,   new   StringBuilder ( prefix ),  results );
         return  results ;
     }

     private   void  collect ( Node  x ,   StringBuilder  prefix ,   Queue < String >  results )   {
         if   ( ==   null )   return ;
         if   ( x . isString )  results . enqueue ( prefix . toString ());
         for   ( char  c  =   0 ;  c  <  R ;  c ++ )   {
            prefix . append ( c );
            collect ( x . next [ c ],  prefix ,  results );
            prefix . deleteCharAt ( prefix . length ()   -   1 );
         }
     }

     /**
     * Returns all of the keys in the set that match { @code  pattern},
     * where . symbol is treated as a wildcard character.
     *  @param  pattern the pattern
     *  @return  all of the keys in the set that match { @code  pattern},
     *     as an iterable, where . is treated as a wildcard character.
     */   
     public   Iterable < String >  keysThatMatch ( String  pattern )   {
         Queue < String >  results  =   new   Queue < String > ();
         StringBuilder  prefix  =   new   StringBuilder ();
        collect ( root ,  prefix ,  pattern ,  results );
         return  results ;
     }
        
     private   void  collect ( Node  x ,   StringBuilder  prefix ,   String  pattern ,   Queue < String >  results )   {
         if   ( ==   null )   return ;
         int  d  =  prefix . length ();
         if   ( ==  pattern . length ()   &&  x . isString )
            results . enqueue ( prefix . toString ());
         if   ( ==  pattern . length ())
             return ;
         char  c  =  pattern . charAt ( d );
         if   ( ==   '.' )   {
             for   ( char  ch  =   0 ;  ch  <  R ;  ch ++ )   {
                prefix . append ( ch );
                collect ( x . next [ ch ],  prefix ,  pattern ,  results );
                prefix . deleteCharAt ( prefix . length ()   -   1 );
             }
         }
         else   {
            prefix . append ( c );
            collect ( x . next [ c ],  prefix ,  pattern ,  results );
            prefix . deleteCharAt ( prefix . length ()   -   1 );
         }
     }

     /**
     * Returns the string in the set that is the longest prefix of { @code  query},
     * or { @code  null}, if no such string.
     *  @param  query the query string
     *  @return  the string in the set that is the longest prefix of { @code  query},
     *     or { @code  null} if no such string
     *  @throws  IllegalArgumentException if { @code  query} is { @code  null}
     */
     public   String  longestPrefixOf ( String  query )   {
         if   ( query  ==   null )   throw   new   IllegalArgumentException ( "argument to longestPrefixOf() is null" );
         int  length  =  longestPrefixOf ( root ,  query ,   0 ,   - 1 );
         if   ( length  ==   - 1 )   return   null ;
         return  query . substring ( 0 ,  length );
     }

     // returns the length of the longest string key in the subtrie
     // rooted at x that is a prefix of the query string,
     // assuming the first d character match and we have already
     // found a prefix match of length length
     private   int  longestPrefixOf ( Node  x ,   String  query ,   int  d ,   int  length )   {
         if   ( ==   null )   return  length ;
         if   ( x . isString )  length  =  d ;
         if   ( ==  query . length ())   return  length ;
         char  c  =  query . charAt ( d );
         return  longestPrefixOf ( x . next [ c ],  query ,  d + 1 ,  length );
     }

     /**
     * Removes the key from the set if the key is present.
     *  @param  key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );
        root  =  delete ( root ,  key ,   0 );
     }

     private   Node  delete ( Node  x ,   String  key ,   int  d )   {
         if   ( ==   null )   return   null ;
         if   ( ==  key . length ())   {
             if   ( x . isString )  n -- ;
            x . isString  =   false ;
         }
         else   {
             char  c  =  key . charAt ( d );
            x . next [ c ]   =  delete ( x . next [ c ],  key ,  d + 1 );
         }

         // remove subtrie rooted at x if it is completely empty
         if   ( x . isString )   return  x ;
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
             if   ( x . next [ c ]   !=   null )
                 return  x ;
         return   null ;
     }


     /**
     * Unit tests the { @code  TrieSET} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         TrieSET  set  =   new   TrieSET ();
         while   ( ! StdIn . isEmpty ())   {
             String  key  =   StdIn . readString ();
            set . add ( key );
         }

         // print results
         if   ( set . size ()   <   100 )   {
             StdOut . println ( "keys(\"\"):" );
             for   ( String  key  :  set )   {
                 StdOut . println ( key );
             }
             StdOut . println ();
         }

         StdOut . println ( "longestPrefixOf(\"shellsort\"):" );
         StdOut . println ( set . longestPrefixOf ( "shellsort" ));
         StdOut . println ();

         StdOut . println ( "longestPrefixOf(\"xshellsort\"):" );
         StdOut . println ( set . longestPrefixOf ( "xshellsort" ));
         StdOut . println ();

         StdOut . println ( "keysWithPrefix(\"shor\"):" );
         for   ( String  s  :  set . keysWithPrefix ( "shor" ))
             StdOut . println ( s );
         StdOut . println ();

         StdOut . println ( "keysWithPrefix(\"shortening\"):" );
         for   ( String  s  :  set . keysWithPrefix ( "shortening" ))
             StdOut . println ( s );
         StdOut . println ();

         StdOut . println ( "keysThatMatch(\".he.l.\"):" );
         for   ( String  s  :  set . keysThatMatch ( ".he.l." ))
             StdOut . println ( s );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TrieST.java

edu/princeton/cs/algs4/TrieST.java

/******************************************************************************
 *  Compilation:  javac TrieST.java
 *  Execution:    java TrieST < words.txt
 *  Dependencies: StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt
 *
 *  A string symbol table for extended ASCII strings, implemented
 *  using a 256-way trie.
 *
 *  % java TrieST < shellsST.txt 
 *  by 4
 *  sea 6
 *  sells 1
 *  she 0
 *  shells 3
 *  shore 7
 *  the 5
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TrieST} class represents an symbol table of key-value
 *  pairs, with string keys and generic values.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides character-based methods for finding the string
 *  in the symbol table that is the <em>longest prefix</em> of a given prefix,
 *  finding all strings in the symbol table that <em>start with</em> a given prefix,
 *  and finding all strings in the symbol table that <em>match</em> a given pattern.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This implementation uses a 256-way trie.
 *  The <em>put</em>, <em>contains</em>, <em>delete</em>, and
 *  <em>longest prefix</em> operations take time proportional to the length
 *  of the key (in the worst case). Construction takes constant time.
 *  The <em>size</em>, and <em>is-empty</em> operations take constant time.
 *  Construction takes constant time.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/52trie">Section 5.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class   TrieST < Value >   {
     private   static   final   int  R  =   256 ;          // extended ASCII


     private   Node  root ;        // root of trie
     private   int  n ;            // number of keys in trie

     // R-way trie node
     private   static   class   Node   {
         private   Object  val ;
         private   Node []  next  =   new   Node [ R ];
     }

    /**
     * Initializes an empty string symbol table.
     */
     public   TrieST ()   {
     }


     /**
     * Returns the value associated with the given key.
     *  @param  key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *     and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to get() is null" );
         Node  x  =  get ( root ,  key ,   0 );
         if   ( ==   null )   return   null ;
         return   ( Value )  x . val ;
     }

     /**
     * Does this symbol table contain the given key?
     *  @param  key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *     { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to contains() is null" );
         return  get ( key )   !=   null ;
     }

     private   Node  get ( Node  x ,   String  key ,   int  d )   {
         if   ( ==   null )   return   null ;
         if   ( ==  key . length ())   return  x ;
         char  c  =  key . charAt ( d );
         return  get ( x . next [ c ],  key ,  d + 1 );
     }

     /**
     * Inserts the key-value pair into the symbol table, overwriting the old value
     * with the new value if the key is already in the symbol table.
     * If the value is { @code  null}, this effectively deletes the key from the symbol table.
     *  @param  key the key
     *  @param  val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( String  key ,   Value  val )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "first argument to put() is null" );
         if   ( val  ==   null )  delete ( key );
         else  root  =  put ( root ,  key ,  val ,   0 );
     }

     private   Node  put ( Node  x ,   String  key ,   Value  val ,   int  d )   {
         if   ( ==   null )  x  =   new   Node ();
         if   ( ==  key . length ())   {
             if   ( x . val  ==   null )  n ++ ;
            x . val  =  val ;
             return  x ;
         }
         char  c  =  key . charAt ( d );
        x . next [ c ]   =  put ( x . next [ c ],  key ,  val ,  d + 1 );
         return  x ;
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Is this symbol table empty?
     *  @return  { @code  true} if this symbol table is empty and { @code  false} otherwise
     */
     public   boolean  isEmpty ()   {
         return  size ()   ==   0 ;
     }

     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *  @return  all keys in the symbol table as an { @code  Iterable}
     */
     public   Iterable < String >  keys ()   {
         return  keysWithPrefix ( "" );
     }

     /**
     * Returns all of the keys in the set that start with { @code  prefix}.
     *  @param  prefix the prefix
     *  @return  all of the keys in the set that start with { @code  prefix},
     *     as an iterable
     */
     public   Iterable < String >  keysWithPrefix ( String  prefix )   {
         Queue < String >  results  =   new   Queue < String > ();
         Node  x  =  get ( root ,  prefix ,   0 );
        collect ( x ,   new   StringBuilder ( prefix ),  results );
         return  results ;
     }

     private   void  collect ( Node  x ,   StringBuilder  prefix ,   Queue < String >  results )   {
         if   ( ==   null )   return ;
         if   ( x . val  !=   null )  results . enqueue ( prefix . toString ());
         for   ( char  c  =   0 ;  c  <  R ;  c ++ )   {
            prefix . append ( c );
            collect ( x . next [ c ],  prefix ,  results );
            prefix . deleteCharAt ( prefix . length ()   -   1 );
         }
     }

     /**
     * Returns all of the keys in the symbol table that match { @code  pattern},
     * where . symbol is treated as a wildcard character.
     *  @param  pattern the pattern
     *  @return  all of the keys in the symbol table that match { @code  pattern},
     *     as an iterable, where . is treated as a wildcard character.
     */
     public   Iterable < String >  keysThatMatch ( String  pattern )   {
         Queue < String >  results  =   new   Queue < String > ();
        collect ( root ,   new   StringBuilder (),  pattern ,  results );
         return  results ;
     }

     private   void  collect ( Node  x ,   StringBuilder  prefix ,   String  pattern ,   Queue < String >  results )   {
         if   ( ==   null )   return ;
         int  d  =  prefix . length ();
         if   ( ==  pattern . length ()   &&  x . val  !=   null )
            results . enqueue ( prefix . toString ());
         if   ( ==  pattern . length ())
             return ;
         char  c  =  pattern . charAt ( d );
         if   ( ==   '.' )   {
             for   ( char  ch  =   0 ;  ch  <  R ;  ch ++ )   {
                prefix . append ( ch );
                collect ( x . next [ ch ],  prefix ,  pattern ,  results );
                prefix . deleteCharAt ( prefix . length ()   -   1 );
             }
         }
         else   {
            prefix . append ( c );
            collect ( x . next [ c ],  prefix ,  pattern ,  results );
            prefix . deleteCharAt ( prefix . length ()   -   1 );
         }
     }

     /**
     * Returns the string in the symbol table that is the longest prefix of { @code  query},
     * or { @code  null}, if no such string.
     *  @param  query the query string
     *  @return  the string in the symbol table that is the longest prefix of { @code  query},
     *     or { @code  null} if no such string
     *  @throws  IllegalArgumentException if { @code  query} is { @code  null}
     */
     public   String  longestPrefixOf ( String  query )   {
         if   ( query  ==   null )   throw   new   IllegalArgumentException ( "argument to longestPrefixOf() is null" );
         int  length  =  longestPrefixOf ( root ,  query ,   0 ,   - 1 );
         if   ( length  ==   - 1 )   return   null ;
         else   return  query . substring ( 0 ,  length );
     }

     // returns the length of the longest string key in the subtrie
     // rooted at x that is a prefix of the query string,
     // assuming the first d character match and we have already
     // found a prefix match of given length (-1 if no such match)
     private   int  longestPrefixOf ( Node  x ,   String  query ,   int  d ,   int  length )   {
         if   ( ==   null )   return  length ;
         if   ( x . val  !=   null )  length  =  d ;
         if   ( ==  query . length ())   return  length ;
         char  c  =  query . charAt ( d );
         return  longestPrefixOf ( x . next [ c ],  query ,  d + 1 ,  length );
     }

     /**
     * Removes the key from the set if the key is present.
     *  @param  key the key
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  delete ( String  key )   {
         if   ( key  ==   null )   throw   new   IllegalArgumentException ( "argument to delete() is null" );
        root  =  delete ( root ,  key ,   0 );
     }

     private   Node  delete ( Node  x ,   String  key ,   int  d )   {
         if   ( ==   null )   return   null ;
         if   ( ==  key . length ())   {
             if   ( x . val  !=   null )  n -- ;
            x . val  =   null ;
         }
         else   {
             char  c  =  key . charAt ( d );
            x . next [ c ]   =  delete ( x . next [ c ],  key ,  d + 1 );
         }

         // remove subtrie rooted at x if it is completely empty
         if   ( x . val  !=   null )   return  x ;
         for   ( int  c  =   0 ;  c  <  R ;  c ++ )
             if   ( x . next [ c ]   !=   null )
                 return  x ;
         return   null ;
     }

     /**
     * Unit tests the { @code  TrieST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // build symbol table from standard input
         TrieST < Integer >  st  =   new   TrieST < Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }

         // print results
         if   ( st . size ()   <   100 )   {
             StdOut . println ( "keys(\"\"):" );
             for   ( String  key  :  st . keys ())   {
                 StdOut . println ( key  +   " "   +  st . get ( key ));
             }
             StdOut . println ();
         }

         StdOut . println ( "longestPrefixOf(\"shellsort\"):" );
         StdOut . println ( st . longestPrefixOf ( "shellsort" ));
         StdOut . println ();

         StdOut . println ( "longestPrefixOf(\"quicksort\"):" );
         StdOut . println ( st . longestPrefixOf ( "quicksort" ));
         StdOut . println ();

         StdOut . println ( "keysWithPrefix(\"shor\"):" );
         for   ( String  s  :  st . keysWithPrefix ( "shor" ))
             StdOut . println ( s );
         StdOut . println ();

         StdOut . println ( "keysThatMatch(\".he.l.\"):" );
         for   ( String  s  :  st . keysThatMatch ( ".he.l." ))
             StdOut . println ( s );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TST.java

edu/princeton/cs/algs4/TST.java

/******************************************************************************
 *  Compilation:  javac TST.java
 *  Execution:    java TST < words.txt
 *  Dependencies: StdIn.java
 *  Data files:   https://algs4.cs.princeton.edu/52trie/shellsST.txt
 *
 *  Symbol table with string keys, implemented using a ternary search
 *  trie (TST).
 *
 *
 *  % java TST < shellsST.txt
 *  keys(""):
 *  by 4
 *  sea 6
 *  sells 1
 *  she 0
 *  shells 3
 *  shore 7
 *  the 5
 *
 *  longestPrefixOf("shellsort"):
 *  shells
 *
 *  keysWithPrefix("shor"):
 *  shore
 *
 *  keysThatMatch(".he.l."):
 *  shells
 *
 *  % java TST
 *  theory the now is the time for all good men
 *
 *  Remarks
 *  --------
 *    - can't use a key that is the empty string ""
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TST} class represents an symbol table of key-value
 *  pairs, with string keys and generic values.
 *  It supports the usual <em>put</em>, <em>get</em>, <em>contains</em>,
 *  <em>delete</em>, <em>size</em>, and <em>is-empty</em> methods.
 *  It also provides character-based methods for finding the string
 *  in the symbol table that is the <em>longest prefix</em> of a given prefix,
 *  finding all strings in the symbol table that <em>start with</em> a given prefix,
 *  and finding all strings in the symbol table that <em>match</em> a given pattern.
 *  A symbol table implements the <em>associative array</em> abstraction:
 *  when associating a value with a key that is already in the symbol table,
 *  the convention is to replace the old value with the new value.
 *  Unlike { @link  java.util.Map}, this class uses the convention that
 *  values cannot be { @code  null}—setting the
 *  value associated with a key to { @code  null} is equivalent to deleting the key
 *  from the symbol table.
 *  <p>
 *  This implementation uses a ternary search trie.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/52trie">Section 5.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 */
public   class  TST < Value >   {
     private   int  n ;                // size
     private   Node < Value >  root ;     // root of TST

     private   static   class   Node < Value >   {
         private   char  c ;                          // character
         private   Node < Value >  left ,  mid ,  right ;    // left, middle, and right subtries
         private   Value  val ;                       // value associated with string
     }

     /**
     * Initializes an empty string symbol table.
     */
     public  TST ()   {
     }

     /**
     * Returns the number of key-value pairs in this symbol table.
     *  @return  the number of key-value pairs in this symbol table
     */
     public   int  size ()   {
         return  n ;
     }

     /**
     * Does this symbol table contain the given key?
     *  @param  key the key
     *  @return  { @code  true} if this symbol table contains { @code  key} and
     *     { @code  false} otherwise
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   boolean  contains ( String  key )   {
         if   ( key  ==   null )   {
             throw   new   IllegalArgumentException ( "argument to contains() is null" );
         }
         return  get ( key )   !=   null ;
     }

     /**
     * Returns the value associated with the given key.
     *  @param  key the key
     *  @return  the value associated with the given key if the key is in the symbol table
     *     and { @code  null} if the key is not in the symbol table
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   Value  get ( String  key )   {
         if   ( key  ==   null )   {
             throw   new   IllegalArgumentException ( "calls get() with null argument" );
         }
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "key must have length >= 1" );
         Node < Value >  x  =  get ( root ,  key ,   0 );
         if   ( ==   null )   return   null ;
         return  x . val ;
     }

     // return subtrie corresponding to given key
     private   Node < Value >  get ( Node < Value >  x ,   String  key ,   int  d )   {
         if   ( ==   null )   return   null ;
         if   ( key . length ()   ==   0 )   throw   new   IllegalArgumentException ( "key must have length >= 1" );
         char  c  =  key . charAt ( d );
         if        ( <  x . c )                return  get ( x . left ,   key ,  d );
         else   if   ( >  x . c )                return  get ( x . right ,  key ,  d );
         else   if   ( <  key . length ()   -   1 )   return  get ( x . mid ,    key ,  d + 1 );
         else                             return  x ;
     }

     /**
     * Inserts the key-value pair into the symbol table, overwriting the old value
     * with the new value if the key is already in the symbol table.
     * If the value is { @code  null}, this effectively deletes the key from the symbol table.
     *  @param  key the key
     *  @param  val the value
     *  @throws  IllegalArgumentException if { @code  key} is { @code  null}
     */
     public   void  put ( String  key ,   Value  val )   {
         if   ( key  ==   null )   {
             throw   new   IllegalArgumentException ( "calls put() with null key" );
         }
         if   ( ! contains ( key ))  n ++ ;
         else   if ( val  ==   null )  n -- ;         // delete existing key
        root  =  put ( root ,  key ,  val ,   0 );
     }

     private   Node < Value >  put ( Node < Value >  x ,   String  key ,   Value  val ,   int  d )   {
         char  c  =  key . charAt ( d );
         if   ( ==   null )   {
            x  =   new   Node < Value > ();
            x . =  c ;
         }
         if        ( <  x . c )                x . left   =  put ( x . left ,   key ,  val ,  d );
         else   if   ( >  x . c )                x . right  =  put ( x . right ,  key ,  val ,  d );
         else   if   ( <  key . length ()   -   1 )   x . mid    =  put ( x . mid ,    key ,  val ,  d + 1 );
         else                             x . val    =  val ;
         return  x ;
     }

     /**
     * Returns the string in the symbol table that is the longest prefix of { @code  query},
     * or { @code  null}, if no such string.
     *  @param  query the query string
     *  @return  the string in the symbol table that is the longest prefix of { @code  query},
     *     or { @code  null} if no such string
     *  @throws  IllegalArgumentException if { @code  query} is { @code  null}
     */
     public   String  longestPrefixOf ( String  query )   {
         if   ( query  ==   null )   {
             throw   new   IllegalArgumentException ( "calls longestPrefixOf() with null argument" );
         }
         if   ( query . length ()   ==   0 )   return   null ;
         int  length  =   0 ;
         Node < Value >  x  =  root ;
         int  i  =   0 ;
         while   ( !=   null   &&  i  <  query . length ())   {
             char  c  =  query . charAt ( i );
             if        ( <  x . c )  x  =  x . left ;
             else   if   ( >  x . c )  x  =  x . right ;
             else   {
                i ++ ;
                 if   ( x . val  !=   null )  length  =  i ;
                x  =  x . mid ;
             }
         }
         return  query . substring ( 0 ,  length );
     }

     /**
     * Returns all keys in the symbol table as an { @code  Iterable}.
     * To iterate over all of the keys in the symbol table named { @code  st},
     * use the foreach notation: { @code  for (Key key : st.keys())}.
     *  @return  all keys in the symbol table as an { @code  Iterable}
     */
     public   Iterable < String >  keys ()   {
         Queue < String >  queue  =   new   Queue < String > ();
        collect ( root ,   new   StringBuilder (),  queue );
         return  queue ;
     }

     /**
     * Returns all of the keys in the set that start with { @code  prefix}.
     *  @param  prefix the prefix
     *  @return  all of the keys in the set that start with { @code  prefix},
     *     as an iterable
     *  @throws  IllegalArgumentException if { @code  prefix} is { @code  null}
     */
     public   Iterable < String >  keysWithPrefix ( String  prefix )   {
         if   ( prefix  ==   null )   {
             throw   new   IllegalArgumentException ( "calls keysWithPrefix() with null argument" );
         }
         Queue < String >  queue  =   new   Queue < String > ();
         Node < Value >  x  =  get ( root ,  prefix ,   0 );
         if   ( ==   null )   return  queue ;
         if   ( x . val  !=   null )  queue . enqueue ( prefix );
        collect ( x . mid ,   new   StringBuilder ( prefix ),  queue );
         return  queue ;
     }

     // all keys in subtrie rooted at x with given prefix
     private   void  collect ( Node < Value >  x ,   StringBuilder  prefix ,   Queue < String >  queue )   {
         if   ( ==   null )   return ;
        collect ( x . left ,   prefix ,  queue );
         if   ( x . val  !=   null )  queue . enqueue ( prefix . toString ()   +  x . c );
        collect ( x . mid ,    prefix . append ( x . c ),  queue );
        prefix . deleteCharAt ( prefix . length ()   -   1 );
        collect ( x . right ,  prefix ,  queue );
     }


     /**
     * Returns all of the keys in the symbol table that match { @code  pattern},
     * where . symbol is treated as a wildcard character.
     *  @param  pattern the pattern
     *  @return  all of the keys in the symbol table that match { @code  pattern},
     *     as an iterable, where . is treated as a wildcard character.
     */
     public   Iterable < String >  keysThatMatch ( String  pattern )   {
         Queue < String >  queue  =   new   Queue < String > ();
        collect ( root ,   new   StringBuilder (),   0 ,  pattern ,  queue );
         return  queue ;
     }
 
     private   void  collect ( Node < Value >  x ,   StringBuilder  prefix ,   int  i ,   String  pattern ,   Queue < String >  queue )   {
         if   ( ==   null )   return ;
         char  c  =  pattern . charAt ( i );
         if   ( ==   '.'   ||  c  <  x . c )  collect ( x . left ,  prefix ,  i ,  pattern ,  queue );
         if   ( ==   '.'   ||  c  ==  x . c )   {
             if   ( ==  pattern . length ()   -   1   &&  x . val  !=   null )  queue . enqueue ( prefix . toString ()   +  x . c );
             if   ( <  pattern . length ()   -   1 )   {
                collect ( x . mid ,  prefix . append ( x . c ),  i + 1 ,  pattern ,  queue );
                prefix . deleteCharAt ( prefix . length ()   -   1 );
             }
         }
         if   ( ==   '.'   ||  c  >  x . c )  collect ( x . right ,  prefix ,  i ,  pattern ,  queue );
     }


     /**
     * Unit tests the { @code  TST} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {

         // build symbol table from standard input
        TST < Integer >  st  =   new  TST < Integer > ();
         for   ( int  i  =   0 ;   ! StdIn . isEmpty ();  i ++ )   {
             String  key  =   StdIn . readString ();
            st . put ( key ,  i );
         }

         // print results
         if   ( st . size ()   <   100 )   {
             StdOut . println ( "keys(\"\"):" );
             for   ( String  key  :  st . keys ())   {
                 StdOut . println ( key  +   " "   +  st . get ( key ));
             }
             StdOut . println ();
         }

         StdOut . println ( "longestPrefixOf(\"shellsort\"):" );
         StdOut . println ( st . longestPrefixOf ( "shellsort" ));
         StdOut . println ();

         StdOut . println ( "longestPrefixOf(\"shell\"):" );
         StdOut . println ( st . longestPrefixOf ( "shell" ));
         StdOut . println ();

         StdOut . println ( "keysWithPrefix(\"shor\"):" );
         for   ( String  s  :  st . keysWithPrefix ( "shor" ))
             StdOut . println ( s );
         StdOut . println ();

         StdOut . println ( "keysThatMatch(\".he.l.\"):" );
         for   ( String  s  :  st . keysThatMatch ( ".he.l." ))
             StdOut . println ( s );
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/TwoPersonZeroSumGame.java

edu/princeton/cs/algs4/TwoPersonZeroSumGame.java

/******************************************************************************
 *  Compilation:  javac TwoPersonZeroSumGame.java
 *  Execution:    java TwoPersonZeroSumGame m n
 *  Dependencies: LinearProgramming.java StdOut.java
 *
 *  Solve an m-by-n two-person zero-sum game by reducing it to
 *  linear programming. Assuming A is a strictly positive payoff
 *  matrix, the optimal row and column player strategies are x* an y*,
 *  scaled to be probability distributions.
 *
 *  (P)  max  y^T 1         (D)  min   1^T x
 *       s.t  A^T y <= 1         s.t   A x >= 1
 *                y >= 0                 x >= 0
 *
 *  Row player is x, column player is y.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  TwoPersonZeroSumGame} class represents a data type for
 *  computing optimal row and column strategies to two-person zero-sum games.
 *  <p>
 *  This implementation solves an <em>m</em>-by-<em>n</em> two-person
 *  zero-sum game by reducing it to a linear programming problem.
 *  Assuming the payoff matrix <em>A</em> is strictly positive, the
 *  optimal row and column player strategies x* and y* are obtained
 *  by solving the following primal and dual pair of linear programs,
 *  scaling the results to be probability distributions.
 *  <blockquote><pre>
 *  (P)  max  y^T 1           (D)  min   1^T x
 *       s.t  A^T y &le; 1         s.t   A x &ge; 1
 *                y &le; 0                 x &ge; 0
 *  </pre></blockquote>
 *  <p>
 *  If the payoff matrix <em>A</em> has any negative entries, we add
 *  the same constant to every entry so that every entry is positive.
 *  This increases the value of the game by that constant, but does not
 *  change solutions to the two-person zero-sum game.
 *  <p>
 *  This implementation is not suitable for large inputs, as it calls
 *  a bare-bones linear programming solver that is neither fast nor
 *  robust with respect to floating-point roundoff error.
 *  <p>
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/65reductions">Section 6.5</a>
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   TwoPersonZeroSumGame   {
     private   static   final   double  EPSILON  =   1E-8 ;

     private   final   int  m ;              // number of rows
     private   final   int  n ;              // number of columns
     private   LinearProgramming  lp ;     // linear program solver
     private   double  constant ;          // constant added to each entry in payoff matrix
                                     // (0 if all entries are strictly positive)
 
     /**
     * Determines an optimal solution to the two-sum zero-sum game
     * with the specified payoff matrix.
     *
     *  @param   payoff the <em>m</em>-by-<em>n</em> payoff matrix
     */  
     public   TwoPersonZeroSumGame ( double [][]  payoff )   {
        m  =  payoff . length ;
        n  =  payoff [ 0 ]. length ;

         double []  c  =   new   double [ n ];
         double []  b  =   new   double [ m ];
         double [][]  A  =   new   double [ m ][ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            b [ i ]   =   1.0 ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            c [ j ]   =   1.0 ;

         // find smallest entry
        constant  =   Double . POSITIVE_INFINITY ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                 if   ( payoff [ i ][ j ]   <  constant )
                    constant  =  payoff [ i ][ j ];

         // add constant  to every entry to make strictly positive
         if   ( constant  <=   0 )  constant  =   - constant  +   1 ;
         else                constant  =   0 ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                A [ i ][ j ]   =  payoff [ i ][ j ]   +  constant ;

        lp  =   new   LinearProgramming ( A ,  b ,  c );

         assert  certifySolution ( payoff );
     }


     /**
     * Returns the optimal value of this two-person zero-sum game.
     *
     *  @return  the optimal value of this two-person zero-sum game
     *
     */
     public   double  value ()   {
         return   1.0   /  scale ()   -  constant ;
     }


     // sum of x[j]
     private   double  scale ()   {
         double []  x  =  lp . primal ();
         double  sum  =   0.0 ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            sum  +=  x [ j ];
         return  sum ;
     }

     /**
     * Returns the optimal row strategy of this two-person zero-sum game.
     *
     *  @return  the optimal row strategy <em>x</em> of this two-person zero-sum game
     */
     public   double []  row ()   {
         double  scale  =  scale ();
         double []  x  =  lp . primal ();
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )
            x [ j ]   /=  scale ;
         return  x ;
     }

     /**
     * Returns the optimal column strategy of this two-person zero-sum game.
     *
     *  @return  the optimal column strategy <em>y</em> of this two-person zero-sum game
     */
     public   double []  column ()   {
         double  scale  =  scale ();
         double []  y  =  lp . dual ();
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
            y [ i ]   /=  scale ;
         return  y ;
     }


     /**************************************************************************
     *
     *  The code below is solely for testing correctness of the data type.
     *
     **************************************************************************/

     // is the row vector x primal feasible?
     private   boolean  isPrimalFeasible ()   {
         double []  x  =  row ();
         double  sum  =   0.0 ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
             if   ( x [ j ]   <   0 )   {
                 StdOut . println ( "row vector not a probability distribution" );
                 StdOut . printf ( "    x[%d] = %f\n" ,  j ,  x [ j ]);
                 return   false ;
             }
            sum  +=  x [ j ];
         }
         if   ( Math . abs ( sum  -   1.0 )   >  EPSILON )   {
             StdOut . println ( "row vector x[] is not a probability distribution" );
             StdOut . println ( "    sum = "   +  sum );
             return   false ;
         }
         return   true ;
     }

     // is the column vector y dual feasible?
     private   boolean  isDualFeasible ()   {
         double []  y  =  column ();
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             if   ( y [ i ]   <   0 )   {
                 StdOut . println ( "column vector y[] is not a probability distribution" );
                 StdOut . printf ( "    y[%d] = %f\n" ,  i ,  y [ i ]);
                 return   false ;
             }
            sum  +=  y [ i ];
         }
         if   ( Math . abs ( sum  -   1.0 )   >  EPSILON )   {
             StdOut . println ( "column vector not a probability distribution" );
             StdOut . println ( "    sum = "   +  sum );
             return   false ;
         }
         return   true ;
     }

     // is the solution a Nash equilibrium?
     private   boolean  isNashEquilibrium ( double [][]  payoff )   {
         double []  x  =  row ();
         double []  y  =  column ();
         double  value  =  value ();

         // given row player's mixed strategy, find column player's best pure strategy
         double  opt1  =   Double . NEGATIVE_INFINITY ;
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
             double  sum  =   0.0 ;
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
                sum  +=  payoff [ i ][ j ]   *  x [ j ];
             }
             if   ( sum  >  opt1 )  opt1  =  sum ;
         }
         if   ( Math . abs ( opt1  -  value )   >  EPSILON )   {
             StdOut . println ( "Optimal value = "   +  value );
             StdOut . println ( "Optimal best response for column player = "   +  opt1 );
             return   false ;
         }

         // given column player's mixed strategy, find row player's best pure strategy
         double  opt2  =   Double . POSITIVE_INFINITY ;
         for   ( int  j  =   0 ;  j  <  n ;  j ++ )   {
             double  sum  =   0.0 ;
             for   ( int  i  =   0 ;  i  <  m ;  i ++ )   {
                sum  +=  payoff [ i ][ j ]   *  y [ i ];
             }
             if   ( sum  <  opt2 )  opt2  =  sum ;
         }
         if   ( Math . abs ( opt2  -  value )   >  EPSILON )   {
             StdOut . println ( "Optimal value = "   +  value );
             StdOut . println ( "Optimal best response for row player = "   +  opt2 );
             return   false ;
         }


         return   true ;
     }

     private   boolean  certifySolution ( double [][]  payoff )   {
         return  isPrimalFeasible ()   &&  isDualFeasible ()   &&  isNashEquilibrium ( payoff );
     }


     private   static   void  test ( String  description ,   double [][]  payoff )   {
         StdOut . println ();
         StdOut . println ( description );
         StdOut . println ( "------------------------------------" );
         int  m  =  payoff . length ;
         int  n  =  payoff [ 0 ]. length ;
         TwoPersonZeroSumGame  zerosum  =   new   TwoPersonZeroSumGame ( payoff );
         double []  x  =  zerosum . row ();
         double []  y  =  zerosum . column ();

         StdOut . print ( "x[] = [" );
         for   ( int  j  =   0 ;  j  <  n - 1 ;  j ++ )
             StdOut . printf ( "%8.4f, " ,  x [ j ]);
         StdOut . printf ( "%8.4f]\n" ,  x [ n - 1 ]);

         StdOut . print ( "y[] = [" );
         for   ( int  i  =   0 ;  i  <  m - 1 ;  i ++ )
             StdOut . printf ( "%8.4f, " ,  y [ i ]);
         StdOut . printf ( "%8.4f]\n" ,  y [ m - 1 ]);
         StdOut . println ( "value =  "   +  zerosum . value ());
        
     }

     // row = { 4/7, 3/7 }, column = { 0, 4/7, 3/7 }, value = 20/7
     // http://en.wikipedia.org/wiki/Zero-sum
     private   static   void  test1 ()   {
         double [][]  payoff  =   {
             {   30 ,   - 10 ,    20   },
             {   10 ,    20 ,   - 20   }
         };
        test ( "wikipedia" ,  payoff );
     }

     // skew-symmetric => value = 0
     // Linear Programming by Chvatal, p. 230
     private   static   void  test2 ()   {
         double [][]  payoff  =   {
             {    0 ,    2 ,   - 3 ,    0   },
             {   - 2 ,    0 ,    0 ,    3   },
             {    3 ,    0 ,    0 ,   - 4   },
             {    0 ,   - 3 ,    4 ,    0   }
         };
        test ( "Chvatal, p. 230" ,  payoff );
     }

     // Linear Programming by Chvatal, p. 234
     // row    = { 0, 56/99, 40/99, 0, 0, 2/99, 0, 1/99 }
     // column = { 28/99, 30/99, 21/99, 20/99 }
     // value  = 4/99
     private   static   void  test3 ()   {
         double [][]  payoff  =   {
             {    0 ,    2 ,   - 3 ,    0   },
             {   - 2 ,    0 ,    0 ,    3   },
             {    3 ,    0 ,    0 ,   - 4   },
             {    0 ,   - 3 ,    4 ,    0   },
             {    0 ,    0 ,   - 3 ,    3   },
             {   - 2 ,    2 ,    0 ,    0   },
             {    3 ,   - 3 ,    0 ,    0   },
             {    0 ,    0 ,    4 ,   - 4   }
         };
        test ( "Chvatal, p. 234" ,  payoff );
     }

     // Linear Programming by Chvatal, p. 236
     // row    = { 0, 2/5, 7/15, 0, 2/15, 0, 0, 0 }
     // column = { 2/3, 0, 0, 1/3 }
     // value  = -1/3
     private   static   void  test4 ()   {
         double [][]  payoff  =   {
             {    0 ,    2 ,   - 1 ,   - 1   },
             {    0 ,    1 ,   - 2 ,   - 1   },
             {   - 1 ,   - 1 ,    1 ,    1   },
             {   - 1 ,    0 ,    0 ,    1   },
             {    1 ,   - 2 ,    0 ,   - 3   },
             {    1 ,   - 1 ,   - 1 ,   - 3   },
             {    0 ,   - 3 ,    2 ,   - 1   },
             {    0 ,   - 2 ,    1 ,   - 1   },
         };
        test ( "Chvatal p. 236" ,  payoff );
     }

     // rock, paper, scissors
     // row    = { 1/3, 1/3, 1/3 }
     // column = { 1/3, 1/3, 1/3 }
     private   static   void  test5 ()   {
         double [][]  payoff  =   {
             {    0 ,   - 1 ,    1   },
             {    1 ,    0 ,   - 1   },
             {   - 1 ,    1 ,    0   }
         };
        test ( "rock, paper, scisssors" ,  payoff );
     }


     /**
     * Unit tests the { @code  ZeroSumGameToLP} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
        test1 ();
        test2 ();
        test3 ();
        test4 ();
        test5 ();

         int  m  =   Integer . parseInt ( args [ 0 ]);
         int  n  =   Integer . parseInt ( args [ 1 ]);
         double [][]  payoff  =   new   double [ m ][ n ];
         for   ( int  i  =   0 ;  i  <  m ;  i ++ )
             for   ( int  j  =   0 ;  j  <  n ;  j ++ )
                payoff [ i ][ j ]   =   StdRandom . uniform ( - 0.5 ,   0.5 );
        test ( "random "   +  m  +   "-by-"   +  n ,  payoff );
     }

}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/UF.java

edu/princeton/cs/algs4/UF.java

/******************************************************************************
 *  Compilation:  javac UF.java
 *  Execution:    java UF < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt
 *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt
 *                https://algs4.cs.princeton.edu/15uf/largeUF.txt
 *
 *  Weighted quick-union by rank with path compression by halving.
 *
 *  % java UF < tinyUF.txt
 *  4 3
 *  3 8
 *  6 5
 *  9 4
 *  2 1
 *  5 0
 *  7 2
 *  6 1
 *  2 components
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;


/**
 *  The { @code  UF} class represents a <em>union–find data type</em>
 *  (also known as the <em>disjoint-sets data type</em>).
 *  It supports the classic <em>union</em> and <em>find</em> operations,
 *  along with a <em>count</em> operation that returns the total number
 *  of sets.
 *  <p>
 *  The union-find data type models a collection of sets containing
 *  <em>n</em> elements, with each element in exactly one set.
 *  The elements are named 0 through <em>n</em>–1.
 *  Initially, there are <em>n</em> sets, with each element in its
 *  own set. The <em>cannonical elemement</em> of a set
 *  (also known as the <em>root</em>, <em>identifier</em>,
 *  <em>leader</em>, or <em>set representative</em>)
 *  is one distinguished element in the set. Here is a summary of
 *  the operations:
 *  <ul>
 *  <li><em>find</em>(<em>p</em>) returns the canonical element
 *      of the set containing <em>p</em>. The <em>find</em> operation
 *      returns the same value for two elements if and only if
 *      they are in the same set.
 *  <li><em>union</em>(<em>p</em>, <em>q</em>) merges the set
 *      containing element <em>p</em> with the set containing
 *      element <em>q</em>. That is, if <em>p</em> and <em>q</em>
 *      are in different sets, replace these two sets
 *      with a new set that is the union of the two.
 *  <li><em>count</em>() returns the number of sets.
 *  </ul>
 *  <p>
 *  The canonical element of a set can change only when the set
 *  itself changes during a call to <em>union</em>&mdash;it cannot
 *  change during a call to either <em>find</em> or <em>count</em>.
 *  <p>
 *  This implementation uses <em>weighted quick union by rank</em>
 *  with <em>path compression by halving</em>.
 *  The constructor takes &Theta;(<em>n</em>) time, where
 *  <em>n</em> is the number of elements.
 *  The <em>union</em> and <em>find</em> operations take
 *  &Theta;(log <em>n</em>) time in the worst case.
 *  The <em>count</em> operation takes &Theta;(1) time.
 *  Moreover, starting from an empty data structure with <em>n</em> sites,
 *  any intermixed sequence of <em>m</em> <em>union</em> and <em>find</em>
 *  operations takes <em>O</em>(m &alpha;(<em>n</em>)) time,
 *  where &alpha;(<em>n</em>) is the inverse of
 *  <a href = "https://en.wikipedia.org/wiki/Ackermann_function#Inverse">Ackermann's function</a>.
 *  <p>
 *  For alternative implementations of the same API, see
 *  { @link  QuickUnionUF}, { @link  QuickFindUF}, and { @link  WeightedQuickUnionUF}.
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */

public   class  UF  {

     private   int []  parent ;    // parent[i] = parent of i
     private   byte []  rank ;     // rank[i] = rank of subtree rooted at i (never more than 31)
     private   int  count ;       // number of components

     /**
     * Initializes an empty union-find data structure with
     * { @code  n} elements { @code  0} through { @code  n-1}.
     * Initially, each elements is in its own set.
     *
     *  @param   n the number of elements
     *  @throws  IllegalArgumentException if { @code  n < 0}
     */
     public  UF ( int  n )   {
         if   ( <   0 )   throw   new   IllegalArgumentException ();
        count  =  n ;
        parent  =   new   int [ n ];
        rank  =   new   byte [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            parent [ i ]   =  i ;
            rank [ i ]   =   0 ;
         }
     }

     /**
     * Returns the canonical element of the set containing element { @code  p}.
     *
     *  @param   p an element
     *  @return  the canonical element of the set containing { @code  p}
     *  @throws  IllegalArgumentException unless { @code  0 <= p < n}
     */
     public   int  find ( int  p )   {
        validate ( p );
         while   ( !=  parent [ p ])   {
            parent [ p ]   =  parent [ parent [ p ]];      // path compression by halving
            p  =  parent [ p ];
         }
         return  p ;
     }

     /**
     * Returns the number of sets.
     *
     *  @return  the number of sets (between { @code  1} and { @code  n})
     */
     public   int  count ()   {
         return  count ;
     }
  
     /**
     * Returns true if the two elements are in the same set.
     *
     *  @param   p one element
     *  @param   q the other element
     *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     *  @deprecated  Replace with two calls to { @link  #find(int)}.
     */
    @ Deprecated
     public   boolean  connected ( int  p ,   int  q )   {
         return  find ( p )   ==  find ( q );
     }
  
     /**
     * Merges the set containing element { @code  p} with the 
     * the set containing element { @code  q}.
     *
     *  @param   p one element
     *  @param   q the other element
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     */
     public   void  union ( int  p ,   int  q )   {
         int  rootP  =  find ( p );
         int  rootQ  =  find ( q );
         if   ( rootP  ==  rootQ )   return ;

         // make root of smaller rank point to root of larger rank
         if        ( rank [ rootP ]   <  rank [ rootQ ])  parent [ rootP ]   =  rootQ ;
         else   if   ( rank [ rootP ]   >  rank [ rootQ ])  parent [ rootQ ]   =  rootP ;
         else   {
            parent [ rootQ ]   =  rootP ;
            rank [ rootP ] ++ ;
         }
        count -- ;
     }

     // validate that p is a valid index
     private   void  validate ( int  p )   {
         int  n  =  parent . length ;
         if   ( <   0   ||  p  >=  n )   {
             throw   new   IllegalArgumentException ( "index "   +  p  +   " is not between 0 and "   +   ( n - 1 ));   
         }
     }

     /**
     * Reads in a an integer { @code  n} and a sequence of pairs of integers
     * (between { @code  0} and { @code  n-1}) from standard input, where each integer
     * in the pair represents some element;
     * if the elements are in different sets, merge the two sets
     * and print the pair to standard output.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
        UF uf  =   new  UF ( n );
         while   ( ! StdIn . isEmpty ())   {
             int  p  =   StdIn . readInt ();
             int  q  =   StdIn . readInt ();
             if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;
            uf . union ( p ,  q );
             StdOut . println ( +   " "   +  q );
         }
         StdOut . println ( uf . count ()   +   " components" );
     }
}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Vector.java

edu/princeton/cs/algs4/Vector.java

/******************************************************************************
 *  Compilation:  javac Vector.java
 *  Execution:    java Vector
 *  Dependencies: StdOut.java
 *
 *  Implementation of a vector of real numbers.
 *
 *  This class is implemented to be immutable: once the client program
 *  initialize a Vector, it cannot change any of its fields
 *  (d or data[i]) either directly or indirectly. Immutability is a
 *  very desirable feature of a data type.
 *
 *  % java Vector
 *     x     = [ 1.0 2.0 3.0 4.0 ]
 *     y     = [ 5.0 2.0 4.0 1.0 ]
 *     z     = [ 6.0 4.0 7.0 5.0 ]
 *   10z     = [ 60.0 40.0 70.0 50.0 ]
 *    |x|    = 5.477225575051661
 *   <x, y>  = 25.0
 * 
 *
 *  Note that Vector is also the name of an unrelated Java library class
 *  in the package java.util.
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Vector} class represents a <em>d</em>-dimensional Euclidean vector.
 *  Vectors are immutable: their values cannot be changed after they are created.
 *  It includes methods for addition, subtraction,
 *  dot product, scalar product, unit vector, Euclidean norm, and the Euclidean
 *  distance between two vectors.
 *  <p>
 *  For additional documentation, 
 *  see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of 
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Vector   {  

     private   int  d ;                 // dimension of the vector
     private   double []  data ;         // array of vector's components


     /**
     * Initializes a d-dimensional zero vector.
     *
     *  @param  d the dimension of the vector
     */
     public   Vector ( int  d )   {
         this . =  d ;
        data  =   new   double [ d ];
     }

     /**
     * Initializes a vector from either an array or a vararg list.
     * The vararg syntax supports a constructor that takes a variable number of
     * arugments such as Vector x = new Vector(1.0, 2.0, 3.0, 4.0).
     *
     *  @param  a  the array or vararg list
     */
     public   Vector ( double ...  a )   {
        d  =  a . length ;

         // defensive copy so that client can't alter our copy of data[]
        data  =   new   double [ d ];
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            data [ i ]   =  a [ i ];
     }

     /**
     * Returns the length of this vector.
     *
     *  @return  the dimension of this vector
     *  @deprecated  Replaced by { @link  #dimension()}.
     */
    @ Deprecated
     public   int  length ()   {
         return  d ;
     }

     /**
     * Returns the dimension of this vector.
     *
     *  @return  the dimension of this vector
     */
     public   int  dimension ()   {
         return  d ;
     }

     /**
     * Returns the dot product of this vector with the specified vector.
     *
     *  @param   that the other vector
     *  @return  the dot product of this vector and that vector
     *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal
     */
     public   double  dot ( Vector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );
         double  sum  =   0.0 ;
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            sum  =  sum  +   ( this . data [ i ]   *  that . data [ i ]);
         return  sum ;
     }

     /**
     * Returns the magnitude of this vector.
     * This is also known as the L2 norm or the Euclidean norm.
     *
     *  @return  the magnitude of this vector
     */
     public   double  magnitude ()   {
         return   Math . sqrt ( this . dot ( this ));
     }

     /**
     * Returns the Euclidean distance between this vector and the specified vector.
     *
     *  @param   that the other vector 
     *  @return  the Euclidean distance between this vector and that vector
     *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal
     */
     public   double  distanceTo ( Vector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );
         return   this . minus ( that ). magnitude ();
     }

     /**
     * Returns the sum of this vector and the specified vector.
     *
     *  @param   that the vector to add to this vector
     *  @return  the vector whose value is { @code  (this + that)}
     *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal
     */
     public   Vector  plus ( Vector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );
         Vector  c  =   new   Vector ( d );
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            c . data [ i ]   =   this . data [ i ]   +  that . data [ i ];
         return  c ;
     }

     /**
     * Returns the difference between this vector and the specified vector.
     *
     *  @param   that the vector to subtract from this vector
     *  @return  the vector whose value is { @code  (this - that)}
     *  @throws  IllegalArgumentException if the dimensions of the two vectors are not equal
     */
     public   Vector  minus ( Vector  that )   {
         if   ( this . !=  that . d )   throw   new   IllegalArgumentException ( "Dimensions don't agree" );
         Vector  c  =   new   Vector ( d );
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            c . data [ i ]   =   this . data [ i ]   -  that . data [ i ];
         return  c ;
     }

     /**
     * Returns the ith cartesian coordinate.
     *
     *  @param   i the coordinate index
     *  @return  the ith cartesian coordinate
     */
     public   double  cartesian ( int  i )   {
         return  data [ i ];
     }

     /**
     * Returns the scalar-vector product of this vector and the specified scalar
     *
     *  @param   alpha the scalar
     *  @return  the vector whose value is { @code  (alpha * this)}
     *  @deprecated  Replaced by { @link  #scale(double)}.
     */
    @ Deprecated
     public   Vector  times ( double  alpha )   {
         Vector  c  =   new   Vector ( d );
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            c . data [ i ]   =  alpha  *  data [ i ];
         return  c ;
     }

     /**
     * Returns the scalar-vector product of this vector and the specified scalar
     *
     *  @param   alpha the scalar
     *  @return  the vector whose value is { @code  (alpha * this)}
     */
     public   Vector  scale ( double  alpha )   {
         Vector  c  =   new   Vector ( d );
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            c . data [ i ]   =  alpha  *  data [ i ];
         return  c ;
     }

     /**
     * Returns a unit vector in the direction of this vector.
     *
     *  @return  a unit vector in the direction of this vector
     *  @throws  ArithmeticException if this vector is the zero vector
     */
     public   Vector  direction ()   {
         if   ( this . magnitude ()   ==   0.0 )   throw   new   ArithmeticException ( "Zero-vector has no direction" );
         return   this . times ( 1.0   /   this . magnitude ());
     }


     /**
     * Returns a string representation of this vector.
     *
     *  @return  a string representation of this vector, which consists of the 
     *         the vector entries, separates by single spaces
     */
     public   String  toString ()   {
         StringBuilder  s  =   new   StringBuilder ();
         for   ( int  i  =   0 ;  i  <  d ;  i ++ )
            s . append ( data [ i ]   +   " " );
         return  s . toString ();
     }

     /**
     * Unit tests the { @code  Vector} data type.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         double []  xdata  =   {   1.0 ,   2.0 ,   3.0 ,   4.0   };
         double []  ydata  =   {   5.0 ,   2.0 ,   4.0 ,   1.0   };
         Vector  x  =   new   Vector ( xdata );
         Vector  y  =   new   Vector ( ydata );

         StdOut . println ( "   x       = "   +  x );
         StdOut . println ( "   y       = "   +  y );

         Vector  z  =  x . plus ( y );
         StdOut . println ( "   z       = "   +  z );

        z  =  z . times ( 10.0 );
         StdOut . println ( " 10z       = "   +  z );

         StdOut . println ( "  |x|      = "   +  x . magnitude ());
         StdOut . println ( " <x, y>    = "   +  x . dot ( y ));
         StdOut . println ( "dist(x, y) = "   +  x . distanceTo ( y ));
         StdOut . println ( "dir(x)     = "   +  x . direction ());

     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/WeightedQuickUnionUF.java

edu/princeton/cs/algs4/WeightedQuickUnionUF.java

/******************************************************************************
 *  Compilation:  javac WeightedQuickUnionUF.java
 *  Execution:  java WeightedQuickUnionUF < input.txt
 *  Dependencies: StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/15uf/tinyUF.txt
 *                https://algs4.cs.princeton.edu/15uf/mediumUF.txt
 *                https://algs4.cs.princeton.edu/15uf/largeUF.txt
 *
 *  Weighted quick-union (without path compression).
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  WeightedQuickUnionUF} class represents a <em>union–find data type</em>
 *  (also known as the <em>disjoint-sets data type</em>).
 *  It supports the classic <em>union</em> and <em>find</em> operations,
 *  along with a <em>count</em> operation that returns the total number
 *  of sets.
 *  <p>
 *  The union-find data type models a collection of sets containing
 *  <em>n</em> elements, with each element in exactly one set.
 *  The elements are named 0 through <em>n</em>–1.
 *  Initially, there are <em>n</em> sets, with each element in its
 *  own set. The <em>cannonical elemement</em> of a set
 *  (also known as the <em>root</em>, <em>identifier</em>,
 *  <em>leader</em>, or <em>set representative</em>)
 *  is one distinguished element in the set. Here is a summary of
 *  the operations:
 *  <ul>
 *  <li><em>find</em>(<em>p</em>) returns the canonical element
 *      of the set containing <em>p</em>. The <em>find</em> operation
 *      returns the same value for two elements if and only if
 *      they are in the same set.
 *  <li><em>union</em>(<em>p</em>, <em>q</em>) merges the set
 *      containing element <em>p</em> with the set containing
 *      element <em>q</em>. That is, if <em>p</em> and <em>q</em>
 *      are in different sets, replace these two sets
 *      with a new set that is the union of the two.
 *  <li><em>count</em>() returns the number of sets.
 *  </ul>
 *  <p>
 *  The canonical element of a set can change only when the set
 *  itself changes during a call to <em>union</em>&mdash;it cannot
 *  change during a call to either <em>find</em> or <em>count</em>.
 *  <p>
 *  This implementation uses <em>weighted quick union by size</em>
 *  (without path compression).
 *  The constructor takes &Theta;(<em>n</em>), where <em>n</em>
 *  is the number of elements.
 *  The <em>union</em> and <em>find</em>
 *  operations  take &Theta;(log <em>n</em>) time in the worst
 *  case. The <em>count</em> operation takes &Theta;(1) time.
 *  <p>
 *  For alternative implementations of the same API, see
 *  { @link  UF}, { @link  QuickFindUF}, and { @link  QuickUnionUF}.
 *  For additional documentation, see
 *  <a href="https://algs4.cs.princeton.edu/15uf">Section 1.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   WeightedQuickUnionUF   {
     private   int []  parent ;     // parent[i] = parent of i
     private   int []  size ;       // size[i] = number of elements in subtree rooted at i
     private   int  count ;        // number of components

     /**
     * Initializes an empty union-find data structure with
     * { @code  n} elements { @code  0} through { @code  n-1}. 
     * Initially, each elements is in its own set.
     *
     *  @param   n the number of elements
     *  @throws  IllegalArgumentException if { @code  n < 0}
     */
     public   WeightedQuickUnionUF ( int  n )   {
        count  =  n ;
        parent  =   new   int [ n ];
        size  =   new   int [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            parent [ i ]   =  i ;
            size [ i ]   =   1 ;
         }
     }

     /**
     * Returns the number of sets.
     *
     *  @return  the number of sets (between { @code  1} and { @code  n})
     */
     public   int  count ()   {
         return  count ;
     }
  
     /**
     * Returns the canonical element of the set containing element { @code  p}.
     *
     *  @param   p an element
     *  @return  the canonical element of the set containing { @code  p}
     *  @throws  IllegalArgumentException unless { @code  0 <= p < n}
     */
     public   int  find ( int  p )   {
        validate ( p );
         while   ( !=  parent [ p ])
            p  =  parent [ p ];
         return  p ;
     }

     /**
     * Returns true if the two elements are in the same set.
     * 
     *  @param   p one element
     *  @param   q the other element
     *  @return  { @code  true} if { @code  p} and { @code  q} are in the same set;
     *         { @code  false} otherwise
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     *  @deprecated  Replace with two calls to { @link  #find(int)}.
     */
    @ Deprecated
     public   boolean  connected ( int  p ,   int  q )   {
         return  find ( p )   ==  find ( q );
     }

     // validate that p is a valid index
     private   void  validate ( int  p )   {
         int  n  =  parent . length ;
         if   ( <   0   ||  p  >=  n )   {
             throw   new   IllegalArgumentException ( "index "   +  p  +   " is not between 0 and "   +   ( n - 1 ));   
         }
     }

     /**
     * Merges the set containing element { @code  p} with the 
     * the set containing element { @code  q}.
     *
     *  @param   p one element
     *  @param   q the other element
     *  @throws  IllegalArgumentException unless
     *         both { @code  0 <= p < n} and { @code  0 <= q < n}
     */
     public   void  union ( int  p ,   int  q )   {
         int  rootP  =  find ( p );
         int  rootQ  =  find ( q );
         if   ( rootP  ==  rootQ )   return ;

         // make smaller root point to larger one
         if   ( size [ rootP ]   <  size [ rootQ ])   {
            parent [ rootP ]   =  rootQ ;
            size [ rootQ ]   +=  size [ rootP ];
         }
         else   {
            parent [ rootQ ]   =  rootP ;
            size [ rootP ]   +=  size [ rootQ ];
         }
        count -- ;
     }


     /**
     * Reads in a an integer { @code  n} and a sequence of pairs of integers
     * (between { @code  0} and { @code  n-1}) from standard input, where each integer
     * in the pair represents some element;
     * if the elements are in different sets, merge the two sets
     * and print the pair to standard output.
     * 
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         int  n  =   StdIn . readInt ();
         WeightedQuickUnionUF  uf  =   new   WeightedQuickUnionUF ( n );
         while   ( ! StdIn . isEmpty ())   {
             int  p  =   StdIn . readInt ();
             int  q  =   StdIn . readInt ();
             if   ( uf . find ( p )   ==  uf . find ( q ))   continue ;
            uf . union ( p ,  q );
             StdOut . println ( +   " "   +  q );
         }
         StdOut . println ( uf . count ()   +   " components" );
     }

}


/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/WhiteFilter.java

edu/princeton/cs/algs4/WhiteFilter.java

/******************************************************************************
 *  Compilation:  javac WhiteFilter.java
 *  Execution:    java WhiteFilter whitelist.txt < input.txt
 *  Dependencies: SET In.java StdIn.java StdOut.java
 *  Data files:   https://algs4.cs.princeton.edu/35applications/tinyTale.txt
 *                https://algs4.cs.princeton.edu/35applications/list.txt
 * 
 *  Read in a whitelist of words from a file. Then read in a list of
 *  words from standard input and print out all those words that
 *  are in the first file.
 * 
 *  % more tinyTale.txt 
 *  it was the best of times it was the worst of times 
 *  it was the age of wisdom it was the age of foolishness 
 *  it was the epoch of belief it was the epoch of incredulity 
 *  it was the season of light it was the season of darkness 
 *  it was the spring of hope it was the winter of despair
 *
 *  % more list.txt 
 *  was it the of 
 * 
 *  % java WhiteFilter list.txt < tinyTale.txt 
 *  it was the of it was the of
 *  it was the of it was the of
 *  it was the of it was the of
 *  it was the of it was the of
 *  it was the of it was the of
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  WhiteFilter} class provides a client for reading in a <em>whitelist</em>
 *  of words from a file; then, reading in a sequence of words from standard input,
 *  printing out each word that appears in the file.
 *  It is useful as a test client for various symbol table implementations.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   WhiteFilter   {   

     // Do not instantiate.
     private   WhiteFilter ()   {   }

     public   static   void  main ( String []  args )   {
        SET < String >  set  =   new  SET < String > ();

         // read in strings and add to set
         In  in  =   new   In ( args [ 0 ]);
         while   ( ! in . isEmpty ())   {
             String  word  =  in . readString ();
            set . add ( word );
         }

         // read in string from standard input, printing out all exceptions
         while   ( ! StdIn . isEmpty ())   {
             String  word  =   StdIn . readString ();
             if   ( set . contains ( word ))
                 StdOut . println ( word );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Whitelist.java

edu/princeton/cs/algs4/Whitelist.java

/******************************************************************************
 *  Compilation:  javac Whitelist.java
 *  Execution:    java Whitelist whitelist.txt < data.txt
 *  Dependencies: StaticSetOfInts.java In.java StdOut.java
 *
 *  Data files:   https://algs4.cs.princeton.edu/11model/tinyW.txt
 *                https://algs4.cs.princeton.edu/11model/tinyT.txt
 *                https://algs4.cs.princeton.edu/11model/largeW.txt
 *                https://algs4.cs.princeton.edu/11model/largeT.txt
 *
 *  Whitelist filter.
 *
 *
 *  % java Whitelist tinyW.txt < tinyT.txt
 *  50
 *  99
 *  13
 *
 *  % java Whitelist largeW.txt < largeT.txt | more
 *  499569
 *  984875
 *  295754
 *  207807
 *  140925
 *  161828
 *  [367,966 total values]
 *
 ******************************************************************************/

package  edu . princeton . cs . algs4 ;

/**
 *  The { @code  Whitelist} class provides a client for reading in
 *  a set of integers from a file; reading in a sequence of integers
 *  from standard input; and printing to standard output those 
 *  integers not in the whitelist.
 *  <p>
 *  For additional documentation, see <a href="https://algs4.cs.princeton.edu/12oop">Section 1.2</a> of
 *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 *
 *   @author  Robert Sedgewick
 *   @author  Kevin Wayne
 */
public   class   Whitelist   {

     // Do not instantiate.
     private   Whitelist ()   {   }

     /**
     * Reads in a sequence of integers from the whitelist file, specified as
     * a command-line argument. Reads in integers from standard input and
     * prints to standard output those integers that are not in the file.
     *
     *  @param  args the command-line arguments
     */
     public   static   void  main ( String []  args )   {
         In  in  =   new   In ( args [ 0 ]);
         int []  white  =  in . readAllInts ();
         StaticSETofInts  set  =   new   StaticSETofInts ( white );

         // Read key, print if not in whitelist.
         while   ( ! StdIn . isEmpty ())   {
             int  key  =   StdIn . readInt ();
             if   ( ! set . contains ( key ))
                 StdOut . println ( key );
         }
     }
}

/******************************************************************************
 *  Copyright 2002-2020, Robert Sedgewick and Kevin Wayne.
 *
 *  This file is part of algs4.jar, which accompanies the textbook
 *
 *      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 *      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 *      http://algs4.cs.princeton.edu
 *
 *
 *  algs4.jar is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  algs4.jar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 ******************************************************************************/

edu/princeton/cs/algs4/Accumulator.class

package edu.princeton.cs.algs4;
public synchronized class Accumulator {
    private int n;
    private double sum;
    private double mu;
    public void Accumulator();
    public void addDataValue(double);
    public double mean();
    public double var();
    public double stddev();
    public int count();
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/AcyclicLP.class

package edu.princeton.cs.algs4;
public synchronized class AcyclicLP {
    private double[] distTo;
    private DirectedEdge[] edgeTo;
    public void AcyclicLP(EdgeWeightedDigraph, int);
    private void relax(DirectedEdge);
    public double distTo(int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/AcyclicSP.class

package edu.princeton.cs.algs4;
public synchronized class AcyclicSP {
    private double[] distTo;
    private DirectedEdge[] edgeTo;
    public void AcyclicSP(EdgeWeightedDigraph, int);
    private void relax(DirectedEdge);
    public double distTo(int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph$AdjIterator.class

package edu.princeton.cs.algs4;
synchronized class AdjMatrixEdgeWeightedDigraph$AdjIterator implements java.util.Iterator, Iterable {
    private int v;
    private int w;
    public void AdjMatrixEdgeWeightedDigraph$AdjIterator(AdjMatrixEdgeWeightedDigraph, int);
    public java.util.Iterator iterator();
    public boolean hasNext();
    public DirectedEdge next();
    public void remove();
}

edu/princeton/cs/algs4/AdjMatrixEdgeWeightedDigraph.class

package edu.princeton.cs.algs4;
public synchronized class AdjMatrixEdgeWeightedDigraph {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private DirectedEdge[][] adj;
    public void AdjMatrixEdgeWeightedDigraph(int);
    public void AdjMatrixEdgeWeightedDigraph(int, int);
    public int V();
    public int E();
    public void addEdge(DirectedEdge);
    public Iterable adj(int);
    public String toString();
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Alphabet.class

package edu.princeton.cs.algs4;
public synchronized class Alphabet {
    public static final Alphabet BINARY;
    public static final Alphabet OCTAL;
    public static final Alphabet DECIMAL;
    public static final Alphabet HEXADECIMAL;
    public static final Alphabet DNA;
    public static final Alphabet LOWERCASE;
    public static final Alphabet UPPERCASE;
    public static final Alphabet PROTEIN;
    public static final Alphabet BASE64;
    public static final Alphabet ASCII;
    public static final Alphabet EXTENDED_ASCII;
    public static final Alphabet UNICODE16;
    private char[] alphabet;
    private int[] inverse;
    private final int R;
    public void Alphabet(String);
    private void Alphabet(int);
    public void Alphabet();
    public boolean contains(char);
    public int R();
    public int radix();
    public int lgR();
    public int toIndex(char);
    public int[] toIndices(String);
    public char toChar(int);
    public String toChars(int[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/AmericanFlag.class

package edu.princeton.cs.algs4;
public synchronized class AmericanFlag {
    private static final int BITS_PER_BYTE = 8;
    private static final int BITS_PER_INT = 32;
    private static final int R = 256;
    private static final int CUTOFF = 15;
    private void AmericanFlag();
    private static int charAt(String, int);
    public static void sort(String[]);
    public static void sort(String[], int, int);
    private static void insertion(String[], int, int, int);
    private static void exch(String[], int, int);
    private static boolean less(String, String, int);
    public static void sort(int[]);
    private static void sort(int[], int, int);
    private static void insertion(int[], int, int, int);
    private static void exch(int[], int, int);
    private static boolean less(int, int, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/AmericanFlagX.class

package edu.princeton.cs.algs4;
public synchronized class AmericanFlagX {
    private static final int R = 256;
    private static final int CUTOFF = 15;
    private void AmericanFlagX();
    private static int charAt(String, int);
    public static void sort(String[]);
    public static void sort(String[], int, int);
    private static void insertion(String[], int, int, int);
    private static void exch(String[], int, int);
    private static boolean less(String, String, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Arbitrage.class

package edu.princeton.cs.algs4;
public synchronized class Arbitrage {
    private void Arbitrage();
    public static void main(String[]);
}

edu/princeton/cs/algs4/AssignmentProblem.class

package edu.princeton.cs.algs4;
public synchronized class AssignmentProblem {
    private static final double FLOATING_POINT_EPSILON = 1.0E-14;
    private static final int UNMATCHED = -1;
    private int n;
    private double[][] weight;
    private double minWeight;
    private double[] px;
    private double[] py;
    private int[] xy;
    private int[] yx;
    public void AssignmentProblem(double[][]);
    private void augment();
    private double reducedCost(int, int);
    public double dualRow(int);
    public double dualCol(int);
    public int sol(int);
    public double weight();
    private void validate(int);
    private boolean isDualFeasible();
    private boolean isComplementarySlack();
    private boolean isPerfectMatching();
    private boolean certifySolution();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Average.class

package edu.princeton.cs.algs4;
public synchronized class Average {
    private void Average();
    public static void main(String[]);
}

edu/princeton/cs/algs4/AVLTreeST.class

package edu.princeton.cs.algs4;
public synchronized class AVLTreeST {
    private AVLTreeST$Node root;
    public void AVLTreeST();
    public boolean isEmpty();
    public int size();
    private int size(AVLTreeST$Node);
    public int height();
    private int height(AVLTreeST$Node);
    public Object get(Comparable);
    private AVLTreeST$Node get(AVLTreeST$Node, Comparable);
    public boolean contains(Comparable);
    public void put(Comparable, Object);
    private AVLTreeST$Node put(AVLTreeST$Node, Comparable, Object);
    private AVLTreeST$Node balance(AVLTreeST$Node);
    private int balanceFactor(AVLTreeST$Node);
    private AVLTreeST$Node rotateRight(AVLTreeST$Node);
    private AVLTreeST$Node rotateLeft(AVLTreeST$Node);
    public void delete(Comparable);
    private AVLTreeST$Node delete(AVLTreeST$Node, Comparable);
    public void deleteMin();
    private AVLTreeST$Node deleteMin(AVLTreeST$Node);
    public void deleteMax();
    private AVLTreeST$Node deleteMax(AVLTreeST$Node);
    public Comparable min();
    private AVLTreeST$Node min(AVLTreeST$Node);
    public Comparable max();
    private AVLTreeST$Node max(AVLTreeST$Node);
    public Comparable floor(Comparable);
    private AVLTreeST$Node floor(AVLTreeST$Node, Comparable);
    public Comparable ceiling(Comparable);
    private AVLTreeST$Node ceiling(AVLTreeST$Node, Comparable);
    public Comparable select(int);
    private AVLTreeST$Node select(AVLTreeST$Node, int);
    public int rank(Comparable);
    private int rank(Comparable, AVLTreeST$Node);
    public Iterable keys();
    public Iterable keysInOrder();
    private void keysInOrder(AVLTreeST$Node, Queue);
    public Iterable keysLevelOrder();
    public Iterable keys(Comparable, Comparable);
    private void keys(AVLTreeST$Node, Queue, Comparable, Comparable);
    public int size(Comparable, Comparable);
    private boolean check();
    private boolean isAVL();
    private boolean isAVL(AVLTreeST$Node);
    private boolean isBST();
    private boolean isBST(AVLTreeST$Node, Comparable, Comparable);
    private boolean isSizeConsistent();
    private boolean isSizeConsistent(AVLTreeST$Node);
    private boolean isRankConsistent();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/AVLTreeST$Node.class

package edu.princeton.cs.algs4;
synchronized class AVLTreeST$Node {
    private final Comparable key;
    private Object val;
    private int height;
    private int size;
    private AVLTreeST$Node left;
    private AVLTreeST$Node right;
    public void AVLTreeST$Node(AVLTreeST, Comparable, Object, int, int);
}

edu/princeton/cs/algs4/Bag$1.class

package edu.princeton.cs.algs4;
synchronized class Bag$1 {
}

edu/princeton/cs/algs4/Bag.class

package edu.princeton.cs.algs4;
public synchronized class Bag implements Iterable {
    private Bag$Node first;
    private int n;
    public void Bag();
    public boolean isEmpty();
    public int size();
    public void add(Object);
    public java.util.Iterator iterator();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Bag$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class Bag$ListIterator implements java.util.Iterator {
    private Bag$Node current;
    public void Bag$ListIterator(Bag, Bag$Node);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/Bag$Node.class

package edu.princeton.cs.algs4;
synchronized class Bag$Node {
    private Object item;
    private Bag$Node next;
    private void Bag$Node();
}

edu/princeton/cs/algs4/BellmanFordSP.class

package edu.princeton.cs.algs4;
public synchronized class BellmanFordSP {
    private double[] distTo;
    private DirectedEdge[] edgeTo;
    private boolean[] onQueue;
    private Queue queue;
    private int cost;
    private Iterable cycle;
    public void BellmanFordSP(EdgeWeightedDigraph, int);
    private void relax(EdgeWeightedDigraph, int);
    public boolean hasNegativeCycle();
    public Iterable negativeCycle();
    private void findNegativeCycle();
    public double distTo(int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private boolean check(EdgeWeightedDigraph, int);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BinaryDump.class

package edu.princeton.cs.algs4;
public synchronized class BinaryDump {
    private void BinaryDump();
    public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryIn.class

package edu.princeton.cs.algs4;
public final synchronized class BinaryIn {
    private static final int EOF = -1;
    private java.io.BufferedInputStream in;
    private int buffer;
    private int n;
    public void BinaryIn();
    public void BinaryIn(java.io.InputStream);
    public void BinaryIn(java.net.Socket);
    public void BinaryIn(java.net.URL);
    public void BinaryIn(String);
    private void fillBuffer();
    public boolean exists();
    public boolean isEmpty();
    public boolean readBoolean();
    public char readChar();
    public char readChar(int);
    public String readString();
    public short readShort();
    public int readInt();
    public int readInt(int);
    public long readLong();
    public double readDouble();
    public float readFloat();
    public byte readByte();
    public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryInsertion.class

package edu.princeton.cs.algs4;
public synchronized class BinaryInsertion {
    private void BinaryInsertion();
    public static void sort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BinaryOut.class

package edu.princeton.cs.algs4;
public final synchronized class BinaryOut {
    private java.io.BufferedOutputStream out;
    private int buffer;
    private int n;
    public void BinaryOut();
    public void BinaryOut(java.io.OutputStream);
    public void BinaryOut(String);
    public void BinaryOut(java.net.Socket);
    private void writeBit(boolean);
    private void writeByte(int);
    private void clearBuffer();
    public void flush();
    public void close();
    public void write(boolean);
    public void write(byte);
    public void write(int);
    public void write(int, int);
    public void write(double);
    public void write(long);
    public void write(float);
    public void write(short);
    public void write(char);
    public void write(char, int);
    public void write(String);
    public void write(String, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BinarySearch.class

package edu.princeton.cs.algs4;
public synchronized class BinarySearch {
    private void BinarySearch();
    public static int indexOf(int[], int);
    public static int rank(int, int[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/BinarySearchST.class

package edu.princeton.cs.algs4;
public synchronized class BinarySearchST {
    private static final int INIT_CAPACITY = 2;
    private Comparable[] keys;
    private Object[] vals;
    private int n;
    public void BinarySearchST();
    public void BinarySearchST(int);
    private void resize(int);
    public int size();
    public boolean isEmpty();
    public boolean contains(Comparable);
    public Object get(Comparable);
    public int rank(Comparable);
    public void put(Comparable, Object);
    public void delete(Comparable);
    public void deleteMin();
    public void deleteMax();
    public Comparable min();
    public Comparable max();
    public Comparable select(int);
    public Comparable floor(Comparable);
    public Comparable ceiling(Comparable);
    public int size(Comparable, Comparable);
    public Iterable keys();
    public Iterable keys(Comparable, Comparable);
    private boolean check();
    private boolean isSorted();
    private boolean rankCheck();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BinaryStdIn.class

package edu.princeton.cs.algs4;
public final synchronized class BinaryStdIn {
    private static final int EOF = -1;
    private static java.io.BufferedInputStream in;
    private static int buffer;
    private static int n;
    private static boolean isInitialized;
    private void BinaryStdIn();
    private static void initialize();
    private static void fillBuffer();
    public static void close();
    public static boolean isEmpty();
    public static boolean readBoolean();
    public static char readChar();
    public static char readChar(int);
    public static String readString();
    public static short readShort();
    public static int readInt();
    public static int readInt(int);
    public static long readLong();
    public static double readDouble();
    public static float readFloat();
    public static byte readByte();
    public static void main(String[]);
}

edu/princeton/cs/algs4/BinaryStdOut.class

package edu.princeton.cs.algs4;
public final synchronized class BinaryStdOut {
    private static java.io.BufferedOutputStream out;
    private static int buffer;
    private static int n;
    private static boolean isInitialized;
    private void BinaryStdOut();
    private static void initialize();
    private static void writeBit(boolean);
    private static void writeByte(int);
    private static void clearBuffer();
    public static void flush();
    public static void close();
    public static void write(boolean);
    public static void write(byte);
    public static void write(int);
    public static void write(int, int);
    public static void write(double);
    public static void write(long);
    public static void write(float);
    public static void write(short);
    public static void write(char);
    public static void write(char, int);
    public static void write(String);
    public static void write(String, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BinomialMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$1 {
}

edu/princeton/cs/algs4/BinomialMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class BinomialMinPQ implements Iterable {
    private BinomialMinPQ$Node head;
    private final java.util.Comparator comp;
    public void BinomialMinPQ();
    public void BinomialMinPQ(java.util.Comparator);
    public void BinomialMinPQ(Object[]);
    public void BinomialMinPQ(java.util.Comparator, Object[]);
    public boolean isEmpty();
    public int size();
    public void insert(Object);
    public Object minKey();
    public Object delMin();
    public BinomialMinPQ union(BinomialMinPQ);
    private boolean greater(Object, Object);
    private void link(BinomialMinPQ$Node, BinomialMinPQ$Node);
    private BinomialMinPQ$Node eraseMin();
    private BinomialMinPQ$Node merge(BinomialMinPQ$Node, BinomialMinPQ$Node, BinomialMinPQ$Node);
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/BinomialMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$MyComparator implements java.util.Comparator {
    private void BinomialMinPQ$MyComparator(BinomialMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/BinomialMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$MyIterator implements java.util.Iterator {
    BinomialMinPQ data;
    public void BinomialMinPQ$MyIterator(BinomialMinPQ);
    private BinomialMinPQ$Node clone(BinomialMinPQ$Node, BinomialMinPQ$Node);
    public boolean hasNext();
    public Object next();
    public void remove();
}

edu/princeton/cs/algs4/BinomialMinPQ$Node.class

package edu.princeton.cs.algs4;
synchronized class BinomialMinPQ$Node {
    Object key;
    int order;
    BinomialMinPQ$Node child;
    BinomialMinPQ$Node sibling;
    private void BinomialMinPQ$Node(BinomialMinPQ);
}

edu/princeton/cs/algs4/Bipartite.class

package edu.princeton.cs.algs4;
public synchronized class Bipartite {
    private boolean isBipartite;
    private boolean[] color;
    private boolean[] marked;
    private int[] edgeTo;
    private Stack cycle;
    public void Bipartite(Graph);
    private void dfs(Graph, int);
    public boolean isBipartite();
    public boolean color(int);
    public Iterable oddCycle();
    private boolean check(Graph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BipartiteMatching.class

package edu.princeton.cs.algs4;
public synchronized class BipartiteMatching {
    private static final int UNMATCHED = -1;
    private final int V;
    private BipartiteX bipartition;
    private int cardinality;
    private int[] mate;
    private boolean[] inMinVertexCover;
    private boolean[] marked;
    private int[] edgeTo;
    public void BipartiteMatching(Graph);
    private boolean hasAugmentingPath(Graph);
    private boolean isResidualGraphEdge(int, int);
    public int mate(int);
    public boolean isMatched(int);
    public int size();
    public boolean isPerfect();
    public boolean inMinVertexCover(int);
    private void validate(int);
    private boolean certifySolution(Graph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BipartiteX.class

package edu.princeton.cs.algs4;
public synchronized class BipartiteX {
    private static final boolean WHITE = 0;
    private static final boolean BLACK = 1;
    private boolean isBipartite;
    private boolean[] color;
    private boolean[] marked;
    private int[] edgeTo;
    private Queue cycle;
    public void BipartiteX(Graph);
    private void bfs(Graph, int);
    public boolean isBipartite();
    public boolean color(int);
    public Iterable oddCycle();
    private boolean check(Graph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BlackFilter.class

package edu.princeton.cs.algs4;
public synchronized class BlackFilter {
    private void BlackFilter();
    public static void main(String[]);
}

edu/princeton/cs/algs4/BoruvkaMST.class

package edu.princeton.cs.algs4;
public synchronized class BoruvkaMST {
    private static final double FLOATING_POINT_EPSILON = 1.0E-12;
    private Bag mst;
    private double weight;
    public void BoruvkaMST(EdgeWeightedGraph);
    public Iterable edges();
    public double weight();
    private static boolean less(Edge, Edge);
    private boolean check(EdgeWeightedGraph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BoyerMoore.class

package edu.princeton.cs.algs4;
public synchronized class BoyerMoore {
    private final int R;
    private int[] right;
    private char[] pattern;
    private String pat;
    public void BoyerMoore(String);
    public void BoyerMoore(char[], int);
    public int search(String);
    public int search(char[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/BreadthFirstDirectedPaths.class

package edu.princeton.cs.algs4;
public synchronized class BreadthFirstDirectedPaths {
    private static final int INFINITY = 2147483647;
    private boolean[] marked;
    private int[] edgeTo;
    private int[] distTo;
    public void BreadthFirstDirectedPaths(Digraph, int);
    public void BreadthFirstDirectedPaths(Digraph, Iterable);
    private void bfs(Digraph, int);
    private void bfs(Digraph, Iterable);
    public boolean hasPathTo(int);
    public int distTo(int);
    public Iterable pathTo(int);
    private void validateVertex(int);
    private void validateVertices(Iterable);
    public static void main(String[]);
}

edu/princeton/cs/algs4/BreadthFirstPaths.class

package edu.princeton.cs.algs4;
public synchronized class BreadthFirstPaths {
    private static final int INFINITY = 2147483647;
    private boolean[] marked;
    private int[] edgeTo;
    private int[] distTo;
    public void BreadthFirstPaths(Graph, int);
    public void BreadthFirstPaths(Graph, Iterable);
    private void bfs(Graph, int);
    private void bfs(Graph, Iterable);
    public boolean hasPathTo(int);
    public int distTo(int);
    public Iterable pathTo(int);
    private boolean check(Graph, int);
    private void validateVertex(int);
    private void validateVertices(Iterable);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BST.class

package edu.princeton.cs.algs4;
public synchronized class BST {
    private BST$Node root;
    public void BST();
    public boolean isEmpty();
    public int size();
    private int size(BST$Node);
    public boolean contains(Comparable);
    public Object get(Comparable);
    private Object get(BST$Node, Comparable);
    public void put(Comparable, Object);
    private BST$Node put(BST$Node, Comparable, Object);
    public void deleteMin();
    private BST$Node deleteMin(BST$Node);
    public void deleteMax();
    private BST$Node deleteMax(BST$Node);
    public void delete(Comparable);
    private BST$Node delete(BST$Node, Comparable);
    public Comparable min();
    private BST$Node min(BST$Node);
    public Comparable max();
    private BST$Node max(BST$Node);
    public Comparable floor(Comparable);
    private BST$Node floor(BST$Node, Comparable);
    public Comparable floor2(Comparable);
    private Comparable floor2(BST$Node, Comparable, Comparable);
    public Comparable ceiling(Comparable);
    private BST$Node ceiling(BST$Node, Comparable);
    public Comparable select(int);
    private BST$Node select(BST$Node, int);
    public int rank(Comparable);
    private int rank(Comparable, BST$Node);
    public Iterable keys();
    public Iterable keys(Comparable, Comparable);
    private void keys(BST$Node, Queue, Comparable, Comparable);
    public int size(Comparable, Comparable);
    public int height();
    private int height(BST$Node);
    public Iterable levelOrder();
    private boolean check();
    private boolean isBST();
    private boolean isBST(BST$Node, Comparable, Comparable);
    private boolean isSizeConsistent();
    private boolean isSizeConsistent(BST$Node);
    private boolean isRankConsistent();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/BST$Node.class

package edu.princeton.cs.algs4;
synchronized class BST$Node {
    private Comparable key;
    private Object val;
    private BST$Node left;
    private BST$Node right;
    private int size;
    public void BST$Node(BST, Comparable, Object, int);
}

edu/princeton/cs/algs4/BTree$1.class

package edu.princeton.cs.algs4;
synchronized class BTree$1 {
}

edu/princeton/cs/algs4/BTree.class

package edu.princeton.cs.algs4;
public synchronized class BTree {
    private static final int M = 4;
    private BTree$Node root;
    private int height;
    private int n;
    public void BTree();
    public boolean isEmpty();
    public int size();
    public int height();
    public Object get(Comparable);
    private Object search(BTree$Node, Comparable, int);
    public void put(Comparable, Object);
    private BTree$Node insert(BTree$Node, Comparable, Object, int);
    private BTree$Node split(BTree$Node);
    public String toString();
    private String toString(BTree$Node, int, String);
    private boolean less(Comparable, Comparable);
    private boolean eq(Comparable, Comparable);
    public static void main(String[]);
}

edu/princeton/cs/algs4/BTree$Entry.class

package edu.princeton.cs.algs4;
synchronized class BTree$Entry {
    private Comparable key;
    private final Object val;
    private BTree$Node next;
    public void BTree$Entry(Comparable, Object, BTree$Node);
}

edu/princeton/cs/algs4/BTree$Node.class

package edu.princeton.cs.algs4;
final synchronized class BTree$Node {
    private int m;
    private BTree$Entry[] children;
    private void BTree$Node(int);
}

edu/princeton/cs/algs4/Cat.class

package edu.princeton.cs.algs4;
public synchronized class Cat {
    private void Cat();
    public static void main(String[]);
}

edu/princeton/cs/algs4/CC.class

package edu.princeton.cs.algs4;
public synchronized class CC {
    private boolean[] marked;
    private int[] id;
    private int[] size;
    private int count;
    public void CC(Graph);
    public void CC(EdgeWeightedGraph);
    private void dfs(Graph, int);
    private void dfs(EdgeWeightedGraph, int);
    public int id(int);
    public int size(int);
    public int count();
    public boolean connected(int, int);
    public boolean areConnected(int, int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/ClosestPair.class

package edu.princeton.cs.algs4;
public synchronized class ClosestPair {
    private Point2D best1;
    private Point2D best2;
    private double bestDistance;
    public void ClosestPair(Point2D[]);
    private double closest(Point2D[], Point2D[], Point2D[], int, int);
    public Point2D either();
    public Point2D other();
    public double distance();
    private static boolean less(Comparable, Comparable);
    private static void merge(Comparable[], Comparable[], int, int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/CollisionSystem.class

package edu.princeton.cs.algs4;
public synchronized class CollisionSystem {
    private static final double HZ = 0.5;
    private MinPQ pq;
    private double t;
    private Particle[] particles;
    public void CollisionSystem(Particle[]);
    private void predict(Particle, double);
    private void redraw(double);
    public void simulate(double);
    public static void main(String[]);
}

edu/princeton/cs/algs4/CollisionSystem$Event.class

package edu.princeton.cs.algs4;
synchronized class CollisionSystem$Event implements Comparable {
    private final double time;
    private final Particle a;
    private final Particle b;
    private final int countA;
    private final int countB;
    public void CollisionSystem$Event(double, Particle, Particle);
    public int compareTo(CollisionSystem$Event);
    public boolean isValid();
}

edu/princeton/cs/algs4/Complex.class

package edu.princeton.cs.algs4;
public synchronized class Complex {
    private final double re;
    private final double im;
    public void Complex(double, double);
    public String toString();
    public double abs();
    public double phase();
    public Complex plus(Complex);
    public Complex minus(Complex);
    public Complex times(Complex);
    public Complex scale(double);
    public Complex times(double);
    public Complex conjugate();
    public Complex reciprocal();
    public double re();
    public double im();
    public Complex divides(Complex);
    public Complex exp();
    public Complex sin();
    public Complex cos();
    public Complex tan();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Count.class

package edu.princeton.cs.algs4;
public synchronized class Count {
    private void Count();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Counter.class

package edu.princeton.cs.algs4;
public synchronized class Counter implements Comparable {
    private final String name;
    private int count;
    public void Counter(String);
    public void increment();
    public int tally();
    public String toString();
    public int compareTo(Counter);
    public static void main(String[]);
}

edu/princeton/cs/algs4/CPM.class

package edu.princeton.cs.algs4;
public synchronized class CPM {
    private void CPM();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Cycle.class

package edu.princeton.cs.algs4;
public synchronized class Cycle {
    private boolean[] marked;
    private int[] edgeTo;
    private Stack cycle;
    public void Cycle(Graph);
    private boolean hasSelfLoop(Graph);
    private boolean hasParallelEdges(Graph);
    public boolean hasCycle();
    public Iterable cycle();
    private void dfs(Graph, int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Date.class

package edu.princeton.cs.algs4;
public synchronized class Date implements Comparable {
    private static final int[] DAYS;
    private final int month;
    private final int day;
    private final int year;
    public void Date(int, int, int);
    public void Date(String);
    public int month();
    public int day();
    public int year();
    private static boolean isValid(int, int, int);
    private static boolean isLeapYear(int);
    public Date next();
    public boolean isAfter(Date);
    public boolean isBefore(Date);
    public int compareTo(Date);
    public String toString();
    public boolean equals(Object);
    public int hashCode();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DeDup.class

package edu.princeton.cs.algs4;
public synchronized class DeDup {
    private void DeDup();
    public static void main(String[]);
}

edu/princeton/cs/algs4/DegreesOfSeparation.class

package edu.princeton.cs.algs4;
public synchronized class DegreesOfSeparation {
    private void DegreesOfSeparation();
    public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstDirectedPaths.class

package edu.princeton.cs.algs4;
public synchronized class DepthFirstDirectedPaths {
    private boolean[] marked;
    private int[] edgeTo;
    private final int s;
    public void DepthFirstDirectedPaths(Digraph, int);
    private void dfs(Digraph, int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstOrder.class

package edu.princeton.cs.algs4;
public synchronized class DepthFirstOrder {
    private boolean[] marked;
    private int[] pre;
    private int[] post;
    private Queue preorder;
    private Queue postorder;
    private int preCounter;
    private int postCounter;
    public void DepthFirstOrder(Digraph);
    public void DepthFirstOrder(EdgeWeightedDigraph);
    private void dfs(Digraph, int);
    private void dfs(EdgeWeightedDigraph, int);
    public int pre(int);
    public int post(int);
    public Iterable post();
    public Iterable pre();
    public Iterable reversePost();
    private boolean check();
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DepthFirstPaths.class

package edu.princeton.cs.algs4;
public synchronized class DepthFirstPaths {
    private boolean[] marked;
    private int[] edgeTo;
    private final int s;
    public void DepthFirstPaths(Graph, int);
    private void dfs(Graph, int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DepthFirstSearch.class

package edu.princeton.cs.algs4;
public synchronized class DepthFirstSearch {
    private boolean[] marked;
    private int count;
    public void DepthFirstSearch(Graph, int);
    private void dfs(Graph, int);
    public boolean marked(int);
    public int count();
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Digraph.class

package edu.princeton.cs.algs4;
public synchronized class Digraph {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private Bag[] adj;
    private int[] indegree;
    public void Digraph(int);
    public void Digraph(In);
    public void Digraph(Digraph);
    public int V();
    public int E();
    private void validateVertex(int);
    public void addEdge(int, int);
    public Iterable adj(int);
    public int outdegree(int);
    public int indegree(int);
    public Digraph reverse();
    public String toString();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DigraphGenerator$1.class

package edu.princeton.cs.algs4;
synchronized class DigraphGenerator$1 {
}

edu/princeton/cs/algs4/DigraphGenerator.class

package edu.princeton.cs.algs4;
public synchronized class DigraphGenerator {
    private void DigraphGenerator();
    public static Digraph simple(int, int);
    public static Digraph simple(int, double);
    public static Digraph complete(int);
    public static Digraph dag(int, int);
    public static Digraph tournament(int);
    public static Digraph completeRootedInDAG(int);
    public static Digraph rootedInDAG(int, int);
    public static Digraph completeRootedOutDAG(int);
    public static Digraph rootedOutDAG(int, int);
    public static Digraph rootedInTree(int);
    public static Digraph rootedOutTree(int);
    public static Digraph path(int);
    public static Digraph binaryTree(int);
    public static Digraph cycle(int);
    public static Digraph eulerianCycle(int, int);
    public static Digraph eulerianPath(int, int);
    public static Digraph strong(int, int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DigraphGenerator$Edge.class

package edu.princeton.cs.algs4;
final synchronized class DigraphGenerator$Edge implements Comparable {
    private final int v;
    private final int w;
    private void DigraphGenerator$Edge(int, int);
    public int compareTo(DigraphGenerator$Edge);
}

edu/princeton/cs/algs4/DijkstraAllPairsSP.class

package edu.princeton.cs.algs4;
public synchronized class DijkstraAllPairsSP {
    private DijkstraSP[] all;
    public void DijkstraAllPairsSP(EdgeWeightedDigraph);
    public Iterable path(int, int);
    public boolean hasPath(int, int);
    public double dist(int, int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DijkstraSP.class

package edu.princeton.cs.algs4;
public synchronized class DijkstraSP {
    private double[] distTo;
    private DirectedEdge[] edgeTo;
    private IndexMinPQ pq;
    public void DijkstraSP(EdgeWeightedDigraph, int);
    private void relax(DirectedEdge);
    public double distTo(int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private boolean check(EdgeWeightedDigraph, int);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DijkstraUndirectedSP.class

package edu.princeton.cs.algs4;
public synchronized class DijkstraUndirectedSP {
    private double[] distTo;
    private Edge[] edgeTo;
    private IndexMinPQ pq;
    public void DijkstraUndirectedSP(EdgeWeightedGraph, int);
    private void relax(Edge, int);
    public double distTo(int);
    public boolean hasPathTo(int);
    public Iterable pathTo(int);
    private boolean check(EdgeWeightedGraph, int);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DirectedCycle.class

package edu.princeton.cs.algs4;
public synchronized class DirectedCycle {
    private boolean[] marked;
    private int[] edgeTo;
    private boolean[] onStack;
    private Stack cycle;
    public void DirectedCycle(Digraph);
    private void dfs(Digraph, int);
    public boolean hasCycle();
    public Iterable cycle();
    private boolean check();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DirectedCycleX.class

package edu.princeton.cs.algs4;
public synchronized class DirectedCycleX {
    private Stack cycle;
    public void DirectedCycleX(Digraph);
    public Iterable cycle();
    public boolean hasCycle();
    private boolean check();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DirectedDFS.class

package edu.princeton.cs.algs4;
public synchronized class DirectedDFS {
    private boolean[] marked;
    private int count;
    public void DirectedDFS(Digraph, int);
    public void DirectedDFS(Digraph, Iterable);
    private void dfs(Digraph, int);
    public boolean marked(int);
    public int count();
    private void validateVertex(int);
    private void validateVertices(Iterable);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DirectedEdge.class

package edu.princeton.cs.algs4;
public synchronized class DirectedEdge {
    private final int v;
    private final int w;
    private final double weight;
    public void DirectedEdge(int, int, double);
    public int from();
    public int to();
    public double weight();
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/DirectedEulerianCycle.class

package edu.princeton.cs.algs4;
public synchronized class DirectedEulerianCycle {
    private Stack cycle;
    public void DirectedEulerianCycle(Digraph);
    public Iterable cycle();
    public boolean hasEulerianCycle();
    private static int nonIsolatedVertex(Digraph);
    private static boolean satisfiesNecessaryAndSufficientConditions(Digraph);
    private boolean certifySolution(Digraph);
    private static void unitTest(Digraph, String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DirectedEulerianPath.class

package edu.princeton.cs.algs4;
public synchronized class DirectedEulerianPath {
    private Stack path;
    public void DirectedEulerianPath(Digraph);
    public Iterable path();
    public boolean hasEulerianPath();
    private static int nonIsolatedVertex(Digraph);
    private static boolean satisfiesNecessaryAndSufficientConditions(Digraph);
    private boolean check(Digraph);
    private static void unitTest(Digraph, String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DoublingRatio.class

package edu.princeton.cs.algs4;
public synchronized class DoublingRatio {
    private static final int MAXIMUM_INTEGER = 1000000;
    private void DoublingRatio();
    public static double timeTrial(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/DoublingTest.class

package edu.princeton.cs.algs4;
public synchronized class DoublingTest {
    private static final int MAXIMUM_INTEGER = 1000000;
    private void DoublingTest();
    public static double timeTrial(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Draw.class

package edu.princeton.cs.algs4;
public final synchronized class Draw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
    public static final java.awt.Color BLACK;
    public static final java.awt.Color BLUE;
    public static final java.awt.Color CYAN;
    public static final java.awt.Color DARK_GRAY;
    public static final java.awt.Color GRAY;
    public static final java.awt.Color GREEN;
    public static final java.awt.Color LIGHT_GRAY;
    public static final java.awt.Color MAGENTA;
    public static final java.awt.Color ORANGE;
    public static final java.awt.Color PINK;
    public static final java.awt.Color RED;
    public static final java.awt.Color WHITE;
    public static final java.awt.Color YELLOW;
    public static final java.awt.Color BOOK_BLUE;
    public static final java.awt.Color BOOK_LIGHT_BLUE;
    public static final java.awt.Color BOOK_RED;
    public static final java.awt.Color PRINCETON_ORANGE;
    private static final java.awt.Color DEFAULT_PEN_COLOR;
    private static final java.awt.Color DEFAULT_CLEAR_COLOR;
    private static final double BORDER = 0.0;
    private static final double DEFAULT_XMIN = 0.0;
    private static final double DEFAULT_XMAX = 1.0;
    private static final double DEFAULT_YMIN = 0.0;
    private static final double DEFAULT_YMAX = 1.0;
    private static final int DEFAULT_SIZE = 512;
    private static final double DEFAULT_PEN_RADIUS = 0.002;
    private static final java.awt.Font DEFAULT_FONT;
    private java.awt.Color penColor;
    private int width;
    private int height;
    private double penRadius;
    private boolean defer;
    private double xmin;
    private double ymin;
    private double xmax;
    private double ymax;
    private String name;
    private final Object mouseLock;
    private final Object keyLock;
    private java.awt.Font font;
    private javax.swing.JLabel draw;
    private java.awt.image.BufferedImage offscreenImage;
    private java.awt.image.BufferedImage onscreenImage;
    private java.awt.Graphics2D offscreen;
    private java.awt.Graphics2D onscreen;
    private javax.swing.JFrame frame;
    private boolean isMousePressed;
    private double mouseX;
    private double mouseY;
    private final java.util.LinkedList keysTyped;
    private final java.util.TreeSet keysDown;
    private final java.util.ArrayList listeners;
    public void Draw(String);
    public void Draw();
    private void init();
    public void setLocationOnScreen(int, int);
    public void setDefaultCloseOperation(int);
    public void setCanvasSize(int, int);
    private javax.swing.JMenuBar createMenuBar();
    private static void validate(double, String);
    private static void validateNonnegative(double, String);
    private static void validateNotNull(Object, String);
    public void setXscale();
    public void setYscale();
    public void setXscale(double, double);
    public void setYscale(double, double);
    private double scaleX(double);
    private double scaleY(double);
    private double factorX(double);
    private double factorY(double);
    private double userX(double);
    private double userY(double);
    public void clear();
    public void clear(java.awt.Color);
    public double getPenRadius();
    public void setPenRadius();
    public void setPenRadius(double);
    public java.awt.Color getPenColor();
    public void setPenColor();
    public void setPenColor(java.awt.Color);
    public void setPenColor(int, int, int);
    public void xorOn();
    public void xorOff();
    public javax.swing.JLabel getJLabel();
    public java.awt.Font getFont();
    public void setFont();
    public void setFont(java.awt.Font);
    public void line(double, double, double, double);
    private void pixel(double, double);
    public void point(double, double);
    public void circle(double, double, double);
    public void filledCircle(double, double, double);
    public void ellipse(double, double, double, double);
    public void filledEllipse(double, double, double, double);
    public void arc(double, double, double, double, double);
    public void square(double, double, double);
    public void filledSquare(double, double, double);
    public void rectangle(double, double, double, double);
    public void filledRectangle(double, double, double, double);
    public void polygon(double[], double[]);
    public void filledPolygon(double[], double[]);
    private static java.awt.Image getImage(String);
    public void picture(double, double, String);
    public void picture(double, double, String, double);
    public void picture(double, double, String, double, double);
    public void picture(double, double, String, double, double, double);
    public void text(double, double, String);
    public void text(double, double, String, double);
    public void textLeft(double, double, String);
    public void textRight(double, double, String);
    public void show(int);
    public void pause(int);
    public void show();
    private void draw();
    public void enableDoubleBuffering();
    public void disableDoubleBuffering();
    public void save(String);
    public void actionPerformed(java.awt.event.ActionEvent);
    public void addListener(DrawListener);
    public boolean isMousePressed();
    public boolean mousePressed();
    public double mouseX();
    public double mouseY();
    public void mouseEntered(java.awt.event.MouseEvent);
    public void mouseExited(java.awt.event.MouseEvent);
    public void mousePressed(java.awt.event.MouseEvent);
    public void mouseReleased(java.awt.event.MouseEvent);
    public void mouseClicked(java.awt.event.MouseEvent);
    public void mouseDragged(java.awt.event.MouseEvent);
    public void mouseMoved(java.awt.event.MouseEvent);
    public boolean hasNextKeyTyped();
    public char nextKeyTyped();
    public boolean isKeyPressed(int);
    public void keyTyped(java.awt.event.KeyEvent);
    public void keyPressed(java.awt.event.KeyEvent);
    public void keyReleased(java.awt.event.KeyEvent);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/DrawListener.class

package edu.princeton.cs.algs4;
public abstract interface DrawListener {
    public abstract void mousePressed(double, double);
    public abstract void mouseDragged(double, double);
    public abstract void mouseReleased(double, double);
    public abstract void mouseClicked(double, double);
    public abstract void keyTyped(char);
    public abstract void keyPressed(int);
    public abstract void keyReleased(int);
}

edu/princeton/cs/algs4/Draw$RetinaImageIcon.class

package edu.princeton.cs.algs4;
synchronized class Draw$RetinaImageIcon extends javax.swing.ImageIcon {
    public void Draw$RetinaImageIcon(java.awt.Image);
    public int getIconWidth();
    public int getIconHeight();
    public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

edu/princeton/cs/algs4/Edge.class

package edu.princeton.cs.algs4;
public synchronized class Edge implements Comparable {
    private final int v;
    private final int w;
    private final double weight;
    public void Edge(int, int, double);
    public double weight();
    public int either();
    public int other(int);
    public int compareTo(Edge);
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/EdgeWeightedDigraph.class

package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedDigraph {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private Bag[] adj;
    private int[] indegree;
    public void EdgeWeightedDigraph(int);
    public void EdgeWeightedDigraph(int, int);
    public void EdgeWeightedDigraph(In);
    public void EdgeWeightedDigraph(EdgeWeightedDigraph);
    public int V();
    public int E();
    private void validateVertex(int);
    public void addEdge(DirectedEdge);
    public Iterable adj(int);
    public int outdegree(int);
    public int indegree(int);
    public Iterable edges();
    public String toString();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/EdgeWeightedDirectedCycle.class

package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedDirectedCycle {
    private boolean[] marked;
    private DirectedEdge[] edgeTo;
    private boolean[] onStack;
    private Stack cycle;
    public void EdgeWeightedDirectedCycle(EdgeWeightedDigraph);
    private void dfs(EdgeWeightedDigraph, int);
    public boolean hasCycle();
    public Iterable cycle();
    private boolean check();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/EdgeWeightedGraph.class

package edu.princeton.cs.algs4;
public synchronized class EdgeWeightedGraph {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private Bag[] adj;
    public void EdgeWeightedGraph(int);
    public void EdgeWeightedGraph(int, int);
    public void EdgeWeightedGraph(In);
    public void EdgeWeightedGraph(EdgeWeightedGraph);
    public int V();
    public int E();
    private void validateVertex(int);
    public void addEdge(Edge);
    public Iterable adj(int);
    public int degree(int);
    public Iterable edges();
    public String toString();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/EulerianCycle.class

package edu.princeton.cs.algs4;
public synchronized class EulerianCycle {
    private Stack cycle;
    public void EulerianCycle(Graph);
    public Iterable cycle();
    public boolean hasEulerianCycle();
    private static int nonIsolatedVertex(Graph);
    private static boolean satisfiesNecessaryAndSufficientConditions(Graph);
    private boolean certifySolution(Graph);
    private static void unitTest(Graph, String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/EulerianCycle$Edge.class

package edu.princeton.cs.algs4;
synchronized class EulerianCycle$Edge {
    private final int v;
    private final int w;
    private boolean isUsed;
    public void EulerianCycle$Edge(int, int);
    public int other(int);
}

edu/princeton/cs/algs4/EulerianPath.class

package edu.princeton.cs.algs4;
public synchronized class EulerianPath {
    private Stack path;
    public void EulerianPath(Graph);
    public Iterable path();
    public boolean hasEulerianPath();
    private static int nonIsolatedVertex(Graph);
    private static boolean satisfiesNecessaryAndSufficientConditions(Graph);
    private boolean certifySolution(Graph);
    private static void unitTest(Graph, String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/EulerianPath$Edge.class

package edu.princeton.cs.algs4;
synchronized class EulerianPath$Edge {
    private final int v;
    private final int w;
    private boolean isUsed;
    public void EulerianPath$Edge(int, int);
    public int other(int);
}

edu/princeton/cs/algs4/FarthestPair.class

package edu.princeton.cs.algs4;
public synchronized class FarthestPair {
    private Point2D best1;
    private Point2D best2;
    private double bestDistanceSquared;
    public void FarthestPair(Point2D[]);
    public Point2D either();
    public Point2D other();
    public double distance();
    public static void main(String[]);
}

edu/princeton/cs/algs4/FenwickTree.class

package edu.princeton.cs.algs4;
public synchronized class FenwickTree {
    int[] array;
    public void FenwickTree(int);
    public int rsq(int);
    public int rsq(int, int);
    public void update(int, int);
    public int size();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/FFT.class

package edu.princeton.cs.algs4;
public synchronized class FFT {
    private static final Complex ZERO;
    private void FFT();
    public static Complex[] fft(Complex[]);
    public static Complex[] ifft(Complex[]);
    public static Complex[] cconvolve(Complex[], Complex[]);
    public static Complex[] convolve(Complex[], Complex[]);
    private static void show(Complex[], String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/FibonacciMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$1 {
}

edu/princeton/cs/algs4/FibonacciMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class FibonacciMinPQ implements Iterable {
    private FibonacciMinPQ$Node head;
    private FibonacciMinPQ$Node min;
    private int size;
    private final java.util.Comparator comp;
    private java.util.HashMap table;
    public void FibonacciMinPQ(java.util.Comparator);
    public void FibonacciMinPQ();
    public void FibonacciMinPQ(Object[]);
    public void FibonacciMinPQ(java.util.Comparator, Object[]);
    public boolean isEmpty();
    public int size();
    public void insert(Object);
    public Object minKey();
    public Object delMin();
    public FibonacciMinPQ union(FibonacciMinPQ);
    private boolean greater(Object, Object);
    private void link(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
    private void consolidate();
    private FibonacciMinPQ$Node insert(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
    private FibonacciMinPQ$Node cut(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
    private FibonacciMinPQ$Node meld(FibonacciMinPQ$Node, FibonacciMinPQ$Node);
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/FibonacciMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$MyComparator implements java.util.Comparator {
    private void FibonacciMinPQ$MyComparator(FibonacciMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/FibonacciMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$MyIterator implements java.util.Iterator {
    private FibonacciMinPQ copy;
    public void FibonacciMinPQ$MyIterator(FibonacciMinPQ);
    private void insertAll(FibonacciMinPQ$Node);
    public void remove();
    public boolean hasNext();
    public Object next();
}

edu/princeton/cs/algs4/FibonacciMinPQ$Node.class

package edu.princeton.cs.algs4;
synchronized class FibonacciMinPQ$Node {
    Object key;
    int order;
    FibonacciMinPQ$Node prev;
    FibonacciMinPQ$Node next;
    FibonacciMinPQ$Node child;
    private void FibonacciMinPQ$Node(FibonacciMinPQ);
}

edu/princeton/cs/algs4/FileIndex.class

package edu.princeton.cs.algs4;
public synchronized class FileIndex {
    private void FileIndex();
    public static void main(String[]);
}

edu/princeton/cs/algs4/FlowEdge.class

package edu.princeton.cs.algs4;
public synchronized class FlowEdge {
    private static final double FLOATING_POINT_EPSILON = 1.0E-10;
    private final int v;
    private final int w;
    private final double capacity;
    private double flow;
    public void FlowEdge(int, int, double);
    public void FlowEdge(int, int, double, double);
    public void FlowEdge(FlowEdge);
    public int from();
    public int to();
    public double capacity();
    public double flow();
    public int other(int);
    public double residualCapacityTo(int);
    public void addResidualFlowTo(int, double);
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/FlowNetwork.class

package edu.princeton.cs.algs4;
public synchronized class FlowNetwork {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private Bag[] adj;
    public void FlowNetwork(int);
    public void FlowNetwork(int, int);
    public void FlowNetwork(In);
    public int V();
    public int E();
    private void validateVertex(int);
    public void addEdge(FlowEdge);
    public Iterable adj(int);
    public Iterable edges();
    public String toString();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/FloydWarshall.class

package edu.princeton.cs.algs4;
public synchronized class FloydWarshall {
    private boolean hasNegativeCycle;
    private double[][] distTo;
    private DirectedEdge[][] edgeTo;
    public void FloydWarshall(AdjMatrixEdgeWeightedDigraph);
    public boolean hasNegativeCycle();
    public Iterable negativeCycle();
    public boolean hasPath(int, int);
    public double dist(int, int);
    public Iterable path(int, int);
    private boolean check(AdjMatrixEdgeWeightedDigraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/FordFulkerson.class

package edu.princeton.cs.algs4;
public synchronized class FordFulkerson {
    private static final double FLOATING_POINT_EPSILON = 1.0E-11;
    private final int V;
    private boolean[] marked;
    private FlowEdge[] edgeTo;
    private double value;
    public void FordFulkerson(FlowNetwork, int, int);
    public double value();
    public boolean inCut(int);
    private void validate(int);
    private boolean hasAugmentingPath(FlowNetwork, int, int);
    private double excess(FlowNetwork, int);
    private boolean isFeasible(FlowNetwork, int, int);
    private boolean check(FlowNetwork, int, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/FrequencyCounter.class

package edu.princeton.cs.algs4;
public synchronized class FrequencyCounter {
    private void FrequencyCounter();
    public static void main(String[]);
}

edu/princeton/cs/algs4/GabowSCC.class

package edu.princeton.cs.algs4;
public synchronized class GabowSCC {
    private boolean[] marked;
    private int[] id;
    private int[] preorder;
    private int pre;
    private int count;
    private Stack stack1;
    private Stack stack2;
    public void GabowSCC(Digraph);
    private void dfs(Digraph, int);
    public int count();
    public boolean stronglyConnected(int, int);
    public int id(int);
    private boolean check(Digraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/GaussianElimination.class

package edu.princeton.cs.algs4;
public synchronized class GaussianElimination {
    private static final double EPSILON = 1.0E-8;
    private final int m;
    private final int n;
    private double[][] a;
    public void GaussianElimination(double[][], double[]);
    private void forwardElimination();
    private void swap(int, int);
    private void pivot(int);
    public double[] primal();
    public boolean isFeasible();
    private boolean certifySolution(double[][], double[]);
    private static void test(String, double[][], double[]);
    private static void test1();
    private static void test2();
    private static void test3();
    private static void test4();
    private static void test5();
    private static void test6();
    private static void test7();
    private static void test8();
    private static void test9();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/GaussJordanElimination.class

package edu.princeton.cs.algs4;
public synchronized class GaussJordanElimination {
    private static final double EPSILON = 1.0E-8;
    private final int n;
    private double[][] a;
    public void GaussJordanElimination(double[][], double[]);
    private void solve();
    private void swap(int, int);
    private void pivot(int, int);
    public double[] primal();
    public double[] dual();
    public boolean isFeasible();
    private void show();
    private boolean certifySolution(double[][], double[]);
    private static void test(String, double[][], double[]);
    private static void test1();
    private static void test2();
    private static void test3();
    private static void test4();
    private static void test5();
    private static void test6();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Genome.class

package edu.princeton.cs.algs4;
public synchronized class Genome {
    private void Genome();
    public static void compress();
    public static void expand();
    public static void main(String[]);
}

edu/princeton/cs/algs4/GlobalMincut.class

package edu.princeton.cs.algs4;
public synchronized class GlobalMincut {
    private static final double FLOATING_POINT_EPSILON = 1.0E-11;
    private double weight;
    private boolean[] cut;
    private int V;
    public void GlobalMincut(EdgeWeightedGraph);
    private void validate(EdgeWeightedGraph);
    public double weight();
    public boolean cut(int);
    private void makeCut(int, UF);
    private void minCut(EdgeWeightedGraph, int);
    private GlobalMincut$CutPhase minCutPhase(EdgeWeightedGraph, boolean[], GlobalMincut$CutPhase);
    private EdgeWeightedGraph contractEdge(EdgeWeightedGraph, int, int);
    private boolean check(EdgeWeightedGraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/GlobalMincut$CutPhase.class

package edu.princeton.cs.algs4;
synchronized class GlobalMincut$CutPhase {
    private double weight;
    private int s;
    private int t;
    public void GlobalMincut$CutPhase(GlobalMincut, double, int, int);
}

edu/princeton/cs/algs4/GrahamScan.class

package edu.princeton.cs.algs4;
public synchronized class GrahamScan {
    private Stack hull;
    public void GrahamScan(Point2D[]);
    public Iterable hull();
    private boolean isConvex();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Graph.class

package edu.princeton.cs.algs4;
public synchronized class Graph {
    private static final String NEWLINE;
    private final int V;
    private int E;
    private Bag[] adj;
    public void Graph(int);
    public void Graph(In);
    public void Graph(Graph);
    public int V();
    public int E();
    private void validateVertex(int);
    public void addEdge(int, int);
    public Iterable adj(int);
    public int degree(int);
    public String toString();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/GraphGenerator$1.class

package edu.princeton.cs.algs4;
synchronized class GraphGenerator$1 {
}

edu/princeton/cs/algs4/GraphGenerator.class

package edu.princeton.cs.algs4;
public synchronized class GraphGenerator {
    private void GraphGenerator();
    public static Graph simple(int, int);
    public static Graph simple(int, double);
    public static Graph complete(int);
    public static Graph completeBipartite(int, int);
    public static Graph bipartite(int, int, int);
    public static Graph bipartite(int, int, double);
    public static Graph path(int);
    public static Graph binaryTree(int);
    public static Graph cycle(int);
    public static Graph eulerianCycle(int, int);
    public static Graph eulerianPath(int, int);
    public static Graph wheel(int);
    public static Graph star(int);
    public static Graph regular(int, int);
    public static Graph tree(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/GraphGenerator$Edge.class

package edu.princeton.cs.algs4;
final synchronized class GraphGenerator$Edge implements Comparable {
    private int v;
    private int w;
    private void GraphGenerator$Edge(int, int);
    public int compareTo(GraphGenerator$Edge);
}

edu/princeton/cs/algs4/GrayscalePicture.class

package edu.princeton.cs.algs4;
public final synchronized class GrayscalePicture implements java.awt.event.ActionListener {
    private java.awt.image.BufferedImage image;
    private javax.swing.JFrame frame;
    private String filename;
    private boolean isOriginUpperLeft;
    private final int width;
    private final int height;
    public void GrayscalePicture(int, int);
    public void GrayscalePicture(GrayscalePicture);
    public void GrayscalePicture(String);
    private static java.awt.Color toGray(java.awt.Color);
    public javax.swing.JLabel getJLabel();
    public void setOriginUpperLeft();
    public void setOriginLowerLeft();
    public void show();
    public int height();
    public int width();
    private void validateRowIndex(int);
    private void validateColumnIndex(int);
    private void validateGrayscaleValue(int);
    public java.awt.Color get(int, int);
    public int getGrayscale(int, int);
    public void set(int, int, java.awt.Color);
    public void setGrayscale(int, int, int);
    public boolean equals(Object);
    public String toString();
    public int hashCode();
    public void save(String);
    public void save(java.io.File);
    public void actionPerformed(java.awt.event.ActionEvent);
    public static void main(String[]);
}

edu/princeton/cs/algs4/GREP.class

package edu.princeton.cs.algs4;
public synchronized class GREP {
    private void GREP();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Heap.class

package edu.princeton.cs.algs4;
public synchronized class Heap {
    private void Heap();
    public static void sort(Comparable[]);
    private static void sink(Comparable[], int, int);
    private static boolean less(Comparable[], int, int);
    private static void exch(Object[], int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/HexDump.class

package edu.princeton.cs.algs4;
public synchronized class HexDump {
    private void HexDump();
    public static void main(String[]);
}

edu/princeton/cs/algs4/HopcroftKarp.class

package edu.princeton.cs.algs4;
public synchronized class HopcroftKarp {
    private static final int UNMATCHED = -1;
    private final int V;
    private BipartiteX bipartition;
    private int cardinality;
    private int[] mate;
    private boolean[] inMinVertexCover;
    private boolean[] marked;
    private int[] distTo;
    public void HopcroftKarp(Graph);
    private static String toString(Iterable);
    private boolean isLevelGraphEdge(int, int);
    private boolean isResidualGraphEdge(int, int);
    private boolean hasAugmentingPath(Graph);
    public int mate(int);
    public boolean isMatched(int);
    public int size();
    public boolean isPerfect();
    public boolean inMinVertexCover(int);
    private void validate(int);
    private boolean certifySolution(Graph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Huffman.class

package edu.princeton.cs.algs4;
public synchronized class Huffman {
    private static final int R = 256;
    private void Huffman();
    public static void compress();
    private static Huffman$Node buildTrie(int[]);
    private static void writeTrie(Huffman$Node);
    private static void buildCode(String[], Huffman$Node, String);
    public static void expand();
    private static Huffman$Node readTrie();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Huffman$Node.class

package edu.princeton.cs.algs4;
synchronized class Huffman$Node implements Comparable {
    private final char ch;
    private final int freq;
    private final Huffman$Node left;
    private final Huffman$Node right;
    void Huffman$Node(char, int, Huffman$Node, Huffman$Node);
    private boolean isLeaf();
    public int compareTo(Huffman$Node);
    static void <clinit>();
}

edu/princeton/cs/algs4/In.class

package edu.princeton.cs.algs4;
public final synchronized class In {
    private static final String CHARSET_NAME = UTF-8;
    private static final java.util.Locale LOCALE;
    private static final java.util.regex.Pattern WHITESPACE_PATTERN;
    private static final java.util.regex.Pattern EMPTY_PATTERN;
    private static final java.util.regex.Pattern EVERYTHING_PATTERN;
    private java.util.Scanner scanner;
    public void In();
    public void In(java.net.Socket);
    public void In(java.net.URL);
    public void In(java.io.File);
    public void In(String);
    public void In(java.util.Scanner);
    public boolean exists();
    public boolean isEmpty();
    public boolean hasNextLine();
    public boolean hasNextChar();
    public String readLine();
    public char readChar();
    public String readAll();
    public String readString();
    public int readInt();
    public double readDouble();
    public float readFloat();
    public long readLong();
    public short readShort();
    public byte readByte();
    public boolean readBoolean();
    public String[] readAllStrings();
    public String[] readAllLines();
    public int[] readAllInts();
    public long[] readAllLongs();
    public double[] readAllDoubles();
    public void close();
    public static int[] readInts(String);
    public static double[] readDoubles(String);
    public static String[] readStrings(String);
    public static int[] readInts();
    public static double[] readDoubles();
    public static String[] readStrings();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$1 {
}

edu/princeton/cs/algs4/IndexBinomialMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class IndexBinomialMinPQ implements Iterable {
    private IndexBinomialMinPQ$Node head;
    private IndexBinomialMinPQ$Node[] nodes;
    private int n;
    private final java.util.Comparator comparator;
    public void IndexBinomialMinPQ(int);
    public void IndexBinomialMinPQ(int, java.util.Comparator);
    public boolean isEmpty();
    public boolean contains(int);
    public int size();
    public void insert(int, Object);
    public int minIndex();
    public Object minKey();
    public int delMin();
    public Object keyOf(int);
    public void changeKey(int, Object);
    public void decreaseKey(int, Object);
    public void increaseKey(int, Object);
    public void delete(int);
    private boolean greater(Object, Object);
    private void exchange(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
    private void link(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
    private void swim(int);
    private void toTheRoot(int);
    private IndexBinomialMinPQ$Node erase(int);
    private IndexBinomialMinPQ$Node eraseMin();
    private IndexBinomialMinPQ$Node merge(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
    private IndexBinomialMinPQ union(IndexBinomialMinPQ);
    private void IndexBinomialMinPQ();
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$MyComparator implements java.util.Comparator {
    private void IndexBinomialMinPQ$MyComparator(IndexBinomialMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$MyIterator implements java.util.Iterator {
    IndexBinomialMinPQ data;
    public void IndexBinomialMinPQ$MyIterator(IndexBinomialMinPQ);
    private IndexBinomialMinPQ$Node clone(IndexBinomialMinPQ$Node, IndexBinomialMinPQ$Node);
    public boolean hasNext();
    public Integer next();
    public void remove();
}

edu/princeton/cs/algs4/IndexBinomialMinPQ$Node.class

package edu.princeton.cs.algs4;
synchronized class IndexBinomialMinPQ$Node {
    Object key;
    int order;
    int index;
    IndexBinomialMinPQ$Node parent;
    IndexBinomialMinPQ$Node child;
    IndexBinomialMinPQ$Node sibling;
    private void IndexBinomialMinPQ$Node(IndexBinomialMinPQ);
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$1 {
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class IndexFibonacciMinPQ implements Iterable {
    private IndexFibonacciMinPQ$Node[] nodes;
    private IndexFibonacciMinPQ$Node head;
    private IndexFibonacciMinPQ$Node min;
    private int size;
    private int n;
    private final java.util.Comparator comp;
    private java.util.HashMap table;
    public void IndexFibonacciMinPQ(int);
    public void IndexFibonacciMinPQ(java.util.Comparator, int);
    public boolean isEmpty();
    public boolean contains(int);
    public int size();
    public void insert(int, Object);
    public int minIndex();
    public Object minKey();
    public int delMin();
    public Object keyOf(int);
    public void changeKey(int, Object);
    public void decreaseKey(int, Object);
    public void increaseKey(int, Object);
    public void delete(int);
    private boolean greater(Object, Object);
    private void link(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
    private void cut(int);
    private void consolidate();
    private IndexFibonacciMinPQ$Node insert(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
    private IndexFibonacciMinPQ$Node cut(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
    private IndexFibonacciMinPQ$Node meld(IndexFibonacciMinPQ$Node, IndexFibonacciMinPQ$Node);
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$MyComparator implements java.util.Comparator {
    private void IndexFibonacciMinPQ$MyComparator(IndexFibonacciMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$MyIterator implements java.util.Iterator {
    private IndexFibonacciMinPQ copy;
    public void IndexFibonacciMinPQ$MyIterator(IndexFibonacciMinPQ);
    public void remove();
    public boolean hasNext();
    public Integer next();
}

edu/princeton/cs/algs4/IndexFibonacciMinPQ$Node.class

package edu.princeton.cs.algs4;
synchronized class IndexFibonacciMinPQ$Node {
    Object key;
    int order;
    int index;
    IndexFibonacciMinPQ$Node prev;
    IndexFibonacciMinPQ$Node next;
    IndexFibonacciMinPQ$Node parent;
    IndexFibonacciMinPQ$Node child;
    boolean mark;
    private void IndexFibonacciMinPQ$Node(IndexFibonacciMinPQ);
}

edu/princeton/cs/algs4/IndexMaxPQ.class

package edu.princeton.cs.algs4;
public synchronized class IndexMaxPQ implements Iterable {
    private int maxN;
    private int n;
    private int[] pq;
    private int[] qp;
    private Comparable[] keys;
    public void IndexMaxPQ(int);
    public boolean isEmpty();
    public boolean contains(int);
    public int size();
    public void insert(int, Comparable);
    public int maxIndex();
    public Comparable maxKey();
    public int delMax();
    public Comparable keyOf(int);
    public void changeKey(int, Comparable);
    public void change(int, Comparable);
    public void increaseKey(int, Comparable);
    public void decreaseKey(int, Comparable);
    public void delete(int);
    private void validateIndex(int);
    private boolean less(int, int);
    private void exch(int, int);
    private void swim(int);
    private void sink(int);
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/IndexMaxPQ$HeapIterator.class

package edu.princeton.cs.algs4;
synchronized class IndexMaxPQ$HeapIterator implements java.util.Iterator {
    private IndexMaxPQ copy;
    public void IndexMaxPQ$HeapIterator(IndexMaxPQ);
    public boolean hasNext();
    public void remove();
    public Integer next();
}

edu/princeton/cs/algs4/IndexMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class IndexMinPQ implements Iterable {
    private int maxN;
    private int n;
    private int[] pq;
    private int[] qp;
    private Comparable[] keys;
    public void IndexMinPQ(int);
    public boolean isEmpty();
    public boolean contains(int);
    public int size();
    public void insert(int, Comparable);
    public int minIndex();
    public Comparable minKey();
    public int delMin();
    public Comparable keyOf(int);
    public void changeKey(int, Comparable);
    public void change(int, Comparable);
    public void decreaseKey(int, Comparable);
    public void increaseKey(int, Comparable);
    public void delete(int);
    private void validateIndex(int);
    private boolean greater(int, int);
    private void exch(int, int);
    private void swim(int);
    private void sink(int);
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/IndexMinPQ$HeapIterator.class

package edu.princeton.cs.algs4;
synchronized class IndexMinPQ$HeapIterator implements java.util.Iterator {
    private IndexMinPQ copy;
    public void IndexMinPQ$HeapIterator(IndexMinPQ);
    public boolean hasNext();
    public void remove();
    public Integer next();
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$1 {
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class IndexMultiwayMinPQ implements Iterable {
    private final int d;
    private int n;
    private int nmax;
    private int[] pq;
    private int[] qp;
    private Object[] keys;
    private final java.util.Comparator comp;
    public void IndexMultiwayMinPQ(int, int);
    public void IndexMultiwayMinPQ(int, java.util.Comparator, int);
    public boolean isEmpty();
    public boolean contains(int);
    public int size();
    public void insert(int, Object);
    public int minIndex();
    public Object minKey();
    public int delMin();
    public Object keyOf(int);
    public void changeKey(int, Object);
    public void decreaseKey(int, Object);
    public void increaseKey(int, Object);
    public void delete(int);
    private boolean greater(int, int);
    private void exch(int, int);
    private void swim(int);
    private void sink(int);
    private int minChild(int);
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$MyComparator implements java.util.Comparator {
    private void IndexMultiwayMinPQ$MyComparator(IndexMultiwayMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/IndexMultiwayMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class IndexMultiwayMinPQ$MyIterator implements java.util.Iterator {
    IndexMultiwayMinPQ clone;
    public void IndexMultiwayMinPQ$MyIterator(IndexMultiwayMinPQ);
    public boolean hasNext();
    public Integer next();
    public void remove();
}

edu/princeton/cs/algs4/InplaceMSD.class

package edu.princeton.cs.algs4;
public synchronized class InplaceMSD {
    private static final int R = 256;
    private static final int CUTOFF = 15;
    private void InplaceMSD();
    public static void sort(String[]);
    private static int charAt(String, int);
    private static void sort(String[], int, int, int);
    private static void insertion(String[], int, int, int);
    private static void exch(String[], int, int);
    private static boolean less(String, String, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Insertion.class

package edu.princeton.cs.algs4;
public synchronized class Insertion {
    private void Insertion();
    public static void sort(Comparable[]);
    public static void sort(Comparable[], int, int);
    public static void sort(Object[], java.util.Comparator);
    public static void sort(Object[], int, int, java.util.Comparator);
    public static int[] indexSort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static boolean less(Object, Object, java.util.Comparator);
    private static void exch(Object[], int, int);
    private static void exch(int[], int, int);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static boolean isSorted(Object[], java.util.Comparator);
    private static boolean isSorted(Object[], int, int, java.util.Comparator);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/InsertionX.class

package edu.princeton.cs.algs4;
public synchronized class InsertionX {
    private void InsertionX();
    public static void sort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Interval1D$1.class

package edu.princeton.cs.algs4;
synchronized class Interval1D$1 {
}

edu/princeton/cs/algs4/Interval1D.class

package edu.princeton.cs.algs4;
public synchronized class Interval1D {
    public static final java.util.Comparator MIN_ENDPOINT_ORDER;
    public static final java.util.Comparator MAX_ENDPOINT_ORDER;
    public static final java.util.Comparator LENGTH_ORDER;
    private final double min;
    private final double max;
    public void Interval1D(double, double);
    public double left();
    public double right();
    public double min();
    public double max();
    public boolean intersects(Interval1D);
    public boolean contains(double);
    public double length();
    public String toString();
    public boolean equals(Object);
    public int hashCode();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Interval1D$LengthComparator.class

package edu.princeton.cs.algs4;
synchronized class Interval1D$LengthComparator implements java.util.Comparator {
    private void Interval1D$LengthComparator();
    public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval1D$MaxEndpointComparator.class

package edu.princeton.cs.algs4;
synchronized class Interval1D$MaxEndpointComparator implements java.util.Comparator {
    private void Interval1D$MaxEndpointComparator();
    public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval1D$MinEndpointComparator.class

package edu.princeton.cs.algs4;
synchronized class Interval1D$MinEndpointComparator implements java.util.Comparator {
    private void Interval1D$MinEndpointComparator();
    public int compare(Interval1D, Interval1D);
}

edu/princeton/cs/algs4/Interval2D.class

package edu.princeton.cs.algs4;
public synchronized class Interval2D {
    private final Interval1D x;
    private final Interval1D y;
    public void Interval2D(Interval1D, Interval1D);
    public boolean intersects(Interval2D);
    public boolean contains(Point2D);
    public double area();
    public String toString();
    public boolean equals(Object);
    public int hashCode();
    public void draw();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Inversions.class

package edu.princeton.cs.algs4;
public synchronized class Inversions {
    private void Inversions();
    private static long merge(int[], int[], int, int, int);
    private static long count(int[], int[], int[], int, int);
    public static long count(int[]);
    private static long merge(Comparable[], Comparable[], int, int, int);
    private static long count(Comparable[], Comparable[], Comparable[], int, int);
    public static long count(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static long brute(Comparable[], int, int);
    private static long brute(int[], int, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/KMP.class

package edu.princeton.cs.algs4;
public synchronized class KMP {
    private final int R;
    private int[][] dfa;
    private char[] pattern;
    private String pat;
    public void KMP(String);
    public void KMP(char[], int);
    public int search(String);
    public int search(char[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Knuth.class

package edu.princeton.cs.algs4;
public synchronized class Knuth {
    private void Knuth();
    public static void shuffle(Object[]);
    public static void shuffleAlternate(Object[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/KosarajuSharirSCC.class

package edu.princeton.cs.algs4;
public synchronized class KosarajuSharirSCC {
    private boolean[] marked;
    private int[] id;
    private int count;
    public void KosarajuSharirSCC(Digraph);
    private void dfs(Digraph, int);
    public int count();
    public boolean stronglyConnected(int, int);
    public int id(int);
    private boolean check(Digraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/KruskalMST.class

package edu.princeton.cs.algs4;
public synchronized class KruskalMST {
    private static final double FLOATING_POINT_EPSILON = 1.0E-12;
    private double weight;
    private Queue mst;
    public void KruskalMST(EdgeWeightedGraph);
    public Iterable edges();
    public double weight();
    private boolean check(EdgeWeightedGraph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/KWIK.class

package edu.princeton.cs.algs4;
public synchronized class KWIK {
    private void KWIK();
    public static void main(String[]);
}

edu/princeton/cs/algs4/LazyPrimMST.class

package edu.princeton.cs.algs4;
public synchronized class LazyPrimMST {
    private static final double FLOATING_POINT_EPSILON = 1.0E-12;
    private double weight;
    private Queue mst;
    private boolean[] marked;
    private MinPQ pq;
    public void LazyPrimMST(EdgeWeightedGraph);
    private void prim(EdgeWeightedGraph, int);
    private void scan(EdgeWeightedGraph, int);
    public Iterable edges();
    public double weight();
    private boolean check(EdgeWeightedGraph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LinearProbingHashST.class

package edu.princeton.cs.algs4;
public synchronized class LinearProbingHashST {
    private static final int INIT_CAPACITY = 4;
    private int n;
    private int m;
    private Object[] keys;
    private Object[] vals;
    public void LinearProbingHashST();
    public void LinearProbingHashST(int);
    public int size();
    public boolean isEmpty();
    public boolean contains(Object);
    private int hash(Object);
    private void resize(int);
    public void put(Object, Object);
    public Object get(Object);
    public void delete(Object);
    public Iterable keys();
    private boolean check();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LinearProgramming.class

package edu.princeton.cs.algs4;
public synchronized class LinearProgramming {
    private static final double EPSILON = 1.0E-10;
    private double[][] a;
    private int m;
    private int n;
    private int[] basis;
    public void LinearProgramming(double[][], double[], double[]);
    private void solve();
    private int bland();
    private int dantzig();
    private int minRatioRule(int);
    private void pivot(int, int);
    public double value();
    public double[] primal();
    public double[] dual();
    private boolean isPrimalFeasible(double[][], double[]);
    private boolean isDualFeasible(double[][], double[]);
    private boolean isOptimal(double[], double[]);
    private boolean check(double[][], double[], double[]);
    private void show();
    private static void test(double[][], double[], double[]);
    private static void test1();
    private static void test2();
    private static void test3();
    private static void test4();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LinearRegression.class

package edu.princeton.cs.algs4;
public synchronized class LinearRegression {
    private final double intercept;
    private final double slope;
    private final double r2;
    private final double svar0;
    private final double svar1;
    public void LinearRegression(double[], double[]);
    public double intercept();
    public double slope();
    public double R2();
    public double interceptStdErr();
    public double slopeStdErr();
    public double predict(double);
    public String toString();
}

edu/princeton/cs/algs4/LinkedBag$1.class

package edu.princeton.cs.algs4;
synchronized class LinkedBag$1 {
}

edu/princeton/cs/algs4/LinkedBag.class

package edu.princeton.cs.algs4;
public synchronized class LinkedBag implements Iterable {
    private LinkedBag$Node first;
    private int n;
    public void LinkedBag();
    public boolean isEmpty();
    public int size();
    public void add(Object);
    public java.util.Iterator iterator();
    public static void main(String[]);
}

edu/princeton/cs/algs4/LinkedBag$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class LinkedBag$ListIterator implements java.util.Iterator {
    private LinkedBag$Node current;
    public void LinkedBag$ListIterator(LinkedBag);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/LinkedBag$Node.class

package edu.princeton.cs.algs4;
synchronized class LinkedBag$Node {
    private Object item;
    private LinkedBag$Node next;
    private void LinkedBag$Node(LinkedBag);
}

edu/princeton/cs/algs4/LinkedQueue$1.class

package edu.princeton.cs.algs4;
synchronized class LinkedQueue$1 {
}

edu/princeton/cs/algs4/LinkedQueue.class

package edu.princeton.cs.algs4;
public synchronized class LinkedQueue implements Iterable {
    private int n;
    private LinkedQueue$Node first;
    private LinkedQueue$Node last;
    public void LinkedQueue();
    public boolean isEmpty();
    public int size();
    public Object peek();
    public void enqueue(Object);
    public Object dequeue();
    public String toString();
    private boolean check();
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LinkedQueue$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class LinkedQueue$ListIterator implements java.util.Iterator {
    private LinkedQueue$Node current;
    private void LinkedQueue$ListIterator(LinkedQueue);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/LinkedQueue$Node.class

package edu.princeton.cs.algs4;
synchronized class LinkedQueue$Node {
    private Object item;
    private LinkedQueue$Node next;
    private void LinkedQueue$Node(LinkedQueue);
}

edu/princeton/cs/algs4/LinkedStack$1.class

package edu.princeton.cs.algs4;
synchronized class LinkedStack$1 {
}

edu/princeton/cs/algs4/LinkedStack.class

package edu.princeton.cs.algs4;
public synchronized class LinkedStack implements Iterable {
    private int n;
    private LinkedStack$Node first;
    public void LinkedStack();
    public boolean isEmpty();
    public int size();
    public void push(Object);
    public Object pop();
    public Object peek();
    public String toString();
    public java.util.Iterator iterator();
    private boolean check();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LinkedStack$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class LinkedStack$ListIterator implements java.util.Iterator {
    private LinkedStack$Node current;
    private void LinkedStack$ListIterator(LinkedStack);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/LinkedStack$Node.class

package edu.princeton.cs.algs4;
synchronized class LinkedStack$Node {
    private Object item;
    private LinkedStack$Node next;
    private void LinkedStack$Node(LinkedStack);
}

edu/princeton/cs/algs4/LongestCommonSubstring.class

package edu.princeton.cs.algs4;
public synchronized class LongestCommonSubstring {
    private void LongestCommonSubstring();
    private static String lcp(String, int, String, int);
    private static int compare(String, int, String, int);
    public static String lcs(String, String);
    public static void main(String[]);
}

edu/princeton/cs/algs4/LongestRepeatedSubstring.class

package edu.princeton.cs.algs4;
public synchronized class LongestRepeatedSubstring {
    private void LongestRepeatedSubstring();
    public static String lrs(String);
    public static void main(String[]);
}

edu/princeton/cs/algs4/LookupCSV.class

package edu.princeton.cs.algs4;
public synchronized class LookupCSV {
    private void LookupCSV();
    public static void main(String[]);
}

edu/princeton/cs/algs4/LookupIndex.class

package edu.princeton.cs.algs4;
public synchronized class LookupIndex {
    private void LookupIndex();
    public static void main(String[]);
}

edu/princeton/cs/algs4/LSD.class

package edu.princeton.cs.algs4;
public synchronized class LSD {
    private static final int BITS_PER_BYTE = 8;
    private void LSD();
    public static void sort(String[], int);
    public static void sort(int[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/LZW.class

package edu.princeton.cs.algs4;
public synchronized class LZW {
    private static final int R = 256;
    private static final int L = 4096;
    private static final int W = 12;
    private void LZW();
    public static void compress();
    public static void expand();
    public static void main(String[]);
}

edu/princeton/cs/algs4/MaxPQ.class

package edu.princeton.cs.algs4;
public synchronized class MaxPQ implements Iterable {
    private Object[] pq;
    private int n;
    private java.util.Comparator comparator;
    public void MaxPQ(int);
    public void MaxPQ();
    public void MaxPQ(int, java.util.Comparator);
    public void MaxPQ(java.util.Comparator);
    public void MaxPQ(Object[]);
    public boolean isEmpty();
    public int size();
    public Object max();
    private void resize(int);
    public void insert(Object);
    public Object delMax();
    private void swim(int);
    private void sink(int);
    private boolean less(int, int);
    private void exch(int, int);
    private boolean isMaxHeap();
    private boolean isMaxHeapOrdered(int);
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/MaxPQ$HeapIterator.class

package edu.princeton.cs.algs4;
synchronized class MaxPQ$HeapIterator implements java.util.Iterator {
    private MaxPQ copy;
    public void MaxPQ$HeapIterator(MaxPQ);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/MergeBU.class

package edu.princeton.cs.algs4;
public synchronized class MergeBU {
    private void MergeBU();
    private static void merge(Comparable[], Comparable[], int, int, int);
    public static void sort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static boolean isSorted(Comparable[]);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Merge.class

package edu.princeton.cs.algs4;
public synchronized class Merge {
    private void Merge();
    private static void merge(Comparable[], Comparable[], int, int, int);
    private static void sort(Comparable[], Comparable[], int, int);
    public static void sort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static void merge(Comparable[], int[], int[], int, int, int);
    public static int[] indexSort(Comparable[]);
    private static void sort(Comparable[], int[], int[], int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/MergeX.class

package edu.princeton.cs.algs4;
public synchronized class MergeX {
    private static final int CUTOFF = 7;
    private void MergeX();
    private static void merge(Comparable[], Comparable[], int, int, int);
    private static void sort(Comparable[], Comparable[], int, int);
    public static void sort(Comparable[]);
    private static void insertionSort(Comparable[], int, int);
    private static void exch(Object[], int, int);
    private static boolean less(Comparable, Comparable);
    private static boolean less(Object, Object, java.util.Comparator);
    public static void sort(Object[], java.util.Comparator);
    private static void merge(Object[], Object[], int, int, int, java.util.Comparator);
    private static void sort(Object[], Object[], int, int, java.util.Comparator);
    private static void insertionSort(Object[], int, int, java.util.Comparator);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static boolean isSorted(Object[], java.util.Comparator);
    private static boolean isSorted(Object[], int, int, java.util.Comparator);
    private static void show(Object[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/MinPQ.class

package edu.princeton.cs.algs4;
public synchronized class MinPQ implements Iterable {
    private Object[] pq;
    private int n;
    private java.util.Comparator comparator;
    public void MinPQ(int);
    public void MinPQ();
    public void MinPQ(int, java.util.Comparator);
    public void MinPQ(java.util.Comparator);
    public void MinPQ(Object[]);
    public boolean isEmpty();
    public int size();
    public Object min();
    private void resize(int);
    public void insert(Object);
    public Object delMin();
    private void swim(int);
    private void sink(int);
    private boolean greater(int, int);
    private void exch(int, int);
    private boolean isMinHeap();
    private boolean isMinHeapOrdered(int);
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/MinPQ$HeapIterator.class

package edu.princeton.cs.algs4;
synchronized class MinPQ$HeapIterator implements java.util.Iterator {
    private MinPQ copy;
    public void MinPQ$HeapIterator(MinPQ);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/MSD.class

package edu.princeton.cs.algs4;
public synchronized class MSD {
    private static final int BITS_PER_BYTE = 8;
    private static final int BITS_PER_INT = 32;
    private static final int R = 256;
    private static final int CUTOFF = 15;
    private void MSD();
    public static void sort(String[]);
    private static int charAt(String, int);
    private static void sort(String[], int, int, int, String[]);
    private static void insertion(String[], int, int, int);
    private static void exch(String[], int, int);
    private static boolean less(String, String, int);
    public static void sort(int[]);
    private static void sort(int[], int, int, int, int[]);
    private static void insertion(int[], int, int, int);
    private static void exch(int[], int, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Multiway.class

package edu.princeton.cs.algs4;
public synchronized class Multiway {
    private void Multiway();
    private static void merge(In[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/MultiwayMinPQ$1.class

package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$1 {
}

edu/princeton/cs/algs4/MultiwayMinPQ.class

package edu.princeton.cs.algs4;
public synchronized class MultiwayMinPQ implements Iterable {
    private final int d;
    private int n;
    private int order;
    private Object[] keys;
    private final java.util.Comparator comp;
    public void MultiwayMinPQ(int);
    public void MultiwayMinPQ(java.util.Comparator, int);
    public void MultiwayMinPQ(Object[], int);
    public void MultiwayMinPQ(java.util.Comparator, Object[], int);
    public boolean isEmpty();
    public int size();
    public void insert(Object);
    public Object minKey();
    public Object delMin();
    private boolean greater(int, int);
    private void exch(int, int);
    private int getN(int);
    private void swim(int);
    private void sink(int);
    private int minChild(int);
    private void resize(int);
    public java.util.Iterator iterator();
}

edu/princeton/cs/algs4/MultiwayMinPQ$MyComparator.class

package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$MyComparator implements java.util.Comparator {
    private void MultiwayMinPQ$MyComparator(MultiwayMinPQ);
    public int compare(Object, Object);
}

edu/princeton/cs/algs4/MultiwayMinPQ$MyIterator.class

package edu.princeton.cs.algs4;
synchronized class MultiwayMinPQ$MyIterator implements java.util.Iterator {
    MultiwayMinPQ data;
    public void MultiwayMinPQ$MyIterator(MultiwayMinPQ);
    public boolean hasNext();
    public Object next();
    public void remove();
}

edu/princeton/cs/algs4/NFA.class

package edu.princeton.cs.algs4;
public synchronized class NFA {
    private Digraph graph;
    private String regexp;
    private final int m;
    public void NFA(String);
    public boolean recognizes(String);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/NonrecursiveDFS.class

package edu.princeton.cs.algs4;
public synchronized class NonrecursiveDFS {
    private boolean[] marked;
    public void NonrecursiveDFS(Graph, int);
    public boolean marked(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/NonrecursiveDirectedDFS.class

package edu.princeton.cs.algs4;
public synchronized class NonrecursiveDirectedDFS {
    private boolean[] marked;
    public void NonrecursiveDirectedDFS(Digraph, int);
    public boolean marked(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Out.class

package edu.princeton.cs.algs4;
public synchronized class Out {
    private static final String CHARSET_NAME = UTF-8;
    private static final java.util.Locale LOCALE;
    private java.io.PrintWriter out;
    public void Out(java.io.OutputStream);
    public void Out();
    public void Out(java.net.Socket);
    public void Out(String);
    public void close();
    public void println();
    public void println(Object);
    public void println(boolean);
    public void println(char);
    public void println(double);
    public void println(float);
    public void println(int);
    public void println(long);
    public void println(byte);
    public void print();
    public void print(Object);
    public void print(boolean);
    public void print(char);
    public void print(double);
    public void print(float);
    public void print(int);
    public void print(long);
    public void print(byte);
    public transient void printf(String, Object[]);
    public transient void printf(java.util.Locale, String, Object[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Particle.class

package edu.princeton.cs.algs4;
public synchronized class Particle {
    private static final double INFINITY = Infinity;
    private double rx;
    private double ry;
    private double vx;
    private double vy;
    private int count;
    private final double radius;
    private final double mass;
    private final java.awt.Color color;
    public void Particle(double, double, double, double, double, double, java.awt.Color);
    public void Particle();
    public void move(double);
    public void draw();
    public int count();
    public double timeToHit(Particle);
    public double timeToHitVerticalWall();
    public double timeToHitHorizontalWall();
    public void bounceOff(Particle);
    public void bounceOffVerticalWall();
    public void bounceOffHorizontalWall();
    public double kineticEnergy();
}

edu/princeton/cs/algs4/PatriciaSET.class

package edu.princeton.cs.algs4;
public synchronized class PatriciaSET implements Iterable {
    private PatriciaSET$Node head;
    private int count;
    public void PatriciaSET();
    public void add(String);
    public boolean contains(String);
    public void delete(String);
    boolean isEmpty();
    int size();
    public java.util.Iterator iterator();
    private void collect(PatriciaSET$Node, int, Queue);
    public String toString();
    private static boolean safeBitTest(String, int);
    private static int bitTest(String, int);
    private static int safeCharAt(String, int);
    private static int firstDifferingBit(String, String);
    public static void main(String[]);
}

edu/princeton/cs/algs4/PatriciaSET$Node.class

package edu.princeton.cs.algs4;
synchronized class PatriciaSET$Node {
    private PatriciaSET$Node left;
    private PatriciaSET$Node right;
    private String key;
    private int b;
    public void PatriciaSET$Node(PatriciaSET, String, int);
}

edu/princeton/cs/algs4/PatriciaST.class

package edu.princeton.cs.algs4;
public synchronized class PatriciaST {
    private PatriciaST$Node head;
    private int count;
    public void PatriciaST();
    public void put(String, Object);
    public Object get(String);
    public void delete(String);
    public boolean contains(String);
    boolean isEmpty();
    int size();
    public Iterable keys();
    private void keys(PatriciaST$Node, int, Queue);
    private static boolean safeBitTest(String, int);
    private static int bitTest(String, int);
    private static int safeCharAt(String, int);
    private static int firstDifferingBit(String, String);
    public static void main(String[]);
}

edu/princeton/cs/algs4/PatriciaST$Node.class

package edu.princeton.cs.algs4;
synchronized class PatriciaST$Node {
    private PatriciaST$Node left;
    private PatriciaST$Node right;
    private String key;
    private Object val;
    private int b;
    public void PatriciaST$Node(PatriciaST, String, Object, int);
}

edu/princeton/cs/algs4/Picture.class

package edu.princeton.cs.algs4;
public final synchronized class Picture implements java.awt.event.ActionListener {
    private java.awt.image.BufferedImage image;
    private javax.swing.JFrame frame;
    private String filename;
    private boolean isOriginUpperLeft;
    private final int width;
    private final int height;
    public void Picture(int, int);
    public void Picture(Picture);
    public void Picture(String);
    public void Picture(java.io.File);
    public javax.swing.JLabel getJLabel();
    public void setOriginUpperLeft();
    public void setOriginLowerLeft();
    public void show();
    public int height();
    public int width();
    private void validateRowIndex(int);
    private void validateColumnIndex(int);
    public java.awt.Color get(int, int);
    public int getRGB(int, int);
    public void set(int, int, java.awt.Color);
    public void setRGB(int, int, int);
    public boolean equals(Object);
    public String toString();
    public int hashCode();
    public void save(String);
    public void save(java.io.File);
    public void actionPerformed(java.awt.event.ActionEvent);
    public static void main(String[]);
}

edu/princeton/cs/algs4/PictureDump.class

package edu.princeton.cs.algs4;
public synchronized class PictureDump {
    private void PictureDump();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Point2D$1.class

package edu.princeton.cs.algs4;
synchronized class Point2D$1 {
}

edu/princeton/cs/algs4/Point2D$Atan2Order.class

package edu.princeton.cs.algs4;
synchronized class Point2D$Atan2Order implements java.util.Comparator {
    private void Point2D$Atan2Order(Point2D);
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D.class

package edu.princeton.cs.algs4;
public final synchronized class Point2D implements Comparable {
    public static final java.util.Comparator X_ORDER;
    public static final java.util.Comparator Y_ORDER;
    public static final java.util.Comparator R_ORDER;
    private final double x;
    private final double y;
    public void Point2D(double, double);
    public double x();
    public double y();
    public double r();
    public double theta();
    private double angleTo(Point2D);
    public static int ccw(Point2D, Point2D, Point2D);
    public static double area2(Point2D, Point2D, Point2D);
    public double distanceTo(Point2D);
    public double distanceSquaredTo(Point2D);
    public int compareTo(Point2D);
    public java.util.Comparator polarOrder();
    public java.util.Comparator atan2Order();
    public java.util.Comparator distanceToOrder();
    public boolean equals(Object);
    public String toString();
    public int hashCode();
    public void draw();
    public void drawTo(Point2D);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Point2D$DistanceToOrder.class

package edu.princeton.cs.algs4;
synchronized class Point2D$DistanceToOrder implements java.util.Comparator {
    private void Point2D$DistanceToOrder(Point2D);
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$PolarOrder.class

package edu.princeton.cs.algs4;
synchronized class Point2D$PolarOrder implements java.util.Comparator {
    private void Point2D$PolarOrder(Point2D);
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$ROrder.class

package edu.princeton.cs.algs4;
synchronized class Point2D$ROrder implements java.util.Comparator {
    private void Point2D$ROrder();
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$XOrder.class

package edu.princeton.cs.algs4;
synchronized class Point2D$XOrder implements java.util.Comparator {
    private void Point2D$XOrder();
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Point2D$YOrder.class

package edu.princeton.cs.algs4;
synchronized class Point2D$YOrder implements java.util.Comparator {
    private void Point2D$YOrder();
    public int compare(Point2D, Point2D);
}

edu/princeton/cs/algs4/Polynomial.class

package edu.princeton.cs.algs4;
public synchronized class Polynomial {
    private int[] coef;
    private int degree;
    public void Polynomial(int, int);
    private void reduce();
    public int degree();
    public Polynomial plus(Polynomial);
    public Polynomial minus(Polynomial);
    public Polynomial times(Polynomial);
    public Polynomial compose(Polynomial);
    public boolean equals(Object);
    public Polynomial differentiate();
    public int evaluate(int);
    public int compareTo(Polynomial);
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/PrimMST.class

package edu.princeton.cs.algs4;
public synchronized class PrimMST {
    private static final double FLOATING_POINT_EPSILON = 1.0E-12;
    private Edge[] edgeTo;
    private double[] distTo;
    private boolean[] marked;
    private IndexMinPQ pq;
    public void PrimMST(EdgeWeightedGraph);
    private void prim(EdgeWeightedGraph, int);
    private void scan(EdgeWeightedGraph, int);
    public Iterable edges();
    public double weight();
    private boolean check(EdgeWeightedGraph);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Queue$1.class

package edu.princeton.cs.algs4;
synchronized class Queue$1 {
}

edu/princeton/cs/algs4/Queue.class

package edu.princeton.cs.algs4;
public synchronized class Queue implements Iterable {
    private Queue$Node first;
    private Queue$Node last;
    private int n;
    public void Queue();
    public boolean isEmpty();
    public int size();
    public Object peek();
    public void enqueue(Object);
    public Object dequeue();
    public String toString();
    public java.util.Iterator iterator();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Queue$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class Queue$ListIterator implements java.util.Iterator {
    private Queue$Node current;
    public void Queue$ListIterator(Queue, Queue$Node);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/Queue$Node.class

package edu.princeton.cs.algs4;
synchronized class Queue$Node {
    private Object item;
    private Queue$Node next;
    private void Queue$Node();
}

edu/princeton/cs/algs4/Quick3string.class

package edu.princeton.cs.algs4;
public synchronized class Quick3string {
    private static final int CUTOFF = 15;
    private void Quick3string();
    public static void sort(String[]);
    private static int charAt(String, int);
    private static void sort(String[], int, int, int);
    private static void insertion(String[], int, int, int);
    private static void exch(String[], int, int);
    private static boolean less(String, String, int);
    private static boolean isSorted(String[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Quick3way.class

package edu.princeton.cs.algs4;
public synchronized class Quick3way {
    private void Quick3way();
    public static void sort(Comparable[]);
    private static void sort(Comparable[], int, int);
    private static boolean less(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/QuickBentleyMcIlroy.class

package edu.princeton.cs.algs4;
public synchronized class QuickBentleyMcIlroy {
    private static final int INSERTION_SORT_CUTOFF = 8;
    private static final int MEDIAN_OF_3_CUTOFF = 40;
    private void QuickBentleyMcIlroy();
    public static void sort(Comparable[]);
    private static void sort(Comparable[], int, int);
    private static void insertionSort(Comparable[], int, int);
    private static int median3(Comparable[], int, int, int);
    private static boolean less(Comparable, Comparable);
    private static boolean eq(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Quick.class

package edu.princeton.cs.algs4;
public synchronized class Quick {
    private void Quick();
    public static void sort(Comparable[]);
    private static void sort(Comparable[], int, int);
    private static int partition(Comparable[], int, int);
    public static Comparable select(Comparable[], int);
    private static boolean less(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/QuickFindUF.class

package edu.princeton.cs.algs4;
public synchronized class QuickFindUF {
    private int[] id;
    private int count;
    public void QuickFindUF(int);
    public int count();
    public int find(int);
    private void validate(int);
    public boolean connected(int, int);
    public void union(int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/QuickUnionUF.class

package edu.princeton.cs.algs4;
public synchronized class QuickUnionUF {
    private int[] parent;
    private int count;
    public void QuickUnionUF(int);
    public int count();
    public int find(int);
    private void validate(int);
    public boolean connected(int, int);
    public void union(int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/QuickX.class

package edu.princeton.cs.algs4;
public synchronized class QuickX {
    private static final int INSERTION_SORT_CUTOFF = 8;
    private void QuickX();
    public static void sort(Comparable[]);
    private static void sort(Comparable[], int, int);
    private static int partition(Comparable[], int, int);
    private static int median3(Comparable[], int, int, int);
    private static boolean less(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/RabinKarp.class

package edu.princeton.cs.algs4;
public synchronized class RabinKarp {
    private String pat;
    private long patHash;
    private int m;
    private long q;
    private int R;
    private long RM;
    public void RabinKarp(char[], int);
    public void RabinKarp(String);
    private long hash(String, int);
    private boolean check(String, int);
    public int search(String);
    private static long longRandomPrime();
    public static void main(String[]);
}

edu/princeton/cs/algs4/RandomSeq.class

package edu.princeton.cs.algs4;
public synchronized class RandomSeq {
    private void RandomSeq();
    public static void main(String[]);
}

edu/princeton/cs/algs4/RectHV.class

package edu.princeton.cs.algs4;
public final synchronized class RectHV {
    private final double xmin;
    private final double ymin;
    private final double xmax;
    private final double ymax;
    public void RectHV(double, double, double, double);
    public double xmin();
    public double xmax();
    public double ymin();
    public double ymax();
    public double width();
    public double height();
    public boolean intersects(RectHV);
    public boolean contains(Point2D);
    public double distanceTo(Point2D);
    public double distanceSquaredTo(Point2D);
    public boolean equals(Object);
    public int hashCode();
    public String toString();
    public void draw();
}

edu/princeton/cs/algs4/RedBlackBST.class

package edu.princeton.cs.algs4;
public synchronized class RedBlackBST {
    private static final boolean RED = 1;
    private static final boolean BLACK = 0;
    private RedBlackBST$Node root;
    public void RedBlackBST();
    private boolean isRed(RedBlackBST$Node);
    private int size(RedBlackBST$Node);
    public int size();
    public boolean isEmpty();
    public Object get(Comparable);
    private Object get(RedBlackBST$Node, Comparable);
    public boolean contains(Comparable);
    public void put(Comparable, Object);
    private RedBlackBST$Node put(RedBlackBST$Node, Comparable, Object);
    public void deleteMin();
    private RedBlackBST$Node deleteMin(RedBlackBST$Node);
    public void deleteMax();
    private RedBlackBST$Node deleteMax(RedBlackBST$Node);
    public void delete(Comparable);
    private RedBlackBST$Node delete(RedBlackBST$Node, Comparable);
    private RedBlackBST$Node rotateRight(RedBlackBST$Node);
    private RedBlackBST$Node rotateLeft(RedBlackBST$Node);
    private void flipColors(RedBlackBST$Node);
    private RedBlackBST$Node moveRedLeft(RedBlackBST$Node);
    private RedBlackBST$Node moveRedRight(RedBlackBST$Node);
    private RedBlackBST$Node balance(RedBlackBST$Node);
    public int height();
    private int height(RedBlackBST$Node);
    public Comparable min();
    private RedBlackBST$Node min(RedBlackBST$Node);
    public Comparable max();
    private RedBlackBST$Node max(RedBlackBST$Node);
    public Comparable floor(Comparable);
    private RedBlackBST$Node floor(RedBlackBST$Node, Comparable);
    public Comparable ceiling(Comparable);
    private RedBlackBST$Node ceiling(RedBlackBST$Node, Comparable);
    public Comparable select(int);
    private RedBlackBST$Node select(RedBlackBST$Node, int);
    public int rank(Comparable);
    private int rank(Comparable, RedBlackBST$Node);
    public Iterable keys();
    public Iterable keys(Comparable, Comparable);
    private void keys(RedBlackBST$Node, Queue, Comparable, Comparable);
    public int size(Comparable, Comparable);
    private boolean check();
    private boolean isBST();
    private boolean isBST(RedBlackBST$Node, Comparable, Comparable);
    private boolean isSizeConsistent();
    private boolean isSizeConsistent(RedBlackBST$Node);
    private boolean isRankConsistent();
    private boolean is23();
    private boolean is23(RedBlackBST$Node);
    private boolean isBalanced();
    private boolean isBalanced(RedBlackBST$Node, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/RedBlackBST$Node.class

package edu.princeton.cs.algs4;
synchronized class RedBlackBST$Node {
    private Comparable key;
    private Object val;
    private RedBlackBST$Node left;
    private RedBlackBST$Node right;
    private boolean color;
    private int size;
    public void RedBlackBST$Node(RedBlackBST, Comparable, Object, boolean, int);
}

edu/princeton/cs/algs4/ResizingArrayBag$1.class

package edu.princeton.cs.algs4;
synchronized class ResizingArrayBag$1 {
}

edu/princeton/cs/algs4/ResizingArrayBag$ArrayIterator.class

package edu.princeton.cs.algs4;
synchronized class ResizingArrayBag$ArrayIterator implements java.util.Iterator {
    private int i;
    private void ResizingArrayBag$ArrayIterator(ResizingArrayBag);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/ResizingArrayBag.class

package edu.princeton.cs.algs4;
public synchronized class ResizingArrayBag implements Iterable {
    private Object[] a;
    private int n;
    public void ResizingArrayBag();
    public boolean isEmpty();
    public int size();
    private void resize(int);
    public void add(Object);
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/ResizingArrayQueue$1.class

package edu.princeton.cs.algs4;
synchronized class ResizingArrayQueue$1 {
}

edu/princeton/cs/algs4/ResizingArrayQueue$ArrayIterator.class

package edu.princeton.cs.algs4;
synchronized class ResizingArrayQueue$ArrayIterator implements java.util.Iterator {
    private int i;
    private void ResizingArrayQueue$ArrayIterator(ResizingArrayQueue);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/ResizingArrayQueue.class

package edu.princeton.cs.algs4;
public synchronized class ResizingArrayQueue implements Iterable {
    private Object[] q;
    private int n;
    private int first;
    private int last;
    public void ResizingArrayQueue();
    public boolean isEmpty();
    public int size();
    private void resize(int);
    public void enqueue(Object);
    public Object dequeue();
    public Object peek();
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/ResizingArrayStack.class

package edu.princeton.cs.algs4;
public synchronized class ResizingArrayStack implements Iterable {
    private Object[] a;
    private int n;
    public void ResizingArrayStack();
    public boolean isEmpty();
    public int size();
    private void resize(int);
    public void push(Object);
    public Object pop();
    public Object peek();
    public java.util.Iterator iterator();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/ResizingArrayStack$ReverseArrayIterator.class

package edu.princeton.cs.algs4;
synchronized class ResizingArrayStack$ReverseArrayIterator implements java.util.Iterator {
    private int i;
    public void ResizingArrayStack$ReverseArrayIterator(ResizingArrayStack);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/RunLength.class

package edu.princeton.cs.algs4;
public synchronized class RunLength {
    private static final int R = 256;
    private static final int LG_R = 8;
    private void RunLength();
    public static void expand();
    public static void compress();
    public static void main(String[]);
}

edu/princeton/cs/algs4/SegmentTree.class

package edu.princeton.cs.algs4;
public synchronized class SegmentTree {
    private SegmentTree$Node[] heap;
    private int[] array;
    private int size;
    public void SegmentTree(int[]);
    public int size();
    private void build(int, int, int);
    public int rsq(int, int);
    private int rsq(int, int, int);
    public int rMinQ(int, int);
    private int rMinQ(int, int, int);
    public void update(int, int, int);
    private void update(int, int, int, int);
    private void propagate(int);
    private void change(SegmentTree$Node, int);
    private boolean contains(int, int, int, int);
    private boolean intersects(int, int, int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/SegmentTree$Node.class

package edu.princeton.cs.algs4;
synchronized class SegmentTree$Node {
    int sum;
    int min;
    Integer pendingVal;
    int from;
    int to;
    void SegmentTree$Node();
    int size();
}

edu/princeton/cs/algs4/Selection.class

package edu.princeton.cs.algs4;
public synchronized class Selection {
    private void Selection();
    public static void sort(Comparable[]);
    public static void sort(Object[], java.util.Comparator);
    private static boolean less(Comparable, Comparable);
    private static boolean less(java.util.Comparator, Object, Object);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static boolean isSorted(Comparable[], int, int);
    private static boolean isSorted(Object[], java.util.Comparator);
    private static boolean isSorted(Object[], java.util.Comparator, int, int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/SeparateChainingHashST.class

package edu.princeton.cs.algs4;
public synchronized class SeparateChainingHashST {
    private static final int INIT_CAPACITY = 4;
    private int n;
    private int m;
    private SequentialSearchST[] st;
    public void SeparateChainingHashST();
    public void SeparateChainingHashST(int);
    private void resize(int);
    private int hash(Object);
    public int size();
    public boolean isEmpty();
    public boolean contains(Object);
    public Object get(Object);
    public void put(Object, Object);
    public void delete(Object);
    public Iterable keys();
    public static void main(String[]);
}

edu/princeton/cs/algs4/SequentialSearchST.class

package edu.princeton.cs.algs4;
public synchronized class SequentialSearchST {
    private int n;
    private SequentialSearchST$Node first;
    public void SequentialSearchST();
    public int size();
    public boolean isEmpty();
    public boolean contains(Object);
    public Object get(Object);
    public void put(Object, Object);
    public void delete(Object);
    private SequentialSearchST$Node delete(SequentialSearchST$Node, Object);
    public Iterable keys();
    public static void main(String[]);
}

edu/princeton/cs/algs4/SequentialSearchST$Node.class

package edu.princeton.cs.algs4;
synchronized class SequentialSearchST$Node {
    private Object key;
    private Object val;
    private SequentialSearchST$Node next;
    public void SequentialSearchST$Node(SequentialSearchST, Object, Object, SequentialSearchST$Node);
}

edu/princeton/cs/algs4/SET.class

package edu.princeton.cs.algs4;
public synchronized class SET implements Iterable {
    private java.util.TreeSet set;
    public void SET();
    public void SET(SET);
    public void add(Comparable);
    public boolean contains(Comparable);
    public void delete(Comparable);
    public void remove(Comparable);
    public int size();
    public boolean isEmpty();
    public java.util.Iterator iterator();
    public Comparable max();
    public Comparable min();
    public Comparable ceiling(Comparable);
    public Comparable floor(Comparable);
    public SET union(SET);
    public SET intersects(SET);
    public boolean equals(Object);
    public int hashCode();
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Shell.class

package edu.princeton.cs.algs4;
public synchronized class Shell {
    private void Shell();
    public static void sort(Comparable[]);
    private static boolean less(Comparable, Comparable);
    private static void exch(Object[], int, int);
    private static boolean isSorted(Comparable[]);
    private static boolean isHsorted(Comparable[], int);
    private static void show(Comparable[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/SparseVector.class

package edu.princeton.cs.algs4;
public synchronized class SparseVector {
    private int d;
    private ST st;
    public void SparseVector(int);
    public void put(int, double);
    public double get(int);
    public int nnz();
    public int size();
    public int dimension();
    public double dot(SparseVector);
    public double dot(double[]);
    public double magnitude();
    public double norm();
    public SparseVector scale(double);
    public SparseVector plus(SparseVector);
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Stack$1.class

package edu.princeton.cs.algs4;
synchronized class Stack$1 {
}

edu/princeton/cs/algs4/Stack.class

package edu.princeton.cs.algs4;
public synchronized class Stack implements Iterable {
    private Stack$Node first;
    private int n;
    public void Stack();
    public boolean isEmpty();
    public int size();
    public void push(Object);
    public Object pop();
    public Object peek();
    public String toString();
    public java.util.Iterator iterator();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Stack$ListIterator.class

package edu.princeton.cs.algs4;
synchronized class Stack$ListIterator implements java.util.Iterator {
    private Stack$Node current;
    public void Stack$ListIterator(Stack, Stack$Node);
    public boolean hasNext();
    public void remove();
    public Object next();
}

edu/princeton/cs/algs4/Stack$Node.class

package edu.princeton.cs.algs4;
synchronized class Stack$Node {
    private Object item;
    private Stack$Node next;
    private void Stack$Node();
}

edu/princeton/cs/algs4/StaticSETofInts.class

package edu.princeton.cs.algs4;
public synchronized class StaticSETofInts {
    private int[] a;
    public void StaticSETofInts(int[]);
    public boolean contains(int);
    public int rank(int);
}

edu/princeton/cs/algs4/ST.class

package edu.princeton.cs.algs4;
public synchronized class ST implements Iterable {
    private java.util.TreeMap st;
    public void ST();
    public Object get(Comparable);
    public void put(Comparable, Object);
    public void delete(Comparable);
    public void remove(Comparable);
    public boolean contains(Comparable);
    public int size();
    public boolean isEmpty();
    public Iterable keys();
    public java.util.Iterator iterator();
    public Comparable min();
    public Comparable max();
    public Comparable ceiling(Comparable);
    public Comparable floor(Comparable);
    public static void main(String[]);
}

edu/princeton/cs/algs4/StdArrayIO.class

package edu.princeton.cs.algs4;
public synchronized class StdArrayIO {
    private void StdArrayIO();
    public static double[] readDouble1D();
    public static void print(double[]);
    public static double[][] readDouble2D();
    public static void print(double[][]);
    public static int[] readInt1D();
    public static void print(int[]);
    public static int[][] readInt2D();
    public static void print(int[][]);
    public static boolean[] readBoolean1D();
    public static void print(boolean[]);
    public static boolean[][] readBoolean2D();
    public static void print(boolean[][]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/StdAudio$1.class

package edu.princeton.cs.algs4;
final synchronized class StdAudio$1 implements Runnable {
    void StdAudio$1(String);
    public void run();
}

edu/princeton/cs/algs4/StdAudio$2.class

package edu.princeton.cs.algs4;
final synchronized class StdAudio$2 implements Runnable {
    void StdAudio$2();
    public void run();
}

edu/princeton/cs/algs4/StdAudio.class

package edu.princeton.cs.algs4;
public final synchronized class StdAudio {
    public static final int SAMPLE_RATE = 44100;
    private static final int BYTES_PER_SAMPLE = 2;
    private static final int BITS_PER_SAMPLE = 16;
    private static final double MAX_16_BIT = 32768.0;
    private static final int SAMPLE_BUFFER_SIZE = 4096;
    private static final int MONO = 1;
    private static final int STEREO = 2;
    private static final boolean LITTLE_ENDIAN = 0;
    private static final boolean BIG_ENDIAN = 1;
    private static final boolean SIGNED = 1;
    private static final boolean UNSIGNED = 0;
    private static javax.sound.sampled.SourceDataLine line;
    private static byte[] buffer;
    private static int bufferSize;
    private void StdAudio();
    private static void init();
    private static javax.sound.sampled.AudioInputStream getAudioInputStreamFromFile(String);
    public static void close();
    public static void play(double);
    public static void play(double[]);
    public static double[] read(String);
    public static void save(String, double[]);
    public static synchronized void play(String);
    private static void stream(javax.sound.sampled.AudioInputStream);
    public static synchronized void loop(String);
    private static double[] note(double, double, double);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/StdDraw.class

package edu.princeton.cs.algs4;
public final synchronized class StdDraw implements java.awt.event.ActionListener, java.awt.event.MouseListener, java.awt.event.MouseMotionListener, java.awt.event.KeyListener {
    public static final java.awt.Color BLACK;
    public static final java.awt.Color BLUE;
    public static final java.awt.Color CYAN;
    public static final java.awt.Color DARK_GRAY;
    public static final java.awt.Color GRAY;
    public static final java.awt.Color GREEN;
    public static final java.awt.Color LIGHT_GRAY;
    public static final java.awt.Color MAGENTA;
    public static final java.awt.Color ORANGE;
    public static final java.awt.Color PINK;
    public static final java.awt.Color RED;
    public static final java.awt.Color WHITE;
    public static final java.awt.Color YELLOW;
    public static final java.awt.Color BOOK_BLUE;
    public static final java.awt.Color BOOK_LIGHT_BLUE;
    public static final java.awt.Color BOOK_RED;
    public static final java.awt.Color PRINCETON_ORANGE;
    private static final java.awt.Color DEFAULT_PEN_COLOR;
    private static final java.awt.Color DEFAULT_CLEAR_COLOR;
    private static java.awt.Color penColor;
    private static final int DEFAULT_SIZE = 512;
    private static int width;
    private static int height;
    private static final double DEFAULT_PEN_RADIUS = 0.002;
    private static double penRadius;
    private static boolean defer;
    private static final double BORDER = 0.0;
    private static final double DEFAULT_XMIN = 0.0;
    private static final double DEFAULT_XMAX = 1.0;
    private static final double DEFAULT_YMIN = 0.0;
    private static final double DEFAULT_YMAX = 1.0;
    private static double xmin;
    private static double ymin;
    private static double xmax;
    private static double ymax;
    private static Object mouseLock;
    private static Object keyLock;
    private static final java.awt.Font DEFAULT_FONT;
    private static java.awt.Font font;
    private static java.awt.image.BufferedImage offscreenImage;
    private static java.awt.image.BufferedImage onscreenImage;
    private static java.awt.Graphics2D offscreen;
    private static java.awt.Graphics2D onscreen;
    private static StdDraw std;
    private static javax.swing.JFrame frame;
    private static boolean isMousePressed;
    private static double mouseX;
    private static double mouseY;
    private static java.util.LinkedList keysTyped;
    private static java.util.TreeSet keysDown;
    private void StdDraw();
    public static void setCanvasSize();
    public static void setCanvasSize(int, int);
    private static void init();
    private static javax.swing.JMenuBar createMenuBar();
    private static void validate(double, String);
    private static void validateNonnegative(double, String);
    private static void validateNotNull(Object, String);
    public static void setXscale();
    public static void setYscale();
    public static void setScale();
    public static void setXscale(double, double);
    public static void setYscale(double, double);
    public static void setScale(double, double);
    private static double scaleX(double);
    private static double scaleY(double);
    private static double factorX(double);
    private static double factorY(double);
    private static double userX(double);
    private static double userY(double);
    public static void clear();
    public static void clear(java.awt.Color);
    public static double getPenRadius();
    public static void setPenRadius();
    public static void setPenRadius(double);
    public static java.awt.Color getPenColor();
    public static void setPenColor();
    public static void setPenColor(java.awt.Color);
    public static void setPenColor(int, int, int);
    public static java.awt.Font getFont();
    public static void setFont();
    public static void setFont(java.awt.Font);
    public static void line(double, double, double, double);
    private static void pixel(double, double);
    public static void point(double, double);
    public static void circle(double, double, double);
    public static void filledCircle(double, double, double);
    public static void ellipse(double, double, double, double);
    public static void filledEllipse(double, double, double, double);
    public static void arc(double, double, double, double, double);
    public static void square(double, double, double);
    public static void filledSquare(double, double, double);
    public static void rectangle(double, double, double, double);
    public static void filledRectangle(double, double, double, double);
    public static void polygon(double[], double[]);
    public static void filledPolygon(double[], double[]);
    private static java.awt.Image getImage(String);
    public static void picture(double, double, String);
    public static void picture(double, double, String, double);
    public static void picture(double, double, String, double, double);
    public static void picture(double, double, String, double, double, double);
    public static void text(double, double, String);
    public static void text(double, double, String, double);
    public static void textLeft(double, double, String);
    public static void textRight(double, double, String);
    public static void show(int);
    public static void pause(int);
    public static void show();
    private static void draw();
    public static void enableDoubleBuffering();
    public static void disableDoubleBuffering();
    public static void save(String);
    public void actionPerformed(java.awt.event.ActionEvent);
    public static boolean isMousePressed();
    public static boolean mousePressed();
    public static double mouseX();
    public static double mouseY();
    public void mouseClicked(java.awt.event.MouseEvent);
    public void mouseEntered(java.awt.event.MouseEvent);
    public void mouseExited(java.awt.event.MouseEvent);
    public void mousePressed(java.awt.event.MouseEvent);
    public void mouseReleased(java.awt.event.MouseEvent);
    public void mouseDragged(java.awt.event.MouseEvent);
    public void mouseMoved(java.awt.event.MouseEvent);
    public static boolean hasNextKeyTyped();
    public static char nextKeyTyped();
    public static boolean isKeyPressed(int);
    public void keyTyped(java.awt.event.KeyEvent);
    public void keyPressed(java.awt.event.KeyEvent);
    public void keyReleased(java.awt.event.KeyEvent);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/StdDraw$RetinaImageIcon.class

package edu.princeton.cs.algs4;
synchronized class StdDraw$RetinaImageIcon extends javax.swing.ImageIcon {
    public void StdDraw$RetinaImageIcon(java.awt.Image);
    public int getIconWidth();
    public int getIconHeight();
    public synchronized void paintIcon(java.awt.Component, java.awt.Graphics, int, int);
}

edu/princeton/cs/algs4/StdIn.class

package edu.princeton.cs.algs4;
public final synchronized class StdIn {
    private static final String CHARSET_NAME = UTF-8;
    private static final java.util.Locale LOCALE;
    private static final java.util.regex.Pattern WHITESPACE_PATTERN;
    private static final java.util.regex.Pattern EMPTY_PATTERN;
    private static final java.util.regex.Pattern EVERYTHING_PATTERN;
    private static java.util.Scanner scanner;
    private void StdIn();
    public static boolean isEmpty();
    public static boolean hasNextLine();
    public static boolean hasNextChar();
    public static String readLine();
    public static char readChar();
    public static String readAll();
    public static String readString();
    public static int readInt();
    public static double readDouble();
    public static float readFloat();
    public static long readLong();
    public static short readShort();
    public static byte readByte();
    public static boolean readBoolean();
    public static String[] readAllStrings();
    public static String[] readAllLines();
    public static int[] readAllInts();
    public static long[] readAllLongs();
    public static double[] readAllDoubles();
    private static void resync();
    private static void setScanner(java.util.Scanner);
    public static int[] readInts();
    public static double[] readDoubles();
    public static String[] readStrings();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/StdOut.class

package edu.princeton.cs.algs4;
public final synchronized class StdOut {
    private static final String CHARSET_NAME = UTF-8;
    private static final java.util.Locale LOCALE;
    private static java.io.PrintWriter out;
    private void StdOut();
    public static void println();
    public static void println(Object);
    public static void println(boolean);
    public static void println(char);
    public static void println(double);
    public static void println(float);
    public static void println(int);
    public static void println(long);
    public static void println(short);
    public static void println(byte);
    public static void print();
    public static void print(Object);
    public static void print(boolean);
    public static void print(char);
    public static void print(double);
    public static void print(float);
    public static void print(int);
    public static void print(long);
    public static void print(short);
    public static void print(byte);
    public static transient void printf(String, Object[]);
    public static transient void printf(java.util.Locale, String, Object[]);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/StdRandom.class

package edu.princeton.cs.algs4;
public final synchronized class StdRandom {
    private static java.util.Random random;
    private static long seed;
    private void StdRandom();
    public static void setSeed(long);
    public static long getSeed();
    public static double uniform();
    public static int uniform(int);
    public static long uniform(long);
    public static double random();
    public static int uniform(int, int);
    public static double uniform(double, double);
    public static boolean bernoulli(double);
    public static boolean bernoulli();
    public static double gaussian();
    public static double gaussian(double, double);
    public static int geometric(double);
    public static int poisson(double);
    public static double pareto();
    public static double pareto(double);
    public static double cauchy();
    public static int discrete(double[]);
    public static int discrete(int[]);
    public static double exp(double);
    public static void shuffle(Object[]);
    public static void shuffle(double[]);
    public static void shuffle(int[]);
    public static void shuffle(char[]);
    public static void shuffle(Object[], int, int);
    public static void shuffle(double[], int, int);
    public static void shuffle(int[], int, int);
    public static int[] permutation(int);
    public static int[] permutation(int, int);
    private static void validateNotNull(Object);
    private static void validateSubarrayIndices(int, int, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/StdStats.class

package edu.princeton.cs.algs4;
public final synchronized class StdStats {
    private void StdStats();
    public static double max(double[]);
    public static double max(double[], int, int);
    public static int max(int[]);
    public static double min(double[]);
    public static double min(double[], int, int);
    public static int min(int[]);
    public static double mean(double[]);
    public static double mean(double[], int, int);
    public static double mean(int[]);
    public static double var(double[]);
    public static double var(double[], int, int);
    public static double var(int[]);
    public static double varp(double[]);
    public static double varp(double[], int, int);
    public static double stddev(double[]);
    public static double stddev(int[]);
    public static double stddev(double[], int, int);
    public static double stddevp(double[]);
    public static double stddevp(double[], int, int);
    private static double sum(double[]);
    private static double sum(double[], int, int);
    private static int sum(int[]);
    public static void plotPoints(double[]);
    public static void plotLines(double[]);
    public static void plotBars(double[]);
    private static void validateNotNull(Object);
    private static void validateSubarrayIndices(int, int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Stopwatch.class

package edu.princeton.cs.algs4;
public synchronized class Stopwatch {
    private final long start;
    public void Stopwatch();
    public double elapsedTime();
    public static void main(String[]);
}

edu/princeton/cs/algs4/StopwatchCPU.class

package edu.princeton.cs.algs4;
public synchronized class StopwatchCPU {
    private static final double NANOSECONDS_PER_SECOND = 1.0E9;
    private final management.ThreadMXBean threadTimer;
    private final long start;
    public void StopwatchCPU();
    public double elapsedTime();
    public static void main(String[]);
}

edu/princeton/cs/algs4/SuffixArray$1.class

package edu.princeton.cs.algs4;
synchronized class SuffixArray$1 {
}

edu/princeton/cs/algs4/SuffixArray.class

package edu.princeton.cs.algs4;
public synchronized class SuffixArray {
    private SuffixArray$Suffix[] suffixes;
    public void SuffixArray(String);
    public int length();
    public int index(int);
    public int lcp(int);
    private static int lcpSuffix(SuffixArray$Suffix, SuffixArray$Suffix);
    public String select(int);
    public int rank(String);
    private static int compare(String, SuffixArray$Suffix);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/SuffixArray$Suffix.class

package edu.princeton.cs.algs4;
synchronized class SuffixArray$Suffix implements Comparable {
    private final String text;
    private final int index;
    private void SuffixArray$Suffix(String, int);
    private int length();
    private char charAt(int);
    public int compareTo(SuffixArray$Suffix);
    public String toString();
}

edu/princeton/cs/algs4/SuffixArrayX.class

package edu.princeton.cs.algs4;
public synchronized class SuffixArrayX {
    private static final int CUTOFF = 5;
    private final char[] text;
    private final int[] index;
    private final int n;
    public void SuffixArrayX(String);
    private void sort(int, int, int);
    private void insertion(int, int, int);
    private boolean less(int, int, int);
    private void exch(int, int);
    public int length();
    public int index(int);
    public int lcp(int);
    private int lcp(int, int);
    public String select(int);
    public int rank(String);
    private int compare(String, int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/SymbolDigraph.class

package edu.princeton.cs.algs4;
public synchronized class SymbolDigraph {
    private ST st;
    private String[] keys;
    private Digraph graph;
    public void SymbolDigraph(String, String);
    public boolean contains(String);
    public int index(String);
    public int indexOf(String);
    public String name(int);
    public String nameOf(int);
    public Digraph G();
    public Digraph digraph();
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/SymbolGraph.class

package edu.princeton.cs.algs4;
public synchronized class SymbolGraph {
    private ST st;
    private String[] keys;
    private Graph graph;
    public void SymbolGraph(String, String);
    public boolean contains(String);
    public int index(String);
    public int indexOf(String);
    public String name(int);
    public String nameOf(int);
    public Graph G();
    public Graph graph();
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TarjanSCC.class

package edu.princeton.cs.algs4;
public synchronized class TarjanSCC {
    private boolean[] marked;
    private int[] id;
    private int[] low;
    private int pre;
    private int count;
    private Stack stack;
    public void TarjanSCC(Digraph);
    private void dfs(Digraph, int);
    public int count();
    public boolean stronglyConnected(int, int);
    public int id(int);
    private boolean check(Digraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/ThreeSum.class

package edu.princeton.cs.algs4;
public synchronized class ThreeSum {
    private void ThreeSum();
    public static void printAll(int[]);
    public static int count(int[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/ThreeSumFast.class

package edu.princeton.cs.algs4;
public synchronized class ThreeSumFast {
    private void ThreeSumFast();
    private static boolean containsDuplicates(int[]);
    public static void printAll(int[]);
    public static int count(int[]);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TopM.class

package edu.princeton.cs.algs4;
public synchronized class TopM {
    private void TopM();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Topological.class

package edu.princeton.cs.algs4;
public synchronized class Topological {
    private Iterable order;
    private int[] rank;
    public void Topological(Digraph);
    public void Topological(EdgeWeightedDigraph);
    public Iterable order();
    public boolean hasOrder();
    public boolean isDAG();
    public int rank(int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TopologicalX.class

package edu.princeton.cs.algs4;
public synchronized class TopologicalX {
    private Queue order;
    private int[] ranks;
    public void TopologicalX(Digraph);
    public void TopologicalX(EdgeWeightedDigraph);
    public Iterable order();
    public boolean hasOrder();
    public int rank(int);
    private boolean check(Digraph);
    private boolean check(EdgeWeightedDigraph);
    private void validateVertex(int);
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/Transaction.class

package edu.princeton.cs.algs4;
public synchronized class Transaction implements Comparable {
    private final String who;
    private final Date when;
    private final double amount;
    public void Transaction(String, Date, double);
    public void Transaction(String);
    public String who();
    public Date when();
    public double amount();
    public String toString();
    public int compareTo(Transaction);
    public boolean equals(Object);
    public int hashCode();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Transaction$HowMuchOrder.class

package edu.princeton.cs.algs4;
public synchronized class Transaction$HowMuchOrder implements java.util.Comparator {
    public void Transaction$HowMuchOrder();
    public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/Transaction$WhenOrder.class

package edu.princeton.cs.algs4;
public synchronized class Transaction$WhenOrder implements java.util.Comparator {
    public void Transaction$WhenOrder();
    public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/Transaction$WhoOrder.class

package edu.princeton.cs.algs4;
public synchronized class Transaction$WhoOrder implements java.util.Comparator {
    public void Transaction$WhoOrder();
    public int compare(Transaction, Transaction);
}

edu/princeton/cs/algs4/TransitiveClosure.class

package edu.princeton.cs.algs4;
public synchronized class TransitiveClosure {
    private DirectedDFS[] tc;
    public void TransitiveClosure(Digraph);
    public boolean reachable(int, int);
    private void validateVertex(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TrieSET$1.class

package edu.princeton.cs.algs4;
synchronized class TrieSET$1 {
}

edu/princeton/cs/algs4/TrieSET.class

package edu.princeton.cs.algs4;
public synchronized class TrieSET implements Iterable {
    private static final int R = 256;
    private TrieSET$Node root;
    private int n;
    public void TrieSET();
    public boolean contains(String);
    private TrieSET$Node get(TrieSET$Node, String, int);
    public void add(String);
    private TrieSET$Node add(TrieSET$Node, String, int);
    public int size();
    public boolean isEmpty();
    public java.util.Iterator iterator();
    public Iterable keysWithPrefix(String);
    private void collect(TrieSET$Node, StringBuilder, Queue);
    public Iterable keysThatMatch(String);
    private void collect(TrieSET$Node, StringBuilder, String, Queue);
    public String longestPrefixOf(String);
    private int longestPrefixOf(TrieSET$Node, String, int, int);
    public void delete(String);
    private TrieSET$Node delete(TrieSET$Node, String, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TrieSET$Node.class

package edu.princeton.cs.algs4;
synchronized class TrieSET$Node {
    private TrieSET$Node[] next;
    private boolean isString;
    private void TrieSET$Node();
}

edu/princeton/cs/algs4/TrieST$1.class

package edu.princeton.cs.algs4;
synchronized class TrieST$1 {
}

edu/princeton/cs/algs4/TrieST.class

package edu.princeton.cs.algs4;
public synchronized class TrieST {
    private static final int R = 256;
    private TrieST$Node root;
    private int n;
    public void TrieST();
    public Object get(String);
    public boolean contains(String);
    private TrieST$Node get(TrieST$Node, String, int);
    public void put(String, Object);
    private TrieST$Node put(TrieST$Node, String, Object, int);
    public int size();
    public boolean isEmpty();
    public Iterable keys();
    public Iterable keysWithPrefix(String);
    private void collect(TrieST$Node, StringBuilder, Queue);
    public Iterable keysThatMatch(String);
    private void collect(TrieST$Node, StringBuilder, String, Queue);
    public String longestPrefixOf(String);
    private int longestPrefixOf(TrieST$Node, String, int, int);
    public void delete(String);
    private TrieST$Node delete(TrieST$Node, String, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TrieST$Node.class

package edu.princeton.cs.algs4;
synchronized class TrieST$Node {
    private Object val;
    private TrieST$Node[] next;
    private void TrieST$Node();
}

edu/princeton/cs/algs4/TST$1.class

package edu.princeton.cs.algs4;
synchronized class TST$1 {
}

edu/princeton/cs/algs4/TST.class

package edu.princeton.cs.algs4;
public synchronized class TST {
    private int n;
    private TST$Node root;
    public void TST();
    public int size();
    public boolean contains(String);
    public Object get(String);
    private TST$Node get(TST$Node, String, int);
    public void put(String, Object);
    private TST$Node put(TST$Node, String, Object, int);
    public String longestPrefixOf(String);
    public Iterable keys();
    public Iterable keysWithPrefix(String);
    private void collect(TST$Node, StringBuilder, Queue);
    public Iterable keysThatMatch(String);
    private void collect(TST$Node, StringBuilder, int, String, Queue);
    public static void main(String[]);
}

edu/princeton/cs/algs4/TST$Node.class

package edu.princeton.cs.algs4;
synchronized class TST$Node {
    private char c;
    private TST$Node left;
    private TST$Node mid;
    private TST$Node right;
    private Object val;
    private void TST$Node();
}

edu/princeton/cs/algs4/TwoPersonZeroSumGame.class

package edu.princeton.cs.algs4;
public synchronized class TwoPersonZeroSumGame {
    private static final double EPSILON = 1.0E-8;
    private final int m;
    private final int n;
    private LinearProgramming lp;
    private double constant;
    public void TwoPersonZeroSumGame(double[][]);
    public double value();
    private double scale();
    public double[] row();
    public double[] column();
    private boolean isPrimalFeasible();
    private boolean isDualFeasible();
    private boolean isNashEquilibrium(double[][]);
    private boolean certifySolution(double[][]);
    private static void test(String, double[][]);
    private static void test1();
    private static void test2();
    private static void test3();
    private static void test4();
    private static void test5();
    public static void main(String[]);
    static void <clinit>();
}

edu/princeton/cs/algs4/UF.class

package edu.princeton.cs.algs4;
public synchronized class UF {
    private int[] parent;
    private byte[] rank;
    private int count;
    public void UF(int);
    public int find(int);
    public int count();
    public boolean connected(int, int);
    public void union(int, int);
    private void validate(int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/Vector.class

package edu.princeton.cs.algs4;
public synchronized class Vector {
    private int d;
    private double[] data;
    public void Vector(int);
    public transient void Vector(double[]);
    public int length();
    public int dimension();
    public double dot(Vector);
    public double magnitude();
    public double distanceTo(Vector);
    public Vector plus(Vector);
    public Vector minus(Vector);
    public double cartesian(int);
    public Vector times(double);
    public Vector scale(double);
    public Vector direction();
    public String toString();
    public static void main(String[]);
}

edu/princeton/cs/algs4/WeightedQuickUnionUF.class

package edu.princeton.cs.algs4;
public synchronized class WeightedQuickUnionUF {
    private int[] parent;
    private int[] size;
    private int count;
    public void WeightedQuickUnionUF(int);
    public int count();
    public int find(int);
    public boolean connected(int, int);
    private void validate(int);
    public void union(int, int);
    public static void main(String[]);
}

edu/princeton/cs/algs4/WhiteFilter.class

package edu.princeton.cs.algs4;
public synchronized class WhiteFilter {
    private void WhiteFilter();
    public static void main(String[]);
}

edu/princeton/cs/algs4/Whitelist.class

package edu.princeton.cs.algs4;
public synchronized class Whitelist {
    private void Whitelist();
    public static void main(String[]);
}

TestAlgs4.java

TestAlgs4.java

/******************************************************************************
 *  Compilation:  javac-algs4 TestAlgs4.java
 *  Execution:    java-algs4 TestAlgs4 n
 *  
 *  Simulates the motion of n hard disks, subject to the laws of elastic
 *  collisions. This program is intended to test that algs4.jar is properly
 *  installed.
 * 
 ******************************************************************************/

import  edu . princeton . cs . algs4 . CollisionSystem ;
import  edu . princeton . cs . algs4 . Particle ;
import  edu . princeton . cs . algs4 . StdDraw ;

public   class   TestAlgs4   {
     public   static   void  main ( String []  args )   {
         int  n  =   20 ;    // number of particles (default 20)
         if   ( args . length  ==   1 )   {
            n  =   Integer . parseInt ( args [ 0 ]);
         }

         // enable double buffering to support animations
         StdDraw . enableDoubleBuffering ();

         // create the n particles
         Particle []  particles  =   new   Particle [ n ];
         for   ( int  i  =   0 ;  i  <  n ;  i ++ )   {
            particles [ i ]   =   new   Particle ();
         }

         // simulate the system
         CollisionSystem  system  =   new   CollisionSystem ( particles );
        system . simulate ( Double . POSITIVE_INFINITY );
     }
}

TestAlgs4.class

public synchronized class TestAlgs4 {
    public void TestAlgs4();
    public static void main(String[]);
}