├── .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 | [](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 | [](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 | [](https://kotlinlang.org)
20 | [](https://developer.android.com/studio)
21 | [](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 | [](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 | [](https://twitch.tv/mouredev)
144 | [](https://mouredev.com/discord)
145 | [](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 | ##  Hola, mi nombre es Brais Moure.
162 | ### Freelance full-stack iOS & Android engineer
163 |
164 | [](https://youtube.com/mouredevapps?sub_confirmation=1)
165 | [](https://twitch.com/mouredev)
166 | [](https://mouredev.com/discord)
167 | [](https://twitter.com/mouredev)
168 | 
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 | [](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 |
--------------------------------------------------------------------------------