├── .gitignore ├── .idea └── .gitignore ├── LICENSE.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── mouredev │ │ └── weeklychallenge2022 │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── mouredev │ │ │ └── weeklychallenge2022 │ │ │ ├── Challenge0.kt │ │ │ ├── Challenge1.kt │ │ │ ├── Challenge10.kt │ │ │ ├── Challenge11.kt │ │ │ ├── Challenge12.kt │ │ │ ├── Challenge13.kt │ │ │ ├── Challenge14.kt │ │ │ ├── Challenge15.kt │ │ │ ├── Challenge16.kt │ │ │ ├── Challenge17.kt │ │ │ ├── Challenge18.kt │ │ │ ├── Challenge19.kt │ │ │ ├── Challenge2.kt │ │ │ ├── Challenge20.kt │ │ │ ├── Challenge21.kt │ │ │ ├── Challenge21.txt │ │ │ ├── Challenge22.kt │ │ │ ├── Challenge23.kt │ │ │ ├── Challenge24.kt │ │ │ ├── Challenge25.kt │ │ │ ├── Challenge26.kt │ │ │ ├── Challenge27.kt │ │ │ ├── Challenge28.kt │ │ │ ├── Challenge29.kt │ │ │ ├── Challenge3.kt │ │ │ ├── Challenge30.kt │ │ │ ├── Challenge31.kt │ │ │ ├── Challenge32.kt │ │ │ ├── Challenge33.kt │ │ │ ├── Challenge34.kt │ │ │ ├── Challenge35.kt │ │ │ ├── Challenge36.kt │ │ │ ├── Challenge37.kt │ │ │ ├── Challenge38.kt │ │ │ ├── Challenge39.kt │ │ │ ├── Challenge4.kt │ │ │ ├── Challenge40.kt │ │ │ ├── Challenge41.kt │ │ │ ├── Challenge42.kt │ │ │ ├── Challenge43.kt │ │ │ ├── Challenge44.kt │ │ │ ├── Challenge45.kt │ │ │ ├── Challenge46.kt │ │ │ ├── Challenge47.kt │ │ │ ├── Challenge48.kt │ │ │ ├── Challenge49.kt │ │ │ ├── Challenge5.kt │ │ │ ├── Challenge50.kt │ │ │ ├── Challenge51.kt │ │ │ ├── Challenge5Activity.kt │ │ │ ├── Challenge6.kt │ │ │ ├── Challenge7.kt │ │ │ ├── Challenge8.kt │ │ │ ├── Challenge9.kt │ │ │ └── Readme.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_challenge5.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── mouredev │ └── weeklychallenge2022 │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/android,androidstudio,kotlin 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=android,androidstudio,kotlin 4 | 5 | ### Android ### 6 | # Built application files 7 | *.apk 8 | *.aar 9 | *.ap_ 10 | *.aab 11 | 12 | # Files for the ART/Dalvik VM 13 | *.dex 14 | 15 | # Java class files 16 | *.class 17 | 18 | # Generated files 19 | bin/ 20 | gen/ 21 | out/ 22 | # Uncomment the following line in case you need and you don't have the release build type files in your app 23 | # release/ 24 | 25 | # Gradle files 26 | .gradle/ 27 | build/ 28 | 29 | # Local configuration file (sdk path, etc) 30 | local.properties 31 | 32 | # Proguard folder generated by Eclipse 33 | proguard/ 34 | 35 | # Log Files 36 | *.log 37 | 38 | # Android Studio Navigation editor temp files 39 | .navigation/ 40 | 41 | # Android Studio captures folder 42 | captures/ 43 | 44 | # IntelliJ 45 | *.iml 46 | .idea/workspace.xml 47 | .idea/tasks.xml 48 | .idea/gradle.xml 49 | .idea/assetWizardSettings.xml 50 | .idea/dictionaries 51 | .idea/libraries 52 | .idea/jarRepositories.xml 53 | # Android Studio 3 in .gitignore file. 54 | .idea/caches 55 | .idea/modules.xml 56 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 57 | .idea/navEditor.xml 58 | 59 | # Keystore files 60 | # Uncomment the following lines if you do not want to check your keystore files in. 61 | #*.jks 62 | #*.keystore 63 | 64 | # External native build folder generated in Android Studio 2.2 and later 65 | .externalNativeBuild 66 | .cxx/ 67 | 68 | # Google Services (e.g. APIs or Firebase) 69 | # google-services.json 70 | 71 | # Freeline 72 | freeline.py 73 | freeline/ 74 | freeline_project_description.json 75 | 76 | # fastlane 77 | fastlane/report.xml 78 | fastlane/Preview.html 79 | fastlane/screenshots 80 | fastlane/test_output 81 | fastlane/readme.md 82 | 83 | # Version control 84 | vcs.xml 85 | 86 | # lint 87 | lint/intermediates/ 88 | lint/generated/ 89 | lint/outputs/ 90 | lint/tmp/ 91 | # lint/reports/ 92 | 93 | # Android Profiling 94 | *.hprof 95 | 96 | ### Android Patch ### 97 | gen-external-apklibs 98 | output.json 99 | 100 | # Replacement of .externalNativeBuild directories introduced 101 | # with Android Studio 3.5. 102 | 103 | ### Kotlin ### 104 | # Compiled class file 105 | 106 | # Log file 107 | 108 | # BlueJ files 109 | *.ctxt 110 | 111 | # Mobile Tools for Java (J2ME) 112 | .mtj.tmp/ 113 | 114 | # Package Files # 115 | *.jar 116 | *.war 117 | *.nar 118 | *.ear 119 | *.zip 120 | *.tar.gz 121 | *.rar 122 | 123 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 124 | hs_err_pid* 125 | 126 | ### AndroidStudio ### 127 | # Covers files to be ignored for android development using Android Studio. 128 | 129 | # Built application files 130 | 131 | # Files for the ART/Dalvik VM 132 | 133 | # Java class files 134 | 135 | # Generated files 136 | 137 | # Gradle files 138 | .gradle 139 | 140 | # Signing files 141 | .signing/ 142 | 143 | # Local configuration file (sdk path, etc) 144 | 145 | # Proguard folder generated by Eclipse 146 | 147 | # Log Files 148 | 149 | # Android Studio 150 | /*/build/ 151 | /*/local.properties 152 | /*/out 153 | /*/*/build 154 | /*/*/production 155 | *.ipr 156 | *~ 157 | *.swp 158 | 159 | # Keystore files 160 | *.jks 161 | *.keystore 162 | 163 | # Google Services (e.g. APIs or Firebase) 164 | # google-services.json 165 | 166 | # Android Patch 167 | 168 | # External native build folder generated in Android Studio 2.2 and later 169 | 170 | # NDK 171 | obj/ 172 | 173 | # IntelliJ IDEA 174 | *.iws 175 | /out/ 176 | 177 | # User-specific configurations 178 | .idea/caches/ 179 | .idea/libraries/ 180 | .idea/shelf/ 181 | .idea/.name 182 | .idea/compiler.xml 183 | .idea/copyright/profiles_settings.xml 184 | .idea/encodings.xml 185 | .idea/misc.xml 186 | .idea/scopes/scope_settings.xml 187 | .idea/vcs.xml 188 | .idea/jsLibraryMappings.xml 189 | .idea/datasources.xml 190 | .idea/dataSources.ids 191 | .idea/sqlDataSources.xml 192 | .idea/dynamic.xml 193 | .idea/uiDesigner.xml 194 | 195 | # OS-specific files 196 | .DS_Store 197 | .DS_Store? 198 | ._* 199 | .Spotlight-V100 200 | .Trashes 201 | ehthumbs.db 202 | Thumbs.db 203 | 204 | # Legacy Eclipse project files 205 | .classpath 206 | .project 207 | .cproject 208 | .settings/ 209 | 210 | # Mobile Tools for Java (J2ME) 211 | 212 | # Package Files # 213 | 214 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) 215 | 216 | ## Plugin-specific files: 217 | 218 | # mpeltonen/sbt-idea plugin 219 | .idea_modules/ 220 | 221 | # JIRA plugin 222 | atlassian-ide-plugin.xml 223 | 224 | # Mongo Explorer plugin 225 | .idea/mongoSettings.xml 226 | 227 | # Crashlytics plugin (for Android Studio and IntelliJ) 228 | com_crashlytics_export_strings.xml 229 | crashlytics.properties 230 | crashlytics-build.properties 231 | fabric.properties 232 | 233 | ### AndroidStudio Patch ### 234 | 235 | !/gradle/wrapper/gradle-wrapper.jar 236 | 237 | # End of https://www.toptal.com/developers/gitignore/api/android,androidstudio,kotlin -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Retos de programación semanales 2022 2 | ## Proyecto de retos semanales de la comunidad **[MoureDev](https://moure.dev)** para practicar lógica de programación. 3 | ### Todos nuestros retos en **[retosdeprogramacion.com/semanales2022](https://retosdeprogramacion.com/semanales2022)** 4 | 5 | 6 | 7 | Si quieres realizar los retos de programación en Swift, utiliza el siguiente repositorio. 8 | 9 | [![GitHub Kotlin](https://img.shields.io/github/stars/mouredev/Weekly-Challenge-2022-Swift?label=Repositorio%20retos%20Semanales%20en%20Swift&style=social)](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin) 10 | 11 | También puedes unirte a nuestra actividad mensual de creación de aplicaciones. 12 | 13 | [![GitHub App](https://img.shields.io/github/stars/mouredev/Monthly-App-Challenge-2022?label=Repositorio%20retos%20Mensuales&style=social)](https://github.com/mouredev/Monthly-App-Challenge-2022) 14 | 15 | ## Información importante 16 | 17 | El proyecto principal de retos de programación semanales se ha creado utilizando Android Studio y resolviendo cada uno de los ejercicio utilizando el lenguaje de programación Kotlin (ya que lo utilizo frecuentemente, su sintáxis es simple y tenía que elegir alguno como ejemplo 😁). 18 | 19 | [![Kotlin](https://img.shields.io/badge/Kotlin-1.5-purple?longCache=true&style=popout-square)](https://kotlinlang.org) 20 | [![Android Studio](https://img.shields.io/badge/Android_Studio-4.2-blue.svg?longCache=true&style=popout-square)](https://developer.android.com/studio) 21 | [![Android](https://img.shields.io/badge/Android-6-green.svg?longCache=true&style=popout-square)](https://www.android.com) 22 | 23 | Puedes utilizar **cualquier lenguaje** para resolver los retos. Tienes soluciones de la comunidad usando todo tipo de lenguajes en la sección de **[Pull Requests](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/pulls)**. 24 | 25 | Tienes toda la información extendida sobre los retos de programación semanales y mensuales en **[retosdeprogramacion.com](https://retosdeprogramacion.com/)**. 26 | 27 | ## Vídeo explicación retos 28 | 29 | 30 | 31 | ## Listado de retos 32 | 33 | ### [Aquí](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/tree/main/app/src/main/java/com/mouredev/weeklychallenge2022) tienes un fichero con el enunciado y el código para cada reto 34 | 35 | * **#0** - 27/12/21 - [`EL FAMOSO "FIZZ BUZZ"`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge0.kt) 36 | * **#1** - 03/01/22 - [`¿ES UN ANAGRAMA?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge1.kt) 37 | * **#2** - 10/01/22 - [`LA SUCESIÓN DE FIBONACCI`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge2.kt) 38 | * **#3** - 17/01/22 - [`¿ES UN NÚMERO PRIMO?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge3.kt) 39 | * **#4** - 24/01/22 - [`ÁREA DE UN POLÍGONO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge4.kt) 40 | * **#5** - 01/02/22 - [`ASPECT RATIO DE UNA IMAGEN`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge5.kt) 41 | * **#6** - 07/02/22 - [`INVIRTIENDO CADENAS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge6.kt) 42 | * **#7** - 14/02/22 - [`CONTANDO PALABRAS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge7.kt) 43 | * **#8** - 18/02/22 - [`DECIMAL A BINARIO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge8.kt) 44 | * **#9** - 02/03/22 - [`CÓDIGO MORSE`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge9.kt) 45 | * **#10** - 07/03/22 - [`EXPRESIONES EQUILIBRADAS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge10.kt) 46 | * **#11** - 14/03/22 - [`ELIMINANDO CARACTERES`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge11.kt) 47 | * **#12** - 21/03/22 - [`¿ES UN PALÍNDROMO?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge12.kt) 48 | * **#13** - 28/03/22 - [`FACTORIAL RECURSIVO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge13.kt) 49 | * **#14** - 04/04/22 - [`¿ES UN NÚMERO DE ARMSTRONG?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge14.kt) 50 | * **#15** - 11/04/22 - [`¿CUÁNTOS DÍAS?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge15.kt) 51 | * **#16** - 18/04/22 - [`EN MAYÚSCULA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge16.kt) 52 | * **#17** - 25/04/22 - [`LA CARRERA DE OBSTÁCULOS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge17.kt) 53 | * **#18** - 02/05/22 - [`TRES EN RAYA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge18.kt) 54 | * **#19** - 09/05/22 - [`CONVERSOR TIEMPO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge19.kt) 55 | * **#20** - 16/05/22 - [`PARANDO EL TIEMPO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge20.kt) 56 | * **#21** - 23/05/22 - [`CALCULADORA .TXT` ](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge21.kt) 57 | * **#22** - 01/06/22 - [`CONJUNTOS` ](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge22.kt) 58 | * **#23** - 07/06/22 - [`MÁXIMO COMÚN DIVISOR Y MÍNIMO COMÚN MÚLTIPLO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge23.kt) 59 | * **#24** - 13/06/22 - [`ITERATION MASTER` ](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge24.kt) 60 | * **#25** - 20/06/22 - [`PIEDRA, PAPEL, TIJERA` ](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge25.kt) 61 | * **#26** - 27/06/22 - [`CUADRADO Y TRIÁNGULO 2D` ](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge26.kt) 62 | * **#27** - 07/07/22 - [`VECTORES ORTOGONALES`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge27.kt) 63 | * **#28** - 11/07/22 - [`MÁQUINA EXPENDEDORA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge28.kt) 64 | * **#29** - 18/07/22 - [`ORDENA LA LISTA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge29.kt) 65 | * **#30** - 26/07/22 - [`MARCO DE PALABRAS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge30.kt) 66 | * **#31** - 01/08/22 - [`AÑOS BISIESTOS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge31.kt) 67 | * **#32** - 08/08/22 - [`EL SEGUNDO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge32.kt) 68 | * **#33** - 15/08/22 - [`CICLO SEXAGENARIO CHINO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge33.kt) 69 | * **#34** - 22/08/22 - [`LOS NÚMEROS PERDIDOS`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge34.kt) 70 | * **#35** - 29/08/22 - [`BATALLA POKÉMON`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge35.kt) 71 | * **#36** - 06/09/22 - [`LOS ANILLOS DE PODER`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge36.kt) 72 | * **#37** - 14/09/22 - [`LOS LANZAMIENTOS DE "THE LEGEND OF ZELDA"`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge37.kt) 73 | * **#38** - 19/09/22 - [`BINARIO A DECIMAL`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge38.kt) 74 | * **#39** - 27/09/22 - [`TOP ALGORITMOS: QUICK SORT`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge39.kt) 75 | * **#40** - 03/10/22 - [`TRIÁNGULO DE PASCAL`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge40.kt) 76 | * **#41** - 10/10/22 - [`LA LEY DE OHM`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge41.kt) 77 | * **#42** - 17/10/22 - [`CONVERSOR DE TEMPERATURA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge42.kt) 78 | * **#43** - 24/10/22 - [`TRUCO O TRATO`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge43.kt) 79 | * **#44** - 02/11/22 - [`BUMERANES`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge44.kt) 80 | * **#45** - 07/11/22 - [`CONTENEDOR DE AGUA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge45.kt) 81 | * **#46** - 14/11/22 - [`¿DÓNDE ESTÁ EL ROBOT?`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge46.kt) 82 | * **#47** - 21/11/22 - [`VOCAL MÁS COMÚN`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge47.kt) 83 | * **#48** - 28/11/22 - [`EL CALENDARIO DE ADEVIENTO 2022`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge48.kt) 84 | * **#49** - 05/12/22 - [`EL DETECTOR DE HANDLES`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge49.kt) 85 | * **#50** - 12/12/22 - [`LA ENCRIPTACIÓN DE KARACA`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt) 86 | * **#51** - 19/12/22 - [`EL RETO RANDOM`](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge51.kt) 87 | 88 | > **[🆕ACCEDE A LOS NUEVOS RETOS SEMANALES PARA 2023](https://github.com/mouredev/retos-programacion-2023)** 89 | 90 | 91 | 92 | *Corrección retos del 0 al 4 en vídeo* 93 | 94 | 95 | 96 | *Corrección retos del 5 al 10 en vídeo* 97 | 98 | 99 | 100 | *Corección retos del 11 al 20 en vídeo* 101 | 102 | 103 | 104 | *Corección retos del 21 al 30 en vídeo* 105 | 106 | 107 | 108 | *Corección retos del 31 al 40 en vídeo* 109 | 110 | 111 | 112 | *Corección retos del 41 al 46 en vídeo* 113 | 114 | 115 | 116 | *Corección retos del 47 al 51 en vídeo* 117 | 118 | ### ¿Cómo puedo participar? 119 | 120 | **Puedes hacer libremente un fork del proyecto y trabajar con Git para ir sincronizando las actualizaciones del proyecto.** 121 | 122 | * Cada lunes se publicará un nuevo reto de código. 123 | * Cada reto será un nuevo fichero dentro de `app/src/main/java/com/mouredev/weeklychallenge2022` donde se indicará la fecha, el enunciado y la información necesaria para llevarlo a cabo. 124 | * Se comunicará en el canal `#🔁reto-semanal` de [Discord](https://mouredev.com/discord), en directo desde [Twitch](https://twitch.tv/mouredev) y se subirá el enunciado al [repositorio](https://github.com/mouredev/Weekly-Challenge-2022-Kotlin). 125 | * Dispondrás de una semana para resolverlo, preguntar tus dudas, debatir y aportar ayuda en el canal de Discord. 126 | * El lunes siguiente se subirá la resolución al repositorio, se comentará en directo desde Twitch (utilizando alguna solución de entre los asistentes o que se haya realizado una pull request al proyecto) y se añadirá el nuevo reto semanal. 127 | * Comenzará de nuevo el proceso. 128 | 129 | *Si no dispones de un editor de código como Android Studio, puedes usar un playground online ([https://play.kotlinlang.org/](https://play.kotlinlang.org/)) para probar tu código.* 130 | 131 | *Si utilizas un editor como Android Studio o semejante, puedes ejecutar el código creando un bloque `fun main() { }` y pulsando el símbolo "play ►" en el lateral.* 132 | 133 | > fun main() { 134 | > 135 | > } 136 | 137 | #### Puedes apoyar mi trabajo haciendo "☆ Star" en el repo o nominarme a "GitHub Star". ¡Gracias! 138 | 139 | [![GitHub Star](https://img.shields.io/badge/GitHub-Nominar_a_star-yellow?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://stars.github.com/nominate/) 140 | 141 | Si quieres unirte a nuestra comunidad de desarrollo, aprender programación de Apps, mejorar tus habilidades y ayudar a la continuidad del proyecto, puedes encontrarnos en: 142 | 143 | [![Twitch](https://img.shields.io/badge/Twitch-Retos_en_directo-9146FF?style=for-the-badge&logo=twitch&logoColor=white&labelColor=101010)](https://twitch.tv/mouredev) 144 | [![Discord](https://img.shields.io/badge/Discord-Canal_de_chat_para_retos-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=101010)](https://mouredev.com/discord) 145 | [![Link](https://img.shields.io/badge/Links_de_interés-moure.dev-39E09B?style=for-the-badge&logo=Linktree&logoColor=white&labelColor=101010)](https://mouredev.com) 146 | 147 | ### Cómo trabajar con Git y GitHub de forma colaborativa 148 | 149 | Deberás realizar flujos de actualización, sincronización y `pull request` desde tu `fork` del proyecto hacia el principal (habitualmente nombrado como `upstream/main`). 150 | Todo esto se puede hacer desde línea de comandos, pero si prefieres puedes usar clientes gráficos como [GitHub Desktop](https://desktop.github.com/) (muy simple) o [GitKraken](https://www.gitkraken.com/invite/cZWhJq1v) (más avanzado y potente). 151 | 152 | * Desde tu repo en la propia web de GitHub podrás realizar muchas acciones. 153 | * Si te resulta más fácil, puedes crear una `branch`(rama) para resolver cada reto y así simplificar la `pull request`. También puedes ignorar ciertos ficheros. 154 | * Resuelve el ejercicio y realiza `commit` y `push` del mismo a tu proyecto. 155 | * Desde GitHub, una vez hecho el `fork` verás opciones como "Contribute" o "Fetch upstream": 156 | * `Contribute` permite abrir una `pull request`(deberás seleccionar el mío como repositorio base contra el que comparar tu proyecto). Así yo podré ver los ficheros modificados de tu proyecto con la solución a los retos. Intenta que el título de la `pull request` siga esta convención: **"Solución Reto #[número del reto] [Lenguaje]" (Solución Reto #0 Kotlin)**. 157 | * `Fetch upstream` permite sincronizar tu proyecto con el original en caso de que se haya actualizado. 158 | * Para sincronizar tu proyecto con el original y mantenerlo actualizado también puedes hacer un `merge commit`, `squash merge` o `rebase`(ten en cuenta que cada uno se comporta de una manera, conservando o no tus propios cambios). 159 | * Una vez se publique el nuevo reto, la solución del anterior, y comente las soluciones, cerraré las pasadas `pull request` para dejar paso a las que se hagan para el nuevo reto. 160 | 161 | ## ![https://mouredev.com](https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_emote.png) Hola, mi nombre es Brais Moure. 162 | ### Freelance full-stack iOS & Android engineer 163 | 164 | [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCxPD7bsocoAMq8Dj18kmGyQ?style=social)](https://youtube.com/mouredevapps?sub_confirmation=1) 165 | [![Twitch Status](https://img.shields.io/twitch/status/mouredev?style=social)](https://twitch.com/mouredev) 166 | [![Discord](https://img.shields.io/discord/729672926432985098?style=social&label=Discord&logo=discord)](https://mouredev.com/discord) 167 | [![Twitter Follow](https://img.shields.io/twitter/follow/mouredev?style=social)](https://twitter.com/mouredev) 168 | ![GitHub Followers](https://img.shields.io/github/followers/mouredev?style=social) 169 | 170 | Soy ingeniero de software desde hace más de 12 años. Desde hace 4 años combino mi trabajo desarrollando Apps con creación de contenido formativo sobre programación y tecnología en diferentes redes sociales como **[@mouredev](https://moure.dev)**. 171 | 172 | ### En mi perfil de GitHub tienes más información 173 | 174 | [![Web](https://img.shields.io/badge/GitHub-MoureDev-14a1f0?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://github.com/mouredev) -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | } 5 | 6 | android { 7 | compileSdk 31 8 | 9 | defaultConfig { 10 | applicationId "com.mouredev.weeklychallenge2022" 11 | minSdk 26 12 | targetSdk 31 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | compileOptions { 26 | sourceCompatibility JavaVersion.VERSION_1_8 27 | targetCompatibility JavaVersion.VERSION_1_8 28 | } 29 | kotlinOptions { 30 | jvmTarget = '1.8' 31 | } 32 | namespace 'com.mouredev.weeklychallenge2022' 33 | } 34 | 35 | dependencies { 36 | 37 | implementation 'androidx.core:core-ktx:1.7.0' 38 | implementation 'androidx.appcompat:appcompat:1.4.0' 39 | implementation 'com.google.android.material:material:1.4.0' 40 | implementation 'androidx.constraintlayout:constraintlayout:2.1.3' 41 | testImplementation 'junit:junit:4.+' 42 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 43 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 44 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/mouredev/weeklychallenge2022/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.mouredev.weeklychallenge2022", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge0.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #0 5 | * EL FAMOSO "FIZZ BUZZ" 6 | * Fecha publicación enunciado: 27/12/21 7 | * Fecha publicación resolución: 03/01/22 8 | * Dificultad: FÁCIL 9 | * Enunciado: Escribe un programa que muestre por consola (con un print) los números de 1 a 100 (ambos incluidos y con un salto de línea entre cada impresión), sustituyendo los siguientes: 10 | * - Múltiplos de 3 por la palabra "fizz". 11 | * - Múltiplos de 5 por la palabra "buzz". 12 | * - Múltiplos de 3 y de 5 a la vez por la palabra "fizzbuzz". 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | 24 | for (index in 1..100) { 25 | val divisibleByThree = index % 3 == 0 26 | val divisibleByFive = index % 5 == 0 27 | if (divisibleByThree && divisibleByFive) { 28 | println("fizzbuzz") 29 | } else if (divisibleByThree) { 30 | println("fizz") 31 | } else if (divisibleByFive) { 32 | println("buzz") 33 | } else { 34 | println(index) 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge1.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #1 5 | * ¿ES UN ANAGRAMA? 6 | * Fecha publicación enunciado: 03/01/22 7 | * Fecha publicación resolución: 10/01/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Escribe una función que reciba dos palabras (String) y retorne verdadero o falso (Boolean) según sean o no anagramas. 11 | * Un Anagrama consiste en formar una palabra reordenando TODAS las letras de otra palabra inicial. 12 | * NO hace falta comprobar que ambas palabras existan. 13 | * Dos palabras exactamente iguales no son anagrama. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | println(isAnagram("amor", "roma")) 25 | } 26 | 27 | private fun isAnagram(wordOne: String, wordTwo: String): Boolean { 28 | if (wordOne.lowercase() == wordTwo.lowercase()) { 29 | return false 30 | } 31 | return wordOne.lowercase().toCharArray().sortedArray().contentEquals(wordTwo.lowercase().toCharArray().sortedArray()) 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge10.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #10 5 | * EXPRESIONES EQUILIBRADAS 6 | * Fecha publicación enunciado: 07/03/22 7 | * Fecha publicación resolución: 14/03/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un programa que comprueba si los paréntesis, llaves y corchetes de una expresión están equilibrados. 11 | * - Equilibrado significa que estos delimitadores se abren y cieran en orden y de forma correcta. 12 | * - Paréntesis, llaves y corchetes son igual de prioritarios. No hay uno más importante que otro. 13 | * - Expresión balanceada: { [ a * ( c + d ) ] - 5 } 14 | * - Expresión no balanceada: { a * ( c + d ) ] - 5 } 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 18 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 19 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 20 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 21 | * 22 | */ 23 | 24 | fun main() { 25 | println(isBalanced("{a + b [c] * (2x2)}}}}")) 26 | println(isBalanced("{ [ a * ( c + d ) ] - 5 }")) 27 | println(isBalanced("{ a * ( c + d ) ] - 5 }")) 28 | println(isBalanced("{a^4 + (((ax4)}")) 29 | println(isBalanced("{ ] a * ( c + d ) + ( 2 - 3 )[ - 5 }")) 30 | println(isBalanced("{{{{{{(}}}}}}")) 31 | println(isBalanced("(a")) 32 | } 33 | 34 | private fun isBalanced(expression: String): Boolean { 35 | 36 | val symbols = mapOf("{" to "}", "[" to "]", "(" to ")") 37 | val stack = arrayListOf() 38 | 39 | expression.forEach { 40 | 41 | val symbol = it.toString() 42 | val containsKey = symbols.containsKey(symbol) 43 | 44 | if (containsKey || symbols.containsValue(symbol)) { 45 | if (containsKey) { 46 | stack.add(symbol) 47 | } else if (stack.isEmpty() || symbol != symbols[stack.removeLast()]) { 48 | return false 49 | } 50 | } 51 | } 52 | 53 | return stack.isEmpty() 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge11.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #11 5 | * ELIMINANDO CARACTERES 6 | * Fecha publicación enunciado: 14/03/22 7 | * Fecha publicación resolución: 21/03/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que reciba dos cadenas como parámetro (str1, str2) e imprima otras dos cadenas como salida (out1, out2). 11 | * - out1 contendrá todos los caracteres presentes en la str1 pero NO estén presentes en str2. 12 | * - out2 contendrá todos los caracteres presentes en la str2 pero NO estén presentes en str1. 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | printNonCommon("brais","moure") 24 | printNonCommon("Me gusta Java","Me gusta Kotlin") 25 | printNonCommon("Usa el canal de nuestro discord (https://mouredev.com/discord) \"\uD83D\uDD01reto-semanal\" para preguntas, dudas o prestar ayuda a la comunidad", 26 | "Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada.") 27 | 28 | // Otra solución utilizando funciones de orden superior 29 | printNonCommonWithFilter("Usa el canal de nuestro discord (https://mouredev.com/discord) \"\uD83D\uDD01reto-semanal\" para preguntas, dudas o prestar ayuda a la comunidad", 30 | "Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada.") 31 | } 32 | 33 | private fun printNonCommon(str1: String, str2: String) { 34 | println("out1: ${findNonCommon(str1, str2)}") 35 | println("out2: ${findNonCommon(str2, str1)}") 36 | } 37 | 38 | private fun findNonCommon(str1: String, str2: String): String { 39 | 40 | var out = "" 41 | 42 | str1.lowercase().forEach { 43 | if (!str2.lowercase().contains(it)) { 44 | out += it 45 | } 46 | } 47 | 48 | return out 49 | } 50 | 51 | private fun printNonCommonWithFilter(str1: String, str2: String) { 52 | println("out1: ${str1.lowercase().filter { !str2.lowercase().contains(it) }}") 53 | println("out2: ${str2.lowercase().filter { !str1.lowercase().contains(it) }}") 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge12.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.Normalizer 4 | 5 | /* 6 | * Reto #12 7 | * ¿ES UN PALÍNDROMO? 8 | * Fecha publicación enunciado: 21/03/22 9 | * Fecha publicación resolución: 28/03/22 10 | * Dificultad: MEDIA 11 | * 12 | * Enunciado: Escribe una función que reciba un texto y retorne verdadero o falso (Boolean) según sean o no palíndromos. 13 | * Un Palíndromo es una palabra o expresión que es igual si se lee de izquierda a derecha que de derecha a izquierda. 14 | * NO se tienen en cuenta los espacios, signos de puntuación y tildes. 15 | * Ejemplo: Ana lleva al oso la avellana. 16 | * 17 | * Información adicional: 18 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 19 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 20 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 21 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 22 | * 23 | */ 24 | 25 | fun main() { 26 | println(isPalindrome("Ana lleva al oso la avellana.")) 27 | println(isPalindrome("Adivina ya te opina, ya ni miles origina, ya ni cetro me domina, ya ni monarcas, a repaso ni mulato carreta, acaso nicotina, ya ni cita vecino, anima cocina, pedazo gallina, cedazo terso nos retoza de canilla goza, de pánico camina, ónice vaticina, ya ni tocino saca, a terracota luminosa pera, sacra nómina y ánimo de mortecina, ya ni giros elimina, ya ni poeta, ya ni vida")) 28 | println(isPalindrome("¿Qué os ha parecido el reto?")) 29 | } 30 | 31 | private fun isPalindrome(text: String): Boolean { 32 | 33 | val normalizedText = Normalizer.normalize(text.lowercase(), Normalizer.Form.NFD) 34 | .replace("[^\\p{ASCII}]".toRegex(), "") 35 | .replace("[^a-z0-9]".toRegex(), "") 36 | return normalizedText == normalizedText.reversed() 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge13.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #13 5 | * FACTORIAL RECURSIVO 6 | * Fecha publicación enunciado: 28/03/22 7 | * Fecha publicación resolución: 04/04/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Escribe una función que calcule y retorne el factorial de un número dado de forma recursiva. 11 | * 12 | * Información adicional: 13 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 14 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 15 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 16 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 17 | * 18 | */ 19 | 20 | fun main() { 21 | println(factorial(0) ?:run { "No tiene factorial" }) 22 | println(factorial(7) ?:run { "No tiene factorial" }) 23 | println(factorial(10) ?:run { "No tiene factorial" }) 24 | println(factorial(1) ?:run { "No tiene factorial" }) 25 | println(factorial(-1) ?:run { "No tiene factorial" }) 26 | } 27 | 28 | private fun factorial(n: Int): Int? { 29 | return if (n < 0) null else if (n <= 1) 1 else n * (factorial(n - 1)!!) 30 | } 31 | 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge14.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import kotlin.math.pow 4 | 5 | /* 6 | * Reto #14 7 | * ¿ES UN NÚMERO DE ARMSTRONG? 8 | * Fecha publicación enunciado: 04/04/22 9 | * Fecha publicación resolución: 11/04/22 10 | * Dificultad: FÁCIL 11 | * 12 | * Enunciado: Escribe una función que calcule si un número dado es un número de Amstrong (o también llamado narcisista). 13 | * Si no conoces qué es un número de Armstrong, debes buscar información al respecto. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | println(isArmstrong(371)) 25 | println(isArmstrong(-371)) 26 | println(isArmstrong(372)) 27 | println(isArmstrong(0)) 28 | } 29 | 30 | private fun isArmstrong(number: Int): Boolean { 31 | 32 | return if (number < 0) { 33 | false 34 | } else { 35 | var sum = 0 36 | val powValue = number.toString().length 37 | 38 | number.toString().forEach { character -> 39 | sum += character.toString().toDouble().pow(powValue).toInt() 40 | } 41 | 42 | number == sum 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge15.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.ParseException 4 | import java.text.SimpleDateFormat 5 | import java.util.concurrent.TimeUnit 6 | import kotlin.math.absoluteValue 7 | 8 | /* 9 | * Reto #15 10 | * ¿CUÁNTOS DÍAS? 11 | * Fecha publicación enunciado: 11/04/22 12 | * Fecha publicación resolución: 18/04/22 13 | * Dificultad: DIFÍCIL 14 | * 15 | * Enunciado: Crea una función que calcule y retorne cuántos días hay entre dos cadenas de texto que representen fechas. 16 | * - Una cadena de texto que representa una fecha tiene el formato "dd/MM/yyyy". 17 | * - La función recibirá dos String y retornará un Int. 18 | * - La diferencia en días será absoluta (no importa el orden de las fechas). 19 | * - Si una de las dos cadenas de texto no representa una fecha correcta se lanzará una excepción. 20 | * 21 | * Información adicional: 22 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 23 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 24 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 25 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 26 | * 27 | */ 28 | 29 | fun main() { 30 | 31 | printDaysBetween("18/05/2022", "29/05/2022") 32 | printDaysBetween("mouredev", "29/04/2022") 33 | printDaysBetween("18/5/2022", "29/04/2022") 34 | } 35 | 36 | private fun printDaysBetween(firstDate: String, secondDate: String) { 37 | try { 38 | println(daysBetween(firstDate, secondDate)) 39 | } catch (e: DaysBetweenError) { 40 | println("Error en el formato de alguna fecha") 41 | } catch (e: Exception) { 42 | println("Error en el parse de alguna fecha") 43 | } 44 | } 45 | 46 | class DaysBetweenError: Exception() 47 | 48 | private fun daysBetween(firstDate: String, secondDate: String): Int { 49 | 50 | val formatter = SimpleDateFormat("dd/MM/yyyy") 51 | val firstParsedDate = formatter.parse(firstDate) 52 | val secondParsedDate = formatter.parse(secondDate) 53 | 54 | val regex = "^([0-9]){2}[/]([0-9]){2}[/]([0-9]){4}$".toRegex() 55 | 56 | if (firstParsedDate != null 57 | && secondParsedDate != null 58 | && firstDate.contains(regex) 59 | && secondDate.contains(regex) 60 | ) { 61 | 62 | return TimeUnit.DAYS.convert( 63 | firstParsedDate.time - secondParsedDate.time, 64 | TimeUnit.MILLISECONDS 65 | ).toInt().absoluteValue 66 | } 67 | throw DaysBetweenError() 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge16.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #16 5 | * EN MAYÚSCULA 6 | * Fecha publicación enunciado: 18/04/22 7 | * Fecha publicación resolución: 25/04/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que reciba un String de cualquier tipo y se encargue de 11 | * poner en mayúscula la primera letra de cada palabra. 12 | * - No se pueden utilizar operaciones del lenguaje que lo resuelvan directamente. 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | println(capitalize("¿hola qué tal estás?")) 24 | println(capitalize("¿hola qué tal estás?")) 25 | println(capitalize("El niño ñoño")) 26 | } 27 | 28 | private fun capitalize(text: String): String { 29 | 30 | var capitalizedText = text 31 | 32 | text.replace("[^A-zÀ-ú]".toRegex(), " ").split(" ").forEach { word -> 33 | capitalizedText = capitalizedText.replace(word, word.replaceFirstChar { it.uppercase() }) 34 | } 35 | 36 | return capitalizedText 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge17.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #17 5 | * LA CARRERA DE OBSTÁCULOS 6 | * Fecha publicación enunciado: 25/04/22 7 | * Fecha publicación resolución: 02/05/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea una función que evalúe si un/a atleta ha superado correctamente una 11 | * carrera de obstáculos. 12 | * - La función recibirá dos parámetros: 13 | * - Un array que sólo puede contener String con las palabras "run" o "jump" 14 | * - Un String que represente la pista y sólo puede contener "_" (suelo) o "|" (valla) 15 | * - La función imprimirá cómo ha finalizado la carrera: 16 | * - Si el/a atleta hace "run" en "_" (suelo) y "jump" en "|" (valla) será correcto y no 17 | * variará el símbolo de esa parte de la pista. 18 | * - Si hace "jump" en "_" (suelo), se variará la pista por "x". 19 | * - Si hace "run" en "|" (valla), se variará la pista por "/". 20 | * - La función retornará un Boolean que indique si ha superado la carrera. 21 | * Para ello tiene que realizar la opción correcta en cada tramo de la pista. 22 | * 23 | * Información adicional: 24 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 25 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 26 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 27 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 28 | * 29 | */ 30 | 31 | fun main() { 32 | println(checkRace(listOf(AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN), "_|_|_")) 33 | println(checkRace(listOf(AthleteState.RUN, AthleteState.RUN, AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN), "_|_|_")) 34 | println(checkRace(listOf(AthleteState.RUN, AthleteState.RUN, AthleteState.JUMP, AthleteState.JUMP, AthleteState.RUN), "_|_|_")) 35 | println(checkRace(listOf(AthleteState.RUN, AthleteState.RUN, AthleteState.JUMP, AthleteState.JUMP, AthleteState.RUN), "_|_|_|_")) 36 | println(checkRace(listOf(AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN, AthleteState.JUMP), "_|_|_")) 37 | println(checkRace(listOf(AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN, AthleteState.JUMP, AthleteState.RUN), "_|_|_")) 38 | println(checkRace(listOf(AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP), "|||||")) 39 | println(checkRace(listOf(AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP, AthleteState.JUMP), "||?||")) 40 | } 41 | 42 | 43 | private enum class AthleteState(val segment: String) { 44 | RUN("_"), 45 | JUMP("|") 46 | } 47 | 48 | private fun checkRace(athlete: List, track: String) : Boolean { 49 | 50 | val totalActions = if (athlete.count() > track.count()) athlete.count() else track.count() 51 | val minActions = if (athlete.count() > track.count()) track.count() else athlete.count() 52 | 53 | val trackSegments = track.toList() 54 | 55 | var athleteTrack = "" 56 | 57 | for (index in (0 until totalActions)) { 58 | athleteTrack += if (index >= minActions) { 59 | "?" 60 | } else { 61 | val segment = trackSegments[index] 62 | when(val state = athlete[index]) { 63 | AthleteState.RUN -> if (segment.toString() == state.segment) state.segment else "/" 64 | AthleteState.JUMP -> if (segment.toString() == state.segment) state.segment else "x" 65 | } 66 | } 67 | } 68 | 69 | println(athleteTrack) 70 | 71 | return track == athleteTrack 72 | } 73 | 74 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge18.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import kotlin.math.absoluteValue 4 | 5 | /* 6 | * Reto #18 7 | * TRES EN RAYA 8 | * Fecha publicación enunciado: 02/05/22 9 | * Fecha publicación resolución: 09/05/22 10 | * Dificultad: DIFÍCIL 11 | * 12 | * Enunciado: Crea una función que analice una matriz 3x3 compuesta por "X" y "O" y retorne lo siguiente: 13 | * - "X" si han ganado las "X" 14 | * - "O" si han ganado los "O" 15 | * - "Empate" si ha habido un empate 16 | * - "Nulo" si la proporción de "X", de "O", o de la matriz no es correcta. O si han ganado los 2. 17 | * Nota: La matriz puede no estar totalmente cubierta. Se podría representar con un vacío "", por ejemplo. 18 | * 19 | * Información adicional: 20 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 21 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 22 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 23 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 24 | * 25 | */ 26 | 27 | fun main() { 28 | 29 | println(checkTicTacToe(arrayOf( 30 | arrayOf(TicTacToeValue.X, TicTacToeValue.O, TicTacToeValue.X), 31 | arrayOf(TicTacToeValue.O, TicTacToeValue.X, TicTacToeValue.O), 32 | arrayOf(TicTacToeValue.O, TicTacToeValue.O, TicTacToeValue.X)))) 33 | 34 | println(checkTicTacToe(arrayOf( 35 | arrayOf(TicTacToeValue.EMPTY, TicTacToeValue.O, TicTacToeValue.X), 36 | arrayOf(TicTacToeValue.EMPTY, TicTacToeValue.X, TicTacToeValue.O), 37 | arrayOf(TicTacToeValue.EMPTY, TicTacToeValue.O, TicTacToeValue.X)))) 38 | 39 | println(checkTicTacToe(arrayOf( 40 | arrayOf(TicTacToeValue.O, TicTacToeValue.O, TicTacToeValue.O), 41 | arrayOf(TicTacToeValue.O, TicTacToeValue.X, TicTacToeValue.X), 42 | arrayOf(TicTacToeValue.O, TicTacToeValue.X, TicTacToeValue.X)))) 43 | 44 | println(checkTicTacToe(arrayOf( 45 | arrayOf(TicTacToeValue.X, TicTacToeValue.O, TicTacToeValue.X), 46 | arrayOf(TicTacToeValue.X, TicTacToeValue.X, TicTacToeValue.O), 47 | arrayOf(TicTacToeValue.X, TicTacToeValue.X, TicTacToeValue.X)))) 48 | } 49 | 50 | private enum class TicTacToeValue { 51 | X, O, EMPTY 52 | } 53 | 54 | private enum class TicTacToeResult { 55 | X, O, DRAW, NULL 56 | } 57 | 58 | private fun checkTicTacToe(board: Array>): TicTacToeResult { 59 | 60 | // Null 61 | 62 | if (board.count() != 3) { 63 | return TicTacToeResult.NULL 64 | } 65 | 66 | var xCount = 0 67 | var oCount = 0 68 | 69 | var flatBoard: Array = emptyArray() 70 | for (row in board) { 71 | flatBoard += row 72 | 73 | if (row.count() != 3) { 74 | return TicTacToeResult.NULL 75 | } 76 | 77 | for (col in row) { 78 | if (col == TicTacToeValue.X) { 79 | xCount += 1 80 | } else if (col == TicTacToeValue.O) { 81 | oCount += 1 82 | } 83 | } 84 | } 85 | 86 | if ((xCount - oCount).absoluteValue > 1) { 87 | return TicTacToeResult.NULL 88 | } 89 | 90 | // Win or Draw 91 | 92 | val winCombinations = arrayOf( 93 | arrayOf(0, 1, 2), arrayOf(3, 4, 5), arrayOf(6, 7, 8), arrayOf(0, 3, 6), 94 | arrayOf(1, 4, 7), arrayOf(2, 5, 8), arrayOf(0, 4, 8), arrayOf(2, 4, 6)) 95 | 96 | var result = TicTacToeResult.DRAW 97 | 98 | for (winCombination in winCombinations) { 99 | 100 | if (flatBoard[winCombination[0]] != TicTacToeValue.EMPTY 101 | && flatBoard[winCombination[0]] == flatBoard[winCombination[1]] 102 | && flatBoard[winCombination[0]] == flatBoard[winCombination[2]]) { 103 | 104 | val winner = flatBoard[winCombination[0]] 105 | 106 | if (result != TicTacToeResult.DRAW 107 | && (if (result == TicTacToeResult.O) TicTacToeValue.O else TicTacToeValue.X) != winner) { 108 | return TicTacToeResult.NULL 109 | } 110 | 111 | result = if (winner == TicTacToeValue.X) TicTacToeResult.X else TicTacToeResult.O 112 | } 113 | } 114 | 115 | return result 116 | } 117 | 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge19.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #19 5 | * CONVERSOR TIEMPO 6 | * Fecha publicación enunciado: 09/05/22 7 | * Fecha publicación resolución: 16/05/22 8 | * Dificultad: FACIL 9 | * 10 | * Enunciado: Crea una función que reciba días, horas, minutos y segundos (como enteros) y retorne su resultado en milisegundos. 11 | * 12 | * Información adicional: 13 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 14 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 15 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 16 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 17 | * 18 | */ 19 | 20 | fun main() { 21 | println(timeToMillis(0, 0, 0, 10)) 22 | println(timeToMillis(2, 5, -45, 10)) 23 | println(timeToMillis(2000000000, 5, 45, 10)) 24 | } 25 | 26 | fun timeToMillis(days: Int, hours: Int, minutes: Int, seconds: Int): Long { 27 | 28 | val daysInMillis = days.toLong() * 24 * 60 * 60 * 1000 29 | val hoursInMillis = hours.toLong() * 60 * 60 * 1000 30 | val minutesInMillis = minutes.toLong() * 60 * 1000 31 | val secondsToMillis = seconds.toLong() * 1000 32 | 33 | return daysInMillis + hoursInMillis + minutesInMillis + secondsToMillis 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge2.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.math.BigInteger 4 | 5 | /* 6 | * Reto #2 7 | * LA SUCESIÓN DE FIBONACCI 8 | * Fecha publicación enunciado: 10/01/22 9 | * Fecha publicación resolución: 17/01/22 10 | * Dificultad: DIFÍCIL 11 | * 12 | * Enunciado: Escribe un programa que imprima los 50 primeros números de la sucesión de Fibonacci empezando en 0. 13 | * La serie Fibonacci se compone por una sucesión de números en la que el siguiente siempre es la suma de los dos anteriores. 14 | * 0, 1, 1, 2, 3, 5, 8, 13... 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 18 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 19 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 20 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 21 | * 22 | */ 23 | 24 | fun main() { 25 | 26 | var n0: Long = 0 27 | var n1: Long = 1 28 | 29 | (1..50).forEach { _ -> 30 | 31 | println(n0) 32 | 33 | val fib = n0 + n1 34 | n0 = n1 35 | n1 = fib 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge20.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #20 5 | * PARANDO EL TIEMPO 6 | * Fecha publicación enunciado: 16/05/22 7 | * Fecha publicación resolución: 23/05/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea una función que sume 2 números y retorne su resultado pasados unos segundos. 11 | * - Recibirá por parámetros los 2 números a sumar y los segundos que debe tardar en finalizar su ejecución. 12 | * - Si el lenguaje lo soporta, deberá retornar el resultado de forma asíncrona, es decir, sin detener la ejecución del programa principal. Se podría ejecutar varias veces al mismo tiempo. 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | 24 | asyncSum(5, 2, 10) { result -> 25 | println(result) 26 | } 27 | 28 | asyncSum(1, 3, 5) { result -> 29 | println(result) 30 | } 31 | } 32 | 33 | private fun asyncSum(numberOne: Int, numberTwo: Int, seconds: Int, result: (Int) -> Unit) { 34 | Thread { 35 | Thread.sleep((seconds * 1000).toLong()) 36 | result(numberOne + numberTwo) 37 | }.start() 38 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge21.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.io.File 4 | 5 | /* 6 | * Reto #21 7 | * CALCULADORA .TXT 8 | * Fecha publicación enunciado: 23/05/22 9 | * Fecha publicación resolución: 01/06/22 10 | * Dificultad: MEDIA 11 | * 12 | * Enunciado: Lee el fichero "Challenge21.txt" incluido en el proyecto, calcula su resultado e imprímelo. 13 | * - El .txt se corresponde con las entradas de una calculadora. 14 | * - Cada línea tendrá un número o una operación representada por un símbolo (alternando ambos). 15 | * - Soporta números enteros y decimales. 16 | * - Soporta las operaciones suma "+", resta "-", multiplicación "*" y división "/". 17 | * - El resultado se muestra al finalizar la lectura de la última línea (si el .txt es correcto). 18 | * - Si el formato del .txt no es correcto, se indicará que no se han podido resolver las operaciones. 19 | * 20 | * Información adicional: 21 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 22 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 23 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 24 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 25 | * 26 | */ 27 | 28 | fun main() { 29 | println(calculate("app/src/main/java/com/mouredev/weeklychallenge2022/Challenge21.txt")) 30 | } 31 | 32 | private fun calculate(filePath: String): String { 33 | 34 | var fileError = false 35 | var result: Double? = null 36 | var lastOperator: String? = null 37 | 38 | try { 39 | File(filePath).forEachLine { line -> 40 | 41 | line.toDoubleOrNull()?.let { number -> 42 | if (result == null) { 43 | result = number 44 | } else { 45 | when(lastOperator) { 46 | "+"-> { 47 | result = result?.plus(number) 48 | } 49 | "-"-> { 50 | result = result?.minus(number) 51 | } 52 | "*"-> { 53 | result = result?.times(number) 54 | } 55 | "/"-> { 56 | result = result?.div(number) 57 | } 58 | else -> { 59 | fileError = true 60 | return@forEachLine 61 | } 62 | } 63 | lastOperator = null 64 | } 65 | } ?: run { 66 | if (lastOperator == null) { 67 | lastOperator = line 68 | } else { 69 | fileError = true 70 | return@forEachLine 71 | } 72 | } 73 | } 74 | 75 | } catch (e: Exception) { 76 | fileError = true 77 | } 78 | 79 | return if (fileError || lastOperator != null) "No se han podido resolver las operaciones" else result!!.toString() 80 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge21.txt: -------------------------------------------------------------------------------- 1 | 5 2 | + 3 | 2 4 | - 5 | 1 6 | * 7 | 8 8 | - 9 | 15 10 | + 11 | 4 12 | / 13 | 2 -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge22.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #22 5 | * CONJUNTOS 6 | * Fecha publicación enunciado: 01/06/22 7 | * Fecha publicación resolución: 07/06/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que reciba dos array, un booleano y retorne un array. 11 | * - Si el booleano es verdadero buscará y retornará los elementos comunes de los dos array. 12 | * - Si el booleano es falso buscará y retornará los elementos no comunes de los dos array. 13 | * - No se pueden utilizar operaciones del lenguaje que lo resuelvan directamente. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | println(calculateSet(listOf(1, 2, 3, 3, 4), listOf(2, 2, 3, 3, 3, 4, 6), true)) 25 | println(calculateSet(listOf(1, 2, 3, 3, 4), listOf(2, 2, 3, 3, 3, 4, 6), false)) 26 | } 27 | 28 | private fun calculateSet(first: List, second: List, common: Boolean): List { 29 | 30 | val commonResult = mutableListOf() 31 | 32 | for (firstValue in first) { 33 | if (!commonResult.contains(firstValue)) { 34 | for (secondValue in second) { 35 | if (firstValue == secondValue && !commonResult.contains(firstValue)) { 36 | commonResult.add(firstValue) 37 | break 38 | } 39 | } 40 | } 41 | } 42 | 43 | return if (common) { 44 | commonResult 45 | } else { 46 | val nonCommonResult = mutableListOf() 47 | nonCommonResult.addAll(first) 48 | nonCommonResult.addAll(second) 49 | 50 | commonResult.forEach { commonValue -> 51 | nonCommonResult.removeAll { nonCommonValue -> 52 | commonValue == nonCommonValue 53 | } 54 | } 55 | 56 | nonCommonResult 57 | } 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge23.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #23 5 | * MÁXIMO COMÚN DIVISOR Y MÍNIMO COMÚN MÚLTIPLO 6 | * Fecha publicación enunciado: 07/06/22 7 | * Fecha publicación resolución: 13/06/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea dos funciones, una que calcule el máximo común divisor (MCD) y otra que calcule el mínimo común múltiplo (mcm) de dos números enteros. 11 | * - No se pueden utilizar operaciones del lenguaje que lo resuelvan directamente. 12 | * 13 | * Información adicional: 14 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 15 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 16 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 17 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 18 | * 19 | */ 20 | 21 | fun main() { 22 | println(mcd(56, 180)) 23 | println(mcdRecursive(56, 180)) 24 | println(mcm(56, 180)) 25 | } 26 | 27 | private fun mcd(firstNumber: Int, secondNumber: Int): Int { 28 | 29 | var a = firstNumber 30 | var b = secondNumber 31 | 32 | while (a != 0 && b != 0) { 33 | val temp = b 34 | b = a % b 35 | a = temp 36 | } 37 | 38 | return a + b 39 | } 40 | 41 | private fun mcm(firstNumber: Int, secondNumber: Int): Int { 42 | return (firstNumber * secondNumber) / mcd(firstNumber, secondNumber) 43 | } 44 | 45 | private fun mcdRecursive(firstNumber: Int, secondNumber: Int): Int { 46 | return if (firstNumber == 0 || secondNumber == 0) (firstNumber + secondNumber) 47 | else mcdRecursive(secondNumber, firstNumber % secondNumber) 48 | } 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge24.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #24 5 | * ITERATION MASTER 6 | * Fecha publicación enunciado: 13/06/22 7 | * Fecha publicación resolución: 20/06/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Quiero contar del 1 al 100 de uno en uno (imprimiendo cada uno). ¿De cuántas maneras eres capaz de hacerlo? Crea el código para cada una de ellas. 11 | * 12 | * Información adicional: 13 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 14 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 15 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 16 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 17 | * 18 | */ 19 | 20 | fun main() { 21 | 22 | // 1 23 | 24 | println("**** 1 ****") 25 | 26 | for (index in (1..100)) { 27 | println(index) 28 | } 29 | 30 | // 2 31 | 32 | println("**** 2 ****") 33 | 34 | (1..100).forEach { index -> 35 | println(index) 36 | } 37 | 38 | // 3 39 | 40 | println("**** 3 ****") 41 | 42 | var whileIndex = 1 43 | 44 | while (whileIndex <= 100) { 45 | println(whileIndex) 46 | whileIndex += 1 47 | } 48 | 49 | // 4 50 | 51 | println("**** 4 ****") 52 | 53 | whileIndex = 1 54 | 55 | do { 56 | println(whileIndex) 57 | whileIndex += 1 58 | } while (whileIndex <= 100) 59 | 60 | // 5 61 | 62 | println("**** 5 ****") 63 | 64 | fun print100(index: Int) { 65 | if (index <= 100) { 66 | println(index) 67 | print100(index + 1) 68 | } 69 | } 70 | 71 | print100(1) 72 | 73 | // 6 74 | 75 | println("**** 6 ****") 76 | 77 | println((1..100).filter { 78 | true 79 | }) 80 | 81 | // 7 82 | 83 | println("**** 7 ****") 84 | 85 | println((1..100).map { it }) 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge25.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #25 5 | * PIEDRA, PAPEL, TIJERA 6 | * Fecha publicación enunciado: 20/06/22 7 | * Fecha publicación resolución: 27/06/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un programa que calcule quien gana más partidas al piedra, papel, tijera. 11 | * - El resultado puede ser: "Player 1", "Player 2", "Tie" (empate) 12 | * - La función recibe un listado que contiene pares, representando cada jugada. 13 | * - El par puede contener combinaciones de "R" (piedra), "P" (papel) o "S" (tijera). 14 | * - Ejemplo. Entrada: [("R","S"), ("S","R"), ("P","S")]. Resultado: "Player 2". 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 18 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 19 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 20 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 21 | * 22 | */ 23 | 24 | fun main() { 25 | println(rockScissorsPaper(arrayListOf(Pair(Move.ROCK, Move.ROCK)))) 26 | println(rockScissorsPaper(arrayListOf(Pair(Move.ROCK, Move.SCISSORS)))) 27 | println(rockScissorsPaper(arrayListOf(Pair(Move.PAPER, Move.SCISSORS)))) 28 | println(rockScissorsPaper(arrayListOf( 29 | Pair(Move.ROCK, Move.ROCK), 30 | Pair(Move.SCISSORS, Move.SCISSORS), 31 | Pair(Move.PAPER, Move.PAPER)))) 32 | println(rockScissorsPaper(arrayListOf( 33 | Pair(Move.ROCK, Move.SCISSORS), 34 | Pair(Move.SCISSORS, Move.PAPER), 35 | Pair(Move.SCISSORS, Move.ROCK)))) 36 | println(rockScissorsPaper(arrayListOf( 37 | Pair(Move.ROCK, Move.PAPER), 38 | Pair(Move.SCISSORS, Move.ROCK), 39 | Pair(Move.PAPER, Move.SCISSORS)))) 40 | } 41 | 42 | enum class Move { 43 | ROCK, SCISSORS, PAPER 44 | } 45 | 46 | private fun rockScissorsPaper(games: List>): String { 47 | 48 | var playerOneGames = 0 49 | var playerTwoGames = 0 50 | 51 | games.forEach { game -> 52 | 53 | val playerOneMove = game.first 54 | val playerTwoMove = game.second 55 | 56 | if (playerOneMove != playerTwoMove) { 57 | 58 | if (playerOneMove == Move.ROCK && playerTwoMove == Move.SCISSORS 59 | || playerOneMove == Move.SCISSORS && playerTwoMove == Move.PAPER 60 | || playerOneMove == Move.PAPER && playerTwoMove == Move.ROCK) { 61 | 62 | playerOneGames += 1 63 | } else { 64 | playerTwoGames += 1 65 | } 66 | } 67 | } 68 | 69 | return if (playerOneGames == playerTwoGames) { 70 | "Tie" 71 | } else if (playerOneGames > playerTwoGames) { 72 | "Player 1" 73 | } else { 74 | "Player 2" 75 | } 76 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge26.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #26 5 | * CUADRADO Y TRIÁNGULO 2D 6 | * Fecha publicación enunciado: 27/06/22 7 | * Fecha publicación resolución: 07/07/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea un programa que dibuje un cuadrado o un triángulo con asteriscos "*". 11 | * - Indicaremos el tamaño del lado y si la figura a dibujar es una u otra. 12 | * - EXTRA: ¿Eres capaz de dibujar más figuras? 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | drawPolygon(10,PolygonType.SQUARE) 24 | drawPolygon(15,PolygonType.TRIANGLE) 25 | drawPolygon(12,PolygonType.DIAMOND) 26 | } 27 | 28 | private enum class PolygonType { 29 | SQUARE, TRIANGLE, DIAMOND 30 | } 31 | 32 | private fun drawPolygon(size: Int, type: PolygonType) { 33 | 34 | if (size < 2) { 35 | println("El tamaño debe ser mayor a 1") 36 | } 37 | 38 | var totalSize = size 39 | if (type == PolygonType.DIAMOND) { 40 | totalSize *= 2 41 | } 42 | 43 | for (value in 1..totalSize) { 44 | when (type) { 45 | PolygonType.SQUARE -> { 46 | println("* ".repeat(totalSize)) 47 | } 48 | PolygonType.TRIANGLE -> { 49 | println("* ".repeat(value)) 50 | } 51 | PolygonType.DIAMOND -> { 52 | if (value <= size) { 53 | println("* ".repeat(value)) 54 | } else { 55 | println("${" ".repeat(value - size)}${"* ".repeat(totalSize - value)}") 56 | } 57 | } 58 | } 59 | } 60 | 61 | println("") 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge27.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #27 5 | * VECTORES ORTOGONALES 6 | * Fecha publicación enunciado: 07/07/22 7 | * Fecha publicación resolución: 11/07/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea un programa que determine si dos vectores son ortogonales. 11 | * - Los dos array deben tener la misma longitud. 12 | * - Cada vector se podría representar como un array. Ejemplo: [1, -2] 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 17 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 18 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 19 | * 20 | */ 21 | 22 | fun main() { 23 | println(areOrthogonal(Pair(1, 2), Pair(2, 1))) 24 | println(areOrthogonal(Pair(2, 1), Pair(-1, 2))) 25 | } 26 | 27 | private fun areOrthogonal(vectorOne: Pair, vectorTwo: Pair): Boolean { 28 | return vectorOne.first * vectorTwo.first + vectorOne.second * vectorTwo.second == 0 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge28.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #28 5 | * MÁQUINA EXPENDEDORA 6 | * Fecha publicación enunciado: 11/07/22 7 | * Fecha publicación resolución: 18/07/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Simula el funcionamiento de una máquina expendedora creando una operación 11 | * que reciba dinero (array de monedas) y un número que indique la selección del producto. 12 | * - El programa retornará el nombre del producto y un array con el dinero de vuelta (con el menor 13 | * número de monedas). 14 | * - Si el dinero es insuficiente o el número de producto no existe, deberá indicarse con un mensaje 15 | * y retornar todas las monedas. 16 | * - Si no hay dinero de vuelta, el array se retornará vacío. 17 | * - Para que resulte más simple, trabajaremos en céntimos con monedas de 5, 10, 50, 100 y 200. 18 | * - Debemos controlar que las monedas enviadas estén dentro de las soportadas. 19 | * 20 | * Información adicional: 21 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 22 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 23 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 24 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 25 | * 26 | */ 27 | 28 | fun main() { 29 | 30 | println(buy(1, arrayOf(Money.FIVE, Money.FIVE, Money.TEN, Money.TEN, Money.TEN, Money.FIVE))) 31 | println(buy(3, arrayOf(Money.FIVE, Money.FIVE, Money.TEN, Money.TEN, Money.TEN, Money.FIVE))) 32 | println(buy(1, arrayOf(Money.FIVE, Money.FIVE, Money.TEN, Money.TEN, Money.TEN, Money.FIVE, Money.FIFTY))) 33 | println(buy(5, arrayOf(Money.TWOHUNDRED))) 34 | 35 | } 36 | 37 | enum class Money(val money: Int) { 38 | 39 | FIVE(5), 40 | TEN(10), 41 | FIFTY(50), 42 | ONEHUNDRED(100), 43 | TWOHUNDRED(200) 44 | 45 | } 46 | 47 | private fun buy(code: Int, money: Array): Pair> { 48 | 49 | val products = mapOf>( 50 | 1 to Pair("Agua", 50), 51 | 2 to Pair("Coca-Cola", 100), 52 | 4 to Pair("Cerveza", 155), 53 | 5 to Pair("Pizza", 200), 54 | 10 to Pair("Donut", 75) 55 | ) 56 | 57 | products[code]?.let { product -> 58 | 59 | var totalMoney = 0 60 | money.forEach { coin -> 61 | totalMoney += coin.money 62 | } 63 | 64 | if (totalMoney < product.second) { 65 | return Pair("El producto con código [${code}] tiene un coste ${product.second}. Has introducido ${totalMoney}.", money) 66 | } 67 | 68 | val pendingMoney = totalMoney - product.second 69 | 70 | return Pair(product.first, returnMoney(pendingMoney)) 71 | } 72 | 73 | return Pair("El producto con código [${code}] no existe.", money) 74 | } 75 | 76 | private fun returnMoney(pendingMoney: Int, money: Array = arrayOf()): Array { 77 | 78 | if (pendingMoney == 0) { 79 | return money 80 | } 81 | 82 | var newPendingMoney = pendingMoney 83 | val newMoney = money.toMutableList() 84 | 85 | for (coin in Money.values().reversed()) { 86 | if (coin.money <= pendingMoney) { 87 | newPendingMoney -= coin.money 88 | newMoney.add(coin) 89 | break 90 | } 91 | } 92 | 93 | return returnMoney(newPendingMoney, newMoney.toTypedArray()) 94 | } 95 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge29.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #29 5 | * ORDENA LA LISTA 6 | * Fecha publicación enunciado: 18/07/22 7 | * Fecha publicación resolución: 26/07/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que ordene y retorne una matriz de números. 11 | * - La función recibirá un listado (por ejemplo [2, 4, 6, 8, 9]) y un parámetro adicional 12 | * "Asc" o "Desc" para indicar si debe ordenarse de menor a mayor o de mayor a menor. 13 | * - No se pueden utilizar funciones propias del lenguaje que lo resuelvan automáticamente. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | println(sort(arrayListOf(4, 6, 1, 8, 2), true)) // 1, 2, 4, 6, 8 25 | println(sort(arrayListOf(4, 6, 1, 8, 2), false)) // 8, 6, 4, 2, 1 26 | } 27 | 28 | fun sort(numbers: List, asc: Boolean): List { 29 | 30 | val sortedNumbers = mutableListOf() 31 | 32 | for (number in numbers) { 33 | 34 | var added = false 35 | 36 | for ((index, sortedNumber) in sortedNumbers.withIndex()) { 37 | 38 | if (if(asc) number < sortedNumber else number > sortedNumber) { 39 | sortedNumbers.add(index, number) 40 | added = true 41 | break 42 | } 43 | } 44 | 45 | if (!added) { 46 | sortedNumbers.add(number) 47 | } 48 | } 49 | 50 | return sortedNumbers 51 | } 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge3.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #3 5 | * ¿ES UN NÚMERO PRIMO? 6 | * Fecha publicación enunciado: 17/01/22 7 | * Fecha publicación resolución: 24/01/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Escribe un programa que se encargue de comprobar si un número es o no primo. 11 | * Hecho esto, imprime los números primos entre 1 y 100. 12 | * 13 | * Información adicional: 14 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 15 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 16 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 17 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 18 | * 19 | */ 20 | 21 | fun main() { 22 | 23 | (1..100).forEach { number -> 24 | if (isPrime(number)) { 25 | println(number) 26 | } 27 | } 28 | } 29 | 30 | private fun isPrime(number: Int): Boolean { 31 | 32 | if (number < 2) { 33 | return false 34 | } 35 | 36 | for (i in 2 until number) { 37 | if (number % i == 0) { 38 | return false 39 | } 40 | } 41 | 42 | return true 43 | } 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge30.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #30 5 | * MARCO DE PALABRAS 6 | * Fecha publicación enunciado: 26/07/22 7 | * Fecha publicación resolución: 01/08/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que reciba un texto y muestre cada palabra en una línea, formando 11 | * un marco rectangular de asteriscos. 12 | * - ¿Qué te parece el reto? Se vería así: 13 | * ********** 14 | * * ¿Qué * 15 | * * te * 16 | * * parece * 17 | * * el * 18 | * * reto? * 19 | * ********** 20 | * 21 | * Información adicional: 22 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 23 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 24 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 25 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 26 | * 27 | */ 28 | 29 | fun main() { 30 | drawFrame("¿Qué te parece el reto?") 31 | drawFrame("¿Qué te parece el reto?") 32 | drawFrame("¿Cuántos retos de código de la comunidad has resuelto?") 33 | } 34 | 35 | private fun drawFrame(text: String) { 36 | 37 | val words = text.split(" ") 38 | var maxLength = 0 39 | words.forEach { word -> 40 | if (word.length > maxLength) { 41 | maxLength = word.length 42 | } 43 | } 44 | 45 | println("*".repeat(maxLength + 4)) 46 | 47 | words.forEach { word -> 48 | if (word.isNotEmpty()) { 49 | println("* $word${" ".repeat(maxLength - word.length)} *") 50 | } 51 | } 52 | 53 | println("*".repeat(maxLength + 4)) 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge31.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #31 5 | * AÑOS BISIESTOS 6 | * Fecha publicación enunciado: 01/08/22 7 | * Fecha publicación resolución: 08/08/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que imprima los 30 próximos años bisiestos siguientes a uno dado. 11 | * - Utiliza el menor número de líneas para resolver el ejercicio. 12 | * 13 | * Información adicional: 14 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 15 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 16 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 17 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 18 | * 19 | */ 20 | 21 | fun main() { 22 | thirtyLeapYears(1999) 23 | thirtyLeapYears(-500) 24 | } 25 | 26 | private fun thirtyLeapYears(year: Int) { 27 | 28 | var currentYear = year + 1 29 | var yearCount = 0 30 | 31 | while (yearCount < 30) { 32 | 33 | if (currentYear % 4 == 0 && (currentYear % 100 != 0 || currentYear % 400 == 0)) { 34 | println(currentYear) 35 | yearCount++ 36 | } 37 | 38 | currentYear++ 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge32.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #32 5 | * EL SEGUNDO 6 | * Fecha publicación enunciado: 08/08/22 7 | * Fecha publicación resolución: 15/08/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Dado un listado de números, encuentra el SEGUNDO más grande. 11 | * 12 | * Información adicional: 13 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 14 | * - Tienes toda la información sobre los retos semanales en https://retosdeprogramacion.com/semanales2022. 15 | * 16 | */ 17 | 18 | fun main() { 19 | println(findSecondGreater(arrayListOf(4, 6, 1, 8, 2))) 20 | println(findSecondGreater(arrayListOf(4, 6, 8, 8, 6))) 21 | println(findSecondGreater(arrayListOf(4, 4))) 22 | println(findSecondGreater(arrayListOf())) 23 | } 24 | 25 | fun findSecondGreater(numbers: List): Int? { 26 | 27 | val sortedNumbers = mutableListOf() 28 | 29 | for (number in numbers) { 30 | 31 | var found = false 32 | 33 | for ((index, sortedNumber) in sortedNumbers.withIndex()) { 34 | 35 | if (number >= sortedNumber) { 36 | if (number != sortedNumber) { 37 | sortedNumbers.add(index, number) 38 | } 39 | found = true 40 | break 41 | } 42 | } 43 | 44 | if (!found) { 45 | sortedNumbers.add(number) 46 | } 47 | } 48 | 49 | return if(sortedNumbers.count() >= 2) sortedNumbers[1] else null 50 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge33.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #33 5 | * CICLO SEXAGENARIO CHINO 6 | * Fecha publicación enunciado: 15/08/22 7 | * Fecha publicación resolución: 22/08/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un función, que dado un año, indique el elemento y animal correspondiente 11 | * en el ciclo sexagenario del zodíaco chino. 12 | * - Información: https://www.travelchinaguide.com/intro/astrology/60year-cycle.htm 13 | * - El ciclo sexagenario se corresponde con la combinación de los elementos madera, 14 | * fuego, tierra, metal, agua y los animales rata, buey, tigre, conejo, dragón, serpiente, 15 | * caballo, oveja, mono, gallo, perro, cerdo (en este orden). 16 | * - Cada elemento se repite dos años seguidos. 17 | * - El último ciclo sexagenario comenzó en 1984 (Madera Rata). 18 | * 19 | * Información adicional: 20 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la comunidad. 21 | * - Tienes toda la información sobre los retos semanales en https://retosdeprogramacion.com/semanales2022. 22 | * 23 | */ 24 | 25 | fun main() { 26 | println(chineseZodiac(1924)) 27 | println(chineseZodiac(1946)) 28 | println(chineseZodiac(1984)) 29 | println(chineseZodiac(604)) 30 | println(chineseZodiac(603)) 31 | println(chineseZodiac(1987)) 32 | println(chineseZodiac(2022)) 33 | } 34 | 35 | private fun chineseZodiac(year: Int) : String { 36 | 37 | val elements = arrayListOf("madera", "fuego", "tierra", "metal", "agua") 38 | val animals = arrayListOf("rata", "buey", "tigre", "conejo", "dragón", "serpiente", "caballo", "oveja", "mono", "gallo", "perro", "cerdo") 39 | 40 | if (year < 604) { 41 | return "El ciclo sexagenario comenzó en el año 604." 42 | } 43 | 44 | val sexagenaryYear = (year - 4) % 60 45 | val element = elements[(sexagenaryYear % 10) / 2] 46 | val animal = animals[sexagenaryYear % 12] 47 | 48 | return "$year: $element $animal" 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge34.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #34 5 | * LOS NÚMEROS PERDIDOS 6 | * Fecha publicación enunciado: 22/08/22 7 | * Fecha publicación resolución: 29/08/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Dado un array de enteros ordenado y sin repetidos, crea una función que calcule 11 | * y retorne todos los que faltan entre el mayor y el menor. 12 | * - Lanza un error si el array de entrada no es correcto. 13 | * 14 | * Información adicional: 15 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 16 | * para preguntas, dudas o prestar ayuda a la comunidad. 17 | * - Tienes toda la información sobre los retos semanales en 18 | * https://retosdeprogramacion.com/semanales2022. 19 | * 20 | */ 21 | 22 | fun main() { 23 | try { 24 | println(lostNumbers(arrayListOf(1, 3, 5))) 25 | println(lostNumbers(arrayListOf(5, 3, 1))) 26 | println(lostNumbers(arrayListOf(5, 1))) 27 | println(lostNumbers(arrayListOf(-5, 1))) 28 | //println(lostNumbers(arrayListOf(1, 3, 3, 5))) 29 | //println(lostNumbers(arrayListOf(5, 7, 1))) 30 | println(lostNumbers(arrayListOf(10, 7, 7, 1))) 31 | } catch (e: LostNumbersException) { 32 | println(e.message) 33 | } 34 | } 35 | 36 | class LostNumbersException: Exception() { 37 | 38 | override val message: String? 39 | get() = "El listado no puede poseer repetidos ni estar desordenado, y debe tener mínimo 2 valores." 40 | 41 | } 42 | 43 | private fun lostNumbers(numbers: List): List { 44 | 45 | // Errors 46 | if (numbers.count() < 2) { 47 | throw LostNumbersException() 48 | } 49 | 50 | val first = numbers.first() 51 | val last = numbers.last() 52 | val asc = first < last 53 | 54 | var prev: Int? = null 55 | numbers.forEach { number -> 56 | prev?.let { prev -> 57 | if (if (asc) number <= prev else number >= prev) { 58 | throw LostNumbersException() 59 | } 60 | } 61 | prev = number 62 | } 63 | 64 | // Lost 65 | val lost = mutableListOf() 66 | 67 | for (number in (if(asc) first else last)..(if(asc) last else first)) { 68 | if (!numbers.contains(number)) { 69 | lost.add(number) 70 | } 71 | } 72 | 73 | return lost 74 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge35.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #35 5 | * BATALLA POKÉMON 6 | * Fecha publicación enunciado: 29/08/22 7 | * Fecha publicación resolución: 06/09/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un programa que calcule el daño de un ataque durante una batalla Pokémon. 11 | * - La fórmula será la siguiente: daño = 50 * (ataque / defensa) * efectividad 12 | * - Efectividad: x2 (súper efectivo), x1 (neutral), x0.5 (no es muy efectivo) 13 | * - Sólo hay 4 tipos de Pokémon: Agua, Fuego, Planta y Eléctrico (buscar su efectividad) 14 | * - El programa recibe los siguientes parámetros: 15 | * - Tipo del Pokémon atacante. 16 | * - Tipo del Pokémon defensor. 17 | * - Ataque: Entre 1 y 100. 18 | * - Defensa: Entre 1 y 100. 19 | * 20 | * Información adicional: 21 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 22 | * para preguntas, dudas o prestar ayuda a la comunidad. 23 | * - Tienes toda la información sobre los retos semanales en 24 | * https://retosdeprogramacion.com/semanales2022. 25 | * 26 | */ 27 | 28 | fun main() { 29 | println(battle(PokemonType.WATER, PokemonType.FIRE, 50, 30)) 30 | println(battle(PokemonType.WATER, PokemonType.FIRE, 101, -10)) 31 | println(battle(PokemonType.FIRE, PokemonType.WATER, 50, 30)) 32 | println(battle(PokemonType.FIRE, PokemonType.FIRE, 50, 30)) 33 | println(battle(PokemonType.GRASS, PokemonType.ELECTRIC, 30, 50)) 34 | } 35 | 36 | enum class PokemonType(name: String) { 37 | WATER("Agua"), 38 | FIRE("Fuego"), 39 | GRASS("Planta"), 40 | ELECTRIC("Eléctrico") 41 | } 42 | 43 | private data class PokemonChart(val effective: PokemonType, val notEffective: PokemonType) 44 | 45 | private fun battle(attacker: PokemonType, defender: PokemonType, attack: Int, defense: Int): Double? { 46 | 47 | if (attack <= 0 || attack > 100 || defense <= 0 || defense > 100) { 48 | println("El ataque o la defensa contiene un valor incorrecto") 49 | return null 50 | } 51 | 52 | val typeChart = mapOf( 53 | PokemonType.WATER to PokemonChart(PokemonType.FIRE, PokemonType.GRASS), 54 | PokemonType.FIRE to PokemonChart(PokemonType.GRASS, PokemonType.WATER), 55 | PokemonType.GRASS to PokemonChart(PokemonType.WATER, PokemonType.FIRE), 56 | PokemonType.ELECTRIC to PokemonChart(PokemonType.WATER, PokemonType.GRASS) 57 | ) 58 | 59 | var effectivity = 1.0 60 | if (attacker == defender || typeChart[attacker]!!.notEffective == defender) { 61 | effectivity = 0.5 62 | println("No es muy efectivo") 63 | } else if (typeChart[attacker]!!.effective == defender) { 64 | effectivity = 2.0 65 | println("Es súper efectivo") 66 | } else { 67 | println("Es neutro") 68 | } 69 | 70 | return 50 * attack.toDouble() / defense.toDouble() * effectivity 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge36.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #36 5 | * LOS ANILLOS DE PODER 6 | * Fecha publicación enunciado: 06/09/22 7 | * Fecha publicación resolución: 14/09/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: ¡La Tierra Media está en guerra! En ella lucharán razas leales a Sauron 11 | * contra otras bondadosas que no quieren que el mal reine sobre sus tierras. 12 | * Cada raza tiene asociado un "valor" entre 1 y 5: 13 | * - Razas bondadosas: Pelosos (1), Sureños buenos (2), Enanos (3), Númenóreanos (4), Elfos (5) 14 | * - Razas malvadas: Sureños malos (2), Orcos (2), Goblins (2), Huargos (3), Trolls (5) 15 | * Crea un programa que calcule el resultado de la batalla entre los 2 tipos de ejércitos: 16 | * - El resultado puede ser que gane el bien, el mal, o exista un empate. Dependiendo de la 17 | * suma del valor del ejército y el número de integrantes. 18 | * - Cada ejército puede estar compuesto por un número de integrantes variable de cada raza. 19 | * - Tienes total libertad para modelar los datos del ejercicio. 20 | * Ej: 1 Peloso pierde contra 1 Orco, 2 Pelosos empatan contra 1 Orco, 3 Pelosos ganan a 1 Orco. 21 | * 22 | * Información adicional: 23 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 24 | * para preguntas, dudas o prestar ayuda a la comunidad. 25 | * - Tienes toda la información sobre los retos semanales en 26 | * https://retosdeprogramacion.com/semanales2022. 27 | * 28 | */ 29 | 30 | fun main() { 31 | 32 | battleForTheMiddleEarth( 33 | listOf(Pair(KindArmy.ELF, 1)), 34 | listOf(Pair(EvilArmy.TROLL, 1))) 35 | 36 | battleForTheMiddleEarth( 37 | listOf(Pair(KindArmy.ELF, 1), Pair(KindArmy.HARFOOT, 1)), 38 | listOf(Pair(EvilArmy.TROLL, 1))) 39 | 40 | battleForTheMiddleEarth( 41 | listOf(Pair(KindArmy.ELF, 1), Pair(KindArmy.HARFOOT, 1)), 42 | listOf(Pair(EvilArmy.TROLL, 1), Pair(EvilArmy.ORC, 1))) 43 | 44 | battleForTheMiddleEarth( 45 | listOf(Pair(KindArmy.ELF, 56), Pair(KindArmy.HARFOOT, 80), Pair(KindArmy.DWARF, 5)), 46 | listOf(Pair(EvilArmy.TROLL, 17), Pair(EvilArmy.ORC, 51), Pair(EvilArmy.WARG, 10), Pair(EvilArmy.SOUTHERNER, 2))) 47 | } 48 | 49 | enum class KindArmy() { 50 | 51 | HARFOOT, SOUTHERNER, DWARF, NUMENOREAN, ELF; 52 | 53 | var bravery: Int = 0 54 | get() { 55 | return when (this) { 56 | HARFOOT -> 1 57 | SOUTHERNER -> 2 58 | DWARF -> 3 59 | NUMENOREAN -> 4 60 | ELF -> 5 61 | } 62 | } 63 | } 64 | 65 | enum class EvilArmy() { 66 | 67 | SOUTHERNER, ORC, GOBLIN, WARG, TROLL; 68 | 69 | var bravery: Int = 0 70 | get() { 71 | return when (this) { 72 | SOUTHERNER, ORC, GOBLIN -> 2 73 | WARG -> 3 74 | TROLL -> 5 75 | } 76 | } 77 | } 78 | 79 | private fun battleForTheMiddleEarth(kindArmy: List>, evilArmy: List>) { 80 | 81 | var kindArmyPoints = 0 82 | var evilArmyPoints = 0 83 | 84 | kindArmy.forEach { army -> 85 | kindArmyPoints += army.first.bravery * army.second 86 | } 87 | 88 | evilArmy.forEach { army -> 89 | evilArmyPoints += army.first.bravery * army.second 90 | } 91 | 92 | if (kindArmyPoints > evilArmyPoints) { 93 | println("Gana el bien") 94 | } else if (evilArmyPoints > kindArmyPoints) { 95 | println("Gana el mal") 96 | } else { 97 | println("Empate") 98 | } 99 | 100 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge37.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.SimpleDateFormat 4 | import java.util.* 5 | 6 | /* 7 | * Reto #37 8 | * LOS LANZAMIENTOS DE "THE LEGEND OF ZELDA" 9 | * Fecha publicación enunciado: 14/09/22 10 | * Fecha publicación resolución: 19/09/22 11 | * Dificultad: MEDIA 12 | * 13 | * Enunciado: ¡Han anunciado un nuevo "The Legend of Zelda"! Se llamará "Tears of the Kingdom" 14 | * y se lanzará el 12 de mayo de 2023. 15 | * Pero, ¿recuerdas cuánto tiempo ha pasado entre los distintos "The Legend of Zelda" de la historia? 16 | * Crea un programa que calcule cuántos años y días hay entre 2 juegos de Zelda que tú selecciones. 17 | * - Debes buscar cada uno de los títulos y su día de lanzamiento (si no encuentras el día exacto 18 | * puedes usar el mes, o incluso inventártelo) 19 | * 20 | * Información adicional: 21 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 22 | * para preguntas, dudas o prestar ayuda a la comunidad. 23 | * - Tienes toda la información sobre los retos semanales en 24 | * https://retosdeprogramacion.com/semanales2022. 25 | * 26 | */ 27 | 28 | fun main() { 29 | println(ZeldaGame.THE_LEGEND_OF_ZELDA.timeBetweenRelease(ZeldaGame.TEARS_OF_THE_KINGDOM)) 30 | println(ZeldaGame.TEARS_OF_THE_KINGDOM.timeBetweenRelease(ZeldaGame.THE_LEGEND_OF_ZELDA)) 31 | println(ZeldaGame.THE_LEGEND_OF_ZELDA.timeBetweenRelease(ZeldaGame.THE_ADVENTURE_OF_LINK)) 32 | println(ZeldaGame.THE_ADVENTURE_OF_LINK.timeBetweenRelease(ZeldaGame.THE_LEGEND_OF_ZELDA)) 33 | println(ZeldaGame.THE_LEGEND_OF_ZELDA.timeBetweenRelease(ZeldaGame.THE_LEGEND_OF_ZELDA)) 34 | println(ZeldaGame.ORACLE_OF_SEASONS.timeBetweenRelease(ZeldaGame.ORACLE_OF_AGES)) 35 | } 36 | 37 | enum class ZeldaGame(val title: String) { 38 | 39 | THE_LEGEND_OF_ZELDA("The Legend of Zelda"), 40 | THE_ADVENTURE_OF_LINK("Zelda II: The Adventure of Link"), 41 | A_LINK_TO_THE_PAST("The Legend of Zelda: A Link to the Past"), 42 | LINKS_AWAKENING("The Legend of Zelda: Link's Awakening"), 43 | OCARINA_OF_TIME("The Legend of Zelda: Ocarina of Time"), 44 | MAJORAS_MASK("Zelda: Majora's Mask"), 45 | ORACLE_OF_SEASONS("The Legend of Zelda: Oracle of Seasons"), 46 | ORACLE_OF_AGES("The Legend of Zelda: Oracle of Ages"), 47 | FOUR_SWORDS("The Legend of Zelda: Four Swords"), 48 | THE_WIND_WAKER("The Legend of Zelda: The Wind Waker"), 49 | FOUR_SWORDS_ADVENTURES("The Legend of Zelda: Four Swords Adventures"), 50 | THE_MINISH_CUP("The Legend of Zelda: The Minish Cap"), 51 | TWILIGHT_PRINCES("The Legend of Zelda: Twilight Princess"), 52 | PHANTHOM_HOURGLASS("The Legend of Zelda: Phantom Hourglass"), 53 | SPIRIT_TRACKS("The Legend of Zelda: Spirit Tracks"), 54 | SKYWARD_SWORD("The Legend of Zelda: Skyward Sword"), 55 | A_LINK_BETWEEN_WORLDS("The Legend of Zelda: A Link Between Worlds"), 56 | TRI_FORCE_HEROES("The Legend of Zelda: Tri Force Heroes"), 57 | BREATH_OF_THE_WILD("The Legend of Zelda: Breath of the Wild"), 58 | TEARS_OF_THE_KINGDOM("The Legend of Zelda: Tears of the Kingdom"); 59 | 60 | private var releaseDate: Date? = null 61 | get() { 62 | val formatter = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()) 63 | return when (this) { 64 | THE_LEGEND_OF_ZELDA -> formatter.parse("21/02/1986") 65 | THE_ADVENTURE_OF_LINK -> formatter.parse("14/01/1987") 66 | A_LINK_TO_THE_PAST -> formatter.parse("21/11/1991") 67 | LINKS_AWAKENING -> formatter.parse("06/06/1993") 68 | OCARINA_OF_TIME -> formatter.parse("21/11/1998") 69 | MAJORAS_MASK -> formatter.parse("27/04/2000") 70 | ORACLE_OF_SEASONS, ORACLE_OF_AGES -> formatter.parse("27/02/2001") 71 | FOUR_SWORDS -> formatter.parse("03/12/2002") 72 | THE_WIND_WAKER -> formatter.parse("13/12/2002") 73 | FOUR_SWORDS_ADVENTURES -> formatter.parse("18/03/2004") 74 | THE_MINISH_CUP -> formatter.parse("04/11/2004") 75 | TWILIGHT_PRINCES -> formatter.parse("19/11/2006") 76 | PHANTHOM_HOURGLASS -> formatter.parse("23/06/2007") 77 | SPIRIT_TRACKS -> formatter.parse("07/12/2009") 78 | SKYWARD_SWORD -> formatter.parse("18/11/2011") 79 | A_LINK_BETWEEN_WORLDS -> formatter.parse("23/11/2013") 80 | TRI_FORCE_HEROES -> formatter.parse("11/10/2015") 81 | BREATH_OF_THE_WILD -> formatter.parse("03/03/2017") 82 | TEARS_OF_THE_KINGDOM -> formatter.parse("12/05/2023") 83 | } 84 | } 85 | 86 | fun timeBetweenRelease(game: ZeldaGame): String { 87 | 88 | if (this == game) { 89 | return "Se está intentando comparar el mismo juego" 90 | } 91 | 92 | this.releaseDate?.let { currentReleaseDate -> 93 | game.releaseDate?.let { newReleaseDate -> 94 | 95 | val startDate = if (currentReleaseDate < newReleaseDate) currentReleaseDate else newReleaseDate 96 | val endDate = if (newReleaseDate > currentReleaseDate) newReleaseDate else currentReleaseDate 97 | 98 | val startCalendar = Calendar.getInstance() 99 | startCalendar.time = startDate 100 | val startReleaseYear = startCalendar.get(Calendar.YEAR) 101 | 102 | val endCalendar = Calendar.getInstance() 103 | endCalendar.time = endDate 104 | val endReleaseYear = endCalendar.get(Calendar.YEAR) 105 | 106 | var years = endReleaseYear - startReleaseYear 107 | 108 | startCalendar.set(Calendar.YEAR, endReleaseYear) 109 | 110 | // Nos encontramos con un día y un mes en la fecha inicial posterior a la final 111 | if (startCalendar.timeInMillis > endCalendar.timeInMillis) { 112 | startCalendar.set(Calendar.YEAR, endReleaseYear - 1) 113 | years -= 1 114 | } 115 | 116 | val startMillis = if (startCalendar.timeInMillis < endCalendar.timeInMillis) startCalendar.timeInMillis else endCalendar.timeInMillis 117 | val endMillis = if (endCalendar.timeInMillis > startCalendar.timeInMillis) endCalendar.timeInMillis else startCalendar.timeInMillis 118 | 119 | val days = (endMillis - startMillis) / (60 * 60 * 24 * 1000) 120 | 121 | return "Entre la fecha de lanzamiento de ${this.title} y ${game.title} hay $years años y $days días" 122 | } 123 | 124 | } 125 | 126 | return "No se ha podido calcular el tiempo entre fechas de lanzamiento" 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge38.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import kotlin.math.pow 4 | 5 | /* 6 | * Reto #38 7 | * BINARIO A DECIMAL 8 | * Fecha publicación enunciado: 19/09/22 9 | * Fecha publicación resolución: 27/09/22 10 | * Dificultad: MEDIA 11 | * 12 | * Enunciado: Crea un programa se encargue de transformar un número binario a decimal sin utilizar 13 | * funciones propias del lenguaje que lo hagan directamente. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 17 | * para preguntas, dudas o prestar ayuda a la comunidad. 18 | * - Tienes toda la información sobre los retos semanales en 19 | * https://retosdeprogramacion.com/semanales2022. 20 | * 21 | */ 22 | 23 | fun main() { 24 | println(binaryToDecimal("00110")) 25 | println(binaryToDecimal("01100")) 26 | println(binaryToDecimal("000000000")) 27 | println(binaryToDecimal("00210")) 28 | println(binaryToDecimal("001101001110")) 29 | println(binaryToDecimal("00b10")) 30 | println(binaryToDecimal("")) 31 | println(binaryToDecimal("-00110")) 32 | println(binaryToDecimal(" ")) 33 | println(binaryToDecimal(" 10011")) 34 | println(binaryToDecimal("1O1OO11")) 35 | } 36 | 37 | private fun binaryToDecimal(binary: String): Int? { 38 | 39 | val length = binary.length - 1 40 | 41 | var decimal: Int? = null 42 | 43 | for (index in 0..length) { 44 | val digitChar = binary.toCharArray()[length - index] 45 | if (digitChar == '0' || digitChar == '1') { 46 | if (decimal == null) { 47 | decimal = 0 48 | } 49 | decimal += digitChar.digitToInt() * 2.0.pow(index).toInt() 50 | } else { 51 | return null 52 | } 53 | } 54 | 55 | return decimal 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge39.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #39 5 | * TOP ALGORITMOS: QUICK SORT 6 | * Fecha publicación enunciado: 27/09/22 7 | * Fecha publicación resolución: 03/10/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Implementa uno de los algoritmos de ordenación más famosos: el "Quick Sort", 11 | * creado por C.A.R. Hoare. 12 | * - Entender el funcionamiento de los algoritmos más utilizados de la historia nos ayuda a 13 | * mejorar nuestro conocimiento sobre ingeniería de software. Dedícale tiempo a entenderlo, 14 | * no únicamente a copiar su implementación. 15 | * - Esta es una nueva serie de retos llamada "TOP ALGORITMOS", donde trabajaremos y entenderemos 16 | * los más famosos de la historia. 17 | * 18 | * Información adicional: 19 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 20 | * para preguntas, dudas o prestar ayuda a la comunidad. 21 | * - Tienes toda la información sobre los retos semanales en 22 | * https://retosdeprogramacion.com/semanales2022. 23 | * 24 | */ 25 | 26 | // Basado en https://www.genbeta.com/desarrollo/implementando-el-algoritmo-quicksort 27 | 28 | fun main() { 29 | val sortedArray = quicksort(arrayOf(3, 5, 1, 8, 9, 0)) 30 | sortedArray.forEach { 31 | println(it) 32 | } 33 | } 34 | 35 | private fun quicksort(array: Array): Array { 36 | return if (array.isEmpty()) array else quicksort(array, 0, array.size - 1) 37 | } 38 | 39 | private fun quicksort(array: Array, first: Int, last: Int): Array { 40 | 41 | var i = first 42 | var j = last 43 | var array = array 44 | val pivot = (array[i] + array[j]) / 2 45 | 46 | while (i < j) { 47 | 48 | while (array[i] < pivot) { 49 | i += 1 50 | } 51 | 52 | while (array[j] > pivot) { 53 | j -= 1 54 | } 55 | 56 | if (i <= j) { 57 | 58 | val x = array[j] 59 | 60 | array[j] = array[i] 61 | array[i] = x 62 | 63 | i += 1 64 | j -= 1 65 | } 66 | } 67 | 68 | if (first < j) { 69 | array = quicksort(array, first, j) 70 | } 71 | 72 | if (last > i) { 73 | array = quicksort(array, i, last) 74 | } 75 | 76 | return array 77 | } 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge4.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #4 5 | * ÁREA DE UN POLÍGONO 6 | * Fecha publicación enunciado: 24/01/22 7 | * Fecha publicación resolución: 31/01/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea UNA ÚNICA FUNCIÓN (importante que sólo sea una) que sea capaz de calcular y retornar el área de un polígono. 11 | * - La función recibirá por parámetro sólo UN polígono a la vez. 12 | * - Los polígonos soportados serán Triángulo, Cuadrado y Rectángulo. 13 | * - Imprime el cálculo del área de un polígono de cada tipo. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | 25 | area(Triangle(10.0, 5.0)) 26 | area(Rectangle(5.0, 7.0)) 27 | area(Square(4.0)) 28 | } 29 | 30 | interface Polygon { 31 | 32 | fun area(): Double 33 | fun printArea() 34 | } 35 | 36 | data class Triangle(val base: Double, val height: Double): Polygon { 37 | 38 | override fun area(): Double { 39 | return (base * height) / 2 40 | } 41 | 42 | override fun printArea() { 43 | println("El área del triángulo es ${area()}") 44 | } 45 | } 46 | 47 | data class Rectangle(val length: Double, val width: Double): Polygon { 48 | 49 | override fun area(): Double { 50 | return length * width 51 | } 52 | 53 | override fun printArea() { 54 | println("El área del rectángulo es ${area()}") 55 | } 56 | } 57 | 58 | data class Square(val side: Double): Polygon { 59 | 60 | override fun area(): Double { 61 | return side * side 62 | } 63 | 64 | override fun printArea() { 65 | println("El área del cuadrado es ${area()}") 66 | } 67 | } 68 | 69 | private fun area(polygon: Polygon): Double { 70 | polygon.printArea() 71 | return polygon.area() 72 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge40.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #40 5 | * TRIÁNGULO DE PASCAL 6 | * Fecha publicación enunciado: 03/10/22 7 | * Fecha publicación resolución: 10/10/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea una función que sea capaz de dibujar el "Triángulo de Pascal" indicándole 11 | * únicamente el tamaño del lado. 12 | * - Aquí puedes ver rápidamente cómo se calcula el triángulo: 13 | * https://commons.wikimedia.org/wiki/File:PascalTriangleAnimated2.gif 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 17 | * para preguntas, dudas o prestar ayuda a la comunidad. 18 | * - Tienes toda la información sobre los retos semanales en 19 | * https://retosdeprogramacion.com/semanales2022. 20 | * 21 | */ 22 | 23 | fun main() { 24 | pascalTriangle(5) 25 | pascalTriangle(1) 26 | pascalTriangle(0) 27 | pascalTriangle(-5) 28 | } 29 | 30 | private fun pascalTriangle(size: Int) { 31 | 32 | var lastRow = arrayListOf() 33 | 34 | for (row in 0 until size) { 35 | 36 | val currentRow = arrayListOf() 37 | 38 | var triangleRow = "" 39 | 40 | for (element in 0..row) { 41 | 42 | if (element in 1 until row) { 43 | val value = lastRow[element - 1] + lastRow[element] 44 | triangleRow += "$value " 45 | currentRow.add(value) 46 | } else { 47 | triangleRow += "1 " 48 | currentRow.add(1) 49 | } 50 | } 51 | 52 | println(" ".repeat(size - row) + triangleRow) 53 | 54 | lastRow = currentRow 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge41.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.DecimalFormat 4 | 5 | /* 6 | * Reto #41 7 | * LA LEY DE OHM 8 | * Fecha publicación enunciado: 10/10/22 9 | * Fecha publicación resolución: 17/10/22 10 | * Dificultad: FÁCIL 11 | * 12 | * Enunciado: Crea una función que calcule el valor del parámetro perdido correspondiente a la ley de Ohm. 13 | * - Enviaremos a la función 2 de los 3 parámetros (V, R, I), y retornará el valor del tercero (redondeado a 2 decimales). 14 | * - Si los parámetros son incorrectos o insuficientes, la función retornará la cadena de texto "Invalid values". 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 18 | * para preguntas, dudas o prestar ayuda a la comunidad. 19 | * - Tienes toda la información sobre los retos semanales en 20 | * https://retosdeprogramacion.com/semanales2022. 21 | * 22 | */ 23 | 24 | fun main() { 25 | println(ohm()) 26 | println(ohm(v = 5.0)) 27 | println(ohm(v = 5.0, r = 4.0)) 28 | println(ohm(v = 5.0, i = 4.0)) 29 | println(ohm(r = 5.0, i = 4.0)) 30 | println(ohm(v = 5.125, r = 4.0)) 31 | println(ohm(v = 5.0, i = 4.125)) 32 | println(ohm(r = 5.0, i = 4.125)) 33 | println(ohm(v = 5.0, r = 0.0)) 34 | println(ohm(v = 5.0, i = 0.0)) 35 | println(ohm(r = 5.0, i = 0.0)) 36 | println(ohm(v = 5.0, r = 4.0, i = 3.0)) 37 | } 38 | 39 | // V = R * I 40 | private fun ohm(v: Double? = null, r: Double? = null, i: Double? = null) : String { 41 | 42 | val formatter = DecimalFormat("#.##") 43 | 44 | if (v != null && r != null && i == null) { 45 | return "I = ${formatter.format(v / r)}" 46 | } else if (v != null && i != null && r == null) { 47 | return "R = ${formatter.format(v / i)}" 48 | } else if (r != null && i != null && v == null) { 49 | return "V = ${formatter.format(r * i)}" 50 | } 51 | 52 | return "Invalid values" 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge42.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.DecimalFormat 4 | 5 | /* 6 | * Reto #42 7 | * CONVERSOR DE TEMPERATURA 8 | * Fecha publicación enunciado: 17/10/22 9 | * Fecha publicación resolución: 24/10/22 10 | * Dificultad: FÁCIL 11 | * 12 | * Enunciado: Crea una función que transforme grados Celsius en Fahrenheit y viceversa. 13 | * - Para que un dato de entrada sea correcto debe poseer un símbolo "°" y su unidad ("C" o "F"). 14 | * - En caso contrario retornará un error. 15 | * - ¿Quieres emplear lo aprendido en este reto? 16 | * Revisa el reto mensual y crea una App: https://retosdeprogramacion.com/mensuales2022 17 | * 18 | * Información adicional: 19 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 20 | * para preguntas, dudas o prestar ayuda a la comunidad. 21 | * - Tienes toda la información sobre los retos semanales en 22 | * https://retosdeprogramacion.com/semanales2022. 23 | * 24 | */ 25 | 26 | fun main() { 27 | println(temperatureConverter("100°C")) 28 | println(temperatureConverter("100°F")) 29 | println(temperatureConverter("100C")) 30 | println(temperatureConverter("100F")) 31 | println(temperatureConverter("100")) 32 | println(temperatureConverter("100")) 33 | println(temperatureConverter("- 100 °C ")) 34 | println(temperatureConverter("- 100 °F ")) 35 | println(temperatureConverter("100A°C")) 36 | println(temperatureConverter("100A°F")) 37 | println(temperatureConverter("°C")) 38 | println(temperatureConverter("°F")) 39 | } 40 | 41 | private fun temperatureConverter(degrees: String): String? { 42 | 43 | val formatter = DecimalFormat("#.##") 44 | 45 | try { 46 | 47 | if (degrees.replace(" ", "").contains("°C")) { 48 | val celsiusDegrees = degrees.replace(" ", "") 49 | .replace("°C", "") 50 | .toDouble() 51 | return "${formatter.format((celsiusDegrees * 9/5) + 32)}°F" 52 | 53 | } else if (degrees.replace(" ", "").contains("°F")) { 54 | val fahrenheitDegrees = degrees.replace(" ", "") 55 | .replace("°F", "") 56 | .toDouble() 57 | return "${formatter.format((fahrenheitDegrees - 32) * 5/9)}°C" 58 | } 59 | 60 | } catch (e: Exception) { 61 | return null 62 | } 63 | 64 | return null 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge43.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #43 5 | * TRUCO O TRATO 6 | * Fecha publicación enunciado: 24/10/22 7 | * Fecha publicación resolución: 02/11/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Este es un reto especial por Halloween. 11 | * Deberemos crear un programa al que le indiquemos si queremos realizar "Truco o Trato" y 12 | * un listado (array) de personas con las siguientes propiedades: 13 | * - Nombre de la niña o niño 14 | * - Edad 15 | * - Altura en centímetros 16 | * 17 | * Si las personas han pedido truco, el programa retornará sustos (aleatorios) 18 | * siguiendo estos criterios: 19 | * - Un susto por cada 2 letras del nombre por persona 20 | * - Dos sustos por cada edad que sea un número par 21 | * - Tres sustos por cada 100 cm de altura entre todas las personas 22 | * - Sustos: 🎃 👻 💀 🕷 🕸 🦇 23 | * 24 | * Si las personas han pedido trato, el programa retornará dulces (aleatorios) 25 | * siguiendo estos criterios: 26 | * - Un dulce por cada letra de nombre 27 | * - Un dulce por cada 3 años cumplidos hasta un máximo de 10 años por persona 28 | * - Dos dulces por cada 50 cm de altura hasta un máximo de 150 cm por persona 29 | * - Dulces: 🍰 🍬 🍡 🍭 🍪 🍫 🧁 🍩 30 | * 31 | * Información adicional: 32 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 33 | * para preguntas, dudas o prestar ayuda a la comunidad. 34 | * - Tienes toda la información sobre los retos semanales en 35 | * https://retosdeprogramacion.com/semanales2022. 36 | * 37 | */ 38 | 39 | fun main() { 40 | println(trickOrTreat(Halloween.TRICK, arrayOf( 41 | Person("Brais", 35, 177), 42 | Person("Sara", 9, 122), 43 | Person("Pedro", 5, 80), 44 | Person("Roswell", 3, 54)))) 45 | 46 | println(trickOrTreat(Halloween.TREAT, arrayOf( 47 | Person("Brais", 35, 177), 48 | Person("Sara", 9, 122), 49 | Person("Pedro", 5, 80), 50 | Person("Roswell", 3, 54)))) 51 | } 52 | 53 | enum class Halloween { 54 | TRICK, TREAT 55 | } 56 | 57 | data class Person(val name: String, val age: Int, val height: Int) 58 | 59 | private fun trickOrTreat(halloween: Halloween, people: Array): String { 60 | 61 | val scares = arrayOf("🎃", "👻", "💀", "🕷", "🕸", "🦇") 62 | val candies = arrayOf("🍰", "🍬", "🍡", "🍭", "🍪", "🍫", "🧁", "🍩") 63 | 64 | var result = "" 65 | var height = 0 66 | 67 | people.forEach { person -> 68 | 69 | when (halloween) { 70 | Halloween.TRICK -> { 71 | 72 | // Name 73 | (1 .. (person.name.replace(" ", "").length / 2)).forEach { _ -> 74 | result += scares.random() 75 | } 76 | 77 | // Age 78 | if (person.age % 2 == 0) { 79 | result += scares.random() 80 | result += scares.random() 81 | } 82 | 83 | // Height 84 | height += person.height 85 | while (height >= 100) { 86 | result += scares.random() 87 | result += scares.random() 88 | result += scares.random() 89 | height -= 100 90 | } 91 | 92 | } 93 | Halloween.TREAT -> { 94 | 95 | // Name 96 | (1 .. (person.name.replace(" ", "").length)).forEach { _ -> 97 | result += candies.random() 98 | } 99 | 100 | // Age 101 | if (person.age <= 10) { 102 | (1 .. (person.age / 3)).forEach { _ -> 103 | result += candies.random() 104 | } 105 | } 106 | 107 | // Height 108 | if (person.height <= 150) { 109 | (1 .. (person.height / 50)).forEach { _ -> 110 | result += candies.random() 111 | result += candies.random() 112 | } 113 | } 114 | } 115 | } 116 | 117 | } 118 | 119 | return result 120 | } 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge44.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #44 5 | * BUMERANES 6 | * Fecha publicación enunciado: 02/10/22 7 | * Fecha publicación resolución: 07/11/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que retorne el número total de bumeranes de un array de números 11 | * enteros e imprima cada uno de ellos. 12 | * - Un bumerán (búmeran, boomerang) es una secuencia formada por 3 números seguidos, en el que el 13 | * primero y el último son iguales, y el segundo es diferente. Por ejemplo [2, 1, 2]. 14 | * - En el array [2, 1, 2, 3, 3, 4, 2, 4] hay 2 bumeranes ([2, 1, 2] y [4, 2, 4]). 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 18 | * para preguntas, dudas o prestar ayuda a la comunidad. 19 | * - Tienes toda la información sobre los retos semanales en 20 | * https://retosdeprogramacion.com/semanales2022. 21 | * 22 | */ 23 | 24 | fun main() { 25 | 26 | println(numberOfBoomerangs(arrayOf(2, 1, 2, 3, 3, 4, 2, 4))) 27 | println(numberOfBoomerangs(arrayOf(2, 1, 2, 1, 2))) 28 | println(numberOfBoomerangs(arrayOf(1, 2, 3, 4, 5))) 29 | println(numberOfBoomerangs(arrayOf(2, 2, 2, 2, 2))) 30 | println(numberOfBoomerangs(arrayOf(2, -2, 2, -2, 2))) 31 | println(numberOfBoomerangs(arrayOf(2, -2))) 32 | println(numberOfBoomerangs(arrayOf(2))) 33 | println(numberOfBoomerangs(arrayOf())) 34 | } 35 | 36 | private fun numberOfBoomerangs(numbers: Array): Int { 37 | 38 | if (numbers.size < 3) return 0 39 | 40 | var boomerangs = 0 41 | 42 | (1 until numbers.size - 1).forEach { index -> 43 | 44 | val prev = numbers[index - 1] 45 | val current = numbers[index] 46 | val next = numbers[index + 1] 47 | 48 | if (prev == next && prev != current) { 49 | println("[$prev, $current, $next]") 50 | boomerangs += 1 51 | } 52 | } 53 | 54 | return boomerangs 55 | } 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge45.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #45 5 | * CONTENEDOR DE AGUA 6 | * Fecha publicación enunciado: 07/10/22 7 | * Fecha publicación resolución: 14/11/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Dado un array de números enteros positivos, donde cada uno representa unidades 11 | * de bloques apilados, debemos calcular cuantas unidades de agua quedarán atrapadas entre ellos. 12 | * 13 | * - Ejemplo: Dado el array [4, 0, 3, 6, 1, 3]. 14 | * 15 | * ⏹ 16 | * ⏹ 17 | * ⏹💧💧⏹ 18 | * ⏹💧⏹⏹💧⏹ 19 | * ⏹💧⏹⏹💧⏹ 20 | * ⏹💧⏹⏹⏹⏹ 21 | * 22 | * Representando bloque con ⏹︎ y agua con 💧, quedarán atrapadas 7 unidades de agua. 23 | * Suponemos que existe un suelo impermeable en la parte inferior que retiene el agua. 24 | * 25 | * 26 | * Información adicional: 27 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 28 | * para preguntas, dudas o prestar ayuda a la comunidad. 29 | * - Tienes toda la información sobre los retos semanales en 30 | * https://retosdeprogramacion.com/semanales2022. 31 | * 32 | */ 33 | 34 | fun main() { 35 | println(calculateWaterUnits(arrayOf(4, 0, 3, 6))) 36 | println(calculateWaterUnits(arrayOf(4, 0, 3, 6, 1, 3))) 37 | println(calculateWaterUnits(arrayOf(5, 4, 3, 2, 1, 0))) 38 | println(calculateWaterUnits(arrayOf(0, 1, 2, 3, 4, 5))) 39 | println(calculateWaterUnits(arrayOf(4, 0, 3, 6, 1, 3, 0, 1, 6))) 40 | } 41 | 42 | private fun calculateWaterUnits(container: Array): Int { 43 | 44 | var units = 0 45 | var wall = 0 46 | var nextWall = 0 47 | 48 | container.forEachIndexed { index, blocks -> 49 | 50 | if (blocks < 0) { 51 | return@forEachIndexed 52 | } 53 | 54 | if (index != container.size - 1 && (index == 0 || nextWall == blocks)) { 55 | 56 | wall = if (index == 0) blocks else nextWall 57 | 58 | nextWall = 0 59 | for (nextBlocksIndex in index + 1 until container.size) { 60 | if (container[nextBlocksIndex] >= nextWall && wall >= nextWall) { 61 | nextWall = container[nextBlocksIndex] 62 | } 63 | } 64 | } else { 65 | val referenceWall = if (nextWall > wall) wall else nextWall 66 | val currentBlocks = referenceWall - blocks 67 | units += if (currentBlocks >= 0) currentBlocks else 0 68 | } 69 | } 70 | 71 | return units 72 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge46.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #46 5 | * ¿DÓNDE ESTÁ EL ROBOT? 6 | * Fecha publicación enunciado: 14/11/22 7 | * Fecha publicación resolución: 21/11/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Calcula dónde estará un robot (sus coordenadas finales) que se encuentra en una cuadrícula 11 | * representada por los ejes "x" e "y". 12 | * - El robot comienza en la coordenada (0, 0). 13 | * - Para idicarle que se mueva, le enviamos un array formado por enteros (positivos o negativos) 14 | * que indican la secuencia de pasos a dar. 15 | * - Por ejemplo: [10, 5, -2] indica que primero se mueve 10 pasos, se detiene, luego 5, se detiene, 16 | * y finalmente 2. El resultado en este caso sería (x: -5, y: 12) 17 | * - Si el número de pasos es negativo, se desplazaría en sentido contrario al que está mirando. 18 | * - Los primeros pasos los hace en el eje "y". Interpretamos que está mirando hacia la parte 19 | * positiva del eje "y". 20 | * - El robot tiene un fallo en su programación: cada vez que finaliza una secuencia de pasos gira 21 | * 90 grados en el sentido contrario a las agujas del reloj. 22 | * 23 | * Información adicional: 24 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 25 | * para preguntas, dudas o prestar ayuda a la comunidad. 26 | * - Tienes toda la información sobre los retos semanales en 27 | * https://retosdeprogramacion.com/semanales2022. 28 | * 29 | */ 30 | 31 | fun main() { 32 | println(whereIsTheRobot(arrayOf(10, 5, -2))) 33 | println(whereIsTheRobot(arrayOf(0, 0, 0))) 34 | println(whereIsTheRobot(arrayOf())) 35 | println(whereIsTheRobot(arrayOf(-10, -5, 2))) 36 | println(whereIsTheRobot(arrayOf(-10, -5, 2, 4, -8))) 37 | } 38 | 39 | private enum class Direction { 40 | 41 | POSITIVEY, NEGATIVEX, NEGATIVEY, POSITIVEX; 42 | 43 | fun turn(): Direction { 44 | 45 | return when (this) { 46 | POSITIVEY -> NEGATIVEX 47 | NEGATIVEX -> NEGATIVEY 48 | NEGATIVEY -> POSITIVEX 49 | POSITIVEX -> POSITIVEY 50 | 51 | } 52 | } 53 | 54 | } 55 | 56 | private fun whereIsTheRobot(steps: Array): String { 57 | 58 | var x = 0 59 | var y = 0 60 | 61 | var direction = Direction.POSITIVEY 62 | 63 | steps.forEach { step -> 64 | 65 | when (direction) { 66 | Direction.POSITIVEY -> y += step 67 | Direction.NEGATIVEX -> x -= step 68 | Direction.NEGATIVEY -> y -= step 69 | Direction.POSITIVEX -> x += step 70 | } 71 | 72 | direction = direction.turn() 73 | } 74 | 75 | return "x: $x, y: $y, direction: $direction" 76 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge47.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.text.Normalizer 4 | 5 | /* 6 | * Reto #47 7 | * VOCAL MÁS COMÚN 8 | * Fecha publicación enunciado: 21/11/22 9 | * Fecha publicación resolución: 28/11/22 10 | * Dificultad: FÁCIL 11 | * 12 | * Enunciado: Crea un función que reciba un texto y retorne la vocal que más veces se repita. 13 | * - Ten cuidado con algunos casos especiales. 14 | * - Si no hay vocales podrá devolver vacío. 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 18 | * para preguntas, dudas o prestar ayuda a la comunidad. 19 | * - Tienes toda la información sobre los retos semanales en 20 | * https://retosdeprogramacion.com/semanales2022. 21 | * 22 | */ 23 | 24 | fun main() { 25 | println(mostRepeatedVowel("aaaaaeeeeiiioou")) 26 | println(mostRepeatedVowel("AáaaaEeeeIiiOoU")) 27 | println(mostRepeatedVowel("eeeeiiioouaaaaa")) 28 | println(mostRepeatedVowel(".-Aá?aaaBbEeeweIiiOoU:")) 29 | println(mostRepeatedVowel(".-Aá?aaa BbEeew eIiiOoU:")) 30 | println(mostRepeatedVowel(".-Aá?aaa BbEeew eEIiiOoU:")) 31 | println(mostRepeatedVowel(".-Aá?aaa BbEeew eEIiiOoUuuuuu:")) 32 | println(mostRepeatedVowel("aeiou")) 33 | println(mostRepeatedVowel("brp qyz")) 34 | } 35 | 36 | private fun mostRepeatedVowel(text: String) : List { 37 | 38 | val vowelCount = mutableMapOf() 39 | 40 | Normalizer.normalize(text.lowercase(), Normalizer.Form.NFD).forEach { character -> 41 | if (character == 'a' || character == 'e' || character == 'i' || character == 'o' || character == 'u') { 42 | vowelCount[character] = vowelCount[character]?.plus(1) ?: 1 43 | } 44 | } 45 | 46 | val mostRepeated = mutableListOf() 47 | var maxRepeated = 0 48 | 49 | vowelCount.forEach { (vowel: Char, count: Int) -> 50 | if (count >= maxRepeated) { 51 | if (count > maxRepeated) { 52 | mostRepeated.clear() 53 | } 54 | mostRepeated.add(vowel.toString()) 55 | 56 | maxRepeated = count 57 | } 58 | } 59 | 60 | return mostRepeated 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge48.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import java.time.LocalDateTime 4 | import java.time.ZoneId 5 | import java.time.format.DateTimeFormatter 6 | import java.util.Calendar 7 | import java.util.Date 8 | 9 | /* 10 | * Reto #48 11 | * EL CALENDARIO DE ADEVIENTO 2022 12 | * Fecha publicación enunciado: 28/11/22 13 | * Fecha publicación resolución: 05/12/22 14 | * Dificultad: FÁCIL 15 | * 16 | * ¿Conoces el calendario de adviento de la comunidad (https://adviento.dev)? 17 | * 24 días, 24 regalos sorpresa relacionados con desarrollo de software, ciencia y tecnología desde el 1 de diciembre. 18 | * 19 | * Enunciado: Crea una función que reciba un objeto de tipo "Date" y retorne lo siguiente: 20 | * - Si la fecha coincide con el calendario de aDEViento 2022: Retornará el regalo de ese día (a tu elección) y cuánto queda para que finalice el sorteo de ese día. 21 | * - Si la fecha es anterior: Cuánto queda para que comience el calendario. 22 | * - Si la fecha es posterior: Cuánto tiempo ha pasado desde que ha finalizado. 23 | * 24 | * Notas: 25 | * - Tenemos en cuenta que cada día del calendario comienza a medianoche 00:00:00 y finaliza a las 23:59:59. 26 | * - Debemos trabajar con fechas que tengan año, mes, día, horas, minutos y segundos. 27 | * - 🎁 Cada persona que aporte su solución entrará en un nuevo sorteo del calendario de aDEViento hasta el día de su corrección (sorteo exclusivo para quien entregue su solución). 28 | * 29 | * Información adicional: 30 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 31 | * para preguntas, dudas o prestar ayuda a la comunidad. 32 | * - Tienes toda la información sobre los retos semanales en 33 | * https://retosdeprogramacion.com/semanales2022. 34 | * 35 | */ 36 | 37 | fun main() { 38 | 39 | // aDEViento2022(LocalDateTime.of(2022, 12, 5, 20, 27, 56).toDate()) 40 | 41 | val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") 42 | println(aDEViento2022(LocalDateTime.parse("2022/12/05 20:27:56", formatter).toDate())) 43 | println(aDEViento2022(LocalDateTime.parse("2022/12/01 00:00:00", formatter).toDate())) 44 | println(aDEViento2022(LocalDateTime.parse("2022/12/24 23:59:59", formatter).toDate())) 45 | println(aDEViento2022(LocalDateTime.parse("2022/11/30 23:59:59", formatter).toDate())) 46 | println(aDEViento2022(LocalDateTime.parse("2022/12/25 00:00:00", formatter).toDate())) 47 | println(aDEViento2022(LocalDateTime.parse("2022/10/30 00:00:00", formatter).toDate())) 48 | println(aDEViento2022(LocalDateTime.parse("2022/12/30 04:32:12", formatter).toDate())) 49 | println(aDEViento2022(LocalDateTime.parse("2020/10/30 00:00:00", formatter).toDate())) 50 | println(aDEViento2022(LocalDateTime.parse("2024/12/30 04:32:12", formatter).toDate())) 51 | } 52 | 53 | private fun LocalDateTime.toDate(): Date { 54 | return Date.from(this.atZone(ZoneId.systemDefault()).toInstant()) 55 | } 56 | 57 | private fun aDEViento2022(date: Date): String { 58 | 59 | val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss") 60 | val startDate = LocalDateTime.parse("2022/12/01 00:00:00", formatter).toDate() 61 | val endDate = LocalDateTime.parse("2022/12/24 23:59:59", formatter).toDate() 62 | 63 | if (date in startDate..endDate) { 64 | 65 | val gifts = arrayOf( 66 | "El programador pragmático", 67 | "while True: learn()", 68 | "Aprende Javascript ES9, HTML, CSS3 y NodeJS desde cero", 69 | "Patrones de Diseño en JavaScript y TypeScript", 70 | "Aprende Python en un fin de semana", 71 | "Regalo 6", 72 | "Regalo 7", 73 | "Regalo 8", 74 | "Regalo 9", 75 | "Regalo 10", 76 | "Regalo 11", 77 | "Regalo 12", 78 | "Regalo 13", 79 | "Regalo 14", 80 | "Regalo 15", 81 | "Regalo 16", 82 | "Regalo 17", 83 | "Regalo 18", 84 | "Regalo 19", 85 | "Regalo 20", 86 | "Regalo 21", 87 | "Regalo 22", 88 | "Regalo 23", 89 | "Regalo 24") 90 | 91 | val calendar = Calendar.getInstance() 92 | calendar.time = date 93 | calendar.set(Calendar.HOUR_OF_DAY, 23) 94 | calendar.set(Calendar.MINUTE, 59) 95 | calendar.set(Calendar.SECOND, 59) 96 | 97 | val day = calendar.get(Calendar.DAY_OF_MONTH) 98 | 99 | return "El regalo del día es: ${gifts[day - 1]} y el sorteo del día acaba en: ${diffTimeComponentsText(date, calendar.time)}" 100 | } 101 | 102 | val intro = if (date < startDate) "El calendario de aDEViento 2022 comenzará en:" else "El calendario de aDEViento 2022 ha finalizado hace:" 103 | val timeComponents = diffTimeComponentsText(if (date < startDate) date else endDate, 104 | if (date < startDate) startDate else date) 105 | return "$intro $timeComponents" 106 | } 107 | 108 | private fun diffTimeComponentsText(startDate: Date, endDate: Date): String { 109 | 110 | val diffInMillis = endDate.time - startDate.time 111 | 112 | val second = diffInMillis / 1000L % 60 113 | val minutes = diffInMillis / (1000L * 60) % 60 114 | val hours = diffInMillis / (1000L * 60 * 60) % 24 115 | val days = diffInMillis / (1000L * 60 * 60 * 24) % 365 116 | val years = diffInMillis / (1000L * 60 * 60 * 24 * 365) 117 | 118 | return "$years años, $days días, $hours horas, $minutes minutos, $second segundos" 119 | } 120 | 121 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge49.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #49 5 | * EL DETECTOR DE HANDLES 6 | * Fecha publicación enunciado: 05/12/22 7 | * Fecha publicación resolución: 12/12/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que sea capaz de detectar y retornar todos los handles de un texto usando solamente Expresiones Regulares. 11 | * Debes crear una expresión regular para cada caso: 12 | * - Handle usuario: Los que comienzan por "@" 13 | * - Handle hashtag: Los que comienzan por "#" 14 | * - Handle web: Los que comienzan por "www.", "http://", "https://" y finalizan con un dominio (.com, .es...) 15 | * 16 | * Información adicional: 17 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 18 | * para preguntas, dudas o prestar ayuda a la comunidad. 19 | * - Tienes toda la información sobre los retos semanales en 20 | * https://retosdeprogramacion.com/semanales2022. 21 | * 22 | */ 23 | 24 | fun main() { 25 | println(handlesDetector("En esta actividad de @mouredev, resolvemos #retos de #programacion desde https://retosdeprogramacion.com/semanales2022, que @braismoure aloja en www.github.com")) 26 | } 27 | 28 | private fun handlesDetector(text: String): Map> { 29 | 30 | val handles = mutableMapOf>() 31 | 32 | handles["user"] = "@(\\w{2,15})".toRegex().findAll(text).toList().map { it.value } 33 | handles["hashtag"] = "#[^ !@$^#&,.?():%<>{}\\[\\]|\"]+".toRegex().findAll(text).toList().map { it.value } 34 | handles["url"] = "((https?://(www\\.)?)|www\\.)[\\w#+\\=]{2,256}\\.[a-zA-Z]{2,7}[\\w\\/?=&.+-]*".toRegex().findAll(text).toList().map { it.value } 35 | 36 | return handles 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge5.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import android.graphics.BitmapFactory 4 | import java.net.URL 5 | import kotlin.math.roundToInt 6 | 7 | /* 8 | * Reto #5 9 | * ASPECT RATIO DE UNA IMAGEN 10 | * Fecha publicación enunciado: 01/02/22 11 | * Fecha publicación resolución: 07/02/22 12 | * Dificultad: DIFÍCIL 13 | * 14 | * Enunciado: Crea un programa que se encargue de calcular el aspect ratio de una imagen a partir de una url. 15 | * - Nota: Esta prueba no se puede resolver con el playground online de Kotlin. Se necesita Android Studio. 16 | * - Url de ejemplo: https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_github_profile.png 17 | * - Por ratio hacemos referencia por ejemplo a los "16:9" de una imagen de 1920*1080px. 18 | * 19 | * Información adicional: 20 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 21 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 22 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 23 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 24 | * 25 | */ 26 | 27 | class Challenge5() { 28 | 29 | fun aspectRatio(url: String) { 30 | 31 | Thread { 32 | var aspectRationStr: String? = null 33 | 34 | val url = URL(url) 35 | val bitmap = BitmapFactory.decodeStream(url.openStream()) 36 | 37 | val height = bitmap.height 38 | val width = bitmap.width 39 | val aspectRatio = rationalAspectRatio(height.toDouble() / width.toDouble()) 40 | aspectRationStr = "${aspectRatio.second}:${aspectRatio.first}" 41 | 42 | aspectRationStr?.let { ratio -> 43 | println("El aspect ratio es ${ratio}") 44 | } ?: run { 45 | println("No se ha podido calcular el aspect ratio") 46 | } 47 | }.start() 48 | } 49 | 50 | data class Quadruple(val h1: Int, val k1: Int, val h: Int, val k: Int) 51 | 52 | private fun rationalAspectRatio(aspectRatio: Double): Pair { 53 | val precision = 1.0E-6 54 | var x = aspectRatio 55 | var a = x.roundToInt() 56 | var q = Quadruple(1, 0, a, 1) 57 | 58 | while (x - a > precision * q.k.toDouble() * q.k.toDouble()) { 59 | x = 1.0 / (x - a) 60 | a = x.roundToInt() 61 | q = Quadruple(q.h, q.k, q.h1 + a * q.h, q.k1 + a * q.k) 62 | } 63 | return Pair(q.h, q.k) 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #50 5 | * LA ENCRIPTACIÓN DE KARACA 6 | * Fecha publicación enunciado: 12/12/22 7 | * Fecha publicación resolución: 19/12/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea una función que sea capaz de encriptar y desencriptar texto utilizando el 11 | * algoritmo de encriptación de Karaca (debes buscar información sobre él). 12 | * 13 | * Información adicional: 14 | * - Usa el canal de nuestro Discord (https://mouredev.com/discord) "🔁reto-semanal" 15 | * para preguntas, dudas o prestar ayuda a la comunidad. 16 | * - Tienes toda la información sobre los retos semanales en 17 | * https://retosdeprogramacion.com/semanales2022. 18 | * 19 | */ 20 | 21 | fun main() { 22 | 23 | println(karaca("placa", false)) 24 | println(karaca("0c0lpaca", true)) 25 | 26 | println(karaca("Este es el penúltimo reto de programación del año", false)) 27 | println(karaca("1ts1aca s1aca l1aca 3m2tlún1paca 3t1raca 1daca nó2c0m0rg3rpaca l1daca 3ñ0aca", true)) 28 | 29 | // El algoritmo no soporta estos casos 30 | println(karaca("1", false)) 31 | println(karaca("1aca ", true)) 32 | } 33 | 34 | private fun karaca(text: String, isKaraca: Boolean): String { 35 | 36 | var result = "" 37 | 38 | text.lowercase().split(" ").forEach { word -> 39 | 40 | if (isKaraca) { 41 | result += word 42 | .dropLast(3) 43 | .replace("0", "a") 44 | .replace("1", "e") 45 | .replace("2", "i") 46 | .replace("3", "o") 47 | .replace("4", "u") 48 | .reversed().plus(" ") 49 | } else { 50 | result += word 51 | .reversed() 52 | .replace("a", "0") 53 | .replace("e", "1") 54 | .replace("i", "2") 55 | .replace("o", "3") 56 | .replace("u", "4") 57 | .plus("aca ") 58 | } 59 | } 60 | 61 | return result 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge51.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #51 5 | * EL RETO RANDOM 6 | * Fecha publicación enunciado: 19/12/22 7 | * Fecha publicación resolución: 26/12/22 8 | * Dificultad: ? 9 | * 10 | * Enunciado: Crea tu propio enunciado para que forme parte de los retos de 2023. 11 | * - Ten en cuenta que su dificultad debe ser asumible por la comunidad y seguir un estilo 12 | * semejante a los que hemos realizado durante el año. 13 | * - Si quieres también puedes proponer tu propia solución al reto (en el lenguaje que quieras). 14 | * 15 | * El día 26/12/22 presentaré las novedades para el nuevo año. 16 | * Prepárate para los nuevos retos de 2023... 17 | * 18 | */ -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge5Activity.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | 6 | // Activity necesaria para resolver el Challenge 5 7 | class Challenge5Activity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | setContentView(R.layout.activity_challenge5) 12 | 13 | Challenge5().aspectRatio("https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_github_profile.png") 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge6.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #6 5 | * INVIRTIENDO CADENAS 6 | * Fecha publicación enunciado: 07/02/22 7 | * Fecha publicación resolución: 14/02/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea un programa que invierta el orden de una cadena de texto sin usar funciones propias del lenguaje que lo hagan de forma automática. 11 | * - Si le pasamos "Hola mundo" nos retornaría "odnum aloH" 12 | * 13 | * Información adicional: 14 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 15 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 16 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 17 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 18 | * 19 | */ 20 | 21 | fun main() { 22 | println(reverse("Hola mundo")) 23 | println(recursiveReverse("Hola mundo")) 24 | } 25 | 26 | private fun reverse(text: String): String { 27 | val textCount = text.count() - 1 28 | var reversedText = "" 29 | for (index in 0..textCount) { 30 | reversedText += text[textCount - index] 31 | } 32 | return reversedText 33 | } 34 | 35 | // Sin un bucle, mediante una función recursiva 36 | private fun recursiveReverse(text: String, index: Int = 0, reversedText: String = ""): String { 37 | val textCount = text.count() - 1 38 | var newReversedText = reversedText 39 | newReversedText += text[textCount - index] 40 | if (index < textCount) { 41 | val newIndex = index + 1 42 | newReversedText = recursiveReverse(text, newIndex, newReversedText) 43 | } 44 | return newReversedText 45 | } 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge7.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #7 5 | * CONTANDO PALABRAS 6 | * Fecha publicación enunciado: 14/02/22 7 | * Fecha publicación resolución: 21/02/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un programa que cuente cuantas veces se repite cada palabra y que muestre el recuento final de todas ellas. 11 | * - Los signos de puntuación no forman parte de la palabra. 12 | * - Una palabra es la misma aunque aparezca en mayúsculas y minúsculas. 13 | * - No se pueden utilizar funciones propias del lenguaje que lo resuelvan automáticamente. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | countWords("Hola, mi nombre es brais. Mi nombre completo es Brais Moure (MoureDev).") 25 | } 26 | 27 | fun countWords(text: String) { 28 | 29 | val words = mutableMapOf() 30 | 31 | text.lowercase().replace("[^a-z0-9]".toRegex(), " ").split(" ").forEach { key -> 32 | if (key.isEmpty()) { 33 | return@forEach 34 | } 35 | if (words[key] != null) { 36 | words[key] = words.getValue(key) + 1 37 | } else { 38 | words[key] = 1 39 | } 40 | } 41 | 42 | words.forEach { word -> 43 | println("${word.key} se ha repetido ${word.value} ${if(word.value == 1) "vez" else "veces"}") 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge8.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #8 5 | * DECIMAL A BINARIO 6 | * Fecha publicación enunciado: 18/02/22 7 | * Fecha publicación resolución: 02/03/22 8 | * Dificultad: FÁCIL 9 | * 10 | * Enunciado: Crea un programa se encargue de transformar un número decimal a binario sin utilizar funciones propias del lenguaje que lo hagan directamente. 11 | * 12 | * Información adicional: 13 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 14 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 15 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 16 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 17 | * 18 | */ 19 | 20 | fun main() { 21 | println(decimalToBinary(387)) 22 | println(decimalToBinary(0)) 23 | } 24 | 25 | fun decimalToBinary(decimal: Int): String { 26 | 27 | var number = decimal 28 | var binary = "" 29 | 30 | while (number != 0) { 31 | 32 | val reminder = number % 2 33 | number /= 2 34 | 35 | binary = "$reminder$binary" 36 | } 37 | 38 | return binary.ifEmpty { "0" } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Challenge9.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Reto #9 5 | * CÓDIGO MORSE 6 | * Fecha publicación enunciado: 02/03/22 7 | * Fecha publicación resolución: 07/03/22 8 | * Dificultad: MEDIA 9 | * 10 | * Enunciado: Crea un programa que sea capaz de transformar texto natural a código morse y viceversa. 11 | * - Debe detectar automáticamente de qué tipo se trata y realizar la conversión. 12 | * - En morse se soporta raya "—", punto ".", un espacio " " entre letras o símbolos y dos espacios entre palabras " ". 13 | * - El alfabeto morse soportado será el mostrado en https://es.wikipedia.org/wiki/Código_morse. 14 | * 15 | * Información adicional: 16 | * - Usa el canal de nuestro discord (https://mouredev.com/discord) "🔁reto-semanal" para preguntas, dudas o prestar ayuda a la acomunidad. 17 | * - Puedes hacer un Fork del repo y una Pull Request al repo original para que veamos tu solución aportada. 18 | * - Revisaré el ejercicio en directo desde Twitch el lunes siguiente al de su publicación. 19 | * - Subiré una posible solución al ejercicio el lunes siguiente al de su publicación. 20 | * 21 | */ 22 | 23 | fun main() { 24 | 25 | val naturalText = "Chocapic. Es una marca de cereales?" 26 | val morseText = decoder(naturalText) 27 | println(morseText) 28 | println(decoder(morseText)) 29 | } 30 | 31 | private fun decoder(input: String): String { 32 | 33 | var decodedInput = "" 34 | 35 | val naturalDict = mapOf("A" to ".—", "N" to "—.", "0" to "—————", 36 | "B" to "—...", "Ñ" to "——.——", "1" to ".————", 37 | "C" to "—.—.", "O" to "———", "2" to "..———", 38 | "CH" to "————", "P" to ".——.", "3" to "...——", 39 | "D" to "—..", "Q" to "——.—", "4" to "....—", 40 | "E" to ".", "R" to ".—.", "5" to ".....", 41 | "F" to "..—.", "S" to "...", "6" to "—....", 42 | "G" to "——.", "T" to "—", "7" to "——...", 43 | "H" to "....", "U" to "..—", "8" to "———..", 44 | "I" to "..", "V" to "...—", "9" to "————.", 45 | "J" to ".———", "W" to ".——", "." to ".—.—.—", 46 | "K" to "—.—", "X" to "—..—", "," to "——..——", 47 | "L" to ".—..", "Y" to "—.——", "?" to "..——..", 48 | "M" to "——", "Z" to "——..", "\"" to ".—..—.", "/" to "—..—.") 49 | 50 | val morseDict = mutableMapOf() 51 | naturalDict.forEach { 52 | morseDict[it.value] = it.key 53 | } 54 | 55 | if (input.contains("[a-zA-Z0-9]".toRegex())) { 56 | 57 | // Natural 58 | 59 | var index = 0 60 | var ch = false 61 | 62 | input.uppercase().forEach { character -> 63 | if (!ch && character.toString() != " ") { 64 | val nextIndex = index + 1 65 | if (character.toString() == "C" && nextIndex < input.length && input.uppercase()[nextIndex].toString() == "H") { 66 | decodedInput += naturalDict["CH"] 67 | ch = true 68 | } else { 69 | decodedInput += naturalDict[character.toString()] 70 | } 71 | 72 | decodedInput += " " 73 | } else { 74 | if (!ch) { 75 | decodedInput += " " 76 | } 77 | ch = false 78 | } 79 | 80 | index++ 81 | } 82 | 83 | } else if (input.contains(".") || input.contains("—")) { 84 | 85 | // Morse 86 | 87 | input.split(" ").forEach { word -> 88 | word.split(" ").forEach { symbols -> 89 | if (symbols.isNotEmpty()) { 90 | decodedInput += morseDict[symbols] 91 | } 92 | } 93 | decodedInput += " " 94 | } 95 | } 96 | 97 | return decodedInput 98 | } -------------------------------------------------------------------------------- /app/src/main/java/com/mouredev/weeklychallenge2022/Readme.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | /* 4 | * Tienes toda la información ensencial en: 5 | * https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/README.md 6 | * 7 | * Cada nuevo reto se añadirá en un fichero .kt 8 | * 9 | * Recuerda que puedes ejecutar código Kotlin de una forma muy simple 10 | * utilizando fun main() { } y pulsando el botón de "play ►" en el lateral. 11 | */ 12 | 13 | fun main() { 14 | print("¡Hola comunidad!") 15 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_challenge5.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mouredev/Weekly-Challenge-2022-Kotlin/211814959bd8e98566b2440e3e4237dd210a74f2/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Weekly Challenge 2022 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/test/java/com/mouredev/weeklychallenge2022/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.mouredev.weeklychallenge2022 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:7.3.1' 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" 10 | 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | task clean(type: Delete) { 17 | delete rootProject.buildDir 18 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Dec 21 19:27:36 CET 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | google() 5 | mavenCentral() 6 | jcenter() // Warning: this repository is going to shut down soon 7 | } 8 | } 9 | rootProject.name = "Weekly Challenge 2022" 10 | include ':app' 11 | --------------------------------------------------------------------------------