From b457f4cbb84b6d0a12616162ccd75d77b4e67b24 Mon Sep 17 00:00:00 2001 From: humpwhale Date: Sun, 20 Apr 2025 10:04:34 +0800 Subject: [PATCH 1/2] update --- exercises/.quiz2.rs.un~ | Bin 0 -> 54294 bytes exercises/.quiz3.rs.un~ | Bin 0 -> 7291 bytes exercises/algorithm/.algorithm1.rs.un~ | Bin 0 -> 3368 bytes exercises/algorithm/.algorithm10.rs.un~ | Bin 0 -> 1431 bytes exercises/algorithm/.algorithm2.rs.un~ | Bin 0 -> 1895 bytes exercises/algorithm/.algorithm3.rs.un~ | Bin 0 -> 14167 bytes exercises/algorithm/.algorithm4.rs.un~ | Bin 0 -> 7179 bytes exercises/algorithm/.algorithm5.rs.un~ | Bin 0 -> 2340 bytes exercises/algorithm/.algorithm6.rs.un~ | Bin 0 -> 1429 bytes exercises/algorithm/.algorithm7.rs.un~ | Bin 0 -> 2744 bytes exercises/algorithm/.algorithm8.rs.un~ | Bin 0 -> 4135 bytes exercises/algorithm/.algorithm9.rs.un~ | Bin 0 -> 6230 bytes exercises/algorithm/algorithm1.rs | 50 ++++- exercises/algorithm/algorithm1.rs~ | 203 ++++++++++++++++++ exercises/algorithm/algorithm10.rs | 21 +- exercises/algorithm/algorithm10.rs~ | 82 ++++++++ exercises/algorithm/algorithm2.rs | 23 +- exercises/algorithm/algorithm2.rs~ | 174 +++++++++++++++ exercises/algorithm/algorithm3.rs | 15 +- exercises/algorithm/algorithm3.rs~ | 40 ++++ exercises/algorithm/algorithm4.rs | 64 +++++- exercises/algorithm/algorithm4.rs~ | 172 +++++++++++++++ exercises/algorithm/algorithm5.rs | 23 +- exercises/algorithm/algorithm5.rs~ | 100 +++++++++ exercises/algorithm/algorithm6.rs | 12 +- exercises/algorithm/algorithm6.rs~ | 84 ++++++++ exercises/algorithm/algorithm7.rs | 40 +++- exercises/algorithm/algorithm7.rs~ | 168 +++++++++++++++ exercises/algorithm/algorithm8.rs | 40 +++- exercises/algorithm/algorithm8.rs~ | 124 +++++++++++ exercises/algorithm/algorithm9.rs | 55 ++++- exercises/algorithm/algorithm9.rs~ | 193 +++++++++++++++++ exercises/clippy/.clippy1.rs.un~ | Bin 0 -> 1468 bytes exercises/clippy/.clippy2.rs.un~ | Bin 0 -> 2350 bytes exercises/clippy/.clippy3.rs.un~ | Bin 0 -> 12845 bytes exercises/clippy/clippy1.rs | 4 +- exercises/clippy/clippy1.rs~ | 24 +++ exercises/clippy/clippy2.rs | 4 +- exercises/clippy/clippy2.rs~ | 13 ++ exercises/clippy/clippy3.rs | 13 +- exercises/clippy/clippy3.rs~ | 28 +++ exercises/conversions/.as_ref_mut.rs.un~ | Bin 0 -> 8264 bytes exercises/conversions/.from_into.rs.un~ | Bin 0 -> 59999 bytes exercises/conversions/.from_str.rs.un~ | Bin 0 -> 73144 bytes exercises/conversions/.try_from_into.rs.un~ | Bin 0 -> 99532 bytes exercises/conversions/.using_as.rs.un~ | Bin 0 -> 1014 bytes exercises/conversions/as_ref_mut.rs | 12 +- exercises/conversions/as_ref_mut.rs~ | 65 ++++++ exercises/conversions/from_into.rs | 24 ++- exercises/conversions/from_into.rs~ | 162 ++++++++++++++ exercises/conversions/from_str.rs | 22 +- exercises/conversions/from_str.rs~ | 151 +++++++++++++ exercises/conversions/try_from_into.rs | 45 +++- exercises/conversions/try_from_into.rs~ | 222 ++++++++++++++++++++ exercises/conversions/using_as.rs | 4 +- exercises/conversions/using_as.rs~ | 31 +++ exercises/enums/.enums1.rs.un~ | Bin 0 -> 1436 bytes exercises/enums/.enums2.rs.un~ | Bin 0 -> 9520 bytes exercises/enums/.enums3.rs.un~ | Bin 0 -> 62508 bytes exercises/enums/enums1.rs | 7 +- exercises/enums/enums1.rs~ | 20 ++ exercises/enums/enums2.rs | 5 +- exercises/enums/enums2.rs~ | 33 +++ exercises/enums/enums3.rs | 12 +- exercises/enums/enums3.rs~ | 80 +++++++ exercises/error_handling/.errors1.rs.un~ | Bin 0 -> 18598 bytes exercises/error_handling/.errors2.rs.un~ | Bin 0 -> 25248 bytes exercises/error_handling/.errors3.rs.un~ | Bin 0 -> 2959 bytes exercises/error_handling/.errors4.rs.un~ | Bin 0 -> 10104 bytes exercises/error_handling/.errors5.rs.un~ | Bin 0 -> 5935 bytes exercises/error_handling/.errors6.rs.un~ | Bin 0 -> 2524 bytes exercises/error_handling/errors1.rs | 8 +- exercises/error_handling/errors1.rs~ | 41 ++++ exercises/error_handling/errors2.rs | 5 +- exercises/error_handling/errors2.rs~ | 49 +++++ exercises/error_handling/errors3.rs | 3 +- exercises/error_handling/errors3.rs~ | 33 +++ exercises/error_handling/errors4.rs | 12 +- exercises/error_handling/errors4.rs~ | 38 ++++ exercises/error_handling/errors5.rs | 4 +- exercises/error_handling/errors5.rs~ | 69 ++++++ exercises/error_handling/errors6.rs | 7 +- exercises/error_handling/errors6.rs~ | 95 +++++++++ exercises/generics/.generics1.rs.un~ | Bin 0 -> 2009 bytes exercises/generics/.generics2.rs.un~ | Bin 0 -> 4988 bytes exercises/generics/generics1.rs | 4 +- exercises/generics/generics1.rs~ | 12 ++ exercises/generics/generics2.rs | 10 +- exercises/generics/generics2.rs~ | 32 +++ exercises/hashmaps/.hashmaps1.rs.un~ | Bin 0 -> 6172 bytes exercises/hashmaps/.hashmaps2.rs.un~ | Bin 0 -> 14201 bytes exercises/hashmaps/.hashmaps3.rs.un~ | Bin 0 -> 73450 bytes exercises/hashmaps/hashmaps1.rs | 5 +- exercises/hashmaps/hashmaps1.rs~ | 45 ++++ exercises/hashmaps/hashmaps2.rs | 7 +- exercises/hashmaps/hashmaps2.rs~ | 98 +++++++++ exercises/hashmaps/hashmaps3.rs | 24 ++- exercises/hashmaps/hashmaps3.rs~ | 109 ++++++++++ exercises/iterators/.iterators1.rs.un~ | Bin 0 -> 9058 bytes exercises/iterators/.iterators2.rs.un~ | Bin 0 -> 25949 bytes exercises/iterators/.iterators3.rs.un~ | Bin 0 -> 38236 bytes exercises/iterators/.iterators4.rs.un~ | Bin 0 -> 29861 bytes exercises/iterators/.iterators5.rs.un~ | Bin 0 -> 86939 bytes exercises/iterators/iterators1.rs | 10 +- exercises/iterators/iterators1.rs~ | 23 ++ exercises/iterators/iterators2.rs | 26 ++- exercises/iterators/iterators2.rs~ | 79 +++++++ exercises/iterators/iterators3.rs | 23 +- exercises/iterators/iterators3.rs~ | 99 +++++++++ exercises/iterators/iterators4.rs | 16 +- exercises/iterators/iterators4.rs~ | 54 +++++ exercises/iterators/iterators5.rs | 44 +++- exercises/iterators/iterators5.rs~ | 192 +++++++++++++++++ exercises/lifetimes/.lifetimes1.rs.un~ | Bin 0 -> 4828 bytes exercises/lifetimes/.lifetimes2.rs.un~ | Bin 0 -> 1952 bytes exercises/lifetimes/.lifetimes3.rs.un~ | Bin 0 -> 4112 bytes exercises/lifetimes/lifetimes1.rs | 4 +- exercises/lifetimes/lifetimes1.rs~ | 25 +++ exercises/lifetimes/lifetimes2.rs | 4 +- exercises/lifetimes/lifetimes2.rs~ | 25 +++ exercises/lifetimes/lifetimes3.rs | 8 +- exercises/lifetimes/lifetimes3.rs~ | 19 ++ exercises/macros/.macros1.rs.un~ | Bin 0 -> 996 bytes exercises/macros/.macros2.rs.un~ | Bin 0 -> 1443 bytes exercises/macros/.macros3.rs.un~ | Bin 0 -> 18194 bytes exercises/macros/.macros4.rs.un~ | Bin 0 -> 1404 bytes exercises/macros/macros1.rs | 4 +- exercises/macros/macros1.rs~ | 14 ++ exercises/macros/macros2.rs | 10 +- exercises/macros/macros2.rs~ | 14 ++ exercises/macros/macros3.rs | 4 +- exercises/macros/macros3.rs~ | 20 ++ exercises/macros/macros4.rs | 6 +- exercises/macros/macros4.rs~ | 19 ++ exercises/modules/.modules1.rs.un~ | Bin 0 -> 1012 bytes exercises/modules/.modules2.rs.un~ | Bin 0 -> 10877 bytes exercises/modules/.modules3.rs.un~ | Bin 0 -> 3227 bytes exercises/modules/modules1.rs | 4 +- exercises/modules/modules1.rs~ | 20 ++ exercises/modules/modules2.rs | 6 +- exercises/modules/modules2.rs~ | 32 +++ exercises/modules/modules3.rs | 3 +- exercises/modules/modules3.rs~ | 20 ++ exercises/options/.options1.rs.un~ | Bin 0 -> 19197 bytes exercises/options/.options2.rs.un~ | Bin 0 -> 8504 bytes exercises/options/.options3.rs.un~ | Bin 0 -> 1096 bytes exercises/options/options1.rs | 12 +- exercises/options/options1.rs~ | 43 ++++ exercises/options/options2.rs | 12 +- exercises/options/options2.rs~ | 44 ++++ exercises/options/options3.rs | 4 +- exercises/options/options3.rs~ | 19 ++ exercises/quiz2.rs | 22 +- exercises/quiz2.rs~ | 78 +++++++ exercises/quiz3.rs | 10 +- exercises/quiz3.rs~ | 62 ++++++ exercises/smart_pointers/.arc1.rs.un~ | Bin 0 -> 6948 bytes exercises/smart_pointers/.box1.rs.un~ | Bin 0 -> 8181 bytes exercises/smart_pointers/.cow1.rs.un~ | Bin 0 -> 2349 bytes exercises/smart_pointers/.rc1.rs.un~ | Bin 0 -> 7865 bytes exercises/smart_pointers/arc1.rs | 6 +- exercises/smart_pointers/arc1.rs~ | 43 ++++ exercises/smart_pointers/box1.rs | 8 +- exercises/smart_pointers/box1.rs~ | 56 +++++ exercises/smart_pointers/cow1.rs | 8 +- exercises/smart_pointers/cow1.rs~ | 82 ++++++++ exercises/smart_pointers/rc1.rs | 11 +- exercises/smart_pointers/rc1.rs~ | 105 +++++++++ exercises/strings/.strings1.rs.un~ | Bin 0 -> 1883 bytes exercises/strings/.strings2.rs.un~ | Bin 0 -> 1022 bytes exercises/strings/.strings3.rs.un~ | Bin 0 -> 21377 bytes exercises/strings/.strings4.rs.un~ | Bin 0 -> 9359 bytes exercises/strings/strings1.rs | 3 +- exercises/strings/strings1.rs~ | 17 ++ exercises/strings/strings2.rs | 3 +- exercises/strings/strings2.rs~ | 20 ++ exercises/strings/strings3.rs | 13 +- exercises/strings/strings3.rs~ | 50 +++++ exercises/strings/strings4.rs | 21 +- exercises/strings/strings4.rs~ | 29 +++ exercises/structs/.structs1.rs.un~ | Bin 0 -> 8900 bytes exercises/structs/.structs2.rs.un~ | Bin 0 -> 4177 bytes exercises/structs/.structs3.rs.un~ | Bin 0 -> 5604 bytes exercises/structs/structs1.rs | 13 +- exercises/structs/structs1.rs~ | 54 +++++ exercises/structs/structs2.rs | 12 +- exercises/structs/structs2.rs~ | 58 +++++ exercises/structs/structs3.rs | 11 +- exercises/structs/structs3.rs~ | 92 ++++++++ exercises/tests/.build.rs.un~ | Bin 0 -> 23843 bytes exercises/tests/.tests1.rs.un~ | Bin 0 -> 1446 bytes exercises/tests/.tests2.rs.un~ | Bin 0 -> 1008 bytes exercises/tests/.tests3.rs.un~ | Bin 0 -> 3236 bytes exercises/tests/.tests4.rs.un~ | Bin 0 -> 3316 bytes exercises/tests/.tests5.rs.un~ | Bin 0 -> 5481 bytes exercises/tests/.tests6.rs.un~ | Bin 0 -> 5812 bytes exercises/tests/.tests7.rs.un~ | Bin 0 -> 962 bytes exercises/tests/.tests8.rs.un~ | Bin 0 -> 998 bytes exercises/tests/.tests9.rs.un~ | Bin 0 -> 3690 bytes exercises/tests/Cargo.lock | 7 + exercises/tests/Cargo.toml | 7 + exercises/tests/build.rs | 9 +- exercises/tests/build.rs~ | 23 ++ exercises/tests/tests1.rs | 4 +- exercises/tests/tests1.rs~ | 19 ++ exercises/tests/tests2.rs | 4 +- exercises/tests/tests2.rs~ | 15 ++ exercises/tests/tests3.rs | 6 +- exercises/tests/tests3.rs~ | 27 +++ exercises/tests/tests4.rs | 8 +- exercises/tests/tests4.rs~ | 48 +++++ exercises/tests/tests5.rs | 5 +- exercises/tests/tests5.rs~ | 50 +++++ exercises/tests/tests6.rs | 8 +- exercises/tests/tests6.rs~ | 43 ++++ exercises/tests/tests7.rs | 2 - exercises/tests/tests7.rs~ | 52 +++++ exercises/tests/tests8.rs | 3 - exercises/tests/tests8.rs~ | 23 ++ exercises/tests/tests9.rs | 7 +- exercises/tests/tests9.rs~ | 61 ++++++ exercises/threads/.threads1.rs.un~ | Bin 0 -> 10018 bytes exercises/threads/.threads2.rs.un~ | Bin 0 -> 19423 bytes exercises/threads/.threads3.rs.un~ | Bin 0 -> 5578 bytes exercises/threads/threads1.rs | 4 +- exercises/threads/threads1.rs~ | 40 ++++ exercises/threads/threads2.rs | 9 +- exercises/threads/threads2.rs~ | 40 ++++ exercises/threads/threads3.rs | 5 +- exercises/threads/threads3.rs~ | 65 ++++++ exercises/traits/.traits1.rs.un~ | Bin 0 -> 8173 bytes exercises/traits/.traits2.rs.un~ | Bin 0 -> 25554 bytes exercises/traits/.traits3.rs.un~ | Bin 0 -> 5158 bytes exercises/traits/.traits4.rs.un~ | Bin 0 -> 8171 bytes exercises/traits/.traits5.rs.un~ | Bin 0 -> 2945 bytes exercises/traits/traits1.rs | 7 +- exercises/traits/traits1.rs~ | 45 ++++ exercises/traits/traits2.rs | 12 +- exercises/traits/traits2.rs~ | 37 ++++ exercises/traits/traits3.rs | 6 +- exercises/traits/traits3.rs~ | 42 ++++ exercises/traits/traits4.rs | 4 +- exercises/traits/traits4.rs~ | 47 +++++ exercises/traits/traits5.rs | 4 +- exercises/traits/traits5.rs~ | 38 ++++ 245 files changed, 5738 insertions(+), 320 deletions(-) create mode 100644 exercises/.quiz2.rs.un~ create mode 100644 exercises/.quiz3.rs.un~ create mode 100644 exercises/algorithm/.algorithm1.rs.un~ create mode 100644 exercises/algorithm/.algorithm10.rs.un~ create mode 100644 exercises/algorithm/.algorithm2.rs.un~ create mode 100644 exercises/algorithm/.algorithm3.rs.un~ create mode 100644 exercises/algorithm/.algorithm4.rs.un~ create mode 100644 exercises/algorithm/.algorithm5.rs.un~ create mode 100644 exercises/algorithm/.algorithm6.rs.un~ create mode 100644 exercises/algorithm/.algorithm7.rs.un~ create mode 100644 exercises/algorithm/.algorithm8.rs.un~ create mode 100644 exercises/algorithm/.algorithm9.rs.un~ create mode 100644 exercises/algorithm/algorithm1.rs~ create mode 100644 exercises/algorithm/algorithm10.rs~ create mode 100644 exercises/algorithm/algorithm2.rs~ create mode 100644 exercises/algorithm/algorithm3.rs~ create mode 100644 exercises/algorithm/algorithm4.rs~ create mode 100644 exercises/algorithm/algorithm5.rs~ create mode 100644 exercises/algorithm/algorithm6.rs~ create mode 100644 exercises/algorithm/algorithm7.rs~ create mode 100644 exercises/algorithm/algorithm8.rs~ create mode 100644 exercises/algorithm/algorithm9.rs~ create mode 100644 exercises/clippy/.clippy1.rs.un~ create mode 100644 exercises/clippy/.clippy2.rs.un~ create mode 100644 exercises/clippy/.clippy3.rs.un~ create mode 100644 exercises/clippy/clippy1.rs~ create mode 100644 exercises/clippy/clippy2.rs~ create mode 100644 exercises/clippy/clippy3.rs~ create mode 100644 exercises/conversions/.as_ref_mut.rs.un~ create mode 100644 exercises/conversions/.from_into.rs.un~ create mode 100644 exercises/conversions/.from_str.rs.un~ create mode 100644 exercises/conversions/.try_from_into.rs.un~ create mode 100644 exercises/conversions/.using_as.rs.un~ create mode 100644 exercises/conversions/as_ref_mut.rs~ create mode 100644 exercises/conversions/from_into.rs~ create mode 100644 exercises/conversions/from_str.rs~ create mode 100644 exercises/conversions/try_from_into.rs~ create mode 100644 exercises/conversions/using_as.rs~ create mode 100644 exercises/enums/.enums1.rs.un~ create mode 100644 exercises/enums/.enums2.rs.un~ create mode 100644 exercises/enums/.enums3.rs.un~ create mode 100644 exercises/enums/enums1.rs~ create mode 100644 exercises/enums/enums2.rs~ create mode 100644 exercises/enums/enums3.rs~ create mode 100644 exercises/error_handling/.errors1.rs.un~ create mode 100644 exercises/error_handling/.errors2.rs.un~ create mode 100644 exercises/error_handling/.errors3.rs.un~ create mode 100644 exercises/error_handling/.errors4.rs.un~ create mode 100644 exercises/error_handling/.errors5.rs.un~ create mode 100644 exercises/error_handling/.errors6.rs.un~ create mode 100644 exercises/error_handling/errors1.rs~ create mode 100644 exercises/error_handling/errors2.rs~ create mode 100644 exercises/error_handling/errors3.rs~ create mode 100644 exercises/error_handling/errors4.rs~ create mode 100644 exercises/error_handling/errors5.rs~ create mode 100644 exercises/error_handling/errors6.rs~ create mode 100644 exercises/generics/.generics1.rs.un~ create mode 100644 exercises/generics/.generics2.rs.un~ create mode 100644 exercises/generics/generics1.rs~ create mode 100644 exercises/generics/generics2.rs~ create mode 100644 exercises/hashmaps/.hashmaps1.rs.un~ create mode 100644 exercises/hashmaps/.hashmaps2.rs.un~ create mode 100644 exercises/hashmaps/.hashmaps3.rs.un~ create mode 100644 exercises/hashmaps/hashmaps1.rs~ create mode 100644 exercises/hashmaps/hashmaps2.rs~ create mode 100644 exercises/hashmaps/hashmaps3.rs~ create mode 100644 exercises/iterators/.iterators1.rs.un~ create mode 100644 exercises/iterators/.iterators2.rs.un~ create mode 100644 exercises/iterators/.iterators3.rs.un~ create mode 100644 exercises/iterators/.iterators4.rs.un~ create mode 100644 exercises/iterators/.iterators5.rs.un~ create mode 100644 exercises/iterators/iterators1.rs~ create mode 100644 exercises/iterators/iterators2.rs~ create mode 100644 exercises/iterators/iterators3.rs~ create mode 100644 exercises/iterators/iterators4.rs~ create mode 100644 exercises/iterators/iterators5.rs~ create mode 100644 exercises/lifetimes/.lifetimes1.rs.un~ create mode 100644 exercises/lifetimes/.lifetimes2.rs.un~ create mode 100644 exercises/lifetimes/.lifetimes3.rs.un~ create mode 100644 exercises/lifetimes/lifetimes1.rs~ create mode 100644 exercises/lifetimes/lifetimes2.rs~ create mode 100644 exercises/lifetimes/lifetimes3.rs~ create mode 100644 exercises/macros/.macros1.rs.un~ create mode 100644 exercises/macros/.macros2.rs.un~ create mode 100644 exercises/macros/.macros3.rs.un~ create mode 100644 exercises/macros/.macros4.rs.un~ create mode 100644 exercises/macros/macros1.rs~ create mode 100644 exercises/macros/macros2.rs~ create mode 100644 exercises/macros/macros3.rs~ create mode 100644 exercises/macros/macros4.rs~ create mode 100644 exercises/modules/.modules1.rs.un~ create mode 100644 exercises/modules/.modules2.rs.un~ create mode 100644 exercises/modules/.modules3.rs.un~ create mode 100644 exercises/modules/modules1.rs~ create mode 100644 exercises/modules/modules2.rs~ create mode 100644 exercises/modules/modules3.rs~ create mode 100644 exercises/options/.options1.rs.un~ create mode 100644 exercises/options/.options2.rs.un~ create mode 100644 exercises/options/.options3.rs.un~ create mode 100644 exercises/options/options1.rs~ create mode 100644 exercises/options/options2.rs~ create mode 100644 exercises/options/options3.rs~ create mode 100644 exercises/quiz2.rs~ create mode 100644 exercises/quiz3.rs~ create mode 100644 exercises/smart_pointers/.arc1.rs.un~ create mode 100644 exercises/smart_pointers/.box1.rs.un~ create mode 100644 exercises/smart_pointers/.cow1.rs.un~ create mode 100644 exercises/smart_pointers/.rc1.rs.un~ create mode 100644 exercises/smart_pointers/arc1.rs~ create mode 100644 exercises/smart_pointers/box1.rs~ create mode 100644 exercises/smart_pointers/cow1.rs~ create mode 100644 exercises/smart_pointers/rc1.rs~ create mode 100644 exercises/strings/.strings1.rs.un~ create mode 100644 exercises/strings/.strings2.rs.un~ create mode 100644 exercises/strings/.strings3.rs.un~ create mode 100644 exercises/strings/.strings4.rs.un~ create mode 100644 exercises/strings/strings1.rs~ create mode 100644 exercises/strings/strings2.rs~ create mode 100644 exercises/strings/strings3.rs~ create mode 100644 exercises/strings/strings4.rs~ create mode 100644 exercises/structs/.structs1.rs.un~ create mode 100644 exercises/structs/.structs2.rs.un~ create mode 100644 exercises/structs/.structs3.rs.un~ create mode 100644 exercises/structs/structs1.rs~ create mode 100644 exercises/structs/structs2.rs~ create mode 100644 exercises/structs/structs3.rs~ create mode 100644 exercises/tests/.build.rs.un~ create mode 100644 exercises/tests/.tests1.rs.un~ create mode 100644 exercises/tests/.tests2.rs.un~ create mode 100644 exercises/tests/.tests3.rs.un~ create mode 100644 exercises/tests/.tests4.rs.un~ create mode 100644 exercises/tests/.tests5.rs.un~ create mode 100644 exercises/tests/.tests6.rs.un~ create mode 100644 exercises/tests/.tests7.rs.un~ create mode 100644 exercises/tests/.tests8.rs.un~ create mode 100644 exercises/tests/.tests9.rs.un~ create mode 100644 exercises/tests/Cargo.lock create mode 100644 exercises/tests/Cargo.toml create mode 100644 exercises/tests/build.rs~ create mode 100644 exercises/tests/tests1.rs~ create mode 100644 exercises/tests/tests2.rs~ create mode 100644 exercises/tests/tests3.rs~ create mode 100644 exercises/tests/tests4.rs~ create mode 100644 exercises/tests/tests5.rs~ create mode 100644 exercises/tests/tests6.rs~ create mode 100644 exercises/tests/tests7.rs~ create mode 100644 exercises/tests/tests8.rs~ create mode 100644 exercises/tests/tests9.rs~ create mode 100644 exercises/threads/.threads1.rs.un~ create mode 100644 exercises/threads/.threads2.rs.un~ create mode 100644 exercises/threads/.threads3.rs.un~ create mode 100644 exercises/threads/threads1.rs~ create mode 100644 exercises/threads/threads2.rs~ create mode 100644 exercises/threads/threads3.rs~ create mode 100644 exercises/traits/.traits1.rs.un~ create mode 100644 exercises/traits/.traits2.rs.un~ create mode 100644 exercises/traits/.traits3.rs.un~ create mode 100644 exercises/traits/.traits4.rs.un~ create mode 100644 exercises/traits/.traits5.rs.un~ create mode 100644 exercises/traits/traits1.rs~ create mode 100644 exercises/traits/traits2.rs~ create mode 100644 exercises/traits/traits3.rs~ create mode 100644 exercises/traits/traits4.rs~ create mode 100644 exercises/traits/traits5.rs~ diff --git a/exercises/.quiz2.rs.un~ b/exercises/.quiz2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..54e629a88bd58e239bb200e5679261eb5607d268 GIT binary patch literal 54294 zcmeI5TZ~m#8Gr{$TY8~|mI7^Q*#n*F87{-6Kw*GkD6~LJp%hB1ln%pin2s_tbS{Jz zN~=%$;)C(Q2a~=SA2fYY6BA8rq7RKmO%tQh)Wl2DX!OB2^_Cc;>sx#Md;W9IKKrcM zi+NjrvSzKlXYX^?{=fbI>%PvZ;gNS<7(FodQQQ1?KU{Rz&i{;k?u$#_uU>n1#ScF` ze()#X{%GNopI!U!f#kgp*0i;?9W_B@g-OgaVZxmtme4lz@%!Iez<+z%`af_N%y%&n z|KbC!{LhFzBPU{fgEcTTedSLU$GodTDC1C)vAqZ&$LRmpHk)?K74rx83AEf(W`DCh+lXktkZ2OEE3}G5u{xQIOid`T3UFT}1Q5j?x3z|w!`4=y zp(ys>=4w&Uz0Cv>$aCFeoQSm1!d!}>y*JR5Q`)^Xe!3}c@ZPQ-2=w6Y=3K;$76JrK z+PaO2Nw>Stx-4mf`;f)GAm6wj_cd;fyEnPolsA0uaJe9YJ&t@c2az{g2oN9M=d^jF z`n4uJVFJ$lL3oRd3``EbnhcJOj0}vPcTDAmeeQ<4THtmim_M+*Vs1ODe4e8qej;P;yV`1P72>HR78o}L#jU8;@`4op;&J-x|sk@jg>_p*9bs~Gwa-E9IdHQ znex>6S;#F>nT0AOW93LGrF7DVh*c>hDCvWBdy%=8biz{@`GGKRdF4mdQLV);y-BSd%d5_XeizcfFuLf-Q zc=b|sV6xIB4jH0$a+`Y&XhV26$B{5v2oN8_HN$)Lwc_2gHeDgSIYSK6`_)5$8^mNT zB1Q=z;)6IH(z`hw(yK?jCj_y~b%f~y>M`IA<5irCW{egB#E0=qMUMJ_2jg@or#s(Y z8*3KSpnXt14A?=Pa4w=o3jq?0`l%MED_v?Fpe1bJ+WE@vkpK_u4vr&iv=AUZu+Lb# zz9rvxA87@9YGU|}YS*lggZLr!P~ZpoLC!_wXdys+kdGF*@@M>z&&J3hEVF`mH0Vc< zjwWt|_z-{162CRy$Zr(!D>G#{gl*N#Js|WW@f$&#&+s9B-4b7z5=Zq613hIz^C4fk ziV+JL@&#PNu@j(j9iJ4PHA)B(ACO*Kpm9xImx@cBr3*C10K#55+By4-M zW6`WMQzq#{`>VQW7K0Sp%j#+OQwpzlWBQ57lU;w}@&?H5CfKD65uVdZ*~kap_bt5J zQ&Zh$zUgrj1m2y%n=-Q+&2n66>Vk+576Bj7_j4j5Lkj`ogY1_U*&TE0UBy75%jy#m z@`r)ii8ztAsHJ4=L;DYw_MQ0#xm|E$^;;k9kjn$CQcoGs6>WsZKH$D$!QGt?ZdC)go*uP=2urs9wC#ilr>fkqk5DP7ZAQKe80Hl#D%CURz^Xy1CxcvXi#Howw9{ zUlI17(2Lg9akj&V%%YG-pyour2+>+mLWuYf?zDvONv*Y>u*W*}N>{o@J&&%`gXI}$ zl0>?qjnLSK?v5h+?ZFop+i#_ReSZO9fZ9c??pYXpAzQZpCpu`Sm9mi!;GQDDJ3Rmw z@`dL{m3>%8zDglMNguwuiumsE;agz7;M}Ah0n}uQ5KCW_5F$Q!4_LhS=9j*GK6qs* zRsm+P+BF>RX+TcJ%X;qUrJYvFMn0Hdw3wHsn59)C)#&D{b#k{GkZ~3$ZdI9vFcmHu zyU}=2LWuZK9k5iFr&OgSBUBGzyjtp(OjbPREUYz?76dnV8EoC+o(lB5N%TQR+$bSL zd~nxnX)N7Lg1h+&kDQHu>UM<@#2~fS>z)MMAhuQ>{j}3c*~ka+KXq-Z9&z&tgf)oM zy{x;3M<=S|W`&kp4^X=gkPw&I6Y@;ZhxlPmMB->6KzxX&yCJVgeRw_br?vkko%!$r z;`zYsZZn{zoWNmCgH5RWCfQ%F$cL;Og+o2TB)!i;$)WE}7pdnTGT+MUVmINISB3aZR{`*X3rxGOqk9HGN4QQI z!I2N#<3(`oWVsr+Zo(Cu?Am&lM;P*EScw%k(L~AEhuia-8^tGPBStyXB$u;N-2&7e zl`SAfa7rOTNgr@0i@6h{&G)!xhKDLIADGeuZS%y_p9u~Im=OWs7fbXQ)zmvh`ZD zN|X>HnN64vA)QC^yO!ibDarc6v!Oc`k}V5QS;_-U`td~oO*WQtBAO{$2oN8*?^(F2 z;h{^<)deosnW?Md0*=l+5uoz*vFsF$gv34|e_%mAoLVV2Fd+T33A8I$NHV-In_nc|3xIVjD3k4u|ivXAI zU)#AJfr?s6#vVYg&)2S&ZX#A)2vEC!Ws9{PC+x4zt(RFX1v7|&`;2-Nz6Hk~%T=Y6 z(n%lKw_4aqzB_K%8v<)S=ZaET9Z`9MV`Qfk5|s2|w@4c*H|V0YVYe&TbqYLSJ*zSZ z$OumcUR!geN&?1p4GhhR{FeqkZL=evqOBQ5jKFF3P**PG;L?z&k+7(xWb8xuXZ3_x%rBjM z4drXLR7D76F|KAhp7a4vdmv=AUZY=5iSVpgy{Vgd%+o@cPC(<$2%7;c|5K?J67q&^opqJ$9f z;rM&Yv65D!>p3=*pm5b3&q;d-aHmyXfyy2pi#Zn!5-kLX56Hh-kXXwi+gwC35o;Tr~%Pvg$_9Yz0niX0I5Fd^|(niS*n9(s4ij7jP#C*jl zfmh|&31IoOl^jQyXdyt*WV^c`J|Z-WtPD-R^&1USj8b6k%`-~>VpOJAK=p$AN+O7p zx42dcZG?&s<=+)iw)^+jlNQQ@-39d|0SwR~^&G&a{7pC)%@{2Nh!5bjmvLiSwsHf5 zFk;3ndl?6%a0T3}Dyu-{)0T2Bf25H*^U}F5SO%F}KeaKqsrrJu9fNW~1 z=S{Q5%TfV4Y=Q`|qos;ALSrAm>86pJOIqrAu~fi)O63=*fVAa(v{a>;GD#nhFI!99 zQW9k5asl^gl}Dgb4~vx}rIgZ1ACQ-I!Jecu z>*U>)bqDf=*tGOKfOCvvC!hvz!f`ZIv=AUZc&}N!+tTv0-t9JBNDf|H?+jwsSr5QV zCXBjl12>kVP8q>bYoH&$|GEXbJs;?%B6|hs3A>8C0V^0^Q`rY`v{R*!prjAh&s(gI z=VRU446CgkIa_Ul7L?;E`(Os`D$Ye0j1~gK2W|SZ=XGPKl#=sIXlk*7wh2}+PNBDdxn60hCOTdj*2WTZ8>VU^ z1B>G-S?}LjbB72ZfyyVY=VWxNXdys+V6L%lbzQA}3d~u}BWsupEL};@sYiI;q>r1> zVM27mN-?FA>&%^YeA2|Eb4Jy!r@!*@ND7(#%`kCU#+YsWA>F#Ewe}>Zs)M`JrOJDf z%hkd5(`SSzFBU!*!T2%RwI;Ni5X}}Pgvc6m^TX}~NL#I%m~m2@9-6*()taqqx^$U; zfc_~H=9$p^S5##|D_Dm|hq}$*x&?4DZ5yOoz|HsA!XbKQt(p>PAH>%!;$^APR?L@R kVS;#1ea$Ibu~GAzni=P@{web-dE6vuDU)cC5lO=_yEAsZJ4OJl20YM>Yw1#LiLk@_OGX&SXQCO3kQg^CMZ zh<*UUy`R93;Wuz4ilDCSR?q)r&h2m;!*H+5IdC$Q-08i;|JU=FyWHG-fB9Z{>x-8x zpRF&xdG+)~DRE}z+s7x*-!%$vi&w9;A68yp_b+reJkKkU=agZMc5SUbr-~=13v_9g zJVTx!A0>xj6!#k2cYdXCHSOK}gsWu9-oT%@G%nx&knyeL2RHs_1sdD8M;J%K`#nkb z9wQg|1+q6^Rv$w9Z(G!`@wpA2Y=6@g9= zOOZ6e=)4{}EJ%?fLV+ej*s2@Nj=JA%K2m&79t0gKW2<{h>9V+fs#wtEKx&V% zH&6sQE|ZR&p-hyi4Y@0W$c=}{&6flmK&6d60V2SmR=SXb2yx5?+{z$u*)X_jDL@BQ zdyU-zqlBzOX9yE%8Uz9Tbx?z7juwUM5w$2cOmyfhu~4#Q4wRp%wf%Fo z_L_RkttdFjVo&E#@Y_c&2DV4ZUG)=1;*2&tYbH;e7|=Hg&#~ra>+WunASBC#B*^V2 z7XwwSLzQ%q2@&F$4arp|nd}`N!X&dHlJnJ)4$FQp0q=mZUx39HTv!^SM4sBf?3iIG z6;8r3v%5k{Zv#>|U5bGsp68lUQ6$c2Pj09ehGBByrnDM#HUKqZ>)@>s{0twI%I4NB<0nqtA2(sk*0x?T2&m-VdzVFPJQWT zrZ?Q9H$xXrlS{(<*9&e<5451V}s*A@4#DBE&Hpcs~Zgn-p*uHN1R&2cH>t*eFoqq5NOsVh@tUFdKY7 W8DH8ybAle9=y7*Rvvdyp`r$9gC@GQv literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm1.rs.un~ b/exercises/algorithm/.algorithm1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..6c5e093f4c0ff92bc51e8b911dec9517019b1b1d GIT binary patch literal 3368 zcmeH}&o2W(6vwCAQkyt%Al&9if|3wPiICLq>PnQW5K9~F){i0~jkr3C3yG6Uk;dJB z;3Cpv6DM(S;m|YhJKYy6E~^~(CEvc8_h$C+{p@UKA(_6Iw<4Kmp*208p6%uP`}AUc z>tWAv>7qT-Rh}xIoagovclq8cA;dk2qmc$aQqV3SvqZuld=H=-5Q`7?0?p1yXw~ri zgF;of;N^dIAmOjQR5*O1+(OR|kl22pXb6Smq#T)%F(WP`Mr^e2NMS?IPvQW=S)O>< z*oi7L+=RmjjBC|Mh+WD$#&n7b3Y(~4GpNS)W1}x;bHZ*gnFF*Cb(s z11LVLC<7wasPMqC6IEt6;GUe|aMCiQ0!e|hF#$`E!~tX*BwSpChY2qHA>3ekbz%ad zO;V8rOvC!d&azy!WZK+XGuu+h?d;-GIGVK9&6Oxk2IE5=s<`~U*e*MVG@IK0@RJ_fJic$5)7LEDe@-`ofq@|r zh+%*W$Y2CwW~cy&hGB*bmJnSQkSr5J`~|22CMXS}KvJwQ{(m3u-*;0HyEfWE$hr-Gxef}ekgf{VYOE69G+MsU<2$1zA4q+Sk)xj~%K zr~`!pEdekmDTAYq0TOkfpw|cDU?2uX4VMBG=<9={79_6##6ds|i$dg_2NDKlQ;<3i q5N9+BL7_lP0E|K%XkiGBB3Ynipx_4qP!#eZqAX|G&zU> literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm2.rs.un~ b/exercises/algorithm/.algorithm2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..6685406fb350989df332a77d2f2c4502173d15cc GIT binary patch literal 1895 zcmWH`%$*;a=aT=Ffr)L$gr)sX;tp{FF%GZ)>;B_%`nr*`;&E8W3}e@VpwLwe3=Hdl z7zPA@3`QVkfeL_V7-q;|=7?ee$+9xUUw|rLg3=%gA_W!r4+LNlBn6{PYK8zXIvByx z!N~Ac0%$NOo>-w4fTBe}Uthsf!O>U2&p$-L#ox~rBxl+Pjyh0OF@yL}08;M-#2g_0 zXw-p1ftCOmb#CCOV}e8-DClE>cpeagqJ~=m3V=}vj$4odA0VC!#IQI7#ThK0f`mcw z=?%o7JUkkQpg^E00LEbeI1ZT+aR`c{^*{`YLtR)L!swjT5{2B-5{2Z_qN3Ei5(Qg@ z;?$fpz2cI@q7rLpzC_NGAlHN97Zms4Vs9Y$?L2{&fr1|dKyk{+ R$qCGnA^tA@rj5^60RUExPJsXb literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm3.rs.un~ b/exercises/algorithm/.algorithm3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..76e7f6f28280021a85c5360e3405c797681defb8 GIT binary patch literal 14167 zcmeI3&u>&k9Kav#w%vt7u~2?g3Imi{N??mgFQOQedLU8uvS>`xkdn0NCep@jA&|zH zp1gbU$i)+9qh9m~@urFKA25b^@?bpU_w#-8eVw=6tfV-e=9|pUdo%Oin|wd>{mysh zz5Sqd_tCAj`SstkzVYpIH=g`;`IBERoc(U&+2myP?el-kK3IA>_vgLmzfS!2S(atf zl1{CxxsCPq=9|sy(@X94(!)30)ZKfVZlSq&aZBolB-JGClXONBLT)Krtu&ris2$F3 z|3s}wU!LhNRfBf^TtshW1u6fJHL%)WT~-|XvcFHry$2+j`ayBHUUxU#JMX)jji#G# z+8n6}4y#SqiFi^4t8ZE>W0sXiWG>9f80lFK$^K{7L1DB$r zOazo%e~^=e4=uzL!S{8DkEszmHGEy|)T0BHxnlYV#)J+{{4XNtzUhT-tmI;6ypQ$l zU_~fo0!P>lQ;^IKEyNUI_if0|RDVGpir1{d4$*1PYB5Uln*d{)GXW-st7QqGsU=n} z0Ke}9i24x#4(Irs`*?ZNd7HDPhc=QQP=Qt@Au~cP20~nBJ!WsCI7{X>_SWvWx7_SC56*1Qx<^D=z)X(P)DkNfaD%Tu9GFoJH3vV;yT#1ug{rs(?e&FRj`?RaQzIl9>^R|R)dGSEd(0f!+9+PAOW`ZI8a3W2Irj}T_pnWeyYjNmBc_0S4dq;Yju6TIBI?lNl zKr*4GSjIFGH5Ygv_JUWe|JutN_6^#iM+YiCW-uNx#hEkmNInJYHXYI%eUWZkW;DjZ7H?^p z8cQu03g&1bJkGfn=ohh5nk7vwv2r2aR%;z7FB;8SPXMpH(I&e!SBvc$aJ?FI4wT?y zFr@euB}5g$_fYW-b;oxy#5Yy!w(anP*Qub3u*B*Uzd$K_KEx7iE4pxMQg&aGE)Ip? z7s{`i^E1;i^HY8udp1{Px74pfj8y1QAvht)1iH}V*2yAK!pq2u5PhUXYdKMyLXBv* zDbxq9kUAZ74vKu%q`_>O3IomTT5< z#9foBiPE&mR~X^cDGg53pzzE3AE>-V?wqBCu25+uJ4Z9NbtL6TjdJAE{5%`b6YmB> z7eGCu%0^roNnT@n&KMLnk~r3BSn_ZrJ<*XgoR6eIspKUHyF(ar&;P*9Z9jYb4+Rt3 AHUIzs literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm4.rs.un~ b/exercises/algorithm/.algorithm4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..9840d3bda8bf97e069ff8269fdf2e221b0560826 GIT binary patch literal 7179 zcmeI0y=xRf7>75P%a_K)!a^kA7&Y9P$RVO)6pe6EQJpsE3~BcdJ#0w!EY zGNj&Jx0s?B6V{&)Er`I>Zd};(WA>nNDTm<64^`)(A1WsT7focp`~MJgU)`|`!_ToX$j>_00J#! z8g3*W0}AvWfB*X48eKF$BFer zqWdCnuHT$!J_1|w5n$Umb^**GJqQ5RiKJQqxM%^k#Lv02ve1xQjEz6hsT-7fwNY|; z2c}Lt8~=bXE3zm9HqV(vx`OSgpLZEq<&fy1h`ielvf`jARBsMAVvyOvl!$=duqY72 zjl@HUEm>l%aiZmA#q*;75Q9*ccVp0lm?ao;%yTA@t`K`+iM9Qm*sir4Gp66(6Ol(0%sHBPTUPk3^KmHqhmA#(pwkazsQX z>aGM{`t_M%SaN~z_Kh2xjg9d8=JTt|ir7!2L6>oU<&9zen*v|J z{{CsjPfV@|=l~ZdwjwqH_q&DL5!Y28F3H&f+`HbcMemB|A5kv^Ai#4 Vb=R`?RAiLuNoo>*yfFND`5Sx*@{Irh literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm5.rs.un~ b/exercises/algorithm/.algorithm5.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..2d679dd0d5705f60e79365e1a230769b23e8badb GIT binary patch literal 2340 zcmWH`%$*;a=aT=Ffoa~sXngwY6u zg$PY)U<5iNN1#45_(7I}q6Qv;AT}qbzJ7?mi$65#Kv4zDra&e*8bMJ92BUco7810g zfl=pzFX}+{s>1SLPHKrlZfS`^S!Qu&Nql}$N@|gUtwLF9vSM_sH8ehvvmr<`C~iUV k393p*%TiDv&=kPqlNnN$B42z^~=%_MHFKm)cz8E$gQ-FffDw zF${138H_;83>5&;FwBs_64=ZFk&V9qRlo$LK@>=e6~_M$1Yi-Ez$i`S5CBF;6gWB< z8NNyY&1L~&Sn$K5ML=I)!BfG}SHaIeM8U=1&(*XM9CgTX400Aoy*LmHgE*s62MPsR z0$|kDfuoKA5_O=UR|H~TAO=MZhXNFUBNikp3B*1?%m9r*SOkNFKme3UK_-AQ@Mr{r n0)eIg7=caDq7WQK3P9UH!4CqU2;_rBpuT>Hzl*qL(f#4o`iI;Mrs+_6wH5YSlE%+@cAi*wmwNVdlu9BdVUv@8Nj^Rk&85qYHTk z&^=moDn&Pn%O;>Rh-mtZ3*fVCd0-4Wg_L7RW@Iiwo_t8bP#noMgW+?Q;kdJ(ml917 z1fUm3^$3%45QMGfrXxpEQmGhPiiQJ5QGKZo`F(=iizVm(RiAO!vHGOISX_MhNf22g zlLC`Ckyi$$?`(n5`V;6JA|}lqX}cqLcAyR<@Ur#AWrF0lEzklUEy*+RU(vJhbXsG_ YxQzBQ*d2S(99?fL1qXX=w8ppFUm_e_-2eap literal 0 HcmV?d00001 diff --git a/exercises/algorithm/.algorithm8.rs.un~ b/exercises/algorithm/.algorithm8.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..7ac9d9b6a178a0823ed8fed077a3eaf66bffdd84 GIT binary patch literal 4135 zcmeH~&r2IY9L2{ZHW_NIUTpBR*n=#ZD{yl|@^lj3gH1ycSc2iPYMWX`1^;e?U`!-77VJT*6-z`bG!a|9NDWE5ZGuTQ})&A`Iwbx6V7Y6S=yz#lWfARf7Pvp_zOJII?WWlCRbH9X;8dDLJ|2YHs(5WYaqs{uU4P%EOlYU~^kVvQz zb!1ef(&H+bP95d^1M`B8s5*GBgZ(3ra1YR#wD?s5-77(7x#*bsICKjlnjWPikr1?O zk3u&ggOJFG+yrs5A1!PJ2$=;x0|?&29zhwOvYHSN zLOXa9fMXW?41inodXK5+(s&1=_qq)@aUNTTpxclENMLJtuY)i-Lf|};5noFH{4M}H zT<0Zq`Z?+H&g%$=_iFQzRTq2eAV;#3l{7G)NsC`4j*wGc^D*`3pa&4m7oz#Zcx*Wa z-G_|v2un=HIs`!;hvXy^z++1M48SXR;StXW^c*6*J!a*cE~{K4mn+(tMkN|4HR`Hn z7pLQ@Fm>U8YSaoB?U=fx4M~P!$OQS4sYJlkWWui!OpAYFx?7n34NwB?@w_hK%JGMF z0Z>n7e7OWr#|t!tSx!R6q-~eA@yKPZ=M~6|or9gwlNA3h!Ko&kLhdPM6jRYAhEpev zXIPOQ|A7igMHIn{-N*Y&BbVsOeqfl%D8zm+f<^+tQ zU01Cx>X2-#eXSaKXi(vopJAt3b(+$y@^;n6C}Zvz%6&*)qp#M?R`^idGi*!-Na5+G zy{l@goD5Yc&v+hG*wwSS;w*;UZidA$c%#Npb!KZ5 yB6xFx_by_rCd@fq1^|(WRmDmGeiVRR?m~72)6MBAm;dU#CLB&VWqV-$+vA_P!933Z literal 0 HcmV?d00001 diff --git a/exercises/algorithm/algorithm1.rs b/exercises/algorithm/algorithm1.rs index f7a99bf02..4e61f54f9 100644 --- a/exercises/algorithm/algorithm1.rs +++ b/exercises/algorithm/algorithm1.rs @@ -2,7 +2,6 @@ single linked list merge This problem requires you to merge two ordered singly linked lists into one ordered singly linked list */ -// I AM NOT DONE use std::fmt::{self, Display, Formatter}; use std::ptr::NonNull; @@ -69,17 +68,48 @@ impl LinkedList { }, } } - pub fn merge(list_a:LinkedList,list_b:LinkedList) -> Self - { - //TODO - Self { - length: 0, - start: None, - end: None, +} + +impl LinkedList { + pub fn merge(list_a: LinkedList, list_b: LinkedList) -> Self { + let mut merged_list = LinkedList::::new(); + + let mut curr_a = list_a.start; + let mut curr_b = list_b.start; + + while curr_a.is_some() && curr_b.is_some() { + let val_a = unsafe { curr_a.as_ref().unwrap().as_ref().val.clone() }; + let val_b = unsafe { curr_b.as_ref().unwrap().as_ref().val.clone() }; + + if val_a <= val_b { + merged_list.add(val_a); + curr_a = unsafe { curr_a.unwrap().as_ref().next }; + } else { + merged_list.add(val_b); + curr_b = unsafe { curr_b.unwrap().as_ref().next }; + } } - } + + // Append remaining elements from list_a if any + while let Some(node) = curr_a { + let val = unsafe { node.as_ref().val.clone() }; + merged_list.add(val); + curr_a = unsafe { node.as_ref().next }; + } + + // Append remaining elements from list_b if any + while let Some(node) = curr_b { + let val = unsafe { node.as_ref().val.clone() }; + merged_list.add(val); + curr_b = unsafe { node.as_ref().next }; + } + + merged_list + } } + + impl Display for LinkedList where T: Display, @@ -170,4 +200,4 @@ mod tests { assert_eq!(target_vec[i],*list_c.get(i as i32).unwrap()); } } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm1.rs~ b/exercises/algorithm/algorithm1.rs~ new file mode 100644 index 000000000..4e61f54f9 --- /dev/null +++ b/exercises/algorithm/algorithm1.rs~ @@ -0,0 +1,203 @@ +/* + single linked list merge + This problem requires you to merge two ordered singly linked lists into one ordered singly linked list +*/ + +use std::fmt::{self, Display, Formatter}; +use std::ptr::NonNull; +use std::vec::*; + +#[derive(Debug)] +struct Node { + val: T, + next: Option>>, +} + +impl Node { + fn new(t: T) -> Node { + Node { + val: t, + next: None, + } + } +} +#[derive(Debug)] +struct LinkedList { + length: u32, + start: Option>>, + end: Option>>, +} + +impl Default for LinkedList { + fn default() -> Self { + Self::new() + } +} + +impl LinkedList { + pub fn new() -> Self { + Self { + length: 0, + start: None, + end: None, + } + } + + pub fn add(&mut self, obj: T) { + let mut node = Box::new(Node::new(obj)); + node.next = None; + let node_ptr = Some(unsafe { NonNull::new_unchecked(Box::into_raw(node)) }); + match self.end { + None => self.start = node_ptr, + Some(end_ptr) => unsafe { (*end_ptr.as_ptr()).next = node_ptr }, + } + self.end = node_ptr; + self.length += 1; + } + + pub fn get(&mut self, index: i32) -> Option<&T> { + self.get_ith_node(self.start, index) + } + + fn get_ith_node(&mut self, node: Option>>, index: i32) -> Option<&T> { + match node { + None => None, + Some(next_ptr) => match index { + 0 => Some(unsafe { &(*next_ptr.as_ptr()).val }), + _ => self.get_ith_node(unsafe { (*next_ptr.as_ptr()).next }, index - 1), + }, + } + } +} + +impl LinkedList { + pub fn merge(list_a: LinkedList, list_b: LinkedList) -> Self { + let mut merged_list = LinkedList::::new(); + + let mut curr_a = list_a.start; + let mut curr_b = list_b.start; + + while curr_a.is_some() && curr_b.is_some() { + let val_a = unsafe { curr_a.as_ref().unwrap().as_ref().val.clone() }; + let val_b = unsafe { curr_b.as_ref().unwrap().as_ref().val.clone() }; + + if val_a <= val_b { + merged_list.add(val_a); + curr_a = unsafe { curr_a.unwrap().as_ref().next }; + } else { + merged_list.add(val_b); + curr_b = unsafe { curr_b.unwrap().as_ref().next }; + } + } + + // Append remaining elements from list_a if any + while let Some(node) = curr_a { + let val = unsafe { node.as_ref().val.clone() }; + merged_list.add(val); + curr_a = unsafe { node.as_ref().next }; + } + + // Append remaining elements from list_b if any + while let Some(node) = curr_b { + let val = unsafe { node.as_ref().val.clone() }; + merged_list.add(val); + curr_b = unsafe { node.as_ref().next }; + } + + merged_list + } +} + + + +impl Display for LinkedList +where + T: Display, +{ + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.start { + Some(node) => write!(f, "{}", unsafe { node.as_ref() }), + None => Ok(()), + } + } +} + +impl Display for Node +where + T: Display, +{ + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.next { + Some(node) => write!(f, "{}, {}", self.val, unsafe { node.as_ref() }), + None => write!(f, "{}", self.val), + } + } +} + +#[cfg(test)] +mod tests { + use super::LinkedList; + + #[test] + fn create_numeric_list() { + let mut list = LinkedList::::new(); + list.add(1); + list.add(2); + list.add(3); + println!("Linked List is {}", list); + assert_eq!(3, list.length); + } + + #[test] + fn create_string_list() { + let mut list_str = LinkedList::::new(); + list_str.add("A".to_string()); + list_str.add("B".to_string()); + list_str.add("C".to_string()); + println!("Linked List is {}", list_str); + assert_eq!(3, list_str.length); + } + + #[test] + fn test_merge_linked_list_1() { + let mut list_a = LinkedList::::new(); + let mut list_b = LinkedList::::new(); + let vec_a = vec![1,3,5,7]; + let vec_b = vec![2,4,6,8]; + let target_vec = vec![1,2,3,4,5,6,7,8]; + + for i in 0..vec_a.len(){ + list_a.add(vec_a[i]); + } + for i in 0..vec_b.len(){ + list_b.add(vec_b[i]); + } + println!("list a {} list b {}", list_a,list_b); + let mut list_c = LinkedList::::merge(list_a,list_b); + println!("merged List is {}", list_c); + for i in 0..target_vec.len(){ + assert_eq!(target_vec[i],*list_c.get(i as i32).unwrap()); + } + } + #[test] + fn test_merge_linked_list_2() { + let mut list_a = LinkedList::::new(); + let mut list_b = LinkedList::::new(); + let vec_a = vec![11,33,44,88,89,90,100]; + let vec_b = vec![1,22,30,45]; + let target_vec = vec![1,11,22,30,33,44,45,88,89,90,100]; + + for i in 0..vec_a.len(){ + list_a.add(vec_a[i]); + } + for i in 0..vec_b.len(){ + list_b.add(vec_b[i]); + } + println!("list a {} list b {}", list_a,list_b); + let mut list_c = LinkedList::::merge(list_a,list_b); + println!("merged List is {}", list_c); + for i in 0..target_vec.len(){ + assert_eq!(target_vec[i],*list_c.get(i as i32).unwrap()); + } + } +} diff --git a/exercises/algorithm/algorithm10.rs b/exercises/algorithm/algorithm10.rs index a2ad731d0..934e21146 100644 --- a/exercises/algorithm/algorithm10.rs +++ b/exercises/algorithm/algorithm10.rs @@ -2,8 +2,6 @@ graph This problem requires you to implement a basic graph functio */ -// I AM NOT DONE - use std::collections::{HashMap, HashSet}; use std::fmt; #[derive(Debug, Clone)] @@ -29,7 +27,22 @@ impl Graph for UndirectedGraph { &self.adjacency_table } fn add_edge(&mut self, edge: (&str, &str, i32)) { - //TODO + let (from_node, to_node, weight) = edge; + + // Add both nodes if they don't exist + self.add_node(from_node); + self.add_node(to_node); + + // Add edge to both nodes' adjacency lists + self.adjacency_table + .entry(from_node.to_string()) + .and_modify(|neighbors| neighbors.push((to_node.to_string(), weight))) + .or_insert_with(|| vec![(to_node.to_string(), weight)]); + + self.adjacency_table + .entry(to_node.to_string()) + .and_modify(|neighbors| neighbors.push((from_node.to_string(), weight))) + .or_insert_with(|| vec![(from_node.to_string(), weight)]); } } pub trait Graph { @@ -81,4 +94,4 @@ mod test_undirected_graph { assert_eq!(graph.edges().contains(edge), true); } } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm10.rs~ b/exercises/algorithm/algorithm10.rs~ new file mode 100644 index 000000000..0f32fe9ac --- /dev/null +++ b/exercises/algorithm/algorithm10.rs~ @@ -0,0 +1,82 @@ +/* + graph + This problem requires you to implement a basic graph functio +*/ +use std::collections::{HashMap, HashSet}; +use std::fmt; +#[derive(Debug, Clone)] +pub struct NodeNotInGraph; +impl fmt::Display for NodeNotInGraph { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "accessing a node that is not in the graph") + } +} +pub struct UndirectedGraph { + adjacency_table: HashMap>, +} +impl Graph for UndirectedGraph { + fn new() -> UndirectedGraph { + UndirectedGraph { + adjacency_table: HashMap::new(), + } + } + fn adjacency_table_mutable(&mut self) -> &mut HashMap> { + &mut self.adjacency_table + } + fn adjacency_table(&self) -> &HashMap> { + &self.adjacency_table + } + fn add_edge(&mut self, edge: (&str, &str, i32)) { + //TODO + } +} +pub trait Graph { + fn new() -> Self; + fn adjacency_table_mutable(&mut self) -> &mut HashMap>; + fn adjacency_table(&self) -> &HashMap>; + fn add_node(&mut self, node: &str) -> bool { + //TODO + true + } + fn add_edge(&mut self, edge: (&str, &str, i32)) { + //TODO + } + fn contains(&self, node: &str) -> bool { + self.adjacency_table().get(node).is_some() + } + fn nodes(&self) -> HashSet<&String> { + self.adjacency_table().keys().collect() + } + fn edges(&self) -> Vec<(&String, &String, i32)> { + let mut edges = Vec::new(); + for (from_node, from_node_neighbours) in self.adjacency_table() { + for (to_node, weight) in from_node_neighbours { + edges.push((from_node, to_node, *weight)); + } + } + edges + } +} +#[cfg(test)] +mod test_undirected_graph { + use super::Graph; + use super::UndirectedGraph; + #[test] + fn test_add_edge() { + let mut graph = UndirectedGraph::new(); + graph.add_edge(("a", "b", 5)); + graph.add_edge(("b", "c", 10)); + graph.add_edge(("c", "a", 7)); + let expected_edges = [ + (&String::from("a"), &String::from("b"), 5), + (&String::from("b"), &String::from("a"), 5), + (&String::from("c"), &String::from("a"), 7), + (&String::from("a"), &String::from("c"), 7), + (&String::from("b"), &String::from("c"), 10), + (&String::from("c"), &String::from("b"), 10), + ]; + for edge in expected_edges.iter() { + assert_eq!(graph.edges().contains(edge), true); + } + } +} diff --git a/exercises/algorithm/algorithm2.rs b/exercises/algorithm/algorithm2.rs index 08720ff44..a391ccd23 100644 --- a/exercises/algorithm/algorithm2.rs +++ b/exercises/algorithm/algorithm2.rs @@ -2,8 +2,6 @@ double linked list reverse This problem requires you to reverse a doubly linked list */ -// I AM NOT DONE - use std::fmt::{self, Display, Formatter}; use std::ptr::NonNull; use std::vec::*; @@ -73,7 +71,24 @@ impl LinkedList { } } pub fn reverse(&mut self){ - // TODO + let mut current = self.start; + let mut new_end = self.start; + + while let Some(mut curr_ptr) = current { + unsafe { + // Swap next and prev pointers of the current node + let next = (*curr_ptr.as_ptr()).next; + (*curr_ptr.as_mut()).next = (*curr_ptr.as_ptr()).prev; + (*curr_ptr.as_mut()).prev = next; + } + + new_end = current; // Update new_end to current node + current = unsafe { (*curr_ptr.as_ptr()).prev }; // Move current to the previous node + } + + // Swap start and end pointers + self.end = self.start; + self.start = new_end; } } @@ -156,4 +171,4 @@ mod tests { assert_eq!(reverse_vec[i],*list.get(i as i32).unwrap()); } } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm2.rs~ b/exercises/algorithm/algorithm2.rs~ new file mode 100644 index 000000000..a391ccd23 --- /dev/null +++ b/exercises/algorithm/algorithm2.rs~ @@ -0,0 +1,174 @@ +/* + double linked list reverse + This problem requires you to reverse a doubly linked list +*/ +use std::fmt::{self, Display, Formatter}; +use std::ptr::NonNull; +use std::vec::*; + +#[derive(Debug)] +struct Node { + val: T, + next: Option>>, + prev: Option>>, +} + +impl Node { + fn new(t: T) -> Node { + Node { + val: t, + prev: None, + next: None, + } + } +} +#[derive(Debug)] +struct LinkedList { + length: u32, + start: Option>>, + end: Option>>, +} + +impl Default for LinkedList { + fn default() -> Self { + Self::new() + } +} + +impl LinkedList { + pub fn new() -> Self { + Self { + length: 0, + start: None, + end: None, + } + } + + pub fn add(&mut self, obj: T) { + let mut node = Box::new(Node::new(obj)); + node.next = None; + node.prev = self.end; + let node_ptr = Some(unsafe { NonNull::new_unchecked(Box::into_raw(node)) }); + match self.end { + None => self.start = node_ptr, + Some(end_ptr) => unsafe { (*end_ptr.as_ptr()).next = node_ptr }, + } + self.end = node_ptr; + self.length += 1; + } + + pub fn get(&mut self, index: i32) -> Option<&T> { + self.get_ith_node(self.start, index) + } + + fn get_ith_node(&mut self, node: Option>>, index: i32) -> Option<&T> { + match node { + None => None, + Some(next_ptr) => match index { + 0 => Some(unsafe { &(*next_ptr.as_ptr()).val }), + _ => self.get_ith_node(unsafe { (*next_ptr.as_ptr()).next }, index - 1), + }, + } + } + pub fn reverse(&mut self){ + let mut current = self.start; + let mut new_end = self.start; + + while let Some(mut curr_ptr) = current { + unsafe { + // Swap next and prev pointers of the current node + let next = (*curr_ptr.as_ptr()).next; + (*curr_ptr.as_mut()).next = (*curr_ptr.as_ptr()).prev; + (*curr_ptr.as_mut()).prev = next; + } + + new_end = current; // Update new_end to current node + current = unsafe { (*curr_ptr.as_ptr()).prev }; // Move current to the previous node + } + + // Swap start and end pointers + self.end = self.start; + self.start = new_end; + } +} + +impl Display for LinkedList +where + T: Display, +{ + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.start { + Some(node) => write!(f, "{}", unsafe { node.as_ref() }), + None => Ok(()), + } + } +} + +impl Display for Node +where + T: Display, +{ + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match self.next { + Some(node) => write!(f, "{}, {}", self.val, unsafe { node.as_ref() }), + None => write!(f, "{}", self.val), + } + } +} + +#[cfg(test)] +mod tests { + use super::LinkedList; + + #[test] + fn create_numeric_list() { + let mut list = LinkedList::::new(); + list.add(1); + list.add(2); + list.add(3); + println!("Linked List is {}", list); + assert_eq!(3, list.length); + } + + #[test] + fn create_string_list() { + let mut list_str = LinkedList::::new(); + list_str.add("A".to_string()); + list_str.add("B".to_string()); + list_str.add("C".to_string()); + println!("Linked List is {}", list_str); + assert_eq!(3, list_str.length); + } + + #[test] + fn test_reverse_linked_list_1() { + let mut list = LinkedList::::new(); + let original_vec = vec![2,3,5,11,9,7]; + let reverse_vec = vec![7,9,11,5,3,2]; + for i in 0..original_vec.len(){ + list.add(original_vec[i]); + } + println!("Linked List is {}", list); + list.reverse(); + println!("Reversed Linked List is {}", list); + for i in 0..original_vec.len(){ + assert_eq!(reverse_vec[i],*list.get(i as i32).unwrap()); + } + } + + #[test] + fn test_reverse_linked_list_2() { + let mut list = LinkedList::::new(); + let original_vec = vec![34,56,78,25,90,10,19,34,21,45]; + let reverse_vec = vec![45,21,34,19,10,90,25,78,56,34]; + for i in 0..original_vec.len(){ + list.add(original_vec[i]); + } + println!("Linked List is {}", list); + list.reverse(); + println!("Reversed Linked List is {}", list); + for i in 0..original_vec.len(){ + assert_eq!(reverse_vec[i],*list.get(i as i32).unwrap()); + } + } +} diff --git a/exercises/algorithm/algorithm3.rs b/exercises/algorithm/algorithm3.rs index 37878d6a7..502a0f6a7 100644 --- a/exercises/algorithm/algorithm3.rs +++ b/exercises/algorithm/algorithm3.rs @@ -3,10 +3,17 @@ This problem requires you to implement a sorting algorithm you can use bubble sorting, insertion sorting, heap sorting, etc. */ -// I AM NOT DONE -fn sort(array: &mut [T]){ - //TODO +fn sort(array: &mut [T]){ + let len = array.len(); + + for i in 0..len { + for j in 0..len - i - 1 { + if array[j] > array[j + 1] { + array.swap(j, j + 1); + } + } + } } #[cfg(test)] mod tests { @@ -30,4 +37,4 @@ mod tests { sort(&mut vec); assert_eq!(vec, vec![11, 22, 33, 44, 55, 66, 77, 88, 99]); } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm3.rs~ b/exercises/algorithm/algorithm3.rs~ new file mode 100644 index 000000000..502a0f6a7 --- /dev/null +++ b/exercises/algorithm/algorithm3.rs~ @@ -0,0 +1,40 @@ +/* + sort + This problem requires you to implement a sorting algorithm + you can use bubble sorting, insertion sorting, heap sorting, etc. +*/ + +fn sort(array: &mut [T]){ + let len = array.len(); + + for i in 0..len { + for j in 0..len - i - 1 { + if array[j] > array[j + 1] { + array.swap(j, j + 1); + } + } + } +} +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sort_1() { + let mut vec = vec![37, 73, 57, 75, 91, 19, 46, 64]; + sort(&mut vec); + assert_eq!(vec, vec![19, 37, 46, 57, 64, 73, 75, 91]); + } + #[test] + fn test_sort_2() { + let mut vec = vec![1]; + sort(&mut vec); + assert_eq!(vec, vec![1]); + } + #[test] + fn test_sort_3() { + let mut vec = vec![99, 88, 77, 66, 55, 44, 33, 22, 11]; + sort(&mut vec); + assert_eq!(vec, vec![11, 22, 33, 44, 55, 66, 77, 88, 99]); + } +} diff --git a/exercises/algorithm/algorithm4.rs b/exercises/algorithm/algorithm4.rs index 271b772c5..06d313c70 100644 --- a/exercises/algorithm/algorithm4.rs +++ b/exercises/algorithm/algorithm4.rs @@ -2,12 +2,9 @@ binary_search tree This problem requires you to implement a basic interface for a binary tree */ - -//I AM NOT DONE use std::cmp::Ordering; use std::fmt::Debug; - #[derive(Debug)] struct TreeNode where @@ -41,7 +38,7 @@ where impl BinarySearchTree where - T: Ord, + T: Ord + Debug, { fn new() -> Self { @@ -50,23 +47,72 @@ where // Insert a value into the BST fn insert(&mut self, value: T) { - //TODO + if let Some(ref mut root) = self.root { + root.insert(value); + } else { + self.root = Some(Box::new(TreeNode::new(value))); + } } // Search for a value in the BST fn search(&self, value: T) -> bool { - //TODO - true + if let Some(ref root) = self.root { + root.search(value) + } else { + false + } } } impl TreeNode where - T: Ord, + T: Ord + Debug, { // Insert a node into the tree fn insert(&mut self, value: T) { - //TODO + match value.cmp(&self.value) { + Ordering::Less => { + if let Some(ref mut left) = self.left { + left.insert(value); + } else { + self.left = Some(Box::new(TreeNode::new(value))); + } + } + Ordering::Greater => { + if let Some(ref mut right) = self.right { + right.insert(value); + } else { + self.right = Some(Box::new(TreeNode::new(value))); + } + } + Ordering::Equal => { + // Handle duplicate insertion if needed + // For this example, we won't allow duplicates + // So, we'll just ignore the insertion of duplicate values + println!("Value {:?} already exists in the tree", value); + } + } + } + + // Search for a value in the tree + fn search(&self, value: T) -> bool { + match value.cmp(&self.value) { + Ordering::Less => { + if let Some(ref left) = self.left { + left.search(value) + } else { + false + } + } + Ordering::Greater => { + if let Some(ref right) = self.right { + right.search(value) + } else { + false + } + } + Ordering::Equal => true, + } } } diff --git a/exercises/algorithm/algorithm4.rs~ b/exercises/algorithm/algorithm4.rs~ new file mode 100644 index 000000000..06d313c70 --- /dev/null +++ b/exercises/algorithm/algorithm4.rs~ @@ -0,0 +1,172 @@ +/* + binary_search tree + This problem requires you to implement a basic interface for a binary tree +*/ +use std::cmp::Ordering; +use std::fmt::Debug; + +#[derive(Debug)] +struct TreeNode +where + T: Ord, +{ + value: T, + left: Option>>, + right: Option>>, +} + +#[derive(Debug)] +struct BinarySearchTree +where + T: Ord, +{ + root: Option>>, +} + +impl TreeNode +where + T: Ord, +{ + fn new(value: T) -> Self { + TreeNode { + value, + left: None, + right: None, + } + } +} + +impl BinarySearchTree +where + T: Ord + Debug, +{ + + fn new() -> Self { + BinarySearchTree { root: None } + } + + // Insert a value into the BST + fn insert(&mut self, value: T) { + if let Some(ref mut root) = self.root { + root.insert(value); + } else { + self.root = Some(Box::new(TreeNode::new(value))); + } + } + + // Search for a value in the BST + fn search(&self, value: T) -> bool { + if let Some(ref root) = self.root { + root.search(value) + } else { + false + } + } +} + +impl TreeNode +where + T: Ord + Debug, +{ + // Insert a node into the tree + fn insert(&mut self, value: T) { + match value.cmp(&self.value) { + Ordering::Less => { + if let Some(ref mut left) = self.left { + left.insert(value); + } else { + self.left = Some(Box::new(TreeNode::new(value))); + } + } + Ordering::Greater => { + if let Some(ref mut right) = self.right { + right.insert(value); + } else { + self.right = Some(Box::new(TreeNode::new(value))); + } + } + Ordering::Equal => { + // Handle duplicate insertion if needed + // For this example, we won't allow duplicates + // So, we'll just ignore the insertion of duplicate values + println!("Value {:?} already exists in the tree", value); + } + } + } + + // Search for a value in the tree + fn search(&self, value: T) -> bool { + match value.cmp(&self.value) { + Ordering::Less => { + if let Some(ref left) = self.left { + left.search(value) + } else { + false + } + } + Ordering::Greater => { + if let Some(ref right) = self.right { + right.search(value) + } else { + false + } + } + Ordering::Equal => true, + } + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_insert_and_search() { + let mut bst = BinarySearchTree::new(); + + + assert_eq!(bst.search(1), false); + + + bst.insert(5); + bst.insert(3); + bst.insert(7); + bst.insert(2); + bst.insert(4); + + + assert_eq!(bst.search(5), true); + assert_eq!(bst.search(3), true); + assert_eq!(bst.search(7), true); + assert_eq!(bst.search(2), true); + assert_eq!(bst.search(4), true); + + + assert_eq!(bst.search(1), false); + assert_eq!(bst.search(6), false); + } + + #[test] + fn test_insert_duplicate() { + let mut bst = BinarySearchTree::new(); + + + bst.insert(1); + bst.insert(1); + + + assert_eq!(bst.search(1), true); + + + match bst.root { + Some(ref node) => { + assert!(node.left.is_none()); + assert!(node.right.is_none()); + }, + None => panic!("Root should not be None after insertion"), + } + } +} + + diff --git a/exercises/algorithm/algorithm5.rs b/exercises/algorithm/algorithm5.rs index 8f206d1a9..0520e70eb 100644 --- a/exercises/algorithm/algorithm5.rs +++ b/exercises/algorithm/algorithm5.rs @@ -2,8 +2,6 @@ bfs This problem requires you to implement a basic BFS algorithm */ - -//I AM NOT DONE use std::collections::VecDeque; // Define a graph @@ -27,10 +25,25 @@ impl Graph { // Perform a breadth-first search on the graph, return the order of visited nodes fn bfs_with_return(&self, start: usize) -> Vec { - - //TODO + let mut visited = vec![false; self.adj.len()]; // Mark all vertices as not visited + let mut visit_order = vec![]; // Store the order of visited nodes + let mut queue = VecDeque::new(); // Queue to store nodes to visit + + visited[start] = true; // Mark the start node as visited + queue.push_back(start); // Enqueue the start node + + while let Some(node) = queue.pop_front() { + visit_order.push(node); // Add the node to the visit order + + // Visit all neighbors of the current node + for &neighbor in &self.adj[node] { + if !visited[neighbor] { + visited[neighbor] = true; // Mark the neighbor as visited + queue.push_back(neighbor); // Enqueue the neighbor + } + } + } - let mut visit_order = vec![]; visit_order } } diff --git a/exercises/algorithm/algorithm5.rs~ b/exercises/algorithm/algorithm5.rs~ new file mode 100644 index 000000000..0520e70eb --- /dev/null +++ b/exercises/algorithm/algorithm5.rs~ @@ -0,0 +1,100 @@ +/* + bfs + This problem requires you to implement a basic BFS algorithm +*/ +use std::collections::VecDeque; + +// Define a graph +struct Graph { + adj: Vec>, +} + +impl Graph { + // Create a new graph with n vertices + fn new(n: usize) -> Self { + Graph { + adj: vec![vec![]; n], + } + } + + // Add an edge to the graph + fn add_edge(&mut self, src: usize, dest: usize) { + self.adj[src].push(dest); + self.adj[dest].push(src); + } + + // Perform a breadth-first search on the graph, return the order of visited nodes + fn bfs_with_return(&self, start: usize) -> Vec { + let mut visited = vec![false; self.adj.len()]; // Mark all vertices as not visited + let mut visit_order = vec![]; // Store the order of visited nodes + let mut queue = VecDeque::new(); // Queue to store nodes to visit + + visited[start] = true; // Mark the start node as visited + queue.push_back(start); // Enqueue the start node + + while let Some(node) = queue.pop_front() { + visit_order.push(node); // Add the node to the visit order + + // Visit all neighbors of the current node + for &neighbor in &self.adj[node] { + if !visited[neighbor] { + visited[neighbor] = true; // Mark the neighbor as visited + queue.push_back(neighbor); // Enqueue the neighbor + } + } + } + + visit_order + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_bfs_all_nodes_visited() { + let mut graph = Graph::new(5); + graph.add_edge(0, 1); + graph.add_edge(0, 4); + graph.add_edge(1, 2); + graph.add_edge(1, 3); + graph.add_edge(1, 4); + graph.add_edge(2, 3); + graph.add_edge(3, 4); + + let visited_order = graph.bfs_with_return(0); + assert_eq!(visited_order, vec![0, 1, 4, 2, 3]); + } + + #[test] + fn test_bfs_different_start() { + let mut graph = Graph::new(3); + graph.add_edge(0, 1); + graph.add_edge(1, 2); + + let visited_order = graph.bfs_with_return(2); + assert_eq!(visited_order, vec![2, 1, 0]); + } + + #[test] + fn test_bfs_with_cycle() { + let mut graph = Graph::new(3); + graph.add_edge(0, 1); + graph.add_edge(1, 2); + graph.add_edge(2, 0); + + let visited_order = graph.bfs_with_return(0); + assert_eq!(visited_order, vec![0, 1, 2]); + } + + #[test] + fn test_bfs_single_node() { + let mut graph = Graph::new(1); + + let visited_order = graph.bfs_with_return(0); + assert_eq!(visited_order, vec![0]); + } +} + diff --git a/exercises/algorithm/algorithm6.rs b/exercises/algorithm/algorithm6.rs index 813146f7c..7f7c69a31 100644 --- a/exercises/algorithm/algorithm6.rs +++ b/exercises/algorithm/algorithm6.rs @@ -2,8 +2,6 @@ dfs This problem requires you to implement a basic DFS traversal */ - -// I AM NOT DONE use std::collections::HashSet; struct Graph { @@ -23,7 +21,15 @@ impl Graph { } fn dfs_util(&self, v: usize, visited: &mut HashSet, visit_order: &mut Vec) { - //TODO + visited.insert(v); // Mark the current node as visited + visit_order.push(v); // Add the current node to the visit order + + // Visit all neighbors of the current node + for &neighbor in &self.adj[v] { + if !visited.contains(&neighbor) { + self.dfs_util(neighbor, visited, visit_order); // Recursive DFS call + } + } } // Perform a depth-first search on the graph, return the order of visited nodes diff --git a/exercises/algorithm/algorithm6.rs~ b/exercises/algorithm/algorithm6.rs~ new file mode 100644 index 000000000..7f7c69a31 --- /dev/null +++ b/exercises/algorithm/algorithm6.rs~ @@ -0,0 +1,84 @@ +/* + dfs + This problem requires you to implement a basic DFS traversal +*/ +use std::collections::HashSet; + +struct Graph { + adj: Vec>, +} + +impl Graph { + fn new(n: usize) -> Self { + Graph { + adj: vec![vec![]; n], + } + } + + fn add_edge(&mut self, src: usize, dest: usize) { + self.adj[src].push(dest); + self.adj[dest].push(src); + } + + fn dfs_util(&self, v: usize, visited: &mut HashSet, visit_order: &mut Vec) { + visited.insert(v); // Mark the current node as visited + visit_order.push(v); // Add the current node to the visit order + + // Visit all neighbors of the current node + for &neighbor in &self.adj[v] { + if !visited.contains(&neighbor) { + self.dfs_util(neighbor, visited, visit_order); // Recursive DFS call + } + } + } + + // Perform a depth-first search on the graph, return the order of visited nodes + fn dfs(&self, start: usize) -> Vec { + let mut visited = HashSet::new(); + let mut visit_order = Vec::new(); + self.dfs_util(start, &mut visited, &mut visit_order); + visit_order + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_dfs_simple() { + let mut graph = Graph::new(3); + graph.add_edge(0, 1); + graph.add_edge(1, 2); + + let visit_order = graph.dfs(0); + assert_eq!(visit_order, vec![0, 1, 2]); + } + + #[test] + fn test_dfs_with_cycle() { + let mut graph = Graph::new(4); + graph.add_edge(0, 1); + graph.add_edge(0, 2); + graph.add_edge(1, 2); + graph.add_edge(2, 3); + graph.add_edge(3, 3); + + let visit_order = graph.dfs(0); + assert_eq!(visit_order, vec![0, 1, 2, 3]); + } + + #[test] + fn test_dfs_disconnected_graph() { + let mut graph = Graph::new(5); + graph.add_edge(0, 1); + graph.add_edge(0, 2); + graph.add_edge(3, 4); + + let visit_order = graph.dfs(0); + assert_eq!(visit_order, vec![0, 1, 2]); + let visit_order_disconnected = graph.dfs(3); + assert_eq!(visit_order_disconnected, vec![3, 4]); + } +} + diff --git a/exercises/algorithm/algorithm7.rs b/exercises/algorithm/algorithm7.rs index e0c3a5ab2..9413f5b7b 100644 --- a/exercises/algorithm/algorithm7.rs +++ b/exercises/algorithm/algorithm7.rs @@ -2,8 +2,6 @@ stack This question requires you to use a stack to achieve a bracket match */ - -// I AM NOT DONE #[derive(Debug)] struct Stack { size: usize, @@ -31,8 +29,11 @@ impl Stack { self.size += 1; } fn pop(&mut self) -> Option { - // TODO - None + if self.is_empty() { + return None; + } + self.size -= 1; + self.data.pop() } fn peek(&self) -> Option<&T> { if 0 == self.size { @@ -101,8 +102,33 @@ impl<'a, T> Iterator for IterMut<'a, T> { fn bracket_match(bracket: &str) -> bool { - //TODO - true + let mut stack = Stack::new(); + + for c in bracket.chars() { + match c { + '(' | '{' | '[' => { + stack.push(c); + } + ')' => { + if stack.pop() != Some('(') { + return false; + } + } + '}' => { + if stack.pop() != Some('{') { + return false; + } + } + ']' => { + if stack.pop() != Some('[') { + return false; + } + } + _ => {} // Ignore other characters + } + } + + stack.is_empty() } #[cfg(test)] @@ -139,4 +165,4 @@ mod tests { let s = ""; assert_eq!(bracket_match(s),true); } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm7.rs~ b/exercises/algorithm/algorithm7.rs~ new file mode 100644 index 000000000..9413f5b7b --- /dev/null +++ b/exercises/algorithm/algorithm7.rs~ @@ -0,0 +1,168 @@ +/* + stack + This question requires you to use a stack to achieve a bracket match +*/ +#[derive(Debug)] +struct Stack { + size: usize, + data: Vec, +} +impl Stack { + fn new() -> Self { + Self { + size: 0, + data: Vec::new(), + } + } + fn is_empty(&self) -> bool { + 0 == self.size + } + fn len(&self) -> usize { + self.size + } + fn clear(&mut self) { + self.size = 0; + self.data.clear(); + } + fn push(&mut self, val: T) { + self.data.push(val); + self.size += 1; + } + fn pop(&mut self) -> Option { + if self.is_empty() { + return None; + } + self.size -= 1; + self.data.pop() + } + fn peek(&self) -> Option<&T> { + if 0 == self.size { + return None; + } + self.data.get(self.size - 1) + } + fn peek_mut(&mut self) -> Option<&mut T> { + if 0 == self.size { + return None; + } + self.data.get_mut(self.size - 1) + } + fn into_iter(self) -> IntoIter { + IntoIter(self) + } + fn iter(&self) -> Iter { + let mut iterator = Iter { + stack: Vec::new() + }; + for item in self.data.iter() { + iterator.stack.push(item); + } + iterator + } + fn iter_mut(&mut self) -> IterMut { + let mut iterator = IterMut { + stack: Vec::new() + }; + for item in self.data.iter_mut() { + iterator.stack.push(item); + } + iterator + } +} +struct IntoIter(Stack); +impl Iterator for IntoIter { + type Item = T; + fn next(&mut self) -> Option { + if !self.0.is_empty() { + self.0.size -= 1;self.0.data.pop() + } + else { + None + } + } +} +struct Iter<'a, T: 'a> { + stack: Vec<&'a T>, +} +impl<'a, T> Iterator for Iter<'a, T> { + type Item = &'a T; + fn next(&mut self) -> Option { + self.stack.pop() + } +} +struct IterMut<'a, T: 'a> { + stack: Vec<&'a mut T>, +} +impl<'a, T> Iterator for IterMut<'a, T> { + type Item = &'a mut T; + fn next(&mut self) -> Option { + self.stack.pop() + } +} + +fn bracket_match(bracket: &str) -> bool +{ + let mut stack = Stack::new(); + + for c in bracket.chars() { + match c { + '(' | '{' | '[' => { + stack.push(c); + } + ')' => { + if stack.pop() != Some('(') { + return false; + } + } + '}' => { + if stack.pop() != Some('{') { + return false; + } + } + ']' => { + if stack.pop() != Some('[') { + return false; + } + } + _ => {} // Ignore other characters + } + } + + stack.is_empty() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn bracket_matching_1(){ + let s = "(2+3){func}[abc]"; + assert_eq!(bracket_match(s),true); + } + #[test] + fn bracket_matching_2(){ + let s = "(2+3)*(3-1"; + assert_eq!(bracket_match(s),false); + } + #[test] + fn bracket_matching_3(){ + let s = "{{([])}}"; + assert_eq!(bracket_match(s),true); + } + #[test] + fn bracket_matching_4(){ + let s = "{{(}[)]}"; + assert_eq!(bracket_match(s),false); + } + #[test] + fn bracket_matching_5(){ + let s = "[[[]]]]]]]]]"; + assert_eq!(bracket_match(s),false); + } + #[test] + fn bracket_matching_6(){ + let s = ""; + assert_eq!(bracket_match(s),true); + } +} diff --git a/exercises/algorithm/algorithm8.rs b/exercises/algorithm/algorithm8.rs index d1d183b84..5b6d34999 100644 --- a/exercises/algorithm/algorithm8.rs +++ b/exercises/algorithm/algorithm8.rs @@ -2,8 +2,6 @@ queue This question requires you to use queues to implement the functionality of the stac */ -// I AM NOT DONE - #[derive(Debug)] pub struct Queue { elements: Vec, @@ -62,20 +60,42 @@ impl myStack { pub fn new() -> Self { Self { //TODO - q1:Queue::::new(), - q2:Queue::::new() + q1:Queue::new(), + q2:Queue::new() } } pub fn push(&mut self, elem: T) { - //TODO + // To implement push, we want to enqueue the element into the non-empty queue + // If both queues are empty, we'll enqueue into q1 by default + if !self.q1.is_empty() { + self.q1.enqueue(elem); + } else { + self.q2.enqueue(elem); + } } pub fn pop(&mut self) -> Result { - //TODO - Err("Stack is empty") + // To implement pop, we want to dequeue all elements from the non-empty queue + // and enqueue them into the other queue until only one element is left + // that last element is the one we want to pop + + let (src, dest) = if !self.q1.is_empty() { + (&mut self.q1, &mut self.q2) + } else if !self.q2.is_empty() { + (&mut self.q2, &mut self.q1) + } else { + return Err("Stack is empty"); + }; + + while src.size() > 1 { + if let Some(val) = src.dequeue().ok() { + dest.enqueue(val); + } + } + + src.dequeue().map_err(|_| "Stack is empty") } pub fn is_empty(&self) -> bool { - //TODO - true + self.q1.is_empty() && self.q2.is_empty() } } @@ -101,4 +121,4 @@ mod tests { assert_eq!(s.pop(), Err("Stack is empty")); assert_eq!(s.is_empty(), true); } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm8.rs~ b/exercises/algorithm/algorithm8.rs~ new file mode 100644 index 000000000..5b6d34999 --- /dev/null +++ b/exercises/algorithm/algorithm8.rs~ @@ -0,0 +1,124 @@ +/* + queue + This question requires you to use queues to implement the functionality of the stac +*/ +#[derive(Debug)] +pub struct Queue { + elements: Vec, +} + +impl Queue { + pub fn new() -> Queue { + Queue { + elements: Vec::new(), + } + } + + pub fn enqueue(&mut self, value: T) { + self.elements.push(value) + } + + pub fn dequeue(&mut self) -> Result { + if !self.elements.is_empty() { + Ok(self.elements.remove(0usize)) + } else { + Err("Queue is empty") + } + } + + pub fn peek(&self) -> Result<&T, &str> { + match self.elements.first() { + Some(value) => Ok(value), + None => Err("Queue is empty"), + } + } + + pub fn size(&self) -> usize { + self.elements.len() + } + + pub fn is_empty(&self) -> bool { + self.elements.is_empty() + } +} + +impl Default for Queue { + fn default() -> Queue { + Queue { + elements: Vec::new(), + } + } +} + +pub struct myStack +{ + //TODO + q1:Queue, + q2:Queue +} +impl myStack { + pub fn new() -> Self { + Self { + //TODO + q1:Queue::new(), + q2:Queue::new() + } + } + pub fn push(&mut self, elem: T) { + // To implement push, we want to enqueue the element into the non-empty queue + // If both queues are empty, we'll enqueue into q1 by default + if !self.q1.is_empty() { + self.q1.enqueue(elem); + } else { + self.q2.enqueue(elem); + } + } + pub fn pop(&mut self) -> Result { + // To implement pop, we want to dequeue all elements from the non-empty queue + // and enqueue them into the other queue until only one element is left + // that last element is the one we want to pop + + let (src, dest) = if !self.q1.is_empty() { + (&mut self.q1, &mut self.q2) + } else if !self.q2.is_empty() { + (&mut self.q2, &mut self.q1) + } else { + return Err("Stack is empty"); + }; + + while src.size() > 1 { + if let Some(val) = src.dequeue().ok() { + dest.enqueue(val); + } + } + + src.dequeue().map_err(|_| "Stack is empty") + } + pub fn is_empty(&self) -> bool { + self.q1.is_empty() && self.q2.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_queue(){ + let mut s = myStack::::new(); + assert_eq!(s.pop(), Err("Stack is empty")); + s.push(1); + s.push(2); + s.push(3); + assert_eq!(s.pop(), Ok(3)); + assert_eq!(s.pop(), Ok(2)); + s.push(4); + s.push(5); + assert_eq!(s.is_empty(), false); + assert_eq!(s.pop(), Ok(5)); + assert_eq!(s.pop(), Ok(4)); + assert_eq!(s.pop(), Ok(1)); + assert_eq!(s.pop(), Err("Stack is empty")); + assert_eq!(s.is_empty(), true); + } +} diff --git a/exercises/algorithm/algorithm9.rs b/exercises/algorithm/algorithm9.rs index 6c8021a4d..bfd40e26b 100644 --- a/exercises/algorithm/algorithm9.rs +++ b/exercises/algorithm/algorithm9.rs @@ -2,8 +2,6 @@ heap This question requires you to implement a binary heap function */ -// I AM NOT DONE - use std::cmp::Ord; use std::default::Default; @@ -37,7 +35,10 @@ where } pub fn add(&mut self, value: T) { - //TODO + self.count += 1; + self.items.push(value); + let idx = self.count; + self.bubble_up(idx); } fn parent_idx(&self, idx: usize) -> usize { @@ -57,8 +58,38 @@ where } fn smallest_child_idx(&self, idx: usize) -> usize { - //TODO - 0 + let left_idx = self.left_child_idx(idx); + let right_idx = self.right_child_idx(idx); + + if right_idx <= self.count && (self.comparator)(&self.items[right_idx], &self.items[left_idx]) { + right_idx + } else { + left_idx + } + } + + + fn bubble_up(&mut self, idx: usize) { + let mut idx = idx; // Make a mutable copy of idx + while idx > 1 && (self.comparator)(&self.items[idx], &self.items[self.parent_idx(idx)]) { + let parent_idx = self.parent_idx(idx); // Borrow self here + self.items.swap(idx, parent_idx); // Now we're borrowing self.items mutably + idx = parent_idx; + } + } + fn bubble_down(&mut self, mut idx: usize) { + loop { + let smallest_child = self.smallest_child_idx(idx); + if smallest_child > self.count { + break; + } + if (self.comparator)(&self.items[smallest_child], &self.items[idx]) { + self.items.swap(smallest_child, idx); + idx = smallest_child; + } else { + break; + } + } } } @@ -84,8 +115,16 @@ where type Item = T; fn next(&mut self) -> Option { - //TODO - None + if self.is_empty() { + return None; + } + let result = self.items.swap_remove(1); + self.count -= 1; + if self.count > 0 { + self.items.swap(1, self.count ); + self.bubble_down(1); + } + Some(result) } } @@ -151,4 +190,4 @@ mod tests { heap.add(1); assert_eq!(heap.next(), Some(2)); } -} \ No newline at end of file +} diff --git a/exercises/algorithm/algorithm9.rs~ b/exercises/algorithm/algorithm9.rs~ new file mode 100644 index 000000000..bfd40e26b --- /dev/null +++ b/exercises/algorithm/algorithm9.rs~ @@ -0,0 +1,193 @@ +/* + heap + This question requires you to implement a binary heap function +*/ +use std::cmp::Ord; +use std::default::Default; + +pub struct Heap +where + T: Default, +{ + count: usize, + items: Vec, + comparator: fn(&T, &T) -> bool, +} + +impl Heap +where + T: Default, +{ + pub fn new(comparator: fn(&T, &T) -> bool) -> Self { + Self { + count: 0, + items: vec![T::default()], + comparator, + } + } + + pub fn len(&self) -> usize { + self.count + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + pub fn add(&mut self, value: T) { + self.count += 1; + self.items.push(value); + let idx = self.count; + self.bubble_up(idx); + } + + fn parent_idx(&self, idx: usize) -> usize { + idx / 2 + } + + fn children_present(&self, idx: usize) -> bool { + self.left_child_idx(idx) <= self.count + } + + fn left_child_idx(&self, idx: usize) -> usize { + idx * 2 + } + + fn right_child_idx(&self, idx: usize) -> usize { + self.left_child_idx(idx) + 1 + } + + fn smallest_child_idx(&self, idx: usize) -> usize { + let left_idx = self.left_child_idx(idx); + let right_idx = self.right_child_idx(idx); + + if right_idx <= self.count && (self.comparator)(&self.items[right_idx], &self.items[left_idx]) { + right_idx + } else { + left_idx + } + } + + + fn bubble_up(&mut self, idx: usize) { + let mut idx = idx; // Make a mutable copy of idx + while idx > 1 && (self.comparator)(&self.items[idx], &self.items[self.parent_idx(idx)]) { + let parent_idx = self.parent_idx(idx); // Borrow self here + self.items.swap(idx, parent_idx); // Now we're borrowing self.items mutably + idx = parent_idx; + } + } + fn bubble_down(&mut self, mut idx: usize) { + loop { + let smallest_child = self.smallest_child_idx(idx); + if smallest_child > self.count { + break; + } + if (self.comparator)(&self.items[smallest_child], &self.items[idx]) { + self.items.swap(smallest_child, idx); + idx = smallest_child; + } else { + break; + } + } + } +} + +impl Heap +where + T: Default + Ord, +{ + /// Create a new MinHeap + pub fn new_min() -> Self { + Self::new(|a, b| a < b) + } + + /// Create a new MaxHeap + pub fn new_max() -> Self { + Self::new(|a, b| a > b) + } +} + +impl Iterator for Heap +where + T: Default, +{ + type Item = T; + + fn next(&mut self) -> Option { + if self.is_empty() { + return None; + } + let result = self.items.swap_remove(1); + self.count -= 1; + if self.count > 0 { + self.items.swap(1, self.count ); + self.bubble_down(1); + } + Some(result) + } +} + +pub struct MinHeap; + +impl MinHeap { + #[allow(clippy::new_ret_no_self)] + pub fn new() -> Heap + where + T: Default + Ord, + { + Heap::new(|a, b| a < b) + } +} + +pub struct MaxHeap; + +impl MaxHeap { + #[allow(clippy::new_ret_no_self)] + pub fn new() -> Heap + where + T: Default + Ord, + { + Heap::new(|a, b| a > b) + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_empty_heap() { + let mut heap = MaxHeap::new::(); + assert_eq!(heap.next(), None); + } + + #[test] + fn test_min_heap() { + let mut heap = MinHeap::new(); + heap.add(4); + heap.add(2); + heap.add(9); + heap.add(11); + assert_eq!(heap.len(), 4); + assert_eq!(heap.next(), Some(2)); + assert_eq!(heap.next(), Some(4)); + assert_eq!(heap.next(), Some(9)); + heap.add(1); + assert_eq!(heap.next(), Some(1)); + } + + #[test] + fn test_max_heap() { + let mut heap = MaxHeap::new(); + heap.add(4); + heap.add(2); + heap.add(9); + heap.add(11); + assert_eq!(heap.len(), 4); + assert_eq!(heap.next(), Some(11)); + assert_eq!(heap.next(), Some(9)); + assert_eq!(heap.next(), Some(4)); + heap.add(1); + assert_eq!(heap.next(), Some(2)); + } +} diff --git a/exercises/clippy/.clippy1.rs.un~ b/exercises/clippy/.clippy1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..38abcf7fc91ee8f84d9eebebf860c3d384d4b049 GIT binary patch literal 1468 zcmWH`%$*;a=aT=Ffr%&X<$cQ#^*YwBizeGezg8G|WZqcGd{uYh|Cc;d7X?c(Ffd2} zv8VzNGz|q0T@D&uXTtEy9eps{!=<6$ZDmeNo`1yw@ zxcK|Inl^%?4mplN&H|~2#XrMn)PaJ8mH?QO;=xhJ0Es$2pk)F;42nij)L_q}(71!e zEl?d8fbu6O?qoo`(YOPJ0tEmbl0Y*+Y-OlfWiU1{?$V&8AUNBh$DJxl`3fvst*nys T^NLG~t*in(;pMGq7%Q6vy2(B_9p+gHlr3l8vJV8=QtxDpih9g;bC@&|XRpAQUC-%C!_bQS78D zRSrm8LA?Q|3YAuT^^U{|aRDSGIG}Rur7D~Yr-+aD8_%0=Y-hW8Sx)npCNultoyq&{ zdo%lX&sJ+!U#p*7yp!v@J^$W~3t!#*ePV2)aqH#xzx?yN%FW-lUm5%M-uK0yo-SO; z<#Gq4><+AImu452n$^YnjO^VmWtWsKQaB4yYsppCZ+y|u(UIKjj~o^CwJP(MLl5cp z-y(A<-Qny1*aDUHYkwIWTXKJl%C)yiQS&R7ozv67E5VDe2B%J+2~M6q_0qAo4LVS5 zjf{u$cSzaIK93G7WU0#f$FCc7eJym4NM}2x9FzhY=b%$ZO2O1~QjS`1fa;f`0^$== z9%F|GhZVAvfcx5j%eBDmlg=+0OXN;o?gykJ}NMAyiXd3R)P#$p8{{;L8p z*EXm3@*Yc$W7%eAmpE;laDEftCu9jFE(g99UIhuG)QVTCLu=zfl(!)rjNQ{fQk zkn)1hU}QwF<42xX#31gr;ebu3{w92qrSVaZM6V=6|-RKoIC!?J&)k1ET_ zE-WY8oz%eu-biG;fCc6r_W21CD`ct4`t{K`$9yUlro}q%XhQE{DP(&PWTBa7!_&kH zSxRU=X=rZi?wZeZqgh*N>O*BI=pYI~ayKfaOD@k7Rjc$`YgUxs(`H^ot5Qr`h`wux z4z`HmU?9<8yC0&+C0h@#)Gsdc1fokHh>`vw4TPXcboEdFSR<{RCFMf2_u30W(6lA5 zy=n*!wFvUiPCiWu9*5pS*o0tMTWVgKT@BBX!wJugzaa@a$qAxC{;o9~|&g6!7#cV|17vKHtAJYv$Jpcdz literal 0 HcmV?d00001 diff --git a/exercises/clippy/clippy1.rs b/exercises/clippy/clippy1.rs index 95c0141f4..e2b1ebf4b 100644 --- a/exercises/clippy/clippy1.rs +++ b/exercises/clippy/clippy1.rs @@ -9,12 +9,10 @@ // Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::f32; fn main() { - let pi = 3.14f32; + let pi = f32::consts::PI; let radius = 5.00f32; let area = pi * f32::powi(radius, 2); diff --git a/exercises/clippy/clippy1.rs~ b/exercises/clippy/clippy1.rs~ new file mode 100644 index 000000000..e2b1ebf4b --- /dev/null +++ b/exercises/clippy/clippy1.rs~ @@ -0,0 +1,24 @@ +// clippy1.rs +// +// The Clippy tool is a collection of lints to analyze your code so you can +// catch common mistakes and improve your Rust code. +// +// For these exercises the code will fail to compile when there are clippy +// warnings check clippy's suggestions from the output to solve the exercise. +// +// Execute `rustlings hint clippy1` or use the `hint` watch subcommand for a +// hint. + +use std::f32; + +fn main() { + let pi = f32::consts::PI; + let radius = 5.00f32; + + let area = pi * f32::powi(radius, 2); + + println!( + "The area of a circle with radius {:.2} is {:.5}!", + radius, area + ) +} diff --git a/exercises/clippy/clippy2.rs b/exercises/clippy/clippy2.rs index 9b87a0b70..79c5c9fec 100644 --- a/exercises/clippy/clippy2.rs +++ b/exercises/clippy/clippy2.rs @@ -3,12 +3,10 @@ // Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn main() { let mut res = 42; let option = Some(12); - for x in option { + if let Some(x) = option { res += x; } println!("{}", res); diff --git a/exercises/clippy/clippy2.rs~ b/exercises/clippy/clippy2.rs~ new file mode 100644 index 000000000..79c5c9fec --- /dev/null +++ b/exercises/clippy/clippy2.rs~ @@ -0,0 +1,13 @@ +// clippy2.rs +// +// Execute `rustlings hint clippy2` or use the `hint` watch subcommand for a +// hint. + +fn main() { + let mut res = 42; + let option = Some(12); + if let Some(x) = option { + res += x; + } + println!("{}", res); +} diff --git a/exercises/clippy/clippy3.rs b/exercises/clippy/clippy3.rs index 35021f841..0bd6a733e 100644 --- a/exercises/clippy/clippy3.rs +++ b/exercises/clippy/clippy3.rs @@ -4,28 +4,25 @@ // // Execute `rustlings hint clippy3` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - #[allow(unused_variables, unused_assignments)] fn main() { let my_option: Option<()> = None; if my_option.is_none() { - my_option.unwrap(); + println!("{my_option:?}"); } let my_arr = &[ - -1, -2, -3 + -1, -2, -3, -4, -5, -6 ]; println!("My array! Here it is: {:?}", my_arr); - let my_empty_vec = vec![1, 2, 3, 4, 5].resize(0, 5); - println!("This Vec is empty, see? {:?}", my_empty_vec); + vec![1, 2, 3, 4, 5].resize(0, 5); + println!("This Vec is empty, see? {:?}", ()); let mut value_a = 45; let mut value_b = 66; // Let's swap these two! - value_a = value_b; - value_b = value_a; + std::mem::swap(&mut value_a, &mut value_b); println!("value a: {}; value b: {}", value_a, value_b); } diff --git a/exercises/clippy/clippy3.rs~ b/exercises/clippy/clippy3.rs~ new file mode 100644 index 000000000..0bd6a733e --- /dev/null +++ b/exercises/clippy/clippy3.rs~ @@ -0,0 +1,28 @@ +// clippy3.rs +// +// Here's a couple more easy Clippy fixes, so you can see its utility. +// +// Execute `rustlings hint clippy3` or use the `hint` watch subcommand for a hint. + +#[allow(unused_variables, unused_assignments)] +fn main() { + let my_option: Option<()> = None; + if my_option.is_none() { + println!("{my_option:?}"); + } + + let my_arr = &[ + -1, -2, -3, + -4, -5, -6 + ]; + println!("My array! Here it is: {:?}", my_arr); + + vec![1, 2, 3, 4, 5].resize(0, 5); + println!("This Vec is empty, see? {:?}", ()); + + let mut value_a = 45; + let mut value_b = 66; + // Let's swap these two! + std::mem::swap(&mut value_a, &mut value_b); + println!("value a: {}; value b: {}", value_a, value_b); +} diff --git a/exercises/conversions/.as_ref_mut.rs.un~ b/exercises/conversions/.as_ref_mut.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..51ce445e69a047603853016231d95d25401a9c14 GIT binary patch literal 8264 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 E|8kE3)c^nh literal 0 HcmV?d00001 diff --git a/exercises/conversions/.try_from_into.rs.un~ b/exercises/conversions/.try_from_into.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..329ca099f13bbfa9c43d902bc7342ebbc5824db8 GIT binary patch literal 99532 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 literal 0 HcmV?d00001 diff --git a/exercises/conversions/.using_as.rs.un~ b/exercises/conversions/.using_as.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..0eddb8617d74e3287dadffbfead00abbc3823b19 GIT binary patch literal 1014 zcmWH`%$*;a=aT=Ffl1>?pv&^Gt_#%~9;KJm7IGf!%2RA_4G6ioa^vcavrkAfFfhmi zv4jE;l;oEr<|ybZlqKerrWWhvq~>X80_FHY@<7Z8#7sa80w5ZO8Pb0*mtg_PGBd z3V!|}3NHSBuBMIPr~^e6G61QE#s6s3A%_f2*ub154b4g5sN)0LA^^moEDDMmoY~a0 H@%btM1VTOC literal 0 HcmV?d00001 diff --git a/exercises/conversions/as_ref_mut.rs b/exercises/conversions/as_ref_mut.rs index 626a36c45..a8df8caaa 100644 --- a/exercises/conversions/as_ref_mut.rs +++ b/exercises/conversions/as_ref_mut.rs @@ -7,25 +7,25 @@ // Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - // Obtain the number of bytes (not characters) in the given argument. // TODO: Add the AsRef trait appropriately as a trait bound. -fn byte_counter(arg: T) -> usize { +fn byte_counter>(arg: T) -> usize { arg.as_ref().as_bytes().len() } // Obtain the number of characters (not bytes) in the given argument. // TODO: Add the AsRef trait appropriately as a trait bound. -fn char_counter(arg: T) -> usize { +fn char_counter>(arg: T) -> usize { arg.as_ref().chars().count() } // Squares a number using as_mut(). // TODO: Add the appropriate trait bound. -fn num_sq(arg: &mut T) { +fn num_sq>(arg: &mut T) { // TODO: Implement the function body. - ??? + let a = *arg.as_mut(); + *arg.as_mut() = a * a; + } #[cfg(test)] diff --git a/exercises/conversions/as_ref_mut.rs~ b/exercises/conversions/as_ref_mut.rs~ new file mode 100644 index 000000000..a8df8caaa --- /dev/null +++ b/exercises/conversions/as_ref_mut.rs~ @@ -0,0 +1,65 @@ +// as_ref_mut.rs +// +// AsRef and AsMut allow for cheap reference-to-reference conversions. Read more +// about them at https://doc.rust-lang.org/std/convert/trait.AsRef.html and +// https://doc.rust-lang.org/std/convert/trait.AsMut.html, respectively. +// +// Execute `rustlings hint as_ref_mut` or use the `hint` watch subcommand for a +// hint. + +// Obtain the number of bytes (not characters) in the given argument. +// TODO: Add the AsRef trait appropriately as a trait bound. +fn byte_counter>(arg: T) -> usize { + arg.as_ref().as_bytes().len() +} + +// Obtain the number of characters (not bytes) in the given argument. +// TODO: Add the AsRef trait appropriately as a trait bound. +fn char_counter>(arg: T) -> usize { + arg.as_ref().chars().count() +} + +// Squares a number using as_mut(). +// TODO: Add the appropriate trait bound. +fn num_sq>(arg: &mut T) { + // TODO: Implement the function body. + let a = *arg.as_mut(); + *arg.as_mut() = a * a; + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn different_counts() { + let s = "Café au lait"; + assert_ne!(char_counter(s), byte_counter(s)); + } + + #[test] + fn same_counts() { + let s = "Cafe au lait"; + assert_eq!(char_counter(s), byte_counter(s)); + } + + #[test] + fn different_counts_using_string() { + let s = String::from("Café au lait"); + assert_ne!(char_counter(s.clone()), byte_counter(s)); + } + + #[test] + fn same_counts_using_string() { + let s = String::from("Cafe au lait"); + assert_eq!(char_counter(s.clone()), byte_counter(s)); + } + + #[test] + fn mult_box() { + let mut num: Box = Box::new(3); + num_sq(&mut num); + assert_eq!(*num, 9); + } +} diff --git a/exercises/conversions/from_into.rs b/exercises/conversions/from_into.rs index aba471d92..192456f66 100644 --- a/exercises/conversions/from_into.rs +++ b/exercises/conversions/from_into.rs @@ -40,13 +40,35 @@ impl Default for Person { // If while parsing the age, something goes wrong, then return the default of // Person Otherwise, then return an instantiated Person object with the results -// I AM NOT DONE + + impl From<&str> for Person { fn from(s: &str) -> Person { + let l: Vec<_> = s.matches(",").collect(); + if s.len() == 0 || s.find(',').is_none() || l.len() > 1 { + Person::default() + } else { + let a: Vec<_> = s.split(',').collect(); + let (name, age) = (a[0], a[1]); + if name.is_empty() { + Person::default() + + } else if age.to_string().parse::().is_ok() { + Person { + name: name.to_string(), + age: age.to_string().parse::().unwrap(), + } + } else { + Person::default() + } + } + } } + + fn main() { // Use the `from` function let p1 = Person::from("Mark,20"); diff --git a/exercises/conversions/from_into.rs~ b/exercises/conversions/from_into.rs~ new file mode 100644 index 000000000..192456f66 --- /dev/null +++ b/exercises/conversions/from_into.rs~ @@ -0,0 +1,162 @@ +// from_into.rs +// +// The From trait is used for value-to-value conversions. If From is implemented +// correctly for a type, the Into trait should work conversely. You can read +// more about it at https://doc.rust-lang.org/std/convert/trait.From.html +// +// Execute `rustlings hint from_into` or use the `hint` watch subcommand for a +// hint. + +#[derive(Debug)] +struct Person { + name: String, + age: usize, +} + +// We implement the Default trait to use it as a fallback +// when the provided string is not convertible into a Person object +impl Default for Person { + fn default() -> Person { + Person { + name: String::from("John"), + age: 30, + } + } +} + +// Your task is to complete this implementation in order for the line `let p = +// Person::from("Mark,20")` to compile Please note that you'll need to parse the +// age component into a `usize` with something like `"4".parse::()`. The +// outcome of this needs to be handled appropriately. +// +// Steps: +// 1. If the length of the provided string is 0, then return the default of +// Person. +// 2. Split the given string on the commas present in it. +// 3. Extract the first element from the split operation and use it as the name. +// 4. If the name is empty, then return the default of Person. +// 5. Extract the other element from the split operation and parse it into a +// `usize` as the age. +// If while parsing the age, something goes wrong, then return the default of +// Person Otherwise, then return an instantiated Person object with the results + + + + +impl From<&str> for Person { + fn from(s: &str) -> Person { + let l: Vec<_> = s.matches(",").collect(); + if s.len() == 0 || s.find(',').is_none() || l.len() > 1 { + Person::default() + } else { + let a: Vec<_> = s.split(',').collect(); + let (name, age) = (a[0], a[1]); + if name.is_empty() { + Person::default() + + } else if age.to_string().parse::().is_ok() { + Person { + name: name.to_string(), + age: age.to_string().parse::().unwrap(), + } + } else { + Person::default() + } + } + + } +} + + + +fn main() { + // Use the `from` function + let p1 = Person::from("Mark,20"); + // Since From is implemented for Person, we should be able to use Into + let p2: Person = "Gerald,70".into(); + println!("{:?}", p1); + println!("{:?}", p2); +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_default() { + // Test that the default person is 30 year old John + let dp = Person::default(); + assert_eq!(dp.name, "John"); + assert_eq!(dp.age, 30); + } + #[test] + fn test_bad_convert() { + // Test that John is returned when bad string is provided + let p = Person::from(""); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + #[test] + fn test_good_convert() { + // Test that "Mark,20" works + let p = Person::from("Mark,20"); + assert_eq!(p.name, "Mark"); + assert_eq!(p.age, 20); + } + #[test] + fn test_bad_age() { + // Test that "Mark,twenty" will return the default person due to an + // error in parsing age + let p = Person::from("Mark,twenty"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_missing_comma_and_age() { + let p: Person = Person::from("Mark"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_missing_age() { + let p: Person = Person::from("Mark,"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_missing_name() { + let p: Person = Person::from(",1"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_missing_name_and_age() { + let p: Person = Person::from(","); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_missing_name_and_invalid_age() { + let p: Person = Person::from(",one"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_trailing_comma() { + let p: Person = Person::from("Mike,32,"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } + + #[test] + fn test_trailing_comma_and_some_string() { + let p: Person = Person::from("Mike,32,man"); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 30); + } +} diff --git a/exercises/conversions/from_str.rs b/exercises/conversions/from_str.rs index 34472c32c..cd0457fa8 100644 --- a/exercises/conversions/from_str.rs +++ b/exercises/conversions/from_str.rs @@ -31,8 +31,6 @@ enum ParsePersonError { ParseInt(ParseIntError), } -// I AM NOT DONE - // Steps: // 1. If the length of the provided string is 0, an error should be returned // 2. Split the given string on the commas present in it @@ -52,6 +50,26 @@ enum ParsePersonError { impl FromStr for Person { type Err = ParsePersonError; fn from_str(s: &str) -> Result { + if s.is_empty() { + return Err(ParsePersonError::Empty); + } + + let l: Vec<&str> = s.split(',').collect(); + if l.len() != 2 { + return Err(ParsePersonError::BadLen); + } + + let (name, age) = (l[0], l[1]); + if name.is_empty() { + return Err(ParsePersonError::NoName); + } + + let age = age.parse::().map_err(ParsePersonError::ParseInt)?; + + Ok(Person { + name: name.to_string(), + age: age, + }) } } diff --git a/exercises/conversions/from_str.rs~ b/exercises/conversions/from_str.rs~ new file mode 100644 index 000000000..cd0457fa8 --- /dev/null +++ b/exercises/conversions/from_str.rs~ @@ -0,0 +1,151 @@ +// from_str.rs +// +// This is similar to from_into.rs, but this time we'll implement `FromStr` and +// return errors instead of falling back to a default value. Additionally, upon +// implementing FromStr, you can use the `parse` method on strings to generate +// an object of the implementor type. You can read more about it at +// https://doc.rust-lang.org/std/str/trait.FromStr.html +// +// Execute `rustlings hint from_str` or use the `hint` watch subcommand for a +// hint. + +use std::num::ParseIntError; +use std::str::FromStr; + +#[derive(Debug, PartialEq)] +struct Person { + name: String, + age: usize, +} + +// We will use this error type for the `FromStr` implementation. +#[derive(Debug, PartialEq)] +enum ParsePersonError { + // Empty input string + Empty, + // Incorrect number of fields + BadLen, + // Empty name field + NoName, + // Wrapped error from parse::() + ParseInt(ParseIntError), +} + +// Steps: +// 1. If the length of the provided string is 0, an error should be returned +// 2. Split the given string on the commas present in it +// 3. Only 2 elements should be returned from the split, otherwise return an +// error +// 4. Extract the first element from the split operation and use it as the name +// 5. Extract the other element from the split operation and parse it into a +// `usize` as the age with something like `"4".parse::()` +// 6. If while extracting the name and the age something goes wrong, an error +// should be returned +// If everything goes well, then return a Result of a Person object +// +// As an aside: `Box` implements `From<&'_ str>`. This means that if +// you want to return a string error message, you can do so via just using +// return `Err("my error message".into())`. + +impl FromStr for Person { + type Err = ParsePersonError; + fn from_str(s: &str) -> Result { + if s.is_empty() { + return Err(ParsePersonError::Empty); + } + + let l: Vec<&str> = s.split(',').collect(); + if l.len() != 2 { + return Err(ParsePersonError::BadLen); + } + + let (name, age) = (l[0], l[1]); + if name.is_empty() { + return Err(ParsePersonError::NoName); + } + + let age = age.parse::().map_err(ParsePersonError::ParseInt)?; + + Ok(Person { + name: name.to_string(), + age: age, + }) + } +} + +fn main() { + let p = "Mark,20".parse::().unwrap(); + println!("{:?}", p); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn empty_input() { + assert_eq!("".parse::(), Err(ParsePersonError::Empty)); + } + #[test] + fn good_input() { + let p = "John,32".parse::(); + assert!(p.is_ok()); + let p = p.unwrap(); + assert_eq!(p.name, "John"); + assert_eq!(p.age, 32); + } + #[test] + fn missing_age() { + assert!(matches!( + "John,".parse::(), + Err(ParsePersonError::ParseInt(_)) + )); + } + + #[test] + fn invalid_age() { + assert!(matches!( + "John,twenty".parse::(), + Err(ParsePersonError::ParseInt(_)) + )); + } + + #[test] + fn missing_comma_and_age() { + assert_eq!("John".parse::(), Err(ParsePersonError::BadLen)); + } + + #[test] + fn missing_name() { + assert_eq!(",1".parse::(), Err(ParsePersonError::NoName)); + } + + #[test] + fn missing_name_and_age() { + assert!(matches!( + ",".parse::(), + Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_)) + )); + } + + #[test] + fn missing_name_and_invalid_age() { + assert!(matches!( + ",one".parse::(), + Err(ParsePersonError::NoName | ParsePersonError::ParseInt(_)) + )); + } + + #[test] + fn trailing_comma() { + assert_eq!("John,32,".parse::(), Err(ParsePersonError::BadLen)); + } + + #[test] + fn trailing_comma_and_some_string() { + assert_eq!( + "John,32,man".parse::(), + Err(ParsePersonError::BadLen) + ); + } +} diff --git a/exercises/conversions/try_from_into.rs b/exercises/conversions/try_from_into.rs index 32d6ef39e..fd13f6a26 100644 --- a/exercises/conversions/try_from_into.rs +++ b/exercises/conversions/try_from_into.rs @@ -27,8 +27,6 @@ enum IntoColorError { IntConversion, } -// I AM NOT DONE - // Your task is to complete this implementation and return an Ok result of inner // type Color. You need to create an implementation for a tuple of three // integers, an array of three integers, and a slice of integers. @@ -37,27 +35,58 @@ enum IntoColorError { // time, but the slice implementation needs to check the slice length! Also note // that correct RGB color values must be integers in the 0..=255 range. + + + +fn check_and_convert_to_u8>(value: T) -> Result { + let value = value.into(); + if value < 0 || value > 255 { + return Err(IntoColorError::IntConversion); + } + Ok(value as u8) +} + // Tuple implementation -impl TryFrom<(i16, i16, i16)> for Color { +impl TryFrom<(i32, i32, i32)> for Color { type Error = IntoColorError; - fn try_from(tuple: (i16, i16, i16)) -> Result { + fn try_from(tuple: (i32, i32, i32)) -> Result { + let red = check_and_convert_to_u8(tuple.0)?; + let green = check_and_convert_to_u8(tuple.1)?; + let blue = check_and_convert_to_u8(tuple.2)?; + + Ok(Color { red, green, blue }) } } // Array implementation -impl TryFrom<[i16; 3]> for Color { +impl TryFrom<[i32; 3]> for Color { type Error = IntoColorError; - fn try_from(arr: [i16; 3]) -> Result { + fn try_from(arr: [i32; 3]) -> Result { + let red = check_and_convert_to_u8(arr[0])?; + let green = check_and_convert_to_u8(arr[1])?; + let blue = check_and_convert_to_u8(arr[2])?; + + Ok(Color { red, green, blue }) } } // Slice implementation -impl TryFrom<&[i16]> for Color { +impl TryFrom<&[i32]> for Color { type Error = IntoColorError; - fn try_from(slice: &[i16]) -> Result { + fn try_from(slice: &[i32]) -> Result { + if slice.len() != 3 { + return Err(IntoColorError::BadLen); + } + + let red = check_and_convert_to_u8(slice[0])?; + let green = check_and_convert_to_u8(slice[1])?; + let blue = check_and_convert_to_u8(slice[2])?; + + Ok(Color { red, green, blue }) } } + fn main() { // Use the `try_from` function let c1 = Color::try_from((183, 65, 14)); diff --git a/exercises/conversions/try_from_into.rs~ b/exercises/conversions/try_from_into.rs~ new file mode 100644 index 000000000..fd13f6a26 --- /dev/null +++ b/exercises/conversions/try_from_into.rs~ @@ -0,0 +1,222 @@ +// try_from_into.rs +// +// TryFrom is a simple and safe type conversion that may fail in a controlled +// way under some circumstances. Basically, this is the same as From. The main +// difference is that this should return a Result type instead of the target +// type itself. You can read more about it at +// https://doc.rust-lang.org/std/convert/trait.TryFrom.html +// +// Execute `rustlings hint try_from_into` or use the `hint` watch subcommand for +// a hint. + +use std::convert::{TryFrom, TryInto}; + +#[derive(Debug, PartialEq)] +struct Color { + red: u8, + green: u8, + blue: u8, +} + +// We will use this error type for these `TryFrom` conversions. +#[derive(Debug, PartialEq)] +enum IntoColorError { + // Incorrect length of slice + BadLen, + // Integer conversion error + IntConversion, +} + +// Your task is to complete this implementation and return an Ok result of inner +// type Color. You need to create an implementation for a tuple of three +// integers, an array of three integers, and a slice of integers. +// +// Note that the implementation for tuple and array will be checked at compile +// time, but the slice implementation needs to check the slice length! Also note +// that correct RGB color values must be integers in the 0..=255 range. + + + + +fn check_and_convert_to_u8>(value: T) -> Result { + let value = value.into(); + if value < 0 || value > 255 { + return Err(IntoColorError::IntConversion); + } + Ok(value as u8) +} + +// Tuple implementation +impl TryFrom<(i32, i32, i32)> for Color { + type Error = IntoColorError; + fn try_from(tuple: (i32, i32, i32)) -> Result { + let red = check_and_convert_to_u8(tuple.0)?; + let green = check_and_convert_to_u8(tuple.1)?; + let blue = check_and_convert_to_u8(tuple.2)?; + + Ok(Color { red, green, blue }) + } +} + +// Array implementation +impl TryFrom<[i32; 3]> for Color { + type Error = IntoColorError; + fn try_from(arr: [i32; 3]) -> Result { + let red = check_and_convert_to_u8(arr[0])?; + let green = check_and_convert_to_u8(arr[1])?; + let blue = check_and_convert_to_u8(arr[2])?; + + Ok(Color { red, green, blue }) + } +} + +// Slice implementation +impl TryFrom<&[i32]> for Color { + type Error = IntoColorError; + fn try_from(slice: &[i32]) -> Result { + if slice.len() != 3 { + return Err(IntoColorError::BadLen); + } + + let red = check_and_convert_to_u8(slice[0])?; + let green = check_and_convert_to_u8(slice[1])?; + let blue = check_and_convert_to_u8(slice[2])?; + + Ok(Color { red, green, blue }) + } +} + + +fn main() { + // Use the `try_from` function + let c1 = Color::try_from((183, 65, 14)); + println!("{:?}", c1); + + // Since TryFrom is implemented for Color, we should be able to use TryInto + let c2: Result = [183, 65, 14].try_into(); + println!("{:?}", c2); + + let v = vec![183, 65, 14]; + // With slice we should use `try_from` function + let c3 = Color::try_from(&v[..]); + println!("{:?}", c3); + // or take slice within round brackets and use TryInto + let c4: Result = (&v[..]).try_into(); + println!("{:?}", c4); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_tuple_out_of_range_positive() { + assert_eq!( + Color::try_from((256, 1000, 10000)), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_tuple_out_of_range_negative() { + assert_eq!( + Color::try_from((-1, -10, -256)), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_tuple_sum() { + assert_eq!( + Color::try_from((-1, 255, 255)), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_tuple_correct() { + let c: Result = (183, 65, 14).try_into(); + assert!(c.is_ok()); + assert_eq!( + c.unwrap(), + Color { + red: 183, + green: 65, + blue: 14 + } + ); + } + #[test] + fn test_array_out_of_range_positive() { + let c: Result = [1000, 10000, 256].try_into(); + assert_eq!(c, Err(IntoColorError::IntConversion)); + } + #[test] + fn test_array_out_of_range_negative() { + let c: Result = [-10, -256, -1].try_into(); + assert_eq!(c, Err(IntoColorError::IntConversion)); + } + #[test] + fn test_array_sum() { + let c: Result = [-1, 255, 255].try_into(); + assert_eq!(c, Err(IntoColorError::IntConversion)); + } + #[test] + fn test_array_correct() { + let c: Result = [183, 65, 14].try_into(); + assert!(c.is_ok()); + assert_eq!( + c.unwrap(), + Color { + red: 183, + green: 65, + blue: 14 + } + ); + } + #[test] + fn test_slice_out_of_range_positive() { + let arr = [10000, 256, 1000]; + assert_eq!( + Color::try_from(&arr[..]), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_slice_out_of_range_negative() { + let arr = [-256, -1, -10]; + assert_eq!( + Color::try_from(&arr[..]), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_slice_sum() { + let arr = [-1, 255, 255]; + assert_eq!( + Color::try_from(&arr[..]), + Err(IntoColorError::IntConversion) + ); + } + #[test] + fn test_slice_correct() { + let v = vec![183, 65, 14]; + let c: Result = Color::try_from(&v[..]); + assert!(c.is_ok()); + assert_eq!( + c.unwrap(), + Color { + red: 183, + green: 65, + blue: 14 + } + ); + } + #[test] + fn test_slice_excess_length() { + let v = vec![0, 0, 0, 0]; + assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen)); + } + #[test] + fn test_slice_insufficient_length() { + let v = vec![0, 0]; + assert_eq!(Color::try_from(&v[..]), Err(IntoColorError::BadLen)); + } +} diff --git a/exercises/conversions/using_as.rs b/exercises/conversions/using_as.rs index 414cef3a0..a9f1e4496 100644 --- a/exercises/conversions/using_as.rs +++ b/exercises/conversions/using_as.rs @@ -10,11 +10,9 @@ // Execute `rustlings hint using_as` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn average(values: &[f64]) -> f64 { let total = values.iter().sum::(); - total / values.len() + total / values.len() as f64 } fn main() { diff --git a/exercises/conversions/using_as.rs~ b/exercises/conversions/using_as.rs~ new file mode 100644 index 000000000..a9f1e4496 --- /dev/null +++ b/exercises/conversions/using_as.rs~ @@ -0,0 +1,31 @@ +// using_as.rs +// +// Type casting in Rust is done via the usage of the `as` operator. Please note +// that the `as` operator is not only used when type casting. It also helps with +// renaming imports. +// +// The goal is to make sure that the division does not fail to compile and +// returns the proper type. +// +// Execute `rustlings hint using_as` or use the `hint` watch subcommand for a +// hint. + +fn average(values: &[f64]) -> f64 { + let total = values.iter().sum::(); + total / values.len() as f64 +} + +fn main() { + let values = [3.5, 0.3, 13.0, 11.7]; + println!("{}", average(&values)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn returns_proper_type_and_value() { + assert_eq!(average(&[3.5, 0.3, 13.0, 11.7]), 7.125); + } +} diff --git a/exercises/enums/.enums1.rs.un~ b/exercises/enums/.enums1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..4bbf07437b2c70ca7d3ab67ddb27237b02e619e6 GIT binary patch literal 1436 zcmWH`%$*;a=aT=Ff$83H`8~1g+n&xi*mP>L@pF;>UOxfLMSoYD^lmY#*=QTdz`!5^ z#4x}DWH16TGgJUX!!SeoTP+6`h-~}?r~)P^4Wd9&tT6t6AOMTN1V(8phd}yU&7a`t zU}X3z0W=#Fcd+0GMT>yGzJjNMqpyOWe~5yMzn?3}e$z&9)FH<)NEoD^9mD{E(Wrxj z1MNs)PT~be9RnolKtaz5!~#GJiW+tWAOJ=mI9_3r{6Gm<{2^yMkT58Za)1~hFdBc5 paG)Itj6Zv5NeGT2P|))Nu^{tfsyxo6##`JJ3IgY literal 0 HcmV?d00001 diff --git a/exercises/enums/.enums2.rs.un~ b/exercises/enums/.enums2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..468d42bb461b4239e1ad62c3e234a5a1f0074e38 GIT binary patch literal 9520 zcmeI&&ubGw6bJBan>KBtHf=3PrE#K&X$|yLkldv0L9i|2kAwIFDKQP$1WH?#&_h*F z4|?oH!COH=3ZC_U$iFfyQ#*P@4M5f@vHA2Puxr1-GB4v{MNH%5Cl2tXN|PQ+E&TbpA=1{ zx=|{Z)(hroe7s$d|4K_PeP;_C$Nri1$p+?CcF4*D0j26+Bgnm&pb z{P>?EP(GY~t{gqV?^E*Ze(4N9C^9oM=8CzzXqJ|5nEBVR1Ez-{)?ADJI+e zR0IYfEKWAyc`!!9`6yuf-N4cWt8Y^bLQJKYAM_xW!--#Fh=R)|Vqd$7#q~_xbf{+t z2{=?iY(VvpjE3`3Ais5k%*9Ku6J(S^;WlVZ7pC6P3W(doR!4*$p9*KBqh?9KQ41E_ zIVK&|3=0-u#RaAu0}}r;D&1#O1i@(&yoN5q-mu_Av3Wwekq*2u;LWW*sFq7}wMVt} zqKPXPNI{ehia7VBCL`i>6uBQN*Vp{1fHDMfN52OPQT_xN+}XH*JtQOIbQH*+3YiEY zk^Qg)38~)<*ETB~1r{#MqnsA-a7|x=z5-=fT#W*DpkV#&S6&V|6FX`hH`Jnq2RFPa z*&y#784c&7Y*~(~<3M}Ib95|r-WrW0xn?~Aidw0gT3oHT6Ut8eXHBy^2cP}{ D_Um(8 literal 0 HcmV?d00001 diff --git a/exercises/enums/.enums3.rs.un~ b/exercises/enums/.enums3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..d1d16205af3d47fa12a640c86000f575894c3a66 GIT binary patch literal 62508 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 H@4x;3I&P_- literal 0 HcmV?d00001 diff --git a/exercises/enums/enums1.rs b/exercises/enums/enums1.rs index 25525b252..bd0aebf03 100644 --- a/exercises/enums/enums1.rs +++ b/exercises/enums/enums1.rs @@ -2,11 +2,14 @@ // // No hints this time! ;) -// I AM NOT DONE - #[derive(Debug)] enum Message { // TODO: define a few types of messages as used below + + Quit, + Echo, + Move, + ChangeColor, } fn main() { diff --git a/exercises/enums/enums1.rs~ b/exercises/enums/enums1.rs~ new file mode 100644 index 000000000..bd0aebf03 --- /dev/null +++ b/exercises/enums/enums1.rs~ @@ -0,0 +1,20 @@ +// enums1.rs +// +// No hints this time! ;) + +#[derive(Debug)] +enum Message { + // TODO: define a few types of messages as used below + + Quit, + Echo, + Move, + ChangeColor, +} + +fn main() { + println!("{:?}", Message::Quit); + println!("{:?}", Message::Echo); + println!("{:?}", Message::Move); + println!("{:?}", Message::ChangeColor); +} diff --git a/exercises/enums/enums2.rs b/exercises/enums/enums2.rs index df93fe0f1..75479ded2 100644 --- a/exercises/enums/enums2.rs +++ b/exercises/enums/enums2.rs @@ -3,11 +3,14 @@ // Execute `rustlings hint enums2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE #[derive(Debug)] enum Message { // TODO: define the different variants used below + Move {x: u8, y: u8}, + Echo(String), + ChangeColor(u8, u8, u8), + Quit, } impl Message { diff --git a/exercises/enums/enums2.rs~ b/exercises/enums/enums2.rs~ new file mode 100644 index 000000000..75479ded2 --- /dev/null +++ b/exercises/enums/enums2.rs~ @@ -0,0 +1,33 @@ +// enums2.rs +// +// Execute `rustlings hint enums2` or use the `hint` watch subcommand for a +// hint. + + +#[derive(Debug)] +enum Message { + // TODO: define the different variants used below + Move {x: u8, y: u8}, + Echo(String), + ChangeColor(u8, u8, u8), + Quit, +} + +impl Message { + fn call(&self) { + println!("{:?}", self); + } +} + +fn main() { + let messages = [ + Message::Move { x: 10, y: 30 }, + Message::Echo(String::from("hello world")), + Message::ChangeColor(200, 255, 255), + Message::Quit, + ]; + + for message in &messages { + message.call(); + } +} diff --git a/exercises/enums/enums3.rs b/exercises/enums/enums3.rs index 5d284417e..7e3f8a5e2 100644 --- a/exercises/enums/enums3.rs +++ b/exercises/enums/enums3.rs @@ -5,10 +5,12 @@ // Execute `rustlings hint enums3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - enum Message { // TODO: implement the message variant types based on their usage below + Quit, + ChangeColor(u8, u8, u8), + Echo(String), + Move(Point), } struct Point { @@ -43,6 +45,12 @@ impl State { // variants // Remember: When passing a tuple as a function argument, you'll need // extra parentheses: fn function((t, u, p, l, e)) + match message { + Message::ChangeColor(a, b, c) => self.change_color((a, b, c)), + Message::Quit => self.quit(), + Message::Echo(String) => self.echo(String), + Message::Move(Point) => self.move_position(Point), + } } } diff --git a/exercises/enums/enums3.rs~ b/exercises/enums/enums3.rs~ new file mode 100644 index 000000000..7e3f8a5e2 --- /dev/null +++ b/exercises/enums/enums3.rs~ @@ -0,0 +1,80 @@ +// enums3.rs +// +// Address all the TODOs to make the tests pass! +// +// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a +// hint. + +enum Message { + // TODO: implement the message variant types based on their usage below + Quit, + ChangeColor(u8, u8, u8), + Echo(String), + Move(Point), +} + +struct Point { + x: u8, + y: u8, +} + +struct State { + color: (u8, u8, u8), + position: Point, + quit: bool, + message: String +} + +impl State { + fn change_color(&mut self, color: (u8, u8, u8)) { + self.color = color; + } + + fn quit(&mut self) { + self.quit = true; + } + + fn echo(&mut self, s: String) { self.message = s } + + fn move_position(&mut self, p: Point) { + self.position = p; + } + + fn process(&mut self, message: Message) { + // TODO: create a match expression to process the different message + // variants + // Remember: When passing a tuple as a function argument, you'll need + // extra parentheses: fn function((t, u, p, l, e)) + match message { + Message::ChangeColor(a, b, c) => self.change_color((a, b, c)), + Message::Quit => self.quit(), + Message::Echo(String) => self.echo(String), + Message::Move(Point) => self.move_position(Point), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_match_message_call() { + let mut state = State { + quit: false, + position: Point { x: 0, y: 0 }, + color: (0, 0, 0), + message: "hello world".to_string(), + }; + state.process(Message::ChangeColor(255, 0, 255)); + state.process(Message::Echo(String::from("hello world"))); + state.process(Message::Move(Point { x: 10, y: 15 })); + state.process(Message::Quit); + + assert_eq!(state.color, (255, 0, 255)); + assert_eq!(state.position.x, 10); + assert_eq!(state.position.y, 15); + assert_eq!(state.quit, true); + assert_eq!(state.message, "hello world"); + } +} diff --git a/exercises/error_handling/.errors1.rs.un~ b/exercises/error_handling/.errors1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..77ae747e016e23ba3335b87d2ad8f4936ba3c934 GIT binary patch literal 18598 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 F{ts9SYXtxR literal 0 HcmV?d00001 diff --git a/exercises/error_handling/.errors3.rs.un~ b/exercises/error_handling/.errors3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..4af895aeb7dbf98ce458eddf964cae4c1969b56c GIT binary patch literal 2959 zcmeH|OG^S#6vuBqf~1EPk&A>YZDt^KHDse1g)V|rdM?^bl9LEJBlEzbl@NW1Hti}a z+VuhY1}%fu6@38LcFxrs1rZd^ZvOC}!@Y;Ocjo-K=k8Q$=i6FFe<7Z|*Ve;X<5^mN zKbg)+Pm#6I*FKp3FA)l3+3>)TrU=J9D2swM=Vq-ON@Bydjf?*?F zY(dy-0vrJ&n!ldh9#y312Xi4|q#DBsmnv4lNdeW%{!xu3dsLAk@5T7}NEoR~IB=hcVRZdJcjCnV=zikGZq9}6 z886%sFkaN|;l(02D!{wI@Orv-6-^LnG)*^D)2>=6L7by2`eCYc Yq*2o<$+Bt~x*^M14CypImYQ$ZADsBU7ytkO literal 0 HcmV?d00001 diff --git a/exercises/error_handling/.errors4.rs.un~ b/exercises/error_handling/.errors4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..473f4e054877280724ea83c3e4e1ddc8eb7d2a38 GIT binary patch literal 10104 zcmeI2OKTKC5P-)#G%<;J_>5xGNqlS~k{o=12ZJ#YJeY{62p&QX<7P?B%I0w}1oW=I zAcA+V{t!L*3k30`f{>Gl*4NWD_8J+`*tafds=KFlx2bQdyJl+cRvx~*vou-#kTksh zeywrzVqayo_xZv=@6eOY@mCWg6Yu6HpS^i;Z*%T!k|d|3skBR{LE0fVf!3Ckw@jsJ zm&`OLvu~Y2qiCiOKDb}nVFo`$@+(Y4`Oh9GZ}q>oIFe-Rh9fTCjfhvEq6S<1Db5Ar=X2jYZ(>VeABe*u+>=j|9~M?aQB_4au+WBo@I4!rgB5 zAO>q2;~0y0A*2Y_Z$4IB&(V5P8dzI(i_K0^y?nx5?$XPu?NN#q`!xRz4PUsnGIj!U zfF;#&e)H<1n)bK(`5o%pU)bdkr z!_;8|Q-`-O5OSEtVDp?3t}ED%``9?&dZleU<2GEF!DpYh9@xPv=ANEY!gYn0DdN?h zZ;r-1vWX>dl&B__K(qUzTPQ#yMCXj~N+1pvLG17$uDig4QJ1$i_(f)(L&A22*-#NP zKkyV8h`POHfsd5L?w>Iw@jMfxE67HCWVoJ)IW3L*w;UPaX7@_9@b3nI)+0>?pq!F6 zX^9ZkEupkP94&&F-_!xIq))4XM5RLofIzbwXoRM238e+vcoDQ7V5v;iYNfo)04Sbh zt7xS#f>V#|MDuXb)(1q>*Zbu)?F+bDMc}#>8rp)h`zE2KJFDiHkmI4I3RI8kAcmlN z;vY30x2Ke7zYj?}FC_2#B)J7RCXK@{D;NPIpK(d1mX$C<^r>_|g9r^T>_B`_e&2^S zYoRq}h%_H5$&Zq;lztDttF?4)rBYpzP^{K2U7AkIGF(gb81&V966K)U2zitFae4KqD++f2?(Pq|1`J8Y-}?Un}4_?$(Y5MHFl z_toD%aXrzarQ7^*rbc945sy+IfPYm2{lP|^Emgy9wt9%lwOlY_6JU=%!)y#-ybw~# eTYXLTU$83+V9jZa{3s~?=4F~n_A<@KS3d#R{btkv literal 0 HcmV?d00001 diff --git a/exercises/error_handling/.errors5.rs.un~ b/exercises/error_handling/.errors5.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..f440bc7c2ebb18b7c483019515c833767e28ebd4 GIT binary patch literal 5935 zcmeI0&ubGw6vwA&j8=QllRfxj`~kLT8!D&}(=65oDPmHJ3gSTnUBiOig-vYhkBeSK z#iJ)rA_(e5z4|YB_AVYgRmiQN?>pInC#;+4PLA{7WnX6Y*LxqnGdpuVSbcphT!?;% z!sXv%z0LBA=JKak<6AGEd_J(bb^OS&H@APCeEa>;*XLh^5OwkscS5<^3c|@LIbD;> ze&^oZZgq0%l$?(?sw?+H>3LqQCLhwNhsY)Q2>CcU3`gyv-8=fRh~AR8^$opbh5kYP zqH99`|3jv3r5oIF$Q5Y!H&SKBBBaM&8Tib+Xx3Z3YqJ4hXe$)Q+WY^qwt9o+QABH;_3JIM8u z!5ZhCC3k#L1RFEqJDCyc?g#L@t7$Cwqw zDzs)?&C3|mae^2~cd|5q+aYEJu?o!*7t)96^EnYS!XUbfWdYhCEYapBVpPGxObFk| z8mKGz2m|nc=Vl-tV@Ux&kWZt{Ax9M~%mn#Og?uz!)RzV#Z^a#-X5@MtM{)W@%>)j* zyIDRU?*z^YVilUuewrol*=^Cz)HTTNVcCE>NY9|n=^9nAFcZ?x6zO8RuDwB|FUEeW z8$_YfwOryVXL<%zy*q+*K-}pWl^BL$0lY7{5n_A*!?1EzF|C~6XX*L$_9$lxnu{4P z0qky~MkR(}Ca6Cs)TNw)_AxhU6P=7c5~Ed2a{fq@|& zh`khmASbm%p~6Zb)67J{R-st0AhD=8RYOxxFE_CuKDDSwBLE~2kYDVVpI4PylGOe^pt{0+MB6h`#`m1p+1r z1tvjK+%W!sAOIT$6Bwnb90KWImG!~V!N~Ac0%$fD5W|8W7A*q$`U;*3j=l!C$D9{oBqp}uXR0iXTN)pRx^q2?5G_0To zc@dNfz!@0C8I5^RD9{oBW4;F*^GuLT45~ZjfH)S2L7A8Z6!YMc86+bE#GvfW0L`|@ vSr#M=ibz-uJQ{hR5TPjmM&2rL Option { +pub fn generate_nametag_text(name: String) -> Result { if name.is_empty() { // Empty names aren't allowed. - None + Err("`name` was empty; it must be nonempty.".into()) } else { - Some(format!("Hi! My name is {}", name)) + Ok(format!("Hi! My name is {}", name)) } } diff --git a/exercises/error_handling/errors1.rs~ b/exercises/error_handling/errors1.rs~ new file mode 100644 index 000000000..783a501e6 --- /dev/null +++ b/exercises/error_handling/errors1.rs~ @@ -0,0 +1,41 @@ +// errors1.rs +// +// This function refuses to generate text to be printed on a nametag if you pass +// it an empty string. It'd be nicer if it explained what the problem was, +// instead of just sometimes returning `None`. Thankfully, Rust has a similar +// construct to `Result` that can be used to express error conditions. Let's use +// it! +// +// Execute `rustlings hint errors1` or use the `hint` watch subcommand for a +// hint. + +pub fn generate_nametag_text(name: String) -> Result { + if name.is_empty() { + // Empty names aren't allowed. + Err("`name` was empty; it must be nonempty.".into()) + } else { + Ok(format!("Hi! My name is {}", name)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn generates_nametag_text_for_a_nonempty_name() { + assert_eq!( + generate_nametag_text("Beyoncé".into()), + Ok("Hi! My name is Beyoncé".into()) + ); + } + + #[test] + fn explains_why_generating_nametag_text_fails() { + assert_eq!( + generate_nametag_text("".into()), + // Don't change this line + Err("`name` was empty; it must be nonempty.".into()) + ); + } +} diff --git a/exercises/error_handling/errors2.rs b/exercises/error_handling/errors2.rs index d86f326d0..bd239a70d 100644 --- a/exercises/error_handling/errors2.rs +++ b/exercises/error_handling/errors2.rs @@ -19,16 +19,15 @@ // Execute `rustlings hint errors2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::num::ParseIntError; pub fn total_cost(item_quantity: &str) -> Result { let processing_fee = 1; let cost_per_item = 5; - let qty = item_quantity.parse::(); - + let qty = item_quantity.parse::()?; Ok(qty * cost_per_item + processing_fee) + } #[cfg(test)] diff --git a/exercises/error_handling/errors2.rs~ b/exercises/error_handling/errors2.rs~ new file mode 100644 index 000000000..bd239a70d --- /dev/null +++ b/exercises/error_handling/errors2.rs~ @@ -0,0 +1,49 @@ +// errors2.rs +// +// Say we're writing a game where you can buy items with tokens. All items cost +// 5 tokens, and whenever you purchase items there is a processing fee of 1 +// token. A player of the game will type in how many items they want to buy, and +// the `total_cost` function will calculate the total cost of the tokens. Since +// the player typed in the quantity, though, we get it as a string-- and they +// might have typed anything, not just numbers! +// +// Right now, this function isn't handling the error case at all (and isn't +// handling the success case properly either). What we want to do is: if we call +// the `parse` function on a string that is not a number, that function will +// return a `ParseIntError`, and in that case, we want to immediately return +// that error from our function and not try to multiply and add. +// +// There are at least two ways to implement this that are both correct-- but one +// is a lot shorter! +// +// Execute `rustlings hint errors2` or use the `hint` watch subcommand for a +// hint. + + +use std::num::ParseIntError; + +pub fn total_cost(item_quantity: &str) -> Result { + let processing_fee = 1; + let cost_per_item = 5; + let qty = item_quantity.parse::()?; + Ok(qty * cost_per_item + processing_fee) + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn item_quantity_is_a_valid_number() { + assert_eq!(total_cost("34"), Ok(171)); + } + + #[test] + fn item_quantity_is_an_invalid_number() { + assert_eq!( + total_cost("beep boop").unwrap_err().to_string(), + "invalid digit found in string" + ); + } +} diff --git a/exercises/error_handling/errors3.rs b/exercises/error_handling/errors3.rs index d42d3b17c..634a7e164 100644 --- a/exercises/error_handling/errors3.rs +++ b/exercises/error_handling/errors3.rs @@ -7,7 +7,6 @@ // Execute `rustlings hint errors3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::num::ParseIntError; @@ -15,7 +14,7 @@ fn main() { let mut tokens = 100; let pretend_user_input = "8"; - let cost = total_cost(pretend_user_input)?; + let cost = total_cost(pretend_user_input).unwrap(); if cost > tokens { println!("You can't afford that many!"); diff --git a/exercises/error_handling/errors3.rs~ b/exercises/error_handling/errors3.rs~ new file mode 100644 index 000000000..634a7e164 --- /dev/null +++ b/exercises/error_handling/errors3.rs~ @@ -0,0 +1,33 @@ +// errors3.rs +// +// This is a program that is trying to use a completed version of the +// `total_cost` function from the previous exercise. It's not working though! +// Why not? What should we do to fix it? +// +// Execute `rustlings hint errors3` or use the `hint` watch subcommand for a +// hint. + + +use std::num::ParseIntError; + +fn main() { + let mut tokens = 100; + let pretend_user_input = "8"; + + let cost = total_cost(pretend_user_input).unwrap(); + + if cost > tokens { + println!("You can't afford that many!"); + } else { + tokens -= cost; + println!("You now have {} tokens.", tokens); + } +} + +pub fn total_cost(item_quantity: &str) -> Result { + let processing_fee = 1; + let cost_per_item = 5; + let qty = item_quantity.parse::()?; + + Ok(qty * cost_per_item + processing_fee) +} diff --git a/exercises/error_handling/errors4.rs b/exercises/error_handling/errors4.rs index e04bff77a..7406bd6e2 100644 --- a/exercises/error_handling/errors4.rs +++ b/exercises/error_handling/errors4.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint errors4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[derive(PartialEq, Debug)] struct PositiveNonzeroInteger(u64); @@ -17,7 +15,15 @@ enum CreationError { impl PositiveNonzeroInteger { fn new(value: i64) -> Result { // Hmm...? Why is this only returning an Ok value? - Ok(PositiveNonzeroInteger(value as u64)) + if value > 0 { + Ok(PositiveNonzeroInteger(value as u64)) + } else if value == 0 { + Err(CreationError::Zero) + + } else { + Err(CreationError::Negative) + + } } } diff --git a/exercises/error_handling/errors4.rs~ b/exercises/error_handling/errors4.rs~ new file mode 100644 index 000000000..7406bd6e2 --- /dev/null +++ b/exercises/error_handling/errors4.rs~ @@ -0,0 +1,38 @@ +// errors4.rs +// +// Execute `rustlings hint errors4` or use the `hint` watch subcommand for a +// hint. + +#[derive(PartialEq, Debug)] +struct PositiveNonzeroInteger(u64); + +#[derive(PartialEq, Debug)] +enum CreationError { + Negative, + Zero, +} + +impl PositiveNonzeroInteger { + fn new(value: i64) -> Result { + // Hmm...? Why is this only returning an Ok value? + if value > 0 { + Ok(PositiveNonzeroInteger(value as u64)) + } else if value == 0 { + Err(CreationError::Zero) + + } else { + Err(CreationError::Negative) + + } + } +} + +#[test] +fn test_creation() { + assert!(PositiveNonzeroInteger::new(10).is_ok()); + assert_eq!( + Err(CreationError::Negative), + PositiveNonzeroInteger::new(-10) + ); + assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0)); +} diff --git a/exercises/error_handling/errors5.rs b/exercises/error_handling/errors5.rs index 92461a7e0..722c778de 100644 --- a/exercises/error_handling/errors5.rs +++ b/exercises/error_handling/errors5.rs @@ -22,14 +22,12 @@ // Execute `rustlings hint errors5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::error; use std::fmt; use std::num::ParseIntError; // TODO: update the return type of `main()` to make this compile. -fn main() -> Result<(), Box> { +fn main() -> Result<(), Box> { let pretend_user_input = "42"; let x: i64 = pretend_user_input.parse()?; println!("output={:?}", PositiveNonzeroInteger::new(x)?); diff --git a/exercises/error_handling/errors5.rs~ b/exercises/error_handling/errors5.rs~ new file mode 100644 index 000000000..722c778de --- /dev/null +++ b/exercises/error_handling/errors5.rs~ @@ -0,0 +1,69 @@ +// errors5.rs +// +// This program uses an altered version of the code from errors4. +// +// This exercise uses some concepts that we won't get to until later in the +// course, like `Box` and the `From` trait. It's not important to understand +// them in detail right now, but you can read ahead if you like. For now, think +// of the `Box` type as an "I want anything that does ???" type, which, +// given Rust's usual standards for runtime safety, should strike you as +// somewhat lenient! +// +// In short, this particular use case for boxes is for when you want to own a +// value and you care only that it is a type which implements a particular +// trait. To do so, The Box is declared as of type Box where Trait is +// the trait the compiler looks for on any value used in that context. For this +// exercise, that context is the potential errors which can be returned in a +// Result. +// +// What can we use to describe both errors? In other words, is there a trait +// which both errors implement? +// +// Execute `rustlings hint errors5` or use the `hint` watch subcommand for a +// hint. + +use std::error; +use std::fmt; +use std::num::ParseIntError; + +// TODO: update the return type of `main()` to make this compile. +fn main() -> Result<(), Box> { + let pretend_user_input = "42"; + let x: i64 = pretend_user_input.parse()?; + println!("output={:?}", PositiveNonzeroInteger::new(x)?); + Ok(()) +} + +// Don't change anything below this line. + +#[derive(PartialEq, Debug)] +struct PositiveNonzeroInteger(u64); + +#[derive(PartialEq, Debug)] +enum CreationError { + Negative, + Zero, +} + +impl PositiveNonzeroInteger { + fn new(value: i64) -> Result { + match value { + x if x < 0 => Err(CreationError::Negative), + x if x == 0 => Err(CreationError::Zero), + x => Ok(PositiveNonzeroInteger(x as u64)), + } + } +} + +// This is required so that `CreationError` can implement `error::Error`. +impl fmt::Display for CreationError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let description = match *self { + CreationError::Negative => "number is negative", + CreationError::Zero => "number is zero", + }; + f.write_str(description) + } +} + +impl error::Error for CreationError {} diff --git a/exercises/error_handling/errors6.rs b/exercises/error_handling/errors6.rs index aaf0948ef..813ad006d 100644 --- a/exercises/error_handling/errors6.rs +++ b/exercises/error_handling/errors6.rs @@ -9,8 +9,6 @@ // Execute `rustlings hint errors6` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::num::ParseIntError; // This is a custom error type that we will be using in `parse_pos_nonzero()`. @@ -26,12 +24,15 @@ impl ParsePosNonzeroError { } // TODO: add another error conversion function here. // fn from_parseint... + fn from_parseint(err: ParseIntError) -> ParsePosNonzeroError { + ParsePosNonzeroError::ParseInt(err) + } } fn parse_pos_nonzero(s: &str) -> Result { // TODO: change this to return an appropriate error instead of panicking // when `parse()` returns an error. - let x: i64 = s.parse().unwrap(); + let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parseint)?; PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation) } diff --git a/exercises/error_handling/errors6.rs~ b/exercises/error_handling/errors6.rs~ new file mode 100644 index 000000000..813ad006d --- /dev/null +++ b/exercises/error_handling/errors6.rs~ @@ -0,0 +1,95 @@ +// errors6.rs +// +// Using catch-all error types like `Box` isn't recommended +// for library code, where callers might want to make decisions based on the +// error content, instead of printing it out or propagating it further. Here, we +// define a custom error type to make it possible for callers to decide what to +// do next when our function returns an error. +// +// Execute `rustlings hint errors6` or use the `hint` watch subcommand for a +// hint. + +use std::num::ParseIntError; + +// This is a custom error type that we will be using in `parse_pos_nonzero()`. +#[derive(PartialEq, Debug)] +enum ParsePosNonzeroError { + Creation(CreationError), + ParseInt(ParseIntError), +} + +impl ParsePosNonzeroError { + fn from_creation(err: CreationError) -> ParsePosNonzeroError { + ParsePosNonzeroError::Creation(err) + } + // TODO: add another error conversion function here. + // fn from_parseint... + fn from_parseint(err: ParseIntError) -> ParsePosNonzeroError { + ParsePosNonzeroError::ParseInt(err) + } +} + +fn parse_pos_nonzero(s: &str) -> Result { + // TODO: change this to return an appropriate error instead of panicking + // when `parse()` returns an error. + let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parseint)?; + PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation) +} + +// Don't change anything below this line. + +#[derive(PartialEq, Debug)] +struct PositiveNonzeroInteger(u64); + +#[derive(PartialEq, Debug)] +enum CreationError { + Negative, + Zero, +} + +impl PositiveNonzeroInteger { + fn new(value: i64) -> Result { + match value { + x if x < 0 => Err(CreationError::Negative), + x if x == 0 => Err(CreationError::Zero), + x => Ok(PositiveNonzeroInteger(x as u64)), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_error() { + // We can't construct a ParseIntError, so we have to pattern match. + assert!(matches!( + parse_pos_nonzero("not a number"), + Err(ParsePosNonzeroError::ParseInt(_)) + )); + } + + #[test] + fn test_negative() { + assert_eq!( + parse_pos_nonzero("-555"), + Err(ParsePosNonzeroError::Creation(CreationError::Negative)) + ); + } + + #[test] + fn test_zero() { + assert_eq!( + parse_pos_nonzero("0"), + Err(ParsePosNonzeroError::Creation(CreationError::Zero)) + ); + } + + #[test] + fn test_positive() { + let x = PositiveNonzeroInteger::new(42); + assert!(x.is_ok()); + assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap())); + } +} diff --git a/exercises/generics/.generics1.rs.un~ b/exercises/generics/.generics1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..aa19a7e3979c6e519be0d1f93a0e18bf010b5a1b GIT binary patch literal 2009 zcmWH`%$*;a=aT=Ff$7gIt)zRq`gU3$cAaqX#J#%=7EX;1HO|CrQnr7=!riijfq{Vs zi1ihKASbm%A-A+dp*SPIpdd3ZJw7M1xWq~!EH&B2-cG?5#IUl;OD)&Xv<7P70%Ca} zW&~muAO-;t4Z{rSUsay7KxE@DfTbB2n4mO>0!eYg`2T?bECLf4rKubO!06Zqjt)kK zuM$ABIe-`z{GezN(AQV+RB-fF@beE*aPjwZ1=(-f2#z{XR5642PykX7i+_gEsDlLy zt!QA>9Ro)l10?D|(Z&tLpqvYe8d7sFG*&^e2+O%ZCOC#cv8oE0v@6o#j1jNeJDAbx-zu!4e8P~4OfsZ>O;?V|BxrNok!N)khC>Y^aHbmtEc z+_+M3CHOOR?M5hw*mbi~(DTf_Vcy32yCHWvwRXGSk#!w8 zsJ>r)ByF{^*Now2xp$_S=WfB=|HOb=E@|v1xAwT}Uut$KHxS$Z9D(KD_?E>nVtPk) z?cM4w{0>WbVnS}n^sLOyS7l~??%L&N79FVa-uL18ed?BTMCV0jC*6`xf(TYrAGJMW z)?8neG-=V91l?Y}LFh#tG$m16t2MgyN$Fm?cs`{DrCsW7JqWV?5p@%(5rqsELT%bo z%O%uEm`oCNsEtFd-F+ZSEos%Cob3ZVCl@NRP;V^BdWsTs1$Ad&{>=u@ICu zeF2g;$$z2_%JSpYPIqy&zdxqfz~pkQb}d4%@xq9WAY`!+Y_k^IXrjPjY-5AirYe8* zhSmVZCW$c<{T|>VrcR=e!9u{*e7zBNQk|%yx1rN$sy2sLAFu{Mpy3f3LC9j^(DI4e zhM|@H62j9OnCw9^{dOc)kl6!g)LI&qoi-uZ9&V?#Lj%~V{TvA=-(UzgHoYh}f{?{R zxHT-d!oTHq7;Y-Fv}T|3$oVHpk|w(xQ55%X!mx literal 0 HcmV?d00001 diff --git a/exercises/generics/generics1.rs b/exercises/generics/generics1.rs index 35c1d2fee..1f4fa4ac7 100644 --- a/exercises/generics/generics1.rs +++ b/exercises/generics/generics1.rs @@ -6,9 +6,7 @@ // Execute `rustlings hint generics1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn main() { - let mut shopping_list: Vec = Vec::new(); + let mut shopping_list: Vec<&str> = Vec::new(); shopping_list.push("milk"); } diff --git a/exercises/generics/generics1.rs~ b/exercises/generics/generics1.rs~ new file mode 100644 index 000000000..1f4fa4ac7 --- /dev/null +++ b/exercises/generics/generics1.rs~ @@ -0,0 +1,12 @@ +// generics1.rs +// +// This shopping list program isn't compiling! Use your knowledge of generics to +// fix it. +// +// Execute `rustlings hint generics1` or use the `hint` watch subcommand for a +// hint. + +fn main() { + let mut shopping_list: Vec<&str> = Vec::new(); + shopping_list.push("milk"); +} diff --git a/exercises/generics/generics2.rs b/exercises/generics/generics2.rs index 074cd938c..b0cc651f5 100644 --- a/exercises/generics/generics2.rs +++ b/exercises/generics/generics2.rs @@ -6,14 +6,12 @@ // Execute `rustlings hint generics2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -struct Wrapper { - value: u32, +struct Wrapper { + value: T, } -impl Wrapper { - pub fn new(value: u32) -> Self { +impl Wrapper { + pub fn new(value: T) -> Self { Wrapper { value } } } diff --git a/exercises/generics/generics2.rs~ b/exercises/generics/generics2.rs~ new file mode 100644 index 000000000..b0cc651f5 --- /dev/null +++ b/exercises/generics/generics2.rs~ @@ -0,0 +1,32 @@ +// generics2.rs +// +// This powerful wrapper provides the ability to store a positive integer value. +// Rewrite it using generics so that it supports wrapping ANY type. +// +// Execute `rustlings hint generics2` or use the `hint` watch subcommand for a +// hint. + +struct Wrapper { + value: T, +} + +impl Wrapper { + pub fn new(value: T) -> Self { + Wrapper { value } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn store_u32_in_wrapper() { + assert_eq!(Wrapper::new(42).value, 42); + } + + #[test] + fn store_str_in_wrapper() { + assert_eq!(Wrapper::new("Foo").value, "Foo"); + } +} diff --git a/exercises/hashmaps/.hashmaps1.rs.un~ b/exercises/hashmaps/.hashmaps1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..449b2297145d4a5fb69ddc15a27e5ed1005a5f1c GIT binary patch literal 6172 zcmeI$&ubGw6bJB0+E{H%Y4qa3ZgosTlTFxc5szN{ zH^iGL-aLBp=1l}|Ud3Y};91{yb{`$81f$MvUU}K<>=Jh0hu7JiyPe+iJ7K;5Rb=mV zc3x~9Y~^d-rZf5lC{kzX|+s(N*JM%(_Dy1hWc7x%bikCX!P(^WhJB~VG z%l98e{a(2g3+gA0%Wf5jDpzxO0(Cj$%JVVUBZ2L9X;1ovFz=~>9i?VCG}miQE&M2p?c5_ zA|;>n_aoU3hHcpk2C}UpwUo9YJdYXo0BiV`Fy`72Rj?W4J3r3%)^B~+Npd3?_Od01Ef=w900^Q5(5qmRj?U^=4rI4q~92gpN*^NwQ);H zyFo~Q=~`0Sh%n@JBwRdvVd|z#RKt3ZY0Ydzlzx#Crin5}(3*NAMdKzsjk72K$P0t6 z5p_vyeh}KKM#~)%0j)}jiEpAc-6N#9Zg7GYqmIr10C H-(LL$zVt5S literal 0 HcmV?d00001 diff --git a/exercises/hashmaps/.hashmaps2.rs.un~ b/exercises/hashmaps/.hashmaps2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..0953b4cf4db2c0616b70e3315afe59c6de7f30cf GIT binary patch literal 14201 zcmeI(KWrOS9Kdlmf7*r=>b5DNe*(9~rXd!fpfsU0Ed_~zwnITx)sni!Bo@SpVh4tb zAp!o&)HJ>{uf`~ef#LIH|p1VS3kf0>DmVms@c)C$=`lH z{ck3dxg=#r=$!!apaq&y{sV5=oFS06dt$FqZ(**iQd(c9RV|9NVc?mv()Z>0yq zc9SzOSKoiuaBRu^{e--CR*I${ifo|}y%rsNJvw>nOmyPZ$yX*;4I9t(N$HV7K$w@Z zot?l&7SfEl`hjzXEz@8l^@pTfkYXB_wo2hMu6n|GYGn;E>u28vo=;18oc&-(7Saqc zyqIJ-tcI70)ptv^@p7eFTCU~tRu8SMPW_NXZXa ztjNEy=vmc7Z<|wJWYNrVENGI2G($93k~H(4n$y#^b>e5nLR)KW>4W#PA3VuInjxN_ zZ1fzH51f_4__$X+7mBsZ^U*uB%IHdSq~z4M?5Tr#>c*jzu~vstcn8?G0X@x^sc_&X z38{u~f97(NdJKzF;BHx^7-c=f-zZ0GsO6ZB;%PFbV4@!)yD6 zBt63{fb7Lz(1xUF07}7s*=MG?7hBZO>p8$NRPjNJCt?ow9C&?B@=)!v3NlM2LJ?KWVN&RJ9tJ7s2R8KlpgE7!K3F+!# z*L3YeU2{=~l>P+>l|(Vfk%`R+AGuvgjqc$W!QAFXRY3&KTwMuEI#SX__`ppXxWV{= zZeQE%^73M(R$eJ-m&uY{gFo@;k-{-^Joss9(%Q;jRDJI@JU$14^HLzl7NSBlU#!kA Q6ql;cjW1UxR{#9wKc+oJga7~l literal 0 HcmV?d00001 diff --git a/exercises/hashmaps/.hashmaps3.rs.un~ b/exercises/hashmaps/.hashmaps3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..8b43e8e0bbdfe0d33b074ef00188580832b21f53 GIT binary patch literal 73450 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 F{vVi*wVnU~ literal 0 HcmV?d00001 diff --git a/exercises/hashmaps/hashmaps1.rs b/exercises/hashmaps/hashmaps1.rs index 80829eaa6..04e53dd28 100644 --- a/exercises/hashmaps/hashmaps1.rs +++ b/exercises/hashmaps/hashmaps1.rs @@ -11,17 +11,18 @@ // Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::collections::HashMap; fn fruit_basket() -> HashMap { - let mut basket = // TODO: declare your hash map here. + let mut basket = HashMap::new(); // TODO: declare your hash map here. // Two bananas are already given for you :) basket.insert(String::from("banana"), 2); // TODO: Put more fruits in your basket here. + basket.insert(String::from("apple"), 2); + basket.insert(String::from("mango"), 2); basket } diff --git a/exercises/hashmaps/hashmaps1.rs~ b/exercises/hashmaps/hashmaps1.rs~ new file mode 100644 index 000000000..04e53dd28 --- /dev/null +++ b/exercises/hashmaps/hashmaps1.rs~ @@ -0,0 +1,45 @@ +// hashmaps1.rs +// +// A basket of fruits in the form of a hash map needs to be defined. The key +// represents the name of the fruit and the value represents how many of that +// particular fruit is in the basket. You have to put at least three different +// types of fruits (e.g apple, banana, mango) in the basket and the total count +// of all the fruits should be at least five. +// +// Make me compile and pass the tests! +// +// Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a +// hint. + + +use std::collections::HashMap; + +fn fruit_basket() -> HashMap { + let mut basket = HashMap::new(); // TODO: declare your hash map here. + + // Two bananas are already given for you :) + basket.insert(String::from("banana"), 2); + + // TODO: Put more fruits in your basket here. + basket.insert(String::from("apple"), 2); + basket.insert(String::from("mango"), 2); + + basket +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn at_least_three_types_of_fruits() { + let basket = fruit_basket(); + assert!(basket.len() >= 3); + } + + #[test] + fn at_least_five_fruits() { + let basket = fruit_basket(); + assert!(basket.values().sum::() >= 5); + } +} diff --git a/exercises/hashmaps/hashmaps2.rs b/exercises/hashmaps/hashmaps2.rs index a59256909..589862c84 100644 --- a/exercises/hashmaps/hashmaps2.rs +++ b/exercises/hashmaps/hashmaps2.rs @@ -14,7 +14,6 @@ // Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::collections::HashMap; @@ -40,6 +39,12 @@ fn fruit_basket(basket: &mut HashMap) { // TODO: Insert new fruits if they are not already present in the // basket. Note that you are not allowed to put any type of fruit that's // already present! + match fruit { + Fruit::Banana => basket.insert(Fruit::Banana, 1), + Fruit::Pineapple => basket.insert(Fruit::Pineapple, 3), + _ => continue, + }; + } } diff --git a/exercises/hashmaps/hashmaps2.rs~ b/exercises/hashmaps/hashmaps2.rs~ new file mode 100644 index 000000000..589862c84 --- /dev/null +++ b/exercises/hashmaps/hashmaps2.rs~ @@ -0,0 +1,98 @@ +// hashmaps2.rs +// +// We're collecting different fruits to bake a delicious fruit cake. For this, +// we have a basket, which we'll represent in the form of a hash map. The key +// represents the name of each fruit we collect and the value represents how +// many of that particular fruit we have collected. Three types of fruits - +// Apple (4), Mango (2) and Lychee (5) are already in the basket hash map. You +// must add fruit to the basket so that there is at least one of each kind and +// more than 11 in total - we have a lot of mouths to feed. You are not allowed +// to insert any more of these fruits! +// +// Make me pass the tests! +// +// Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a +// hint. + + +use std::collections::HashMap; + +#[derive(Hash, PartialEq, Eq)] +enum Fruit { + Apple, + Banana, + Mango, + Lychee, + Pineapple, +} + +fn fruit_basket(basket: &mut HashMap) { + let fruit_kinds = vec![ + Fruit::Apple, + Fruit::Banana, + Fruit::Mango, + Fruit::Lychee, + Fruit::Pineapple, + ]; + + for fruit in fruit_kinds { + // TODO: Insert new fruits if they are not already present in the + // basket. Note that you are not allowed to put any type of fruit that's + // already present! + match fruit { + Fruit::Banana => basket.insert(Fruit::Banana, 1), + Fruit::Pineapple => basket.insert(Fruit::Pineapple, 3), + _ => continue, + }; + + } +} + +#[cfg(test)] +mod tests { + use super::*; + + // Don't modify this function! + fn get_fruit_basket() -> HashMap { + let mut basket = HashMap::::new(); + basket.insert(Fruit::Apple, 4); + basket.insert(Fruit::Mango, 2); + basket.insert(Fruit::Lychee, 5); + + basket + } + + #[test] + fn test_given_fruits_are_not_modified() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4); + assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2); + assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5); + } + + #[test] + fn at_least_five_types_of_fruits() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + let count_fruit_kinds = basket.len(); + assert!(count_fruit_kinds >= 5); + } + + #[test] + fn greater_than_eleven_fruits() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + let count = basket.values().sum::(); + assert!(count > 11); + } + + #[test] + fn all_fruit_types_in_basket() { + let mut basket = get_fruit_basket(); + fruit_basket(&mut basket); + for amount in basket.values() { + assert_ne!(amount, &0); + } + } +} diff --git a/exercises/hashmaps/hashmaps3.rs b/exercises/hashmaps/hashmaps3.rs index 08e977c33..bfbc17ce0 100644 --- a/exercises/hashmaps/hashmaps3.rs +++ b/exercises/hashmaps/hashmaps3.rs @@ -14,7 +14,6 @@ // Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE use std::collections::HashMap; @@ -39,6 +38,29 @@ fn build_scores_table(results: String) -> HashMap { // will be the number of goals conceded from team_2, and similarly // goals scored by team_2 will be the number of goals conceded by // team_1. + + + if !scores.contains_key(&team_1_name) && !scores.contains_key(&team_2_name) { + scores.insert(team_1_name, Team{goals_scored: team_1_score, goals_conceded: team_2_score}); + scores.insert(team_2_name, Team{goals_scored: team_2_score, goals_conceded: team_1_score}); + + } else if scores.contains_key(&team_1_name) && scores.contains_key(&team_2_name) { + scores.insert(team_1_name.clone(), Team{ goals_scored: scores.get(&team_1_name).unwrap().goals_scored + team_1_score , + goals_conceded: scores.get(&team_1_name).unwrap().goals_conceded + team_2_score ,}); + scores.insert(team_2_name.clone(), Team{ goals_scored: scores.get(&team_2_name).unwrap().goals_scored + team_2_score , + goals_conceded: scores.get(&team_2_name).unwrap().goals_conceded + team_1_score ,}); + } else if scores.contains_key(&team_1_name) && !scores.contains_key(&team_2_name) { + scores.insert(team_1_name.clone(), Team{ goals_scored: scores.get(&team_1_name).unwrap().goals_scored + team_1_score , + goals_conceded: scores.get(&team_1_name).unwrap().goals_conceded + team_2_score ,}); + scores.insert(team_2_name, Team{goals_scored: team_2_score, goals_conceded: team_1_score}); + + } else if scores.contains_key(&team_2_name) && !scores.contains_key(&team_1_name) { + scores.insert(team_2_name.clone(), Team{ goals_scored: scores.get(&team_2_name).unwrap().goals_scored + team_2_score , + goals_conceded: scores.get(&team_2_name).unwrap().goals_conceded + team_1_score ,}); + scores.insert(team_1_name, Team{goals_scored: team_1_score, goals_conceded: team_2_score}); + + } + } scores } diff --git a/exercises/hashmaps/hashmaps3.rs~ b/exercises/hashmaps/hashmaps3.rs~ new file mode 100644 index 000000000..1147bcc4b --- /dev/null +++ b/exercises/hashmaps/hashmaps3.rs~ @@ -0,0 +1,109 @@ +// hashmaps3.rs +// +// A list of scores (one per line) of a soccer match is given. Each line is of +// the form : ",,," +// Example: England,France,4,2 (England scored 4 goals, France 2). +// +// You have to build a scores table containing the name of the team, goals the +// team scored, and goals the team conceded. One approach to build the scores +// table is to use a Hashmap. The solution is partially written to use a +// Hashmap, complete it to pass the test. +// +// Make me pass the tests! +// +// Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a +// hint. + + +use std::collections::HashMap; + +// A structure to store the goal details of a team. +struct Team { + goals_scored: u8, + goals_conceded: u8, +} + +fn build_scores_table(results: String) -> HashMap { + // The name of the team is the key and its associated struct is the value. + let mut scores: HashMap = HashMap::new(); + let mut tmp_scores: HashMap = HashMap::new(); + + for r in results.lines() { + let v: Vec<&str> = r.split(',').collect(); + let team_1_name = v[0].to_string(); + let team_1_score: u8 = v[2].parse().unwrap(); + let team_2_name = v[1].to_string(); + let team_2_score: u8 = v[3].parse().unwrap(); + // TODO: Populate the scores table with details extracted from the + // current line. Keep in mind that goals scored by team_1 + // will be the number of goals conceded from team_2, and similarly + // goals scored by team_2 will be the number of goals conceded by + // team_1. + + + if !scores.contains_key(&team_1_name) && !scores.contains_key(&team_2_name) { + scores.insert(team_1_name, Team{goals_scored: team_1_score, goals_conceded: team_2_score}); + scores.insert(team_2_name, Team{goals_scored: team_2_score, goals_conceded: team_1_score}); + + } else if scores.contains_key(&team_1_name) && scores.contains_key(&team_2_name) { + scores.insert(team_1_name.clone(), Team{ goals_scored: scores.get(&team_1_name).unwrap().goals_scored + team_1_score , + goals_conceded: scores.get(&team_1_name).unwrap().goals_conceded + team_2_score ,}); + scores.insert(team_2_name.clone(), Team{ goals_scored: scores.get(&team_2_name).unwrap().goals_scored + team_2_score , + goals_conceded: scores.get(&team_2_name).unwrap().goals_conceded + team_1_score ,}); + } else if scores.contains_key(&team_1_name) && !scores.contains_key(&team_2_name) { + scores.insert(team_1_name.clone(), Team{ goals_scored: scores.get(&team_1_name).unwrap().goals_scored + team_1_score , + goals_conceded: scores.get(&team_1_name).unwrap().goals_conceded + team_2_score ,}); + scores.insert(team_2_name, Team{goals_scored: team_2_score, goals_conceded: team_1_score}); + + } else if scores.contains_key(&team_2_name) && !scores.contains_key(&team_1_name) { + scores.insert(team_2_name.clone(), Team{ goals_scored: scores.get(&team_2_name).unwrap().goals_scored + team_2_score , + goals_conceded: scores.get(&team_2_name).unwrap().goals_conceded + team_1_score ,}); + scores.insert(team_1_name, Team{goals_scored: team_1_score, goals_conceded: team_2_score}); + + } + + } + scores +} + +#[cfg(test)] +mod tests { + use super::*; + + fn get_results() -> String { + let results = "".to_string() + + "England,France,4,2\n" + + "France,Italy,3,1\n" + + "Poland,Spain,2,0\n" + + "Germany,England,2,1\n"; + results + } + + #[test] + fn build_scores() { + let scores = build_scores_table(get_results()); + + let mut keys: Vec<&String> = scores.keys().collect(); + keys.sort(); + assert_eq!( + keys, + vec!["England", "France", "Germany", "Italy", "Poland", "Spain"] + ); + } + + #[test] + fn validate_team_score_1() { + let scores = build_scores_table(get_results()); + let team = scores.get("England").unwrap(); + assert_eq!(team.goals_scored, 5); + assert_eq!(team.goals_conceded, 4); + } + + #[test] + fn validate_team_score_2() { + let scores = build_scores_table(get_results()); + let team = scores.get("Spain").unwrap(); + assert_eq!(team.goals_scored, 0); + assert_eq!(team.goals_conceded, 2); + } +} diff --git a/exercises/iterators/.iterators1.rs.un~ b/exercises/iterators/.iterators1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..7c57643370fdb84ae09c6f1f017115a3b3a3e95d GIT binary patch literal 9058 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 literal 0 HcmV?d00001 diff --git a/exercises/iterators/.iterators4.rs.un~ b/exercises/iterators/.iterators4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..80c776c6d1af8a9498e5356e841033026fba5486 GIT binary patch literal 29861 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 qbr#zG2WqR`??v "Hello" @@ -15,7 +13,15 @@ pub fn capitalize_first(input: &str) -> String { let mut c = input.chars(); match c.next() { None => String::new(), - Some(first) => ???, + Some(first) => { + let mut s: String = String::new(); + let b = first.to_uppercase().to_string(); + s.push_str(&b); + let d = c.as_str(); + s.push_str(d); + s + + } } } @@ -24,7 +30,12 @@ pub fn capitalize_first(input: &str) -> String { // Return a vector of strings. // ["hello", "world"] -> ["Hello", "World"] pub fn capitalize_words_vector(words: &[&str]) -> Vec { - vec![] + let mut s: Vec = Vec::new(); + for w in words { + let re = capitalize_first(w); + s.push(re); + } + s } // Step 3. @@ -32,7 +43,12 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec { // Return a single string. // ["hello", " ", "world"] -> "Hello World" pub fn capitalize_words_string(words: &[&str]) -> String { - String::new() + let mut s: String = String::new(); + for w in words { + let re = capitalize_first(w); + s.push_str(&re); + } + s } #[cfg(test)] diff --git a/exercises/iterators/iterators2.rs~ b/exercises/iterators/iterators2.rs~ new file mode 100644 index 000000000..c1bd6c302 --- /dev/null +++ b/exercises/iterators/iterators2.rs~ @@ -0,0 +1,79 @@ +// iterators2.rs +// +// In this exercise, you'll learn some of the unique advantages that iterators +// can offer. Follow the steps to complete the exercise. +// +// Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a +// hint. + +// Step 1. +// Complete the `capitalize_first` function. +// "hello" -> "Hello" +pub fn capitalize_first(input: &str) -> String { + let mut c = input.chars(); + match c.next() { + None => String::new(), + Some(first) => { + let mut s: String = String::new(); + let b = first.to_uppercase().to_string(); + s.push_str(&b); + let d = c.as_str(); + s.push_str(d); + s + + } + } +} + +// Step 2. +// Apply the `capitalize_first` function to a slice of string slices. +// Return a vector of strings. +// ["hello", "world"] -> ["Hello", "World"] +pub fn capitalize_words_vector(words: &[&str]) -> Vec { + let mut s: Vec = Vec::new(); + for w in words { + let re = capitalize_first(w); + s.push(re); + } + s +} + +// Step 3. +// Apply the `capitalize_first` function again to a slice of string slices. +// Return a single string. +// ["hello", " ", "world"] -> "Hello World" +pub fn capitalize_words_string(words: &[&str]) -> String { + let mut s: String = String::new(); + for w in words { + let re = capitalize_first(w); + s.push_str(&re); + } + s +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_success() { + assert_eq!(capitalize_first("hello"), "Hello"); + } + + #[test] + fn test_empty() { + assert_eq!(capitalize_first(""), ""); + } + + #[test] + fn test_iterate_string_vec() { + let words = vec!["hello", "world"]; + assert_eq!(capitalize_words_vector(&words), ["Hello", "World"]); + } + + #[test] + fn test_iterate_into_string() { + let words = vec!["hello", " ", "world"]; + assert_eq!(capitalize_words_string(&words), "Hello World"); + } +} diff --git a/exercises/iterators/iterators3.rs b/exercises/iterators/iterators3.rs index 29fa23a3e..b008d7dc3 100644 --- a/exercises/iterators/iterators3.rs +++ b/exercises/iterators/iterators3.rs @@ -9,8 +9,6 @@ // Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[derive(Debug, PartialEq, Eq)] pub enum DivisionError { NotDivisible(NotDivisibleError), @@ -26,23 +24,34 @@ pub struct NotDivisibleError { // Calculate `a` divided by `b` if `a` is evenly divisible by `b`. // Otherwise, return a suitable error. pub fn divide(a: i32, b: i32) -> Result { - todo!(); + if b != 0 && a%b == 0 { + Ok(a/b) + } else if b == 0 { + Err(DivisionError::DivideByZero) + } else { + Err(DivisionError::NotDivisible(NotDivisibleError { + dividend: a, + divisor: b, + })) + } } // Complete the function and return a value of the correct type so the test // passes. // Desired output: Ok([1, 11, 1426, 3]) -fn result_with_list() -> () { +fn result_with_list() ->Result, DivisionError> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + let division_results: Result, DivisionError> = numbers.into_iter().map(|n| divide(n, 27)).collect(); + division_results } // Complete the function and return a value of the correct type so the test // passes. // Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] -fn list_of_results() -> () { +fn list_of_results() -> Vec> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + let division_results: Vec<_> = numbers.into_iter().map(|n| divide(n, 27)).collect(); + division_results } #[cfg(test)] diff --git a/exercises/iterators/iterators3.rs~ b/exercises/iterators/iterators3.rs~ new file mode 100644 index 000000000..b008d7dc3 --- /dev/null +++ b/exercises/iterators/iterators3.rs~ @@ -0,0 +1,99 @@ +// iterators3.rs +// +// This is a bigger exercise than most of the others! You can do it! Here is +// your mission, should you choose to accept it: +// 1. Complete the divide function to get the first four tests to pass. +// 2. Get the remaining tests to pass by completing the result_with_list and +// list_of_results functions. +// +// Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a +// hint. + +#[derive(Debug, PartialEq, Eq)] +pub enum DivisionError { + NotDivisible(NotDivisibleError), + DivideByZero, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct NotDivisibleError { + dividend: i32, + divisor: i32, +} + +// Calculate `a` divided by `b` if `a` is evenly divisible by `b`. +// Otherwise, return a suitable error. +pub fn divide(a: i32, b: i32) -> Result { + if b != 0 && a%b == 0 { + Ok(a/b) + } else if b == 0 { + Err(DivisionError::DivideByZero) + } else { + Err(DivisionError::NotDivisible(NotDivisibleError { + dividend: a, + divisor: b, + })) + } +} + +// Complete the function and return a value of the correct type so the test +// passes. +// Desired output: Ok([1, 11, 1426, 3]) +fn result_with_list() ->Result, DivisionError> { + let numbers = vec![27, 297, 38502, 81]; + let division_results: Result, DivisionError> = numbers.into_iter().map(|n| divide(n, 27)).collect(); + division_results +} + +// Complete the function and return a value of the correct type so the test +// passes. +// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] +fn list_of_results() -> Vec> { + let numbers = vec![27, 297, 38502, 81]; + let division_results: Vec<_> = numbers.into_iter().map(|n| divide(n, 27)).collect(); + division_results +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_success() { + assert_eq!(divide(81, 9), Ok(9)); + } + + #[test] + fn test_not_divisible() { + assert_eq!( + divide(81, 6), + Err(DivisionError::NotDivisible(NotDivisibleError { + dividend: 81, + divisor: 6 + })) + ); + } + + #[test] + fn test_divide_by_0() { + assert_eq!(divide(81, 0), Err(DivisionError::DivideByZero)); + } + + #[test] + fn test_divide_0_by_something() { + assert_eq!(divide(0, 81), Ok(0)); + } + + #[test] + fn test_result_with_list() { + assert_eq!(format!("{:?}", result_with_list()), "Ok([1, 11, 1426, 3])"); + } + + #[test] + fn test_list_of_results() { + assert_eq!( + format!("{:?}", list_of_results()), + "[Ok(1), Ok(11), Ok(1426), Ok(3)]" + ); + } +} diff --git a/exercises/iterators/iterators4.rs b/exercises/iterators/iterators4.rs index 79e1692ba..30aaef155 100644 --- a/exercises/iterators/iterators4.rs +++ b/exercises/iterators/iterators4.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - pub fn factorial(num: u64) -> u64 { // Complete this function to return the factorial of num // Do not use: @@ -15,6 +13,20 @@ pub fn factorial(num: u64) -> u64 { // For an extra challenge, don't use: // - recursion // Execute `rustlings hint iterators4` for hints. + if num == 0 { + 1 + } else if num == 1 { + 1 + } else if num == 2 { + 2 + } else { + let mut a: Vec = vec![]; + for n in 1..=num { + a.push(n.try_into().unwrap()); + } + let m = a.iter().fold(1, |acc, x| acc * x); + m.try_into().unwrap() + } } #[cfg(test)] diff --git a/exercises/iterators/iterators4.rs~ b/exercises/iterators/iterators4.rs~ new file mode 100644 index 000000000..30aaef155 --- /dev/null +++ b/exercises/iterators/iterators4.rs~ @@ -0,0 +1,54 @@ +// iterators4.rs +// +// Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a +// hint. + +pub fn factorial(num: u64) -> u64 { + // Complete this function to return the factorial of num + // Do not use: + // - return + // Try not to use: + // - imperative style loops (for, while) + // - additional variables + // For an extra challenge, don't use: + // - recursion + // Execute `rustlings hint iterators4` for hints. + if num == 0 { + 1 + } else if num == 1 { + 1 + } else if num == 2 { + 2 + } else { + let mut a: Vec = vec![]; + for n in 1..=num { + a.push(n.try_into().unwrap()); + } + let m = a.iter().fold(1, |acc, x| acc * x); + m.try_into().unwrap() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn factorial_of_0() { + assert_eq!(1, factorial(0)); + } + + #[test] + fn factorial_of_1() { + assert_eq!(1, factorial(1)); + } + #[test] + fn factorial_of_2() { + assert_eq!(2, factorial(2)); + } + + #[test] + fn factorial_of_4() { + assert_eq!(24, factorial(4)); + } +} diff --git a/exercises/iterators/iterators5.rs b/exercises/iterators/iterators5.rs index a062ee4c7..d471d92dc 100644 --- a/exercises/iterators/iterators5.rs +++ b/exercises/iterators/iterators5.rs @@ -11,8 +11,6 @@ // Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::collections::HashMap; #[derive(Clone, Copy, PartialEq, Eq)] @@ -35,7 +33,23 @@ fn count_for(map: &HashMap, value: Progress) -> usize { fn count_iterator(map: &HashMap, value: Progress) -> usize { // map is a hashmap with String keys and Progress values. // map = { "variables1": Complete, "from_str": None, ... } - todo!(); + let mut complete_num = 0; + let mut some_num = 0; + let mut none_num = 0; + match value { + Progress::Complete => { + let _complete: Vec<_> = map.values().map(|x| if *x == Progress::Complete { complete_num += 1}).collect(); + complete_num + }, + Progress::Some => { + let _some: Vec<_> = map.values().map(|x| if *x == Progress::Some { some_num += 1}).collect(); + some_num + }, + Progress::None => { + let _none: Vec<_> = map.values().map(|x| if *x == Progress::None { none_num += 1}).collect(); + none_num + }, + } } fn count_collection_for(collection: &[HashMap], value: Progress) -> usize { @@ -54,7 +68,29 @@ fn count_collection_iterator(collection: &[HashMap], value: Pr // collection is a slice of hashmaps. // collection = [{ "variables1": Complete, "from_str": None, ... }, // { "variables2": Complete, ... }, ... ] - todo!(); + let mut complete_num = 0; + let mut some_num = 0; + let mut none_num = 0; + match value { + Progress::Complete => { + let complete: Vec<_> = collection.iter().map(|x| { + complete_num += count_iterator(x, Progress::Complete); + } ).collect(); + complete_num + }, + Progress::Some => { + let some: Vec<_> = collection.iter().map(|x| { + some_num += count_iterator(x, Progress::Some); + } ).collect(); + some_num + }, + Progress::None => { + let none: Vec<_> = collection.iter().map(|x| { + none_num += count_iterator(x, Progress::None); + } ).collect(); + none_num + }, + } } #[cfg(test)] diff --git a/exercises/iterators/iterators5.rs~ b/exercises/iterators/iterators5.rs~ new file mode 100644 index 000000000..d471d92dc --- /dev/null +++ b/exercises/iterators/iterators5.rs~ @@ -0,0 +1,192 @@ +// iterators5.rs +// +// Let's define a simple model to track Rustlings exercise progress. Progress +// will be modelled using a hash map. The name of the exercise is the key and +// the progress is the value. Two counting functions were created to count the +// number of exercises with a given progress. Recreate this counting +// functionality using iterators. Try not to use imperative loops (for, while). +// Only the two iterator methods (count_iterator and count_collection_iterator) +// need to be modified. +// +// Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a +// hint. + +use std::collections::HashMap; + +#[derive(Clone, Copy, PartialEq, Eq)] +enum Progress { + None, + Some, + Complete, +} + +fn count_for(map: &HashMap, value: Progress) -> usize { + let mut count = 0; + for val in map.values() { + if val == &value { + count += 1; + } + } + count +} + +fn count_iterator(map: &HashMap, value: Progress) -> usize { + // map is a hashmap with String keys and Progress values. + // map = { "variables1": Complete, "from_str": None, ... } + let mut complete_num = 0; + let mut some_num = 0; + let mut none_num = 0; + match value { + Progress::Complete => { + let _complete: Vec<_> = map.values().map(|x| if *x == Progress::Complete { complete_num += 1}).collect(); + complete_num + }, + Progress::Some => { + let _some: Vec<_> = map.values().map(|x| if *x == Progress::Some { some_num += 1}).collect(); + some_num + }, + Progress::None => { + let _none: Vec<_> = map.values().map(|x| if *x == Progress::None { none_num += 1}).collect(); + none_num + }, + } +} + +fn count_collection_for(collection: &[HashMap], value: Progress) -> usize { + let mut count = 0; + for map in collection { + for val in map.values() { + if val == &value { + count += 1; + } + } + } + count +} + +fn count_collection_iterator(collection: &[HashMap], value: Progress) -> usize { + // collection is a slice of hashmaps. + // collection = [{ "variables1": Complete, "from_str": None, ... }, + // { "variables2": Complete, ... }, ... ] + let mut complete_num = 0; + let mut some_num = 0; + let mut none_num = 0; + match value { + Progress::Complete => { + let complete: Vec<_> = collection.iter().map(|x| { + complete_num += count_iterator(x, Progress::Complete); + } ).collect(); + complete_num + }, + Progress::Some => { + let some: Vec<_> = collection.iter().map(|x| { + some_num += count_iterator(x, Progress::Some); + } ).collect(); + some_num + }, + Progress::None => { + let none: Vec<_> = collection.iter().map(|x| { + none_num += count_iterator(x, Progress::None); + } ).collect(); + none_num + }, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn count_complete() { + let map = get_map(); + assert_eq!(3, count_iterator(&map, Progress::Complete)); + } + + #[test] + fn count_some() { + let map = get_map(); + assert_eq!(1, count_iterator(&map, Progress::Some)); + } + + #[test] + fn count_none() { + let map = get_map(); + assert_eq!(2, count_iterator(&map, Progress::None)); + } + + #[test] + fn count_complete_equals_for() { + let map = get_map(); + let progress_states = vec![Progress::Complete, Progress::Some, Progress::None]; + for progress_state in progress_states { + assert_eq!( + count_for(&map, progress_state), + count_iterator(&map, progress_state) + ); + } + } + + #[test] + fn count_collection_complete() { + let collection = get_vec_map(); + assert_eq!( + 6, + count_collection_iterator(&collection, Progress::Complete) + ); + } + + #[test] + fn count_collection_some() { + let collection = get_vec_map(); + assert_eq!(1, count_collection_iterator(&collection, Progress::Some)); + } + + #[test] + fn count_collection_none() { + let collection = get_vec_map(); + assert_eq!(4, count_collection_iterator(&collection, Progress::None)); + } + + #[test] + fn count_collection_equals_for() { + let progress_states = vec![Progress::Complete, Progress::Some, Progress::None]; + let collection = get_vec_map(); + + for progress_state in progress_states { + assert_eq!( + count_collection_for(&collection, progress_state), + count_collection_iterator(&collection, progress_state) + ); + } + } + + fn get_map() -> HashMap { + use Progress::*; + + let mut map = HashMap::new(); + map.insert(String::from("variables1"), Complete); + map.insert(String::from("functions1"), Complete); + map.insert(String::from("hashmap1"), Complete); + map.insert(String::from("arc1"), Some); + map.insert(String::from("as_ref_mut"), None); + map.insert(String::from("from_str"), None); + + map + } + + fn get_vec_map() -> Vec> { + use Progress::*; + + let map = get_map(); + + let mut other = HashMap::new(); + other.insert(String::from("variables2"), Complete); + other.insert(String::from("functions2"), Complete); + other.insert(String::from("if1"), Complete); + other.insert(String::from("from_into"), None); + other.insert(String::from("try_from_into"), None); + + vec![map, other] + } +} diff --git a/exercises/lifetimes/.lifetimes1.rs.un~ b/exercises/lifetimes/.lifetimes1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..1bcf94821b1aac61ce5ebaf8554eaa0bf1219d69 GIT binary patch literal 4828 zcmeI0y-or_6om)DAN)y-#zY!36(B+|K^tQ*CRk_!G)nAX3q=$`ffx;qS{Mr-!NkVO zr|=PMd;~RgHrnDnv%4@DSTHNyoa8chhuPW5{W!C`q;kg(JB3*BjSaZ#?+3Ni?sYA8 zcX{u6UVA;QW|tzB$Zh6kEB;vjWQ=(zy!!>7FBY4jeJQsy2CnbQ1P%u%1zKURGtYG?^JMe1MY7aJW0^gvtVxR>|{6G{=6rr!`hBF}H z^!a)L3V=h>ngJI;C(x(vlc+*JML;zxe=f*CwVsHA;IOo2&;`*c^eLjKf(a|9eTh-b&#ECi5vVdfn7~(I0WPyMQLV-z;6vzND_zwhNqhJD~G?haD7#;QC=wM{{DgiW`9f)DU z4~rH7eSHN_1xH^6KmQN~7k@uj(?)RAfuf2T$vq(TqA>lVQHK;VG+_dx?jAVm7$8vx z%6g#S2LVvjkdSeq5ekYxSf&M;0*YK=AO=k9inqQ-~ld!GsD*H3GcZx5fv z&(E& zLBX=q1DK5>p_rixy%aH9Y{$%PVHR0xPy?lY%e+7k)Lh6ZYN$dl^&2&>m0B>^pMckI#xy{$YO}BspDBcD!LqNpZs+LJqqgyqWE_zX8^P%Tc3Rz(S z7qf!HAe=0DYxCmdsTa&cBVRvy%EJo?@i0-}@IVefXYnrSMnYMT%ksyz6O!xgNcvky z26b{|s7{Va@znTFppKVZk#5>f$i=PXU@nxNJ^17HCoRbLKa64vTJ484+f?m>s7ANy Y1muPUX|LTAzJv6^f_#l<2bS)?0Hc+r1poj5 literal 0 HcmV?d00001 diff --git a/exercises/lifetimes/lifetimes1.rs b/exercises/lifetimes/lifetimes1.rs index 87bde490c..5fe45ae0f 100644 --- a/exercises/lifetimes/lifetimes1.rs +++ b/exercises/lifetimes/lifetimes1.rs @@ -8,9 +8,7 @@ // Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -fn longest(x: &str, y: &str) -> &str { +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { diff --git a/exercises/lifetimes/lifetimes1.rs~ b/exercises/lifetimes/lifetimes1.rs~ new file mode 100644 index 000000000..5fe45ae0f --- /dev/null +++ b/exercises/lifetimes/lifetimes1.rs~ @@ -0,0 +1,25 @@ +// lifetimes1.rs +// +// The Rust compiler needs to know how to check whether supplied references are +// valid, so that it can let the programmer know if a reference is at risk of +// going out of scope before it is used. Remember, references are borrows and do +// not own their own data. What if their owner goes out of scope? +// +// Execute `rustlings hint lifetimes1` or use the `hint` watch subcommand for a +// hint. + +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + if x.len() > y.len() { + x + } else { + y + } +} + +fn main() { + let string1 = String::from("abcd"); + let string2 = "xyz"; + + let result = longest(string1.as_str(), string2); + println!("The longest string is '{}'", result); +} diff --git a/exercises/lifetimes/lifetimes2.rs b/exercises/lifetimes/lifetimes2.rs index 4f3d8c185..b0dcb74ef 100644 --- a/exercises/lifetimes/lifetimes2.rs +++ b/exercises/lifetimes/lifetimes2.rs @@ -6,8 +6,6 @@ // Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x @@ -19,8 +17,8 @@ fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { fn main() { let string1 = String::from("long string is long"); let result; + let string2 = String::from("xyz"); { - let string2 = String::from("xyz"); result = longest(string1.as_str(), string2.as_str()); } println!("The longest string is '{}'", result); diff --git a/exercises/lifetimes/lifetimes2.rs~ b/exercises/lifetimes/lifetimes2.rs~ new file mode 100644 index 000000000..33b5565fb --- /dev/null +++ b/exercises/lifetimes/lifetimes2.rs~ @@ -0,0 +1,25 @@ +// lifetimes2.rs +// +// So if the compiler is just validating the references passed to the annotated +// parameters and the return type, what do we need to change? +// +// Execute `rustlings hint lifetimes2` or use the `hint` watch subcommand for a +// hint. + +fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { + if x.len() > y.len() { + x + } else { + y + } +} + +fn main() { + let string1 = String::from("long string is long"); + let result; + { + let string2 = String::from("xyz"); + result = longest(string1.as_str(), string2.as_str()); + } + println!("The longest string is '{}'", result); +} diff --git a/exercises/lifetimes/lifetimes3.rs b/exercises/lifetimes/lifetimes3.rs index 9c59f9c02..aede10de3 100644 --- a/exercises/lifetimes/lifetimes3.rs +++ b/exercises/lifetimes/lifetimes3.rs @@ -5,11 +5,9 @@ // Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -struct Book { - author: &str, - title: &str, +struct Book<'a> { + author: &'a str, + title: &'a str, } fn main() { diff --git a/exercises/lifetimes/lifetimes3.rs~ b/exercises/lifetimes/lifetimes3.rs~ new file mode 100644 index 000000000..aede10de3 --- /dev/null +++ b/exercises/lifetimes/lifetimes3.rs~ @@ -0,0 +1,19 @@ +// lifetimes3.rs +// +// Lifetimes are also needed when structs hold references. +// +// Execute `rustlings hint lifetimes3` or use the `hint` watch subcommand for a +// hint. + +struct Book<'a> { + author: &'a str, + title: &'a str, +} + +fn main() { + let name = String::from("Jill Smith"); + let title = String::from("Fish Flying"); + let book = Book { author: &name, title: &title }; + + println!("{} by {}", book.title, book.author); +} diff --git a/exercises/macros/.macros1.rs.un~ b/exercises/macros/.macros1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..5499d62bf52d74b0794dc51aa0436b5e32f33316 GIT binary patch literal 996 zcmWH`%$*;a=aT=FfhpOW^KHci9?SDb|L#(M88jtX)P2(bJI9rj)B=m9TzYK7z`(!< z#QX|CkXsp_o0wdbuc2uT6ygP99w24}VkRI40T2zt4C%im`dC1+%nb1tK(aspQwU;% zq*y@=5cm%SU=av+l%#qH0HdQB936}dUnPL1vj8zH_+il^ps%msso?0V;O8Hr;NtJ+ xYT5{nI#5(01CV-H{EtQ*a>&qx4UD>8Xifr09Vpv@awQ0Zq6R&8nl?UP1pwo@HyHo` literal 0 HcmV?d00001 diff --git a/exercises/macros/.macros2.rs.un~ b/exercises/macros/.macros2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..569c60502cb66720b1b3ad08785a2ccba27e2887 GIT binary patch literal 1443 zcmWH`%$*;a=aT=Ffys8(J|6KiJEJR`bDAPDw+R=2D4O^4@CnI?+z?UT%JAxiwvp{6yFF+MAL1_>Ll46DN{{sP71ST*_Q#k~H(J>ty9gGZL zC4gqL05L51VbLO>udm>#;OML1=O3cr;_v5b+6az1vsG(^M6l1If5)9Dj sghe+<2n0Y`mJ7@R5~I-x3kh1$!022AEf~Q$5gzm)3o%7Z8=tQN08@uRQvd(} literal 0 HcmV?d00001 diff --git a/exercises/macros/.macros3.rs.un~ b/exercises/macros/.macros3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..88a1e2a06314dd1c7f87a7faa38963ecc475151d GIT binary patch literal 18194 zcmeI3J8T_A6o#*jo%k6);v{|qdqa5GG$~LDOaYNhK|vxRNP|$6fH9HqL%uPBSP597 zqoe^Eq*N$Dw1^fEWrTzT2nD(*0vbS~!9sApvvX$W+GD)A*Gn}=8qeI_+1=6q`OM?& z?AeQpA3nDm(Q)Py*gh%mMy+yhom-1Gm@#+EAy)XH#iMY%NYzA1yet1id32lx3@xW zpn#iBK>U=%A8~`5L9(WCRf1+}RGtg84TaX7JDWkX!EHxpvx?S2m?dteMyt73(y6L* z1}VQLNz20RotU#3w|=IPTRTYZs@^C$hA;Xj`5B2nqIJ@rvI>N{QI0YDK$-Q#eXR>- z!FUE9c$$HZ8xw9RCXnG{IgzZK0$xd}PMKLBhKp%gTlkpjfE|(11kP%nX3` zpOB!LD$V9)pna;)`f_N5wYnu)zu339{E}No5Gw(a;XbDVjcNpv*K_sR*+?W3Tw_6dK$-9bg0xgDgYSv|!l#kQ zC^$e(28{z^0v8CUSC(i8&mcrX-EK_Q7!bB7l>rzjPAaMOKE}d+Klp zi)T%a>l6U(NTx#uwc{dr*=YKy9OJ>Mc!`X7dsdC!SG=V>v{IH+E#1?@joa$@VSH zZao08hk^z|)0Pp5U?5CW#WDoXD#3|jyfgWkR!$V}1+w$?28Xow1Q44JS_jSeG&87_ zihHGiZ2SL23A(r?(uXhO3a)0A#`GeI+e7+;D9l~Qr96cBKqDY&CKBHN_JdpBIK z*kx{K=vHl)dFXK*24sBX<7~1$RzTo=q3|XfM?QnM+Xp?)1&Lu!xTX;qBbMoByeS&y zlxa5eN;*|zuj(#`eJ5*r2&y?mAUWy|k%0?`R7;3Vi6(PD-pKW~Uf@=K*`>%3l>_N8TYa zsDaW(zWBapAo)>C$^ZnK?ng^qq$p9T3A8^#|Jw>pzX#Dx5B1_hM~lZ;%ix!onHrVn zyD{r40-XNaR1m34xz-UlOUNomWe@PkI^%s~r5#vA<#+qdxEC I#+~c`0uWAnz5oCK literal 0 HcmV?d00001 diff --git a/exercises/macros/.macros4.rs.un~ b/exercises/macros/.macros4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..926a50389400e07c03b1882f7916d3f333e6b425 GIT binary patch literal 1404 zcmWH`%$*;a=aT=Ff$2m06&pbXxhv9(HpX;4UTJaX<^4~slY<^*e6Hjv(2US$U|Nv$i`m)OEWMqL1_>Lk^&h32LFKoECLf4 zrKubO!05ORjt)kKuM$ABS%4T8{IF;d(AQV+RB-fF@beE*aPjwZHEje(9daCloCQ+P z1=Bwob)X=jB>+a}V!)RQ=f`wKz XFs`0LOFeKl;{jU42gK-c^?VfooW(wb literal 0 HcmV?d00001 diff --git a/exercises/macros/macros1.rs b/exercises/macros/macros1.rs index 678de6eec..9d0edee3c 100644 --- a/exercises/macros/macros1.rs +++ b/exercises/macros/macros1.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint macros1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - macro_rules! my_macro { () => { println!("Check out my macro!"); @@ -12,5 +10,5 @@ macro_rules! my_macro { } fn main() { - my_macro(); + my_macro!(); } diff --git a/exercises/macros/macros1.rs~ b/exercises/macros/macros1.rs~ new file mode 100644 index 000000000..9d0edee3c --- /dev/null +++ b/exercises/macros/macros1.rs~ @@ -0,0 +1,14 @@ +// macros1.rs +// +// Execute `rustlings hint macros1` or use the `hint` watch subcommand for a +// hint. + +macro_rules! my_macro { + () => { + println!("Check out my macro!"); + }; +} + +fn main() { + my_macro!(); +} diff --git a/exercises/macros/macros2.rs b/exercises/macros/macros2.rs index 788fc16a9..2d1ceb35a 100644 --- a/exercises/macros/macros2.rs +++ b/exercises/macros/macros2.rs @@ -3,14 +3,12 @@ // Execute `rustlings hint macros2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - -fn main() { - my_macro!(); -} - macro_rules! my_macro { () => { println!("Check out my macro!"); }; } +fn main() { + my_macro!(); +} + diff --git a/exercises/macros/macros2.rs~ b/exercises/macros/macros2.rs~ new file mode 100644 index 000000000..2d1ceb35a --- /dev/null +++ b/exercises/macros/macros2.rs~ @@ -0,0 +1,14 @@ +// macros2.rs +// +// Execute `rustlings hint macros2` or use the `hint` watch subcommand for a +// hint. + +macro_rules! my_macro { + () => { + println!("Check out my macro!"); + }; +} +fn main() { + my_macro!(); +} + diff --git a/exercises/macros/macros3.rs b/exercises/macros/macros3.rs index b795c1493..97a3d9806 100644 --- a/exercises/macros/macros3.rs +++ b/exercises/macros/macros3.rs @@ -5,14 +5,14 @@ // Execute `rustlings hint macros3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - +use crate::macros::my_macro; mod macros { macro_rules! my_macro { () => { println!("Check out my macro!"); }; } + pub(crate) use my_macro; } fn main() { diff --git a/exercises/macros/macros3.rs~ b/exercises/macros/macros3.rs~ new file mode 100644 index 000000000..97a3d9806 --- /dev/null +++ b/exercises/macros/macros3.rs~ @@ -0,0 +1,20 @@ +// macros3.rs +// +// Make me compile, without taking the macro out of the module! +// +// Execute `rustlings hint macros3` or use the `hint` watch subcommand for a +// hint. + +use crate::macros::my_macro; +mod macros { + macro_rules! my_macro { + () => { + println!("Check out my macro!"); + }; + } + pub(crate) use my_macro; +} + +fn main() { + my_macro!(); +} diff --git a/exercises/macros/macros4.rs b/exercises/macros/macros4.rs index 71b45a095..a07a9ca53 100644 --- a/exercises/macros/macros4.rs +++ b/exercises/macros/macros4.rs @@ -3,16 +3,14 @@ // Execute `rustlings hint macros4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - #[rustfmt::skip] macro_rules! my_macro { () => { println!("Check out my macro!"); - } + }; ($val:expr) => { println!("Look at this other macro: {}", $val); - } + }; } fn main() { diff --git a/exercises/macros/macros4.rs~ b/exercises/macros/macros4.rs~ new file mode 100644 index 000000000..a07a9ca53 --- /dev/null +++ b/exercises/macros/macros4.rs~ @@ -0,0 +1,19 @@ +// macros4.rs +// +// Execute `rustlings hint macros4` or use the `hint` watch subcommand for a +// hint. + +#[rustfmt::skip] +macro_rules! my_macro { + () => { + println!("Check out my macro!"); + }; + ($val:expr) => { + println!("Look at this other macro: {}", $val); + }; +} + +fn main() { + my_macro!(); + my_macro!(7777); +} diff --git a/exercises/modules/.modules1.rs.un~ b/exercises/modules/.modules1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..b25f3db2a2457fa5f83c8750edcb607b33e1f088 GIT binary patch literal 1012 zcmWH`%$*;a=aT=Ffl0wclQ;g}o7J*8=}{-o71wPkUl!$&UC?8}HtR-_k&6Ta1A_<< ziz@&@TAo5~Vs>hLabjt4VtT5Erb0DPiU){UfS3`8nSdAsKr{?9q<<1EW&z1EGsIs2 z$pQgPA&3o`~ zNDveR1i-?Hs$H(lfm~Gfn;YcU8@1DYx-_adRgB z#cTY&`{CV>Z+{*?y72zv+s&or`-6kOer8@x6;I!ee>$EX^E^+Gvo+H}19?(SU}X2Q zd&yhP__W(ge^y^;R3ip_)WPR}$>a=Axbcu9kll+tlsFo^-(b{E&f#Y)J>%ozl9-$m z^9$F-%)l>XDwR?knHyar4NP&PlQ?r65d{k~;rLo| zYz;Z$f}`Yu9300gIc^8pY%U;>(~HxKb5pYsm<+Ftu7u%kyb(K?G9(s%3}7aDbx|Vp zL*%36fEgm@S%Dd)LfpC!=gOeKLGlwgcPc~_EX)Mlm;~2WiHO0;opfa@$P@$LUk%oC zE4h5BkS=UyR_>4(ckU^Sz}8O=1;c<87>9AXVO;BEwC_5{Q z8%BAy5@prmCY)rT02tR647k`}9Z)SObsw4lP3zj^Qig#J*W6&0D8VeDtr0vOLoFay zhb9bf)MA(b!~d%sRv>7VTM9Y`Nk`8LnRc-`y{_t&YFyHbmZ%I*mmQu8kbo!6)u$YZ zI!6B4cSH7r#SPcdYlM{OC0}deI@?`+^=-tvyv5{XDVPhe7RMo=L;}rrUs!@lI zBVsd}pi4<~9ijZVvtx8I9i3_<%Ix@c3|7dJ!xJ4l8)kg13A^*U?4lk08Oe@xhxAwd z_lk zI-rZ@KV5QIDmY>e8>y2Wf?#7N>|RQCEn)2f2?2p12fHDbT(tEo7cf#}^i3GR;SNrG zh{j=<3BYHy#Mf6AUsQQeSc_UCk{?PI*YK%;SPv%P1|+zqPt=B4uQi`=V-$2qLf|p0SS+}RZDnZ-~0o} Cec*IfJI;eqcoL6ApMg>H8?sL z8NNyY&E^7PSnz|QLO@?%!BfG}SHaIeM8U=1&(*XM9Bq&oWME)|x(5`6ygF@);!qMK zHX4VZP@p9M)?50>ISv%`{6H)U#Go7piCLH^xH^PpK2Su#szQ)LP$Yu#Dj1AL94sVg zMFS(w2w%jhAZ5I2M9$Mu2=()fh<6R}clM~YhDIfF{sXxe6s@2r2ZPb5goOmHXkb*D zfTNNHQI5ibACw2BaF?S<%@&yJK$Rk>`2sRwwAlg+6`In(itsvmUW7GUP@@#qkipXa He7*_*qkV!Z literal 0 HcmV?d00001 diff --git a/exercises/modules/modules1.rs b/exercises/modules/modules1.rs index 9eb5a48b7..a26f5c45d 100644 --- a/exercises/modules/modules1.rs +++ b/exercises/modules/modules1.rs @@ -3,15 +3,13 @@ // Execute `rustlings hint modules1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - mod sausage_factory { // Don't let anybody outside of this module see this! fn get_secret_recipe() -> String { String::from("Ginger") } - fn make_sausage() { + pub fn make_sausage() { get_secret_recipe(); println!("sausage!"); } diff --git a/exercises/modules/modules1.rs~ b/exercises/modules/modules1.rs~ new file mode 100644 index 000000000..a26f5c45d --- /dev/null +++ b/exercises/modules/modules1.rs~ @@ -0,0 +1,20 @@ +// modules1.rs +// +// Execute `rustlings hint modules1` or use the `hint` watch subcommand for a +// hint. + +mod sausage_factory { + // Don't let anybody outside of this module see this! + fn get_secret_recipe() -> String { + String::from("Ginger") + } + + pub fn make_sausage() { + get_secret_recipe(); + println!("sausage!"); + } +} + +fn main() { + sausage_factory::make_sausage(); +} diff --git a/exercises/modules/modules2.rs b/exercises/modules/modules2.rs index 041545431..f5bd7cc08 100644 --- a/exercises/modules/modules2.rs +++ b/exercises/modules/modules2.rs @@ -7,12 +7,10 @@ // Execute `rustlings hint modules2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - mod delicious_snacks { // TODO: Fix these use statements - use self::fruits::PEAR as ??? - use self::veggies::CUCUMBER as ??? + pub use self::fruits::PEAR as fruit; + pub use self::veggies::CUCUMBER as veggie; mod fruits { pub const PEAR: &'static str = "Pear"; diff --git a/exercises/modules/modules2.rs~ b/exercises/modules/modules2.rs~ new file mode 100644 index 000000000..f5bd7cc08 --- /dev/null +++ b/exercises/modules/modules2.rs~ @@ -0,0 +1,32 @@ +// modules2.rs +// +// You can bring module paths into scopes and provide new names for them with +// the 'use' and 'as' keywords. Fix these 'use' statements to make the code +// compile. +// +// Execute `rustlings hint modules2` or use the `hint` watch subcommand for a +// hint. + +mod delicious_snacks { + // TODO: Fix these use statements + pub use self::fruits::PEAR as fruit; + pub use self::veggies::CUCUMBER as veggie; + + mod fruits { + pub const PEAR: &'static str = "Pear"; + pub const APPLE: &'static str = "Apple"; + } + + mod veggies { + pub const CUCUMBER: &'static str = "Cucumber"; + pub const CARROT: &'static str = "Carrot"; + } +} + +fn main() { + println!( + "favorite snacks: {} and {}", + delicious_snacks::fruit, + delicious_snacks::veggie + ); +} diff --git a/exercises/modules/modules3.rs b/exercises/modules/modules3.rs index f2bb05038..d216c7b58 100644 --- a/exercises/modules/modules3.rs +++ b/exercises/modules/modules3.rs @@ -8,10 +8,9 @@ // Execute `rustlings hint modules3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE // TODO: Complete this use statement -use ??? +use std::time::{SystemTime, UNIX_EPOCH}; fn main() { match SystemTime::now().duration_since(UNIX_EPOCH) { diff --git a/exercises/modules/modules3.rs~ b/exercises/modules/modules3.rs~ new file mode 100644 index 000000000..d216c7b58 --- /dev/null +++ b/exercises/modules/modules3.rs~ @@ -0,0 +1,20 @@ +// modules3.rs +// +// You can use the 'use' keyword to bring module paths from modules from +// anywhere and especially from the Rust standard library into your scope. Bring +// SystemTime and UNIX_EPOCH from the std::time module. Bonus style points if +// you can do it with one line! +// +// Execute `rustlings hint modules3` or use the `hint` watch subcommand for a +// hint. + + +// TODO: Complete this use statement +use std::time::{SystemTime, UNIX_EPOCH}; + +fn main() { + match SystemTime::now().duration_since(UNIX_EPOCH) { + Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()), + Err(_) => panic!("SystemTime before UNIX EPOCH!"), + } +} diff --git a/exercises/options/.options1.rs.un~ b/exercises/options/.options1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..54c09713c94b2de2622cd01fac4955f6eca124af GIT binary patch literal 19197 zcmeI4&1+pn7>94$Bu$%E(+@w|^kbqmP1-<1G`O%$5h~b48l};Nl!i-s@&PxwH8*Lg zC5!$6{sjsJ7h0+yh;FosC}O)Qg6>=?ir_{hidexq&)j*F_ulj##yefk3)4Aw&e!C9 z&Trd=1!DdRO>ufq?6GkqnFtvQ^P78b63*+Cg*V=|^=Kf_@ ztNgxe&0R_gQhuL3Ftz;k7Y@g|!k>@YYq!`W?qBck)p_KIIcc69F{ehy%!$!c&kbF1 z=s?BsavT^R@MVRB&Uzxo+SJJ%cKdn%`-06!*q&Ox`K?1&sG{3y%WyvinvDqb`0?YO z7IcIxhd@paPqgqzjD^tpuAbI|_Kr{3gEI!f_G zlX(cNtr`{$CtB&X30UpG!kjW?uWMSp+5oo6CNW?FkccU%4JX7{2*8m%fV-;r)-=IK zMS$?ytf~mh#7{XSYBPl23wiu@H{>S(0Y=X(2222UQIJ|tybxg_08i%u+}jAC85|rI zhA`WrY6;K8P&p)OGn(O^Jchm>1R28oe?;*Hom1mRe{42e3Kcq5R>lc67X5Z!Q! z#6Dd))ID?{bD9_r0O1ptNo_Aqh_MjpXEb#5hU=M81^RX&NbV+L`#dD^)TtP&rEQZdy6YQc|H9Gxao6mZ=lv|^=_%`c2+uXgv& zOk@-DS#h?~Z-)Aw@dAV!f)kU*_;CsnM{!G&c?idgc^nVsbM!sr3Qf_kR2QL*H;&@>Q&hjK+{Uo&D?=a6fFxU;M}SH0-EZT-$|^>GtF#<;C)?-RlA?wQZP~e zkg5TQ2y}QHQk#ksVk`vHRgFnT4ic*Vuk|h8O@i=YRcr7P0x=hxkm7_G3qkspMv9tn zKZf%1=L$SSn7K6$&awtiq{?!1Vu%xBEQI0PnxV9kbad73Qrc5j;-LX)mrajwlr;bn z71lggG*`Glp zIS?9~#K4)+pBl_JpGB9X5wKoi6$ za_Zy|h@a=RsIFJ^Evo)3qeh4@bD!DxJHsnE|gyRTZ!t$BIQ7ZQz6$3xQel8EJiQ z2+NSr6m0IB8DCqFf^m@FNt1XX!a^|qkf+I^#u$f>F~nH=t>S8|1Iu1jdpIYy${|sk zA#8tgY+LUgur|T=$(11`EM0T#{{}dxb*3nw>f{i%zdE*URkrkwtQg6(YR&wd>qGSs zOb4|(WpmG!Whs4u7IxR{(VZ`}-QqFlTVo$RK$=v?8?hEb|1aHY%gf!eV6}F!cu3yv z*P5lCP~_1_H(k!!EYj_#0VvoW~=A*bJpVwIm4H4-`Ng!^J4c;YiO#u%VENuOr_SE38W(qd-HlV-q- zO=o8G{K8Cm?ln_hTsXhDU@Ft)#nL%5HD8>_CKpSkOJ=$_cdnF~iDD(In2Xcdd^U9D Hm+Sul-_kqd literal 0 HcmV?d00001 diff --git a/exercises/options/.options2.rs.un~ b/exercises/options/.options2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..5d90d23bc02b46e38f1f72b770f4ee960e4af4d0 GIT binary patch literal 8504 zcmeI%zi-n(6bEoOO@ER?KtkeymXhCW@5A!AS~I5fWlR zVnD#az`}%(*jV8|pbS)k2{AALe?Wi%kl=mKe&!SET%lJ^I{iJR3Ash>CQynJ-mFpNAkj%nH%ptjHL zz?Pd)?rg2caWr8R-?|@&xm#>-Xqf;0Lm_*(LvMFD1Le-^{gPwA_&!DF9-_wS2Su__ z5NE`xvto7ayjWRVJ$>?)WW%vRY8)WkLv0itnhjZqGKlS?WQ#d$yXnW0)Uwn-BRH;E z_GPgwtVXM1)l1c4t7MnWme_C^!4{{+0aBdj06H`yvJhpIJDV}dXgG|hpuNq}eGu_=Nj&Tj zr|2hVsqqciE80rEWtL4_9ZKD<=0d}2WU}6n3c)eu${~qU3iRpQFtQM3kmx=2HjHAL zqsF3{K1J(l=EbG9-L!0PR0ZF-a>1YlXBvH)6IqBdi1UFT=fZZJ&cND*3dCK?Wdj(f z@+nrMDw&C7mrx%{)Dh>d+g+na1EI3199yBsWzJ(OR1?ZS0CBCXBqZ8hQhpr1bY11_ zQeS4UPALBh$iXbor;8a`2oYW;=^R{SINdrm6dWz+Z9bLEqrHo{@IS?z^>KzP);Ty} zj&+KI=+Mr{LWl_9{3b1(#~f#@@*?#-u{y-gRa#%FwOj5)ie}7qsa`gDl>%y5=HP&+ zR^)7i-3C!yRBy`NinIQTA}1DElGhyhnxU#CIU8ZOK_rj+NzV97Dv-SD$d}9u!1~6@ z840ru4Vm(X{8x~0<9BYjVyrdkf4Eg2IIBT|2aT8>sTF|i>ZQurJ5?l%(ZH@r_ArlXiU u@zbjM>IQ3wSP{mZS+4|B5~2@!jG2_|afh8}H$1(aV?}lR;RjFK}koU zK(7KsRBGw~4dDl3ULa-!VkRI40T2zt4C$XQ-eLjCGBd Option { // value of 0 The Option output should gracefully handle cases where // time_of_day > 23. // TODO: Complete the function body - remember to return an Option! - ??? + if time_of_day >=0 && time_of_day < 22 { + Some(5) + } else if time_of_day >= 22 && time_of_day < 24 { + Some(0) + } else { + None + } } #[cfg(test)] @@ -34,6 +38,6 @@ mod tests { // TODO: Fix this test. How do you get at the value contained in the // Option? let icecreams = maybe_icecream(12); - assert_eq!(icecreams, 5); + assert_eq!(icecreams, Some(5)); } } diff --git a/exercises/options/options1.rs~ b/exercises/options/options1.rs~ new file mode 100644 index 000000000..e004f60d8 --- /dev/null +++ b/exercises/options/options1.rs~ @@ -0,0 +1,43 @@ +// options1.rs +// +// Execute `rustlings hint options1` or use the `hint` watch subcommand for a +// hint. + +// This function returns how much icecream there is left in the fridge. +// If it's before 10PM, there's 5 pieces left. At 10PM, someone eats them +// all, so there'll be no more left :( +fn maybe_icecream(time_of_day: u16) -> Option { + // We use the 24-hour system here, so 10PM is a value of 22 and 12AM is a + // value of 0 The Option output should gracefully handle cases where + // time_of_day > 23. + // TODO: Complete the function body - remember to return an Option! + if time_of_day >=0 && time_of_day < 22 { + Some(5) + } else if time_of_day >= 22 && time_of_day < 24 { + Some(0) + } else { + None + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_icecream() { + assert_eq!(maybe_icecream(9), Some(5)); + assert_eq!(maybe_icecream(10), Some(5)); + assert_eq!(maybe_icecream(23), Some(0)); + assert_eq!(maybe_icecream(22), Some(0)); + assert_eq!(maybe_icecream(25), None); + } + + #[test] + fn raw_value() { + // TODO: Fix this test. How do you get at the value contained in the + // Option? + let icecreams = maybe_icecream(12); + assert_eq!(icecreams, Some(5)); + } +} diff --git a/exercises/options/options2.rs b/exercises/options/options2.rs index 4d998e7d0..0d7147756 100644 --- a/exercises/options/options2.rs +++ b/exercises/options/options2.rs @@ -3,7 +3,6 @@ // Execute `rustlings hint options2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE #[cfg(test)] mod tests { @@ -13,8 +12,8 @@ mod tests { let optional_target = Some(target); // TODO: Make this an if let statement whose value is "Some" type - word = optional_target { - assert_eq!(word, target); + if let word = optional_target { + assert_eq!(word, Some(target)); } } @@ -32,9 +31,12 @@ mod tests { // TODO: make this a while let statement - remember that vector.pop also // adds another layer of Option. You can stack `Option`s into // while let and if let. - integer = optional_integers.pop() { - assert_eq!(integer, cursor); + while let integer = optional_integers.pop() { + assert_eq!(integer, Some(Some(cursor))); cursor -= 1; + if cursor == 0 { + break; + } } assert_eq!(cursor, 0); diff --git a/exercises/options/options2.rs~ b/exercises/options/options2.rs~ new file mode 100644 index 000000000..0d7147756 --- /dev/null +++ b/exercises/options/options2.rs~ @@ -0,0 +1,44 @@ +// options2.rs +// +// Execute `rustlings hint options2` or use the `hint` watch subcommand for a +// hint. + + +#[cfg(test)] +mod tests { + #[test] + fn simple_option() { + let target = "rustlings"; + let optional_target = Some(target); + + // TODO: Make this an if let statement whose value is "Some" type + if let word = optional_target { + assert_eq!(word, Some(target)); + } + } + + #[test] + fn layered_option() { + let range = 10; + let mut optional_integers: Vec> = vec![None]; + + for i in 1..(range + 1) { + optional_integers.push(Some(i)); + } + + let mut cursor = range; + + // TODO: make this a while let statement - remember that vector.pop also + // adds another layer of Option. You can stack `Option`s into + // while let and if let. + while let integer = optional_integers.pop() { + assert_eq!(integer, Some(Some(cursor))); + cursor -= 1; + if cursor == 0 { + break; + } + } + + assert_eq!(cursor, 0); + } +} diff --git a/exercises/options/options3.rs b/exercises/options/options3.rs index 23c15eab8..bca3cff56 100644 --- a/exercises/options/options3.rs +++ b/exercises/options/options3.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint options3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - struct Point { x: i32, y: i32, @@ -14,7 +12,7 @@ fn main() { let y: Option = Some(Point { x: 100, y: 200 }); match y { - Some(p) => println!("Co-ordinates are {},{} ", p.x, p.y), + Some(ref p) => println!("Co-ordinates are {},{} ", p.x, p.y), _ => panic!("no match!"), } y; // Fix without deleting this line. diff --git a/exercises/options/options3.rs~ b/exercises/options/options3.rs~ new file mode 100644 index 000000000..bca3cff56 --- /dev/null +++ b/exercises/options/options3.rs~ @@ -0,0 +1,19 @@ +// options3.rs +// +// Execute `rustlings hint options3` or use the `hint` watch subcommand for a +// hint. + +struct Point { + x: i32, + y: i32, +} + +fn main() { + let y: Option = Some(Point { x: 100, y: 200 }); + + match y { + Some(ref p) => println!("Co-ordinates are {},{} ", p.x, p.y), + _ => panic!("no match!"), + } + y; // Fix without deleting this line. +} diff --git a/exercises/quiz2.rs b/exercises/quiz2.rs index 29925cafc..54ded8b52 100644 --- a/exercises/quiz2.rs +++ b/exercises/quiz2.rs @@ -20,7 +20,6 @@ // // No hints this time! -// I AM NOT DONE pub enum Command { Uppercase, @@ -32,11 +31,26 @@ mod my_module { use super::Command; // TODO: Complete the function signature! - pub fn transformer(input: ???) -> ??? { + pub fn transformer(input: Vec<(String, Command)>) -> Vec { // TODO: Complete the output declaration! - let mut output: ??? = vec![]; + let mut output: Vec = vec![]; for (string, command) in input.iter() { // TODO: Complete the function body. You can do it! + match command { + Command::Uppercase => { + let a = string.to_uppercase(); + output.push(a) + }, + Command::Trim => { + let b = string.trim().to_string(); + output.push(b) + }, + Command::Append(x) => { + let mut c: String = string.to_string(); + c.push_str(&"bar".repeat(*x)); + output.push(c.to_string()) + }, + } } output } @@ -45,7 +59,7 @@ mod my_module { #[cfg(test)] mod tests { // TODO: What do we need to import to have `transformer` in scope? - use ???; + use super::my_module::transformer; use super::Command; #[test] diff --git a/exercises/quiz2.rs~ b/exercises/quiz2.rs~ new file mode 100644 index 000000000..54ded8b52 --- /dev/null +++ b/exercises/quiz2.rs~ @@ -0,0 +1,78 @@ +// quiz2.rs +// +// This is a quiz for the following sections: +// - Strings +// - Vecs +// - Move semantics +// - Modules +// - Enums +// +// Let's build a little machine in the form of a function. As input, we're going +// to give a list of strings and commands. These commands determine what action +// is going to be applied to the string. It can either be: +// - Uppercase the string +// - Trim the string +// - Append "bar" to the string a specified amount of times +// The exact form of this will be: +// - The input is going to be a Vector of a 2-length tuple, +// the first element is the string, the second one is the command. +// - The output element is going to be a Vector of strings. +// +// No hints this time! + + +pub enum Command { + Uppercase, + Trim, + Append(usize), +} + +mod my_module { + use super::Command; + + // TODO: Complete the function signature! + pub fn transformer(input: Vec<(String, Command)>) -> Vec { + // TODO: Complete the output declaration! + let mut output: Vec = vec![]; + for (string, command) in input.iter() { + // TODO: Complete the function body. You can do it! + match command { + Command::Uppercase => { + let a = string.to_uppercase(); + output.push(a) + }, + Command::Trim => { + let b = string.trim().to_string(); + output.push(b) + }, + Command::Append(x) => { + let mut c: String = string.to_string(); + c.push_str(&"bar".repeat(*x)); + output.push(c.to_string()) + }, + } + } + output + } +} + +#[cfg(test)] +mod tests { + // TODO: What do we need to import to have `transformer` in scope? + use super::my_module::transformer; + use super::Command; + + #[test] + fn it_works() { + let output = transformer(vec![ + ("hello".into(), Command::Uppercase), + (" all roads lead to rome! ".into(), Command::Trim), + ("foo".into(), Command::Append(1)), + ("bar".into(), Command::Append(5)), + ]); + assert_eq!(output[0], "HELLO"); + assert_eq!(output[1], "all roads lead to rome!"); + assert_eq!(output[2], "foobar"); + assert_eq!(output[3], "barbarbarbarbarbar"); + } +} diff --git a/exercises/quiz3.rs b/exercises/quiz3.rs index 3b01d3132..d9cb974cd 100644 --- a/exercises/quiz3.rs +++ b/exercises/quiz3.rs @@ -16,15 +16,13 @@ // // Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - -pub struct ReportCard { - pub grade: f32, +pub struct ReportCard { + pub grade: T, pub student_name: String, pub student_age: u8, } -impl ReportCard { +impl ReportCard { pub fn print(&self) -> String { format!("{} ({}) - achieved a grade of {}", &self.student_name, &self.student_age, &self.grade) @@ -52,7 +50,7 @@ mod tests { fn generate_alphabetic_report_card() { // TODO: Make sure to change the grade here after you finish the exercise. let report_card = ReportCard { - grade: 2.1, + grade: "A+", student_name: "Gary Plotter".to_string(), student_age: 11, }; diff --git a/exercises/quiz3.rs~ b/exercises/quiz3.rs~ new file mode 100644 index 000000000..d9cb974cd --- /dev/null +++ b/exercises/quiz3.rs~ @@ -0,0 +1,62 @@ +// quiz3.rs +// +// This quiz tests: +// - Generics +// - Traits +// +// An imaginary magical school has a new report card generation system written +// in Rust! Currently the system only supports creating report cards where the +// student's grade is represented numerically (e.g. 1.0 -> 5.5). However, the +// school also issues alphabetical grades (A+ -> F-) and needs to be able to +// print both types of report card! +// +// Make the necessary code changes in the struct ReportCard and the impl block +// to support alphabetical report cards. Change the Grade in the second test to +// "A+" to show that your changes allow alphabetical grades. +// +// Execute `rustlings hint quiz3` or use the `hint` watch subcommand for a hint. + +pub struct ReportCard { + pub grade: T, + pub student_name: String, + pub student_age: u8, +} + +impl ReportCard { + pub fn print(&self) -> String { + format!("{} ({}) - achieved a grade of {}", + &self.student_name, &self.student_age, &self.grade) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn generate_numeric_report_card() { + let report_card = ReportCard { + grade: 2.1, + student_name: "Tom Wriggle".to_string(), + student_age: 12, + }; + assert_eq!( + report_card.print(), + "Tom Wriggle (12) - achieved a grade of 2.1" + ); + } + + #[test] + fn generate_alphabetic_report_card() { + // TODO: Make sure to change the grade here after you finish the exercise. + let report_card = ReportCard { + grade: "A+", + student_name: "Gary Plotter".to_string(), + student_age: 11, + }; + assert_eq!( + report_card.print(), + "Gary Plotter (11) - achieved a grade of A+" + ); + } +} diff --git a/exercises/smart_pointers/.arc1.rs.un~ b/exercises/smart_pointers/.arc1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..bd76788c4d460561809372aa044ae0785befa8d4 GIT binary patch literal 6948 zcmeI$O=}ZD7{Kvun>4;x5MLrOSz4_Yl|-tSmI{S<5NvX()kC4$xTKXfYMQE7!EfNn zllOvGkA49!;wSJT9z6*X4?6$ZdBPHsbjsv74-7Lq*(AgB?P({Ed|K@eP3O(LfTBdSf933_Qky7W`*tcUaSs->9obY#IHsG=k0`;3p8@k`a8Vq9;ppVo9iOm{)e6;z`X zp$Unts1@#PJZ?r$)*8Fp>rrzjTnLrtamEXTh5 z$bv)INahAf0%^ktTPCqkNIhdBAx=XZ#`w08WW)L)_S-I*7)Eq5 zseX(xS3`nlNIh21kn@9z^~OP2=glUJ<1zlq1jel3BFDa5$$~@JxGredvEJo6y}zrf zQNaZ7cw)K0PN~MO;W0^qOW0u6l10ibDRo2zcOEtcw6?Li)&E@&awk-iK-Ei1He7of z$-0(I#bwzonM0A_PPbdq?5vQbr;1~IP@Gch8s&PhMf*-`g>efM+kKk>Ou^8f$< literal 0 HcmV?d00001 diff --git a/exercises/smart_pointers/.box1.rs.un~ b/exercises/smart_pointers/.box1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..e75477f447bdb94ec4b7cf06263e94c8a982133b GIT binary patch literal 8181 zcmeI$&r1|x7zgliUDqx9v6a<|MI*Jf3rnJA#UMgukWlNzx}}F&WI=ZhibVt=M1Mk; z4tDO+tz-9Y{Q+HqqFWH8h==O=KJz~MxHAp|)7;(%Uf=m4`@TFMp7))Z2d$;``|TfkGn-@{xj}U;#R+$|E1uck_)!~&lyZWN%*?t|GmYEhYfJ~KZZ#kL|7mJRaLv*o3t0wL(g@Qz0o^GY41_30t|FA= zEx)~7ZHJH6sS0UfeeUJ&18wG08+$J&DbCidASZ+5Px|l*~5zLlg%M%E$ULcWYUk( z_E{VubP)GVKo4RZc5#$UWYv?{Qm0sr29x^QT^wPFJ9=>hRv$G9KmzY5E?7KdA|~YBSE+G<5Z`O&>xt$&(@}MX51^Am2r~ZoWd;H#20Mpy zyKo{4DIy8s*SLjqXn#V_qo>UsN4W83XJ!jijBdYnb(qBPXIv>p?1~{mknzfC zrV36BJcx6#(g?#)|UfnHV(E6}6?Z>7W*RIbxWgDsfZIK8&0|P@4 z5UVI40q6X3D=Yub zL^l2cSek)>2}*+~kQ5(`{~rjzA~1nbn#v)N{wrA%936}dUnPKM^8zs}_+il^ps%ms zso?0V;O8Hr;NtJ+YT5{nI#5(GBe@5p-Vlg|Kw_g&2MPsRg7jZ$IpC;cfJ7ZA=uLpw z2V^NYGC?As3<(y2Mj9xRSb!J?KoJPbw4;#*3l(x{ct}D+RTyee8IT6Efss}Sjx;7j z6d400{eT#hpNJ}Fp-~BnI#?MCWP+pB9!PV5IHUOw6bcjo!cqB~aS=EwnITaL3VJ6X z21O-8!~rG(jWp!E2T}-%Kwl681V$qb5)NdO#6;R^aHO$9q6if90Z@z(0YxE5l)<#| G`6>WM*JsQC literal 0 HcmV?d00001 diff --git a/exercises/smart_pointers/.rc1.rs.un~ b/exercises/smart_pointers/.rc1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..23c54687d9f403fbe95d9f9c26c9b2a4b8cd0938 GIT binary patch literal 7865 zcmeI1&rcIU6vr1Rp!kFKW}-10W3V-9qog6WfI+e9!9wK6MUhrmpb;0+cJW|5pcs!H zyqOrU#=k)iUOanHPTq{+MxqIqUi5uu=PeToo1yD*Uh-vjXEwv+`^kGV-JL8ydN<(? zFa5Gwt1rhtPJbWWeDP`R_mAhV*K)7EJbV8pfAa0!#QMV%Q=cu%DwEc@@_lutyh5u2aiq$3#c+&P+DzI**fM zo@+mOno8v)S8$AxIKUVyIExO$6)r>w9j@zwYwPY@&+BlVSzL0Rm zR~1v5z6_j{uI`qrKh<0vq6e>$8gkXElxQnea&?UcBgnhM_>#yr9*F4uzlC|LX z?3t|~d4R+L${;K1g(1tfG}-Eq{S!vEPmgR*)pK_{H-RR8`*46X=w3pHp$iuxMBpUN zf$Kgw7tX`tn$E*pVRUo*qYKJAPsSkHCI2rP(8gL!WriD315TcklLW5PJqQbjiEv#I zZu3vZc^XhFb7ud9w@=7miC@1Q;Czp7O!l%9O|}|ri^tXMh4uGI^CaxLonT8ZBE(w? z9-N~AOa5vFFMe}@Zm^spiHdCa!IB7}!|zlWzb^0-FAGx=7yunnmIQbJ7Dt}}1{WfP z4zM!>1tUt^&JAW;Qw?FJM?32+opBnS>irLx)@8}8xf$DN!Z&OzBp%AH$MCW4 = (0..100u32).collect(); - let shared_numbers = // TODO + let shared_numbers = Arc::new(0); let mut joinhandles = Vec::new(); for offset in 0..8 { - let child_numbers = // TODO + let child_numbers = Vec::new(); joinhandles.push(thread::spawn(move || { let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum(); println!("Sum of offset {} is {}", offset, sum); diff --git a/exercises/smart_pointers/arc1.rs~ b/exercises/smart_pointers/arc1.rs~ new file mode 100644 index 000000000..c7967d7c1 --- /dev/null +++ b/exercises/smart_pointers/arc1.rs~ @@ -0,0 +1,43 @@ +// arc1.rs +// +// In this exercise, we are given a Vec of u32 called "numbers" with values +// ranging from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ] We would like to use this +// set of numbers within 8 different threads simultaneously. Each thread is +// going to get the sum of every eighth value, with an offset. +// +// The first thread (offset 0), will sum 0, 8, 16, ... +// The second thread (offset 1), will sum 1, 9, 17, ... +// The third thread (offset 2), will sum 2, 10, 18, ... +// ... +// The eighth thread (offset 7), will sum 7, 15, 23, ... +// +// Because we are using threads, our values need to be thread-safe. Therefore, +// we are using Arc. We need to make a change in each of the two TODOs. +// +// Make this code compile by filling in a value for `shared_numbers` where the +// first TODO comment is, and create an initial binding for `child_numbers` +// where the second TODO comment is. Try not to create any copies of the +// `numbers` Vec! +// +// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint. + +#![forbid(unused_imports)] // Do not change this, (or the next) line. +use std::sync::Arc; +use std::thread; + +fn main() { + let numbers: Vec<_> = (0..100u32).collect(); + let shared_numbers = Arc::new(0); + let mut joinhandles = Vec::new(); + + for offset in 0..8 { + let child_numbers = Vec::new(); + joinhandles.push(thread::spawn(move || { + let sum: u32 = child_numbers.iter().filter(|&&n| n % 8 == offset).sum(); + println!("Sum of offset {} is {}", offset, sum); + })); + } + for handle in joinhandles.into_iter() { + handle.join().unwrap(); + } +} diff --git a/exercises/smart_pointers/box1.rs b/exercises/smart_pointers/box1.rs index 513e7daa3..71733f612 100644 --- a/exercises/smart_pointers/box1.rs +++ b/exercises/smart_pointers/box1.rs @@ -18,11 +18,9 @@ // // Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - #[derive(PartialEq, Debug)] pub enum List { - Cons(i32, List), + Cons(i32, Box), Nil, } @@ -35,11 +33,11 @@ fn main() { } pub fn create_empty_list() -> List { - todo!() + List::Nil } pub fn create_non_empty_list() -> List { - todo!() + List::Cons(1, Box::new(List::Nil)) } #[cfg(test)] diff --git a/exercises/smart_pointers/box1.rs~ b/exercises/smart_pointers/box1.rs~ new file mode 100644 index 000000000..71733f612 --- /dev/null +++ b/exercises/smart_pointers/box1.rs~ @@ -0,0 +1,56 @@ +// box1.rs +// +// At compile time, Rust needs to know how much space a type takes up. This +// becomes problematic for recursive types, where a value can have as part of +// itself another value of the same type. To get around the issue, we can use a +// `Box` - a smart pointer used to store data on the heap, which also allows us +// to wrap a recursive type. +// +// The recursive type we're implementing in this exercise is the `cons list` - a +// data structure frequently found in functional programming languages. Each +// item in a cons list contains two elements: the value of the current item and +// the next item. The last item is a value called `Nil`. +// +// Step 1: use a `Box` in the enum definition to make the code compile +// Step 2: create both empty and non-empty cons lists by replacing `todo!()` +// +// Note: the tests should not be changed +// +// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint. + +#[derive(PartialEq, Debug)] +pub enum List { + Cons(i32, Box), + Nil, +} + +fn main() { + println!("This is an empty cons list: {:?}", create_empty_list()); + println!( + "This is a non-empty cons list: {:?}", + create_non_empty_list() + ); +} + +pub fn create_empty_list() -> List { + List::Nil +} + +pub fn create_non_empty_list() -> List { + List::Cons(1, Box::new(List::Nil)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_create_empty_list() { + assert_eq!(List::Nil, create_empty_list()) + } + + #[test] + fn test_create_non_empty_list() { + assert_ne!(create_empty_list(), create_non_empty_list()) + } +} diff --git a/exercises/smart_pointers/cow1.rs b/exercises/smart_pointers/cow1.rs index 7ca916866..be901b888 100644 --- a/exercises/smart_pointers/cow1.rs +++ b/exercises/smart_pointers/cow1.rs @@ -12,8 +12,6 @@ // // Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - use std::borrow::Cow; fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> { @@ -49,6 +47,8 @@ mod tests { let mut input = Cow::from(&slice[..]); match abs_all(&mut input) { // TODO + Cow::Borrowed(_) => Ok(()), + _ => Err("Expected owned value"), } } @@ -61,6 +61,8 @@ mod tests { let mut input = Cow::from(slice); match abs_all(&mut input) { // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), } } @@ -73,6 +75,8 @@ mod tests { let mut input = Cow::from(slice); match abs_all(&mut input) { // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), } } } diff --git a/exercises/smart_pointers/cow1.rs~ b/exercises/smart_pointers/cow1.rs~ new file mode 100644 index 000000000..be901b888 --- /dev/null +++ b/exercises/smart_pointers/cow1.rs~ @@ -0,0 +1,82 @@ +// cow1.rs +// +// This exercise explores the Cow, or Clone-On-Write type. Cow is a +// clone-on-write smart pointer. It can enclose and provide immutable access to +// borrowed data, and clone the data lazily when mutation or ownership is +// required. The type is designed to work with general borrowed data via the +// Borrow trait. +// +// This exercise is meant to show you what to expect when passing data to Cow. +// Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the +// TODO markers. +// +// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint. + +use std::borrow::Cow; + +fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> { + for i in 0..input.len() { + let v = input[i]; + if v < 0 { + // Clones into a vector if not already owned. + input.to_mut()[i] = -v; + } + } + input +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn reference_mutation() -> Result<(), &'static str> { + // Clone occurs because `input` needs to be mutated. + let slice = [-1, 0, 1]; + let mut input = Cow::from(&slice[..]); + match abs_all(&mut input) { + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), + } + } + + #[test] + fn reference_no_mutation() -> Result<(), &'static str> { + // No clone occurs because `input` doesn't need to be mutated. + let slice = [0, 1, 2]; + let mut input = Cow::from(&slice[..]); + match abs_all(&mut input) { + // TODO + Cow::Borrowed(_) => Ok(()), + _ => Err("Expected owned value"), + } + } + + #[test] + fn owned_no_mutation() -> Result<(), &'static str> { + // We can also pass `slice` without `&` so Cow owns it directly. In this + // case no mutation occurs and thus also no clone, but the result is + // still owned because it was never borrowed or mutated. + let slice = vec![0, 1, 2]; + let mut input = Cow::from(slice); + match abs_all(&mut input) { + // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), + } + } + + #[test] + fn owned_mutation() -> Result<(), &'static str> { + // Of course this is also the case if a mutation does occur. In this + // case the call to `to_mut()` returns a reference to the same data as + // before. + let slice = vec![-1, 0, 1]; + let mut input = Cow::from(slice); + match abs_all(&mut input) { + // TODO + Cow::Owned(_) => Ok(()), + _ => Err("Expected owned value"), + } + } +} diff --git a/exercises/smart_pointers/rc1.rs b/exercises/smart_pointers/rc1.rs index ad3f1ce29..2ce1c54c5 100644 --- a/exercises/smart_pointers/rc1.rs +++ b/exercises/smart_pointers/rc1.rs @@ -10,8 +10,6 @@ // // Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - use std::rc::Rc; #[derive(Debug)] @@ -60,17 +58,17 @@ fn main() { jupiter.details(); // TODO - let saturn = Planet::Saturn(Rc::new(Sun {})); + let saturn = Planet::Saturn(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 7 references saturn.details(); // TODO - let uranus = Planet::Uranus(Rc::new(Sun {})); + let uranus = Planet::Uranus(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 8 references uranus.details(); // TODO - let neptune = Planet::Neptune(Rc::new(Sun {})); + let neptune = Planet::Neptune(Rc::clone(&sun)); println!("reference count = {}", Rc::strong_count(&sun)); // 9 references neptune.details(); @@ -92,12 +90,15 @@ fn main() { println!("reference count = {}", Rc::strong_count(&sun)); // 4 references // TODO + drop(earth); println!("reference count = {}", Rc::strong_count(&sun)); // 3 references // TODO + drop(venus); println!("reference count = {}", Rc::strong_count(&sun)); // 2 references // TODO + drop(mercury); println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference assert_eq!(Rc::strong_count(&sun), 1); diff --git a/exercises/smart_pointers/rc1.rs~ b/exercises/smart_pointers/rc1.rs~ new file mode 100644 index 000000000..2ce1c54c5 --- /dev/null +++ b/exercises/smart_pointers/rc1.rs~ @@ -0,0 +1,105 @@ +// rc1.rs +// +// In this exercise, we want to express the concept of multiple owners via the +// Rc type. This is a model of our solar system - there is a Sun type and +// multiple Planets. The Planets take ownership of the sun, indicating that they +// revolve around the sun. +// +// Make this code compile by using the proper Rc primitives to express that the +// sun has multiple owners. +// +// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint. + +use std::rc::Rc; + +#[derive(Debug)] +struct Sun {} + +#[derive(Debug)] +enum Planet { + Mercury(Rc), + Venus(Rc), + Earth(Rc), + Mars(Rc), + Jupiter(Rc), + Saturn(Rc), + Uranus(Rc), + Neptune(Rc), +} + +impl Planet { + fn details(&self) { + println!("Hi from {:?}!", self) + } +} + +fn main() { + let sun = Rc::new(Sun {}); + println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference + + let mercury = Planet::Mercury(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 2 references + mercury.details(); + + let venus = Planet::Venus(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 3 references + venus.details(); + + let earth = Planet::Earth(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 4 references + earth.details(); + + let mars = Planet::Mars(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 5 references + mars.details(); + + let jupiter = Planet::Jupiter(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 6 references + jupiter.details(); + + // TODO + let saturn = Planet::Saturn(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 7 references + saturn.details(); + + // TODO + let uranus = Planet::Uranus(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 8 references + uranus.details(); + + // TODO + let neptune = Planet::Neptune(Rc::clone(&sun)); + println!("reference count = {}", Rc::strong_count(&sun)); // 9 references + neptune.details(); + + assert_eq!(Rc::strong_count(&sun), 9); + + drop(neptune); + println!("reference count = {}", Rc::strong_count(&sun)); // 8 references + + drop(uranus); + println!("reference count = {}", Rc::strong_count(&sun)); // 7 references + + drop(saturn); + println!("reference count = {}", Rc::strong_count(&sun)); // 6 references + + drop(jupiter); + println!("reference count = {}", Rc::strong_count(&sun)); // 5 references + + drop(mars); + println!("reference count = {}", Rc::strong_count(&sun)); // 4 references + + // TODO + drop(earth); + println!("reference count = {}", Rc::strong_count(&sun)); // 3 references + + // TODO + drop(venus); + println!("reference count = {}", Rc::strong_count(&sun)); // 2 references + + // TODO + drop(mercury); + println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference + + assert_eq!(Rc::strong_count(&sun), 1); +} diff --git a/exercises/strings/.strings1.rs.un~ b/exercises/strings/.strings1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..0db528856e1423f92f07cd57d2a07a30a039e91a GIT binary patch literal 1883 zcmWH`%$*;a=aT=Ffk{D8(>z4HNaW}a-w3wL>`dJK4R(vO|9^Ko*;FAd60OU?z#ss` zFu($2Faj}%1_2Na!wl(f&Er`>vP=x|7eKN=zyzVdBuENm7+CXvAOIVMq+pau%@6=a zM-VtV7#O}v01f5`VnHYdMFp1v5GW<(l%^_~Hi9DzB+3lLFaU}?P=tYWF^onSC=_T3 zfDsmkFTx~15f)rhl$n=qWtCQxpR1vX5`CcPf@MsQJ3&ziias$AXEgdip+HLjjJ|Mi z^f6-3Z{iry2Z=p!=7eQ4a8`q6N93#sayTe%Ibc2*jZaue(254eXB@OT14j`%Qt*ST ZGJSmoPX$L`1wa1~1s8umSJTGls{l^cPEP;; literal 0 HcmV?d00001 diff --git a/exercises/strings/.strings2.rs.un~ b/exercises/strings/.strings2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..2a6a13306455e40f51ed5fab16ebd5282889bde9 GIT binary patch literal 1022 zcmWH`%$*;a=aT=Ffl0?{<)O*T8Qyb?uZdl|VC~2FrM)LVXs~Kdea+9yW~8-)fq_8; zh~*T3ATv!Nvp7C6J~=-pzbL*uzbHimL})5h166PXu{aPj0x=U1g8+zzVTSY%HxpPO zvhf$d(g=khE=Y<4D$ej92*4sRfl->uApndH3vhHWGJKT)n#~Txu;2$pg@C@kf~SI` zuY#X{h=Pm1pQ~vjINCsR$N&_-u(%(MHsp|@2^$z~@z7iZjy5i!Ej&OB%A}yEA&^l` I8=tQN032yT`v3p{ literal 0 HcmV?d00001 diff --git a/exercises/strings/.strings3.rs.un~ b/exercises/strings/.strings3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..969fa5b577005fffe938f100adfd1e862f088fc6 GIT binary patch literal 21377 zcmeI)O=w(I6u|LmnlDq^q-h(|R@>KUs~Js`8tA5>1hH8tv|0GE62jQVF_2_pJ`hC& zaiQSCRdFez7IE#ug$utB-4zvWT?rzhtC}JRF7*7*yfbs&7;h|iUEK@Md*{6{y`CTE zzI*SynMdarUw>rjZ2iYl$M4nGj-7kvn;l=D`~K?8boJC54_>_gu^W|3FI~Uf_0HtP zbg5LDkfSq`BK3aSa%_|1q#P7#J4&^U!7nzjaUs_&YtC*ZkNUVFPrGe3+5xo|<{+pDW%ySMU)&f?T zR&tIy?p3S$K;P# zTkD*pu&!p&X6tIOcJeweKmwZ9)fSPcwcvf}v(E-Y!|NjZs`*HX%`Vp++>(_GNZh7a zeHF6ulYeOXU3XxEYB%T7M3N}PEJF2dh-#3udPrvfOSRLdpIE6cHdg>Z4Y;m>2;3gd zB{-rGvk2U^5S*?63UF0h0U)L6mG=)tLvi`_4wtlPVpT|Oy+N(aaM9brrZW+A*WUkF`eN3ye#c7&dJ;mf;;F?;30GGtIrq;^G^z zeXfsaBA6zcE-3MuBKW2sIokz?+XY98d~gl9?m-Ek?x&;#bdibD6u!4Zd^+9q2{=-j zY;L76ppvOJm|}Muuk(UyN=1uC^ja)0t7Z4*gJ~fZH4FLlM?mw53|u@?WCcn_(XLeB=vNjZv}X?De@Ay|jyumU8h+RurUhD0G|5xgrQ zya7ho)v@LE)hB0H*H)UJ_`#I9jzI`pnx49##A^y$;Ry)KEXz6lsMfKS%Qjd7rL&j3 zbD7k@>9R28TOO5YmB3xqeCuiKx3t6UZ_BrG_H=z^;o^~|UnX5EyY69`{9HidHpTA; z_3Lf;5qh?x@0Fu?v$HFtq-}PBrSnV9Ndc0De%dV~8qtg3{p@dcwjE}8ZM$XY9CMvQ zE@`=d#BFY+Rs22{ILBRwfJ;~|AaR?5Rd^VpJ+->Huh|zJvANUr2e)M90ur|=-_Eax zhC#m#4b5GyJFr2OK5BJAiPsdWXG2u_eXNza<%Q~n*7vb68gYHX4>NsYJx%dlWTG_1 z?75IxKSQCJwH9V5Ra}Pl7!4A~78GEVJATXq zX_naOQ`32$ab;DQGBOWH+)6Cp-^_AC{#iCEb+1c)_e(z?_p5c=tHet`sLT6_CArA2 zJ*4?4L5Nz!?~{M><7d6}$G><0N!mA+mpJO4wA2)gapfWGp w`ftZspQH2~TRi!Wdh#R)QHywfuAY634}=IkPmS3)+xj5^yMnX~vOm517l%sYS^xk5 literal 0 HcmV?d00001 diff --git a/exercises/strings/.strings4.rs.un~ b/exercises/strings/.strings4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..6a794376a8182df4bf4e1bffd8e758cb1381f178 GIT binary patch literal 9359 zcmeI2-){{;6vx+XsUJoCs9!DSu3y`b+e%a@$qh<0l!q2+5V>x*?Z&;k&EBm>#Dh1_ zUOe(B5{W+e13Y+_@Wi7Ci3n-pRh{qbo-rEg*6=nbIcCi6&Q89co|&^V_k2*je=h8e z-Z{BDQ&UHu+>PJlPJeiRFaPrKvkR{twm#_nd}-(NUEO_8zd4SxnS8GxD;A5MTOAU$ zlfj8Zobrc6Fd%A!!Le&YZXt=TRH8{gE|+S)*U@o^9%?6VB+rqrC5NG8cSfgM4>m5K zmS*S53tT0`189Qb!KJcB|ICo7E8J+yf2hFd^y-fi#{%c;2I_YSIm-_uEuEdBPaNqN zXU-0a-m_6WMpd_oSRHZf$lnN8U<&t1SN^mt@ z0BR=Kq6l8CO!%(ChM;RAXTwWC-eO}#OiC!p*p#Z&rekZD*cwx8K(>yYv9&X{0U2*S zJtJ{c_1v+*{SkS1!D4bY;6xu5AuD21DkU>j87C0RIz?W;M7S_T2+r%t8R0fY=*APZ zLW<21<4>{S|2#%ZuQB{rt_sKS!ltK~%tB337xw!5C*EFG# z-zUGOo3X@S&@yebU}#xtf*4heS#H-^dhVPkfv#B_F0fjZnjl8idQg6mVY%qn)2&=M zv#|UFNswEvjTTfllG}w-6Xma~P?FOgr7E>uC(jnnwFe~0rj#VszfI)4aLS;>)VlNM zG`4iL>~>u2Diro!Rv#olw}PAvSka$F$%>einBF)CLS3p#rH=BozEJ-07R{CGU7l#(C{#m!sp9^noo@_+b9kx3B%axa_|0qjb0HbBRHHYs97Ov-vd zznKg4etjV=diCPYvLwK4(Z&zZ7Op0UQPmi3w+?r{Y{7DsHhyrnY&AiQs`ay7oG!Mr zXXt$z+xemeO6(l60W%hIyZEvqCMA^QJW8obZTjN-R-coxWVVs>;+yBi*A-&SuT&y| z4G3S*W>OqfwT&cj!!|J+n5sA04F{IxFUxv3&Pa|+(h!}^aSJ$lzlA7MCcK2%bIQb< z`aEtR#yvJXSrL;GN^*EARjEx2&(_@%>(Ue}5aEED!}G8T&y%I`@f)H)3WrNK(yiX~ zJJ#zc#Qu1tRQ5fWt|C<)obYSfX1*S^)U`ar;X`nH5DG<1tRBSamuz#27!Lq1BcA_{ z7_x*I2i$B3R~&S!V_7>Rvo!y!q(d4 String { - "blue" + String::from("blue") } diff --git a/exercises/strings/strings1.rs~ b/exercises/strings/strings1.rs~ new file mode 100644 index 000000000..7c0016f9c --- /dev/null +++ b/exercises/strings/strings1.rs~ @@ -0,0 +1,17 @@ +// strings1.rs +// +// Make me compile without changing the function signature! +// +// Execute `rustlings hint strings1` or use the `hint` watch subcommand for a +// hint. + +// I AM NOT DONE + +fn main() { + let answer = current_favorite_color(); + println!("My current favorite color is {}", answer); +} + +fn current_favorite_color() -> String { + String::from("blue") +} diff --git a/exercises/strings/strings2.rs b/exercises/strings/strings2.rs index 4d95d16a1..10f0a73f2 100644 --- a/exercises/strings/strings2.rs +++ b/exercises/strings/strings2.rs @@ -5,11 +5,10 @@ // Execute `rustlings hint strings2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE fn main() { let word = String::from("green"); // Try not changing this line :) - if is_a_color_word(word) { + if is_a_color_word(&word) { println!("That is a color word I know!"); } else { println!("That is not a color word I know."); diff --git a/exercises/strings/strings2.rs~ b/exercises/strings/strings2.rs~ new file mode 100644 index 000000000..7b4d5ed15 --- /dev/null +++ b/exercises/strings/strings2.rs~ @@ -0,0 +1,20 @@ +// strings2.rs +// +// Make me compile without changing the function signature! +// +// Execute `rustlings hint strings2` or use the `hint` watch subcommand for a +// hint. + + +fn main() { + let word = String::from("green"); // Try not changing this line :) + if is_a_color_word(word) { + println!("That is a color word I know!"); + } else { + println!("That is not a color word I know."); + } +} + +fn is_a_color_word(attempt: &str) -> bool { + attempt == "green" || attempt == "blue" || attempt == "red" +} diff --git a/exercises/strings/strings3.rs b/exercises/strings/strings3.rs index b29f9325b..d96c373d5 100644 --- a/exercises/strings/strings3.rs +++ b/exercises/strings/strings3.rs @@ -3,21 +3,26 @@ // Execute `rustlings hint strings3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE fn trim_me(input: &str) -> String { // TODO: Remove whitespace from both ends of a string! - ??? + let a = input.trim(); + let b: String = String::from(a); + b + } fn compose_me(input: &str) -> String { // TODO: Add " world!" to the string! There's multiple ways to do this! - ??? + let mut s = String::from(input); + s.push_str(" world!"); + s } fn replace_me(input: &str) -> String { // TODO: Replace "cars" in the string with "balloons"! - ??? + let b = input.replace("cars","balloons"); + b } #[cfg(test)] diff --git a/exercises/strings/strings3.rs~ b/exercises/strings/strings3.rs~ new file mode 100644 index 000000000..d96c373d5 --- /dev/null +++ b/exercises/strings/strings3.rs~ @@ -0,0 +1,50 @@ +// strings3.rs +// +// Execute `rustlings hint strings3` or use the `hint` watch subcommand for a +// hint. + + +fn trim_me(input: &str) -> String { + // TODO: Remove whitespace from both ends of a string! + let a = input.trim(); + let b: String = String::from(a); + b + +} + +fn compose_me(input: &str) -> String { + // TODO: Add " world!" to the string! There's multiple ways to do this! + let mut s = String::from(input); + s.push_str(" world!"); + s +} + +fn replace_me(input: &str) -> String { + // TODO: Replace "cars" in the string with "balloons"! + let b = input.replace("cars","balloons"); + b +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn trim_a_string() { + assert_eq!(trim_me("Hello! "), "Hello!"); + assert_eq!(trim_me(" What's up!"), "What's up!"); + assert_eq!(trim_me(" Hola! "), "Hola!"); + } + + #[test] + fn compose_a_string() { + assert_eq!(compose_me("Hello"), "Hello world!"); + assert_eq!(compose_me("Goodbye"), "Goodbye world!"); + } + + #[test] + fn replace_a_string() { + assert_eq!(replace_me("I think cars are cool"), "I think balloons are cool"); + assert_eq!(replace_me("I love to look at cars"), "I love to look at balloons"); + } +} diff --git a/exercises/strings/strings4.rs b/exercises/strings/strings4.rs index e8c54acc5..a368fa635 100644 --- a/exercises/strings/strings4.rs +++ b/exercises/strings/strings4.rs @@ -7,7 +7,6 @@ // // No hints this time! -// I AM NOT DONE fn string_slice(arg: &str) { println!("{}", arg); @@ -17,14 +16,14 @@ fn string(arg: String) { } fn main() { - ???("blue"); - ???("red".to_string()); - ???(String::from("hi")); - ???("rust is fun!".to_owned()); - ???("nice weather".into()); - ???(format!("Interpolation {}", "Station")); - ???(&String::from("abc")[0..1]); - ???(" hello there ".trim()); - ???("Happy Monday!".to_string().replace("Mon", "Tues")); - ???("mY sHiFt KeY iS sTiCkY".to_lowercase()); + string_slice("blue"); + string("red".to_string()); + string(String::from("hi")); + string("rust is fun!".to_owned()); + string("nice weather".into()); + string(format!("Interpolation {}", "Station")); + string_slice(&String::from("abc")[0..1]); + string_slice(" hello there ".trim()); + string("Happy Monday!".to_string().replace("Mon", "Tues")); + string("mY sHiFt KeY iS sTiCkY".to_lowercase()); } diff --git a/exercises/strings/strings4.rs~ b/exercises/strings/strings4.rs~ new file mode 100644 index 000000000..a368fa635 --- /dev/null +++ b/exercises/strings/strings4.rs~ @@ -0,0 +1,29 @@ +// strings4.rs +// +// Ok, here are a bunch of values-- some are `String`s, some are `&str`s. Your +// task is to call one of these two functions on each value depending on what +// you think each value is. That is, add either `string_slice` or `string` +// before the parentheses on each line. If you're right, it will compile! +// +// No hints this time! + + +fn string_slice(arg: &str) { + println!("{}", arg); +} +fn string(arg: String) { + println!("{}", arg); +} + +fn main() { + string_slice("blue"); + string("red".to_string()); + string(String::from("hi")); + string("rust is fun!".to_owned()); + string("nice weather".into()); + string(format!("Interpolation {}", "Station")); + string_slice(&String::from("abc")[0..1]); + string_slice(" hello there ".trim()); + string("Happy Monday!".to_string().replace("Mon", "Tues")); + string("mY sHiFt KeY iS sTiCkY".to_lowercase()); +} diff --git a/exercises/structs/.structs1.rs.un~ b/exercises/structs/.structs1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..335d61f79a18e335dff61797929b7218ff5c29de GIT binary patch literal 8900 zcmeI&F-#Lt7zgkJ3Kc=2>foT}fl<-av;q}Uq6n>nF~T6al7dImP}+EHjfr6(#>wd5 zV4QR@4(>WQI5;~vnK(Ka6CIq0MhE@=ukSlPNmFa!ZSPB7?(W@D?!I5X_uf&i7FM2I zDP_x_y!M|DF0S6c^X%7+r(+)vznvU?c>BcqK*!0s8FlyN!oApO&+|s9aVXkpqqf&{ zV9U+RfBo_!g0oR?{++p?-E6VJsUAN5O`&_Z!)>=Y1H{p-IXrKDKYcb*zndC7wUVMp zBvg2E7o8ZP=B3uOA1>;^u?bk>8hnW7{E!8kL4HT1A5z~(4K)dx2>di2pGi?K;{hvz zV-tYvrKbBF9;e0Dmhj>luWh6Fz{Ggnz`L1N$+#&t_;iZ9ffKyC(dWF71)D)$%d*%o zSW2%Rcm@77AqJr?aZk{5Vj>}ScS)?&OsqE)D~xlIfha0&3w%)4s}fgaA~RNYiR`*0 zL$zQr!GmHS$nt^jm(prDm5PUx8(+ke8{Bq?TZAbb(cEB(Bv=h{44OH{gkxF zlb+Db?ZFVXJ8|sl4_UAo<~2`GEr$dihi{|bgDCIC>ht|r%E25&|@gT_@{Ub1!VX(PWwQ{bw{Z= zSR}z}5bR?O+flE@&9EblU^C@nImi@ql}cgpay6(eR{yd#qbwvbwQ@iivd7TjN)}nL z86^9nS;-E!CM%2B!17B8-#w54n?Q$yMHXxZ!M4CY~j%u6nQ60ClKd=4EB8CkFyg#1P$M;gz%nJpmeh4Y3q zWc$UlV4)4^Y4ka1WWi>T^!sMzoZYIlC~DBg#KV9c)NUy)l45U{s6S}x&c;Q(4b-bV zeuH+8coeV?Q&Z@3RgEmz45I!ftNIlEGJIvpufx-_s#p9I{(MEhPlXdTVDZg12hbffXT$n7gzl=>^k(R(e?hnE zEQ=XW1@rJL0$0$sp~?BXF6e088GqU5^y4dRL_htL!UZ*TNzKg8sqE~``PACy=YIgy CeXI8X literal 0 HcmV?d00001 diff --git a/exercises/structs/.structs2.rs.un~ b/exercises/structs/.structs2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..562d4ece2a6993bd2fdb79c7e8e3379c49d34fb2 GIT binary patch literal 4177 zcmeI#&r2IY6bJB0{C(+{@krr*m#DGv1q_ilshq|D(SBWvoqS=MbrmcvF{0BXG z@KSmT{y6vFP)d)z^dKJMwdh6keP`!|sg$s|JC z#eVv7YA|Agau}y98mf>Y25D@!9zSaIKXRYYN+#Mk{QxjV8<9E)Z>ti??Vuj61mRjG zl(R}1R?qYRp-o}Pccm`P&)9SX2i6o-ND)a)SMQpF$f3k^%XKhy7443O1Y8d#2T%dt zj}sOWRY(y@AlEuUj&*>Pe@jBH*LYT_PE#sfD``~bKHVgeo+(+NyI_gsDcJ+bT|Mhy z(q}vd+%SLb@@W+1-d&Xai5|^69S*T2;ux=$pG+$(c+V->s=a*rrE0~IOHt_g8;-Lc z2G#N0>tHoEF{yS&knuR)89}KQPihfh#&t-$prQzAA_?thMVpCVQSZ_gctQOa?VD10 zlU{o~UoO^bQ4FnTEEorjCkHX6I6hx2D~gaNlCXYLtl5|~Pj|!S#xwRYvzCLpA33rx zsol(}h$n<$d*!veB1)1XlDHiyx31U?t0R}6Kja_LhsRs_>YZG0-^)37VSc7@es~Kw C`NfO? literal 0 HcmV?d00001 diff --git a/exercises/structs/.structs3.rs.un~ b/exercises/structs/.structs3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..c1ff584ff9da5f9b0a1a5c34273306f7ebe4cc4d GIT binary patch literal 5604 zcmeI0!D|yi6vnq{np&$;J*iN9(b^_yYoaz6L4!~aBDR8>APP%}lXW58l-(7TqR@lh z{R6~n@n6tW4_@`)(VJ8cwcf;o2Yuh{OxQLOyv%Jr_?XP>q&s~--pkvq`zx<+2aDY; zC-e5WH}$OIKR)>R#qasq=|iI*o;MmtUi~O-PJZbIFE<>=xy#m?B6M5bhd~@Zq5MS( zMay6HMG*HE*Pbe_;FwLF9E_*fV_36X5e1WCuA6DD$V+g&!$!)DX|9?V_>8c%zz)17 zuwZ#13MR$8-b-FXNi7Ah8MfwixW|h`Clb`lGjPhKP6md=Mh&&x5Co%QZl5H#Ov3F1 z-!0EZPlG(00k?KQe&qT=EW)4}``w_~DNIMA(=O8dC92hGw5F;i=#8?qK(@ptEZ8hW z6ikX~{*p9@6PgJ99Qz&{H2XRly+O9HiXoWE4wOd-Jd5lyCYB+hU{c=p&Vpo^O&AvV zX27HwE~t$3MC`VOh>}d4qZYR@k-N$bju$ppE|7ozTwi(u<^I&+fq9mF3~LrGqF_>t z_L@Yi9yoONX|x5Pg?6)~5W_aNpHEa65fQ-N=sEqhWPffm1;cnGyP5d@=RoHx@r z@wN8_v{Fp2*6*+XFkM*aQ({{RpJD@KbIK`<)DT9;Tyk^;OJYjq%2v_)tB@m#6c zN`|T9gLAJU+X|eDjFFH025w8T%_VG6Id%BaAWiVAo~v~EIxQ{VqQ&K Order { + Order { + name: String::from("Bob"), + year: 2019, + made_by_phone: false, + made_by_mobile: false, + made_by_email: true, + item_number: 123, + count: 0, + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn your_order() { + let order_template = create_order_template(); + // TODO: Create your own order using the update syntax and template above! + let your_order = Order { + name: String::from("Hacker in Rust"), + year: 2019, + made_by_phone: false, + made_by_mobile: false, + made_by_email: true, + item_number: 123, + count: 1, + }; + assert_eq!(your_order.name, "Hacker in Rust"); + assert_eq!(your_order.year, order_template.year); + assert_eq!(your_order.made_by_phone, order_template.made_by_phone); + assert_eq!(your_order.made_by_mobile, order_template.made_by_mobile); + assert_eq!(your_order.made_by_email, order_template.made_by_email); + assert_eq!(your_order.item_number, order_template.item_number); + assert_eq!(your_order.count, 1); + } +} diff --git a/exercises/structs/structs3.rs b/exercises/structs/structs3.rs index 4851317c5..ce8d131eb 100644 --- a/exercises/structs/structs3.rs +++ b/exercises/structs/structs3.rs @@ -7,7 +7,6 @@ // Execute `rustlings hint structs3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE #[derive(Debug)] struct Package { @@ -29,12 +28,18 @@ impl Package { } } - fn is_international(&self) -> ??? { + fn is_international(&self) -> bool { // Something goes here... + if self.sender_country != self.recipient_country { + true + } else { + false + } } - fn get_fees(&self, cents_per_gram: i32) -> ??? { + fn get_fees(&self, cents_per_gram: i32) -> i32 { // Something goes here... + cents_per_gram * self.weight_in_grams } } diff --git a/exercises/structs/structs3.rs~ b/exercises/structs/structs3.rs~ new file mode 100644 index 000000000..f5241d5c0 --- /dev/null +++ b/exercises/structs/structs3.rs~ @@ -0,0 +1,92 @@ +// structs3.rs +// +// Structs contain data, but can also have logic. In this exercise we have +// defined the Package struct and we want to test some logic attached to it. +// Make the code compile and the tests pass! +// +// Execute `rustlings hint structs3` or use the `hint` watch subcommand for a +// hint. + +// I AM NOT DONE + +#[derive(Debug)] +struct Package { + sender_country: String, + recipient_country: String, + weight_in_grams: i32, +} + +impl Package { + fn new(sender_country: String, recipient_country: String, weight_in_grams: i32) -> Package { + if weight_in_grams <= 0 { + panic!("Can not ship a weightless package.") + } else { + Package { + sender_country, + recipient_country, + weight_in_grams, + } + } + } + + fn is_international(&self) -> bool { + // Something goes here... + if self.sender_country != self.recipient_country { + true + } else { + false + } + } + + fn get_fees(&self, cents_per_gram: i32) -> i32 { + // Something goes here... + cents_per_gram * self.weight_in_grams + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn fail_creating_weightless_package() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Austria"); + + Package::new(sender_country, recipient_country, -2210); + } + + #[test] + fn create_international_package() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Russia"); + + let package = Package::new(sender_country, recipient_country, 1200); + + assert!(package.is_international()); + } + + #[test] + fn create_local_package() { + let sender_country = String::from("Canada"); + let recipient_country = sender_country.clone(); + + let package = Package::new(sender_country, recipient_country, 1200); + + assert!(!package.is_international()); + } + + #[test] + fn calculate_transport_fees() { + let sender_country = String::from("Spain"); + let recipient_country = String::from("Spain"); + + let cents_per_gram = 3; + + let package = Package::new(sender_country, recipient_country, 1500); + + assert_eq!(package.get_fees(cents_per_gram), 4500); + assert_eq!(package.get_fees(cents_per_gram * 2), 9000); + } +} diff --git a/exercises/tests/.build.rs.un~ b/exercises/tests/.build.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..94765ca7fc6b1c5b387f8e79c65b9fd5fbbfc787 GIT binary patch literal 23843 zcmeI4Piz!b9LKlawiHU`KM0}>qe82tOCg}PRAP`~j1i)gh|rL-EbPYq%kH*HY7ZtF zHU7Jpc=Y1QgNeq(lLyaUym&BCZ~h61(Zpytfxpk&_m;QI>@Yjy+}zkGC;q>XId6jN2P;VcCOiXGVrg(H*s=WeMV z>0wAYbLcgN2qamywSjA$*>H%A5^3dv=&2w?+vR|useuCs;Mi-x0ji5_Z9wGzdf9g1 zP$5kda8HMU>pgw^`O_CBPM*|$2A&?PL7)TIYW6u?sF0=!u9IQ7RvTR7niqUlN$S?E zf*rj2*mk^7Ax#rrr^9&l)p;$iXkrjj!B4jfdJt3Qh#4i)%7xgOFk<}{G2hqBV5B0T zZWa6-v$PQ1R znw%Qy7HBVqLF;dTro$tQ)>_rTk3pR4<6EMnR}^MbidkoE7)E@i8)mS!#u zmn;5|h7M#EN%e_w0WeXcM(r-TYE@FpiXGkkwxc3Fz;{SuMBW8(HJxHUu}9^=!b6P# z5^xTlQ6$w|;B5+nw;gyhg=)jxrZ?`@JEX?NO)FsuyJ2=X=R<`wP55mOi@-*fv~q!(Q&88`pl;Rjb3D2~ldYiM z)&*{(>pP~|!GF+)-m(_9@!&RB%YLtkX<9vtpcTrV! zY9wDW(Kb*%RLK15x`>?JIvZ`Fn zcD-T8VG}@29FDqVN8eSUx7%v4CuL}=V>v&yl!;S}Li4RKnn&@|<^@=z<;6-hzfVH& z__2u-=f?drPdqbu+@A_qn58Lu(s1k}(K#ynETpwi$e9IFsit0;8Q*Q7|0B3!8Twu z6r>KLB}k%Tbc`DtCoGI}?h3_NpPYc&pw&`{x*Mn^NTOmCil5oe$QK}JC?1Al_;7Z- z_5Bl=4_PMwXy7Whb&=LmCQdO5+%Ll5J{AG)c|WB03r{oO#TmdFzRIB;UnEIjQTTqT z_-+dB{T_+RS0LZ^hM=B^0_l)-65s~0>bNP0t+2>fHLIR7z>YD9f{cY zgitJ(`(IangLyv((Z(fUj_a@+RpRC-Y2qqn6-y>*oNRm7X!oO^U;4=#d;oatwbLjEo79)}{ z$U@W2`=Lfsi$JrdPtn|3yJt4jR4bPPryBMZ=9WTc8Eg;bEMN>*dQdLVB0>_2!ga6W zx-FRNDABbwSNoOJ79$iK*BG#IU;wKHO|AoFq=}hF0o-ecVWc-+|^nLWBxs$9%wFWMIZU!Xf>hN|to&ofnj1^~wU zBpCxS4WMopz!4#dMZtPG4C?^`c+hKh=cXDL73(F%x4^2NmDP421J>P{Em2|@qkt_b zuArHA&Eud`nKZQAMCFY-vLlz7_O4cVhQ?dn{?wLx=|9jdbHy_Rx6WQ zR_wg-ts>hKOt!6_)7Y(7JHV(Wqjbwb?69VWvAJTw`e#@mj=4Y$id(E>K^Us46YiYV zQYMw6Q2jfMYCFzqzlQ}z?g7R?3|99(tWhM@T(DkOSXTwd;E27Z+KZDmSKC!N0~j-@ z(#wW(S5!#T8(?CM8!Lp gGh`gevpDPbKbP6HveNJi*9=Pn{!M;6`L|F115U@IWdHyG literal 0 HcmV?d00001 diff --git a/exercises/tests/.tests1.rs.un~ b/exercises/tests/.tests1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..4d1f31ee5b7352fae1551337aa669e03608b7104 GIT binary patch literal 1446 zcmWH`%$*;a=aT=Ffhq6$7NMLImF6E?xxi=6RtA8TC(1_ogu z7E*wM#Ny)Aq7p?7O>3a2AP@@xF(VK&12G7IXc%Tl|CXD_0+MB6h`#`m1p+1r1tvjK zJTU%$AOIT$6Bwnb90I`Thyq6kBg0n-pxN9&3=4i(vsfWcs!)Vljf`pa;7GOf6HxP0m(8m#9si(0s%}R zhz*kB05L$|KM;ULAly-s>LCD(j&g8xFfx3V0GiGY#IWFpMT>yGzJjNMqpyOWe~5yM zzn`mVBRJ|nQH2aZ>S6Ie8ggu662^@7iKwJ2L7?eLjQG-2?nl?UP1ps>4 BI;{Wz literal 0 HcmV?d00001 diff --git a/exercises/tests/.tests3.rs.un~ b/exercises/tests/.tests3.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..8e2c7ef63bf82fe8c5390b228e337ec1f7075e23 GIT binary patch literal 3236 zcmWH`%$*;a=aT=Ffl2?@;yrtmKW!2F)6{4Dhb5=K+Fil>_7|xAR2}l(!b@tVFAgqGQ?j1$pQfrgaVTw zDNY#wKM;V8f(eY$R1N`Pbo7FwgOTB@1kh{_Ach4$ELsHg^%Xo79DNo1{6iF6{QX=_ z8^KWriYjI#_kh%k0I>i_Y&7aXp+HLjjJng{sAGUcoiNZcQ6L6oPEgcf$)M1P14R@o z5W@f{5=Y}u92OvSo(=-#PIhi=iw z#Y5NrgrI9s-J-uBgD&+xvpckcC1l?Ag~u6Z_8r&v$1}6Lp39%D6%xBI%w5aR)q3tO zZZ-n9ALRq()PH@xc^OiNma8X^$AkQcF*ZT+atdmL=#yNeZW02m6w~X)XD?=bEOU=p z3b)yaPkSQ!q!3HlE^xa4SpmJCe-}7h>}`M+_K_qviKSOj_!6IA<;hflo*#YjLCfh7@J<+4_)WVF4&xT>mA9-j!$ za$=e_wCoPw&uv!>izo=fy)r--M29ip5JeR_8ANnZ5M|AY#!a3LL`zz>5)%x6;R=pj zwmS!7PI8=TE6Sg{sARvDjlQTVwN=?Ct}BA8$K(o21xV7V(I#AlQzsjoYG^s#s9077 zLTuJDfEVjRj#W{Fc7juKE2L?G)Z5&uQ%#V5Ta|$Sya|J(Jc98bKsikEcB%u+6Yd$t>8Tgcs|pX UW0Vjg;T5G3o}2+zg7hLAo)2;?BX@4I<2f#qDXv6~0)-s}uBJG{?*=f|!#wvJb}=Ywx5 z>%CvQI+&Y_J}!P;yu4^U8OrRb)9Y$6@Bf&+`FZk1DOD!#*T$$^z%zM7Dt{D+K(k_s39a|Y__m&Z7ix_L@t!zKMdG3KrCy;UTTAe(&4r zlGK;*QiBLcdaX$S7gkX=he$H5w55|ZakG8a$sPLy3p zzA>T%x<}Szfz_?ARzgx06QFFb+dHH->Bn1fv?+=x>5i9Ri3Pnu^fd;uj;3TIZG1@s z$Uzn5n1gD2qZ`dhp~=Fm)@n^Z3}a6}B2NI6Z#0-b-~uRL7~M*Xl%%jJ>MKA|P6QMi z9WIBE=iO&D{xGAd2CdWNas#o|h-$zDKz^+Qh?JzTB#PW-MdstT%D({$7<2dkes&AR Ck>A7s literal 0 HcmV?d00001 diff --git a/exercises/tests/.tests6.rs.un~ b/exercises/tests/.tests6.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..c953db547beb42d3145ed299c6061174a1800ec7 GIT binary patch literal 5812 zcmeI0&ubGw6vwA&qxHwZgFjEc1PWPOtW~Uosi6#1)f_BwHg$4<187 z{{y}Eq<=&I0r998FXBx^@u0Mg?>oDLYb<3k>}|gAGP^VT^L_H(zL~oZ>aUg>v+9#b zW#%SEo`0BsF}cxsKmBgw&BuqAe_ra`Si8Nv^m?khz9xhiWjjZqYSO2Q>$@~fSJjhz zz9HMW>q^m6a`QAXM$36BsfMIgr@*ICc=`ah2iYLB#)K!jTSFL4i}G8HvQj~#e=)Sr z>~~oLJyr>Mz!RGtjblLkIL`MNW;5g5aLWGlMROI_R@R;e{l{ zL|;Y&ub1ddETWJ6Cb_NPn_6wEdb#PgbIu>gfV!709li>H+prCtk$l6DzwQRP5F4_t znsy=#qWIn#fi?)AMTZSzcp*tK;cvSUz7UJ>zjSpS1&$`mi!g12uc@u@VqlNsCb46A z!wX4@d4JcuQ$fAdo3`Uc^xwRZ#3MNyME6JD0krWiIE6k-7+y$HOn5sQ(QrK`Bx7u- zh=&o;kPcBZibBkUD1aTnekj1iak_rC0F7IcYI$)Wr2!5GA!@QH?gxOnR`yjzWpdd? zPjb23@<~<6=k0r{BI&-8E%IbjW}PtUf}mN5z-2&}*fe!Zls(apFyp|S6T==i7d2lq=f Ux_e8ii-z{DYa2Vxfj_VR2KJ#vE&u=k literal 0 HcmV?d00001 diff --git a/exercises/tests/.tests7.rs.un~ b/exercises/tests/.tests7.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..3093c279f19bf326edbe0268ee09f07d551584d8 GIT binary patch literal 962 zcmWH`%$*;a=aT=Ff$2e&znp`-p6=1u7^S2cTi*sAP)hhEn(*yj%-gq1RSQlsFff<` zF*0BTa+uICNQ@zanKh9G#A0TMzW@>d0+2!&07If;n@ R9CaE%i?m>tnKnLO1pv=8Dw_ZR literal 0 HcmV?d00001 diff --git a/exercises/tests/.tests8.rs.un~ b/exercises/tests/.tests8.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..f6232880b6b71f41d7795667efd3922b9ae3d53a GIT binary patch literal 998 zcmWH`%$*;a=aT=Ffyp9Ov$4mt_(FXO`-Xx|Uw`b;C=Z)+*psLKtyb#9ZCgGuFffP# zF*0BTa+sh3AR2}lGMHJOu|Q4+b167F7#Y4w z0L|tAVp#CQ;!i+dU%^ws(O1FGKSaUB-_O;w5gc`(s6qxH^+G@lGJ|0>>Oi4DO90GC yPoX&p9Cd;~%Rs>o0-&f-fC1&`>9PXln~iDprM#1vmeJ2o8dZ zf5Fi~M+g6cIO?KnJ?~A91{92~V-CDM$+@{ncpuKqZN8$Pts0rylTg+Y`CwyyVz2aG zE$22LPfl+}c8?;(MEvz-DRdl+2_a@lNtHrxXxl}-rj-tit^G>PPz&{MHLXys6zWqn zWtik6c}QI(1TssMy~>pjqXD5kV3a~Jll;X{KcBZK3{gg0WLA zZdk~G$ZvZy-~(0}Zm+QuZDuFP?(E25{Savq50nchDiN+&&;Thw;s8KgBg2KpPPCbw zK)aXFd|!wFjTgwD`V5GIwig1vC bool { num % 2 == 0 } @@ -19,11 +17,11 @@ mod tests { #[test] fn is_true_when_even() { - assert!(); + assert!(is_even(4)); } #[test] fn is_false_when_odd() { - assert!(); + assert!(!is_even(5)); } } diff --git a/exercises/tests/tests3.rs~ b/exercises/tests/tests3.rs~ new file mode 100644 index 000000000..bbd3834f5 --- /dev/null +++ b/exercises/tests/tests3.rs~ @@ -0,0 +1,27 @@ +// tests3.rs +// +// This test isn't testing our function -- make it do that in such a way that +// the test passes. Then write a second test that tests whether we get the +// result we expect to get when we call `is_even(5)`. +// +// Execute `rustlings hint tests3` or use the `hint` watch subcommand for a +// hint. + +pub fn is_even(num: i32) -> bool { + num % 2 == 0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_true_when_even() { + assert!(is_even(4)); + } + + #[test] + fn is_false_when_odd() { + assert!(!is_even(5)); + } +} diff --git a/exercises/tests/tests4.rs b/exercises/tests/tests4.rs index 935d0db17..57dbc530b 100644 --- a/exercises/tests/tests4.rs +++ b/exercises/tests/tests4.rs @@ -5,8 +5,6 @@ // Execute `rustlings hint tests4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - struct Rectangle { width: i32, height: i32 @@ -30,17 +28,19 @@ mod tests { fn correct_width_and_height() { // This test should check if the rectangle is the size that we pass into its constructor let rect = Rectangle::new(10, 20); - assert_eq!(???, 10); // check width - assert_eq!(???, 20); // check height + assert_eq!(rect.width, 10); // check width + assert_eq!(rect.height, 20); // check height } #[test] + #[should_panic] fn negative_width() { // This test should check if program panics when we try to create rectangle with negative width let _rect = Rectangle::new(-10, 10); } #[test] + #[should_panic] fn negative_height() { // This test should check if program panics when we try to create rectangle with negative height let _rect = Rectangle::new(10, -10); diff --git a/exercises/tests/tests4.rs~ b/exercises/tests/tests4.rs~ new file mode 100644 index 000000000..57dbc530b --- /dev/null +++ b/exercises/tests/tests4.rs~ @@ -0,0 +1,48 @@ +// tests4.rs +// +// Make sure that we're testing for the correct conditions! +// +// Execute `rustlings hint tests4` or use the `hint` watch subcommand for a +// hint. + +struct Rectangle { + width: i32, + height: i32 +} + +impl Rectangle { + // Only change the test functions themselves + pub fn new(width: i32, height: i32) -> Self { + if width <= 0 || height <= 0 { + panic!("Rectangle width and height cannot be negative!") + } + Rectangle {width, height} + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn correct_width_and_height() { + // This test should check if the rectangle is the size that we pass into its constructor + let rect = Rectangle::new(10, 20); + assert_eq!(rect.width, 10); // check width + assert_eq!(rect.height, 20); // check height + } + + #[test] + #[should_panic] + fn negative_width() { + // This test should check if program panics when we try to create rectangle with negative width + let _rect = Rectangle::new(-10, 10); + } + + #[test] + #[should_panic] + fn negative_height() { + // This test should check if program panics when we try to create rectangle with negative height + let _rect = Rectangle::new(10, -10); + } +} diff --git a/exercises/tests/tests5.rs b/exercises/tests/tests5.rs index 0cd5cb256..7847d6dc9 100644 --- a/exercises/tests/tests5.rs +++ b/exercises/tests/tests5.rs @@ -22,8 +22,6 @@ // Execute `rustlings hint tests5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - /// # Safety /// /// The `address` must contain a mutable reference to a valid `u32` value. @@ -32,7 +30,8 @@ unsafe fn modify_by_address(address: usize) { // code's behavior and the contract of this function. You may use the // comment of the test below as your format reference. unsafe { - todo!("Your code goes here") + let a = address as *mut u32; + *a = 0xAABBCCDD; } } diff --git a/exercises/tests/tests5.rs~ b/exercises/tests/tests5.rs~ new file mode 100644 index 000000000..7847d6dc9 --- /dev/null +++ b/exercises/tests/tests5.rs~ @@ -0,0 +1,50 @@ +// tests5.rs +// +// An `unsafe` in Rust serves as a contract. +// +// When `unsafe` is marked on an item declaration, such as a function, +// a trait or so on, it declares a contract alongside it. However, +// the content of the contract cannot be expressed only by a single keyword. +// Hence, its your responsibility to manually state it in the `# Safety` +// section of your documentation comment on the item. +// +// When `unsafe` is marked on a code block enclosed by curly braces, +// it declares an observance of some contract, such as the validity of some +// pointer parameter, the ownership of some memory address. However, like +// the text above, you still need to state how the contract is observed in +// the comment on the code block. +// +// NOTE: All the comments are for the readability and the maintainability of +// your code, while the Rust compiler hands its trust of soundness of your +// code to yourself! If you cannot prove the memory safety and soundness of +// your own code, take a step back and use safe code instead! +// +// Execute `rustlings hint tests5` or use the `hint` watch subcommand for a +// hint. + +/// # Safety +/// +/// The `address` must contain a mutable reference to a valid `u32` value. +unsafe fn modify_by_address(address: usize) { + // TODO: Fill your safety notice of the code block below to match your + // code's behavior and the contract of this function. You may use the + // comment of the test below as your format reference. + unsafe { + let a = address as *mut u32; + *a = 0xAABBCCDD; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_success() { + let mut t: u32 = 0x12345678; + // SAFETY: The address is guaranteed to be valid and contains + // a unique reference to a `u32` local variable. + unsafe { modify_by_address(&mut t as *mut u32 as usize) }; + assert!(t == 0xAABBCCDD); + } +} diff --git a/exercises/tests/tests6.rs b/exercises/tests/tests6.rs index 4c913779d..913e72d57 100644 --- a/exercises/tests/tests6.rs +++ b/exercises/tests/tests6.rs @@ -7,8 +7,6 @@ // Execute `rustlings hint tests6` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - struct Foo { a: u128, b: Option, @@ -20,8 +18,8 @@ struct Foo { unsafe fn raw_pointer_to_box(ptr: *mut Foo) -> Box { // SAFETY: The `ptr` contains an owned box of `Foo` by contract. We // simply reconstruct the box from that pointer. - let mut ret: Box = unsafe { ??? }; - todo!("The rest of the code goes here") + let mut ret: Box = unsafe { Box::from_raw(ptr) }; + ret } #[cfg(test)] @@ -31,7 +29,7 @@ mod tests { #[test] fn test_success() { - let data = Box::new(Foo { a: 1, b: None }); + let data = Box::new(Foo { a: 1, b: Some("hello".to_owned())}); let ptr_1 = &data.a as *const u128 as usize; // SAFETY: We pass an owned box of `Foo`. diff --git a/exercises/tests/tests6.rs~ b/exercises/tests/tests6.rs~ new file mode 100644 index 000000000..913e72d57 --- /dev/null +++ b/exercises/tests/tests6.rs~ @@ -0,0 +1,43 @@ +// tests6.rs +// +// In this example we take a shallow dive into the Rust standard library's +// unsafe functions. Fix all the question marks and todos to make the test +// pass. +// +// Execute `rustlings hint tests6` or use the `hint` watch subcommand for a +// hint. + +struct Foo { + a: u128, + b: Option, +} + +/// # Safety +/// +/// The `ptr` must contain an owned box of `Foo`. +unsafe fn raw_pointer_to_box(ptr: *mut Foo) -> Box { + // SAFETY: The `ptr` contains an owned box of `Foo` by contract. We + // simply reconstruct the box from that pointer. + let mut ret: Box = unsafe { Box::from_raw(ptr) }; + ret +} + +#[cfg(test)] +mod tests { + use super::*; + use std::time::Instant; + + #[test] + fn test_success() { + let data = Box::new(Foo { a: 1, b: Some("hello".to_owned())}); + + let ptr_1 = &data.a as *const u128 as usize; + // SAFETY: We pass an owned box of `Foo`. + let ret = unsafe { raw_pointer_to_box(Box::into_raw(data)) }; + + let ptr_2 = &ret.a as *const u128 as usize; + + assert!(ptr_1 == ptr_2); + assert!(ret.b == Some("hello".to_owned())); + } +} diff --git a/exercises/tests/tests7.rs b/exercises/tests/tests7.rs index 66b37b72d..79883a9b6 100644 --- a/exercises/tests/tests7.rs +++ b/exercises/tests/tests7.rs @@ -34,8 +34,6 @@ // Execute `rustlings hint tests7` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn main() {} #[cfg(test)] diff --git a/exercises/tests/tests7.rs~ b/exercises/tests/tests7.rs~ new file mode 100644 index 000000000..02417a605 --- /dev/null +++ b/exercises/tests/tests7.rs~ @@ -0,0 +1,52 @@ +// tests7.rs +// +// When building packages, some dependencies can neither be imported in +// `Cargo.toml` nor be directly linked; some preprocesses varies from code +// generation to set-up package-specific configurations. +// +// Cargo does not aim to replace other build tools, but it does integrate +// with them with custom build scripts called `build.rs`. This file is +// usually placed in the root of the project, while in this case the same +// directory of this exercise. +// +// It can be used to: +// +// - Building a bundled C library. +// - Finding a C library on the host system. +// - Generating a Rust module from a specification. +// - Performing any platform-specific configuration needed for the crate. +// +// When setting up configurations, we can `println!` in the build script +// to tell Cargo to follow some instructions. The generic format is: +// +// println!("cargo:{}", your_command_in_string); +// +// Please see the official Cargo book about build scripts for more +// information: +// https://doc.rust-lang.org/cargo/reference/build-scripts.html +// +// In this exercise, we look for an environment variable and expect it to +// fall in a range. You can look into the testcase to find out the details. +// +// You should NOT modify this file. Modify `build.rs` in the same directory +// to pass this exercise. +// +// Execute `rustlings hint tests7` or use the `hint` watch subcommand for a +// hint. + +fn main() {} + +#[cfg(test)] +mod tests { + + #[test] + fn test_success() { + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_secs(); + let s = std::env::var("TEST_FOO").unwrap(); + let e: u64 = s.parse().unwrap(); + assert!(timestamp >= e && timestamp < e + 10); + } +} diff --git a/exercises/tests/tests8.rs b/exercises/tests/tests8.rs index ce7e35d8d..1f99e786d 100644 --- a/exercises/tests/tests8.rs +++ b/exercises/tests/tests8.rs @@ -7,8 +7,6 @@ // Execute `rustlings hint tests8` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - fn main() {} #[cfg(test)] @@ -17,7 +15,6 @@ mod tests { #[test] fn test_success() { - #[cfg(feature = "pass")] return; panic!("no cfg set"); diff --git a/exercises/tests/tests8.rs~ b/exercises/tests/tests8.rs~ new file mode 100644 index 000000000..dfa37d7ac --- /dev/null +++ b/exercises/tests/tests8.rs~ @@ -0,0 +1,23 @@ +// tests8.rs +// +// This execrise shares `build.rs` with the previous exercise. +// You need to add some code to `build.rs` to make both this exercise and +// the previous one work. +// +// Execute `rustlings hint tests8` or use the `hint` watch subcommand for a +// hint. + +fn main() {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_success() { + #[cfg(feature = "pass")] + return; + + panic!("no cfg set"); + } +} diff --git a/exercises/tests/tests9.rs b/exercises/tests/tests9.rs index ea2a8ec02..3d67d2576 100644 --- a/exercises/tests/tests9.rs +++ b/exercises/tests/tests9.rs @@ -27,23 +27,24 @@ // // You should NOT modify any existing code except for adding two lines of attributes. -// I AM NOT DONE - extern "Rust" { fn my_demo_function(a: u32) -> u32; fn my_demo_function_alias(a: u32) -> u32; } - mod Foo { // No `extern` equals `extern "Rust"`. + #[no_mangle] fn my_demo_function(a: u32) -> u32 { a } + + use my_demo_function as my_demo_function_alias; } #[cfg(test)] mod tests { use super::*; + use my_demo_function as my_demo_function_alias; #[test] fn test_success() { diff --git a/exercises/tests/tests9.rs~ b/exercises/tests/tests9.rs~ new file mode 100644 index 000000000..dcccf9796 --- /dev/null +++ b/exercises/tests/tests9.rs~ @@ -0,0 +1,61 @@ +// tests9.rs +// +// Rust is highly capable of sharing FFI interfaces with C/C++ and other statically compiled +// languages, and it can even link within the code itself! It makes it through the extern +// block, just like the code below. +// +// The short string after the `extern` keyword indicates which ABI the externally imported +// function would follow. In this exercise, "Rust" is used, while other variants exists like +// "C" for standard C ABI, "stdcall" for the Windows ABI. +// +// The externally imported functions are declared in the extern blocks, with a semicolon to +// mark the end of signature instead of curly braces. Some attributes can be applied to those +// function declarations to modify the linking behavior, such as #[link_name = ".."] to +// modify the actual symbol names. +// +// If you want to export your symbol to the linking environment, the `extern` keyword can +// also be marked before a function definition with the same ABI string note. The default ABI +// for Rust functions is literally "Rust", so if you want to link against pure Rust functions, +// the whole extern term can be omitted. +// +// Rust mangles symbols by default, just like C++ does. To suppress this behavior and make +// those functions addressable by name, the attribute #[no_mangle] can be applied. +// +// In this exercise, your task is to make the testcase able to call the `my_demo_function` in +// module Foo. the `my_demo_function_alias` is an alias for `my_demo_function`, so the two +// line of code in the testcase should call the same function. +// +// You should NOT modify any existing code except for adding two lines of attributes. + +extern "Rust" { + fn my_demo_function(a: u32) -> u32; + fn my_demo_function_alias(a: u32) -> u32; +} +mod Foo { + // No `extern` equals `extern "Rust"`. + #[no_mangle] + fn my_demo_function(a: u32) -> u32 { + a + } + + my_demo_function as my_demo_function_alias; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_success() { + // The externally imported functions are UNSAFE by default + // because of untrusted source of other languages. You may + // wrap them in safe Rust APIs to ease the burden of callers. + // + // SAFETY: We know those functions are aliases of a safe + // Rust function. + unsafe { + my_demo_function(123); + my_demo_function_alias(456); + } + } +} diff --git a/exercises/threads/.threads1.rs.un~ b/exercises/threads/.threads1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..81862b9239cd9edb300c91bd4e252adbec9bfde3 GIT binary patch literal 10018 zcmeI2%}Z2K6u_V3n3^BiCw-X@3>z(UC4tf+Fe0dNQ|6+G0f$kU8D&0lky8B!MVlb9 zA}ESl)S^G2TC|E5ZQ2(>``XN+&hO4U02l7ynEP|9C~?S_0`AGspl^~9SwpYA-XG!q>wI_v!&wj zV!1e*7?eA`qB}*KcuEw(ss@=#``b8oTZ2m@b*7@AX902 zZE!RN-*?Nq+eOv=ilt{{Bs>)!KNBV=&xR9|$rGd34LVRYTjSyReWGn#^XTw`OUYDX z(*|8oMThGNzeA#+>Chk*e1@$)Fd#RBh#}14oJRuB{i6Mxdxm(yr3l0M-x(f|4=Tfh z$}pQQg|n&rOg0@J3rn+wbZTa7thkt3$|nXRl%Q*|1`Af^Ll@UPO1$7w1ZCDnNfd#S z^^$PxQj}O_2BS@)D)95n)EmyNFw1Skj7kP(oi;O*Lv5;>LxI+6jTN9ihguGCdngc> zY=|s#1m2J+5RWLt201jha5)_=FNarZ3ng#RY0&={Z-|mG>`nb67GYlSDqj=f4d)_r z;i^3s$fbRvheauM+Lh#roYX~k#1CH7z$$R_{L~xHt?;{M_{FLX&<;^*yX(p8Iu*El8G>l)B{tZ@PqfF@1)lxTUz z$)P}8*Ug*wk*@)9uU#+F4CczEFkjBeFKSWk2(Ycz*nr7Y@ZFo`6nBTRH+0vILOOZe zj{xwWI{64G2u)qdOGLoSr0_`bhI0|5t2WZwnkHWcX>F5YrPjbfXuCBq==mVD9OCv+ zh~2k|>8_D(Nz`T0`u*Q1)k}3_aCm-UZf!RZX8I2p3>2O)G@HMkAue$# z!tj}4*iyeauR%D_kl}DSzf?#q*0y%-U}V&QC1}lc4-=QT6oL81z-+C;B#vm}73LrQ z9V%K5?H|eL5NYv&w@1{s_Bg?*NLScv;Kl3V(YUi5_Gu(y>*|?eDOD)RPW{)XzW_?_ Ba9#ia literal 0 HcmV?d00001 diff --git a/exercises/threads/.threads2.rs.un~ b/exercises/threads/.threads2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..e71abb4727bfd7d76d1178fb17b8b72928b825aa GIT binary patch literal 19423 zcmeI4%WqXh7{G7Kv%DWI7DX6}*n6QA5`&A|Kqb7QhKCU}kr=qNS16WS(g&!71<@E| zqKR8KEKS(Da^XVbO5@`{U}cCKb>oVK&hI<(ozAVNx5J&Xn=hHpoH^&7Gw1uA@0)Mt z%;_6r*YBNg9Gm#P)cMvAcRo1x=FrbyzVu*4|HH37d*|10%UxZUJ|6z-(?8DqIr2%V zR4Uta$XK~CIo6mSZ|p4hU7NT(Wkx2h-x#k?*GJ9mJADIY&(w5ndS+^Hd}8F?a%FI) zaci=6qg*i+Gh|QDZ_{?0I&7-ggpg}0U3t`7Tgu+v(#7A{Yo#;GAd1V=~dpI&?Jl{TsR70ZVG`_0Sd$SHIB%sF%H%<1C??+Q9lE%DmJ@lV^d zkGg~oEj&rN@@UmHL08JqZM7GB#-`_O0?it1Sw-OL5xec)l7k4erEEI^C=fTZogkux z2!Y2M_j}5?N93kWQnnC3Yz47f0g_uUY_88t8-WQV#jP-bx6CFLz;fIHDiTbz5FsHj zKWYW@KoQKWJH0q{wKiEF9i+#-nD@BOM!~q;YdDC(dXlVFxqOmkN&n*f&s-u%m?t z3Bi6(urDdb{@P+=A9CE`tPwXi$TI-!rr-P?q*8y%y1Mq-SPGwRd;NNSuj)}uHGVLxd-8wna( zh!8qq>DFvcxxg^Hw+po8vxtD!Zxd4*n`fr#))+^t)v5OzBh~7W$q{v_P+Dt~3P0<% zi3cT-LkTewLayqY8`DQUHYvFw-07?8pSFJYcx5}?fTz*}ql+A6^+?`g<0duFK zgdw`ly9sDRSZ1@5ZF-t%rx-%`a4W(x3N9vmYG%6rUIx1oN*lW3b=}QC9@@v*PPEZN zgoMyOBD7azo_MZ3pP1jCJ=zPxmYGbjs;|(QOmNG{*WDzKf*3m63BS`yyIBbS`+|RE zhW|NxCE_G?=X*6eZvC!scz8H>-w@pBH5j_IBZXF;Qra$t5dB(+c4b6~i?-RML=P*` zX2W*#(xC%epvnNp-3Y*w**axJXCaWk^ZV$zX1mY6$#oKLxGRnYWZRR0Je{5x@ZS<}hpJ|hIV3dfeMq=_1qCd4F zx+m1_=HU_mw|H$PKu#v=DI}^G4s>;~*R2Es&3VG_DX-12O*}n?L={7LJ`e+4Q_Qm* z#xutWKGw^rfHvV&ZN%mwIR9?tZyy&Y_*fmM0$OmA(sTn#h>-xCJ$)g&J;sW z=KWoxAq&a9Y^U%REksBN&9cy3TkLE11<|}(YmAQ9jWX4>tJ-k*!nBWy#1t(=NC?vx zgz36srh|{c)P5=8UbpHbl(w8^?6gVNK_#fFmNxScsM#dHdn0b_g|H``6WpOtGh4Ka zQ^y+KCm%}DzYa}hS`mu!vMy0XB@yClmvX^N^PXd3n(H&uH1;5$;%=qL%ek6q%@THe zzoWwIdfY6JL~^qzAx1)2zA7v?7Q5Me1^N8bx7A_$l~x9M*3p7-hu3ltgSAXuGEubf zB*lL8wpFk?M>}_3en3rh0j#Drixh;$YczO4I!s+ciWZ)vSfttdvQ5R7dNdU2Jl|7# zq#;Xxs$y&*MMGlaasQeRPP6{?&;mWIvFDXRi_H

OnLX3ov9`H${dcs(F zB_<1xs9{TL95f)&J*xna{mDF4BQbe6wC>E=Dl{FEE~0rtmeZ?fP$t8l6hNt3+RQ^p zzgT3RN_v<8YN2>|p5V!I!b(+dLv21$R*l5u;goxd?OB$c%}<%JY^(n`;+(d63B45@ zcD__RnX;;-%{&D1QQwqx@h-Cq9b8m;TdkF;BnJ*q9HqiOg7Ho&5;(LFA;dB|w4p39 zjLrR_&52gvmh8Ilwj%|ZicKm|qP=ut^gP`q2Me!g-LlDx`+N3Ex2tE4| zJcv0-PomYcUqJEX#iNKIUIifseZSd#c9cX{x5xRz%gnyn*$nTO_a?Jf@2ot!(pXsi z7^HW0A0B`A<@x9N2T#}97q{{+kF~S+*LFYLXl{*sD;zx&1VKftU>r3!r`D^D+r`O^ z<$7tV)o9;azFREK$!+6ehs9E2hr|%AT2SkDu4fp{1vlR^DoTfq{bVSs*WX31lJpR4$ptrORevY4QB*wnYc30cSnjKPFbd=g|>` z1Ue~mk3{o{s`fXuU+X@8V$lU5IwJ#2s)&JRSQFNQHR55kEEYrn)6xaF3YdJA!QlZC zg#;oE6dIA&z6X5Pb}AOjxdR znLR{Is)(h;{w)K6mlIO~5tw-#zMK+;1d0Rmy@i?W4RcbEdr188M*_i>PJ#gpX|1V|&s$eK}e!;nXG#t zHBS4^ful2H;SGk_sE8EaDDcR_=H}_}m~pGV+Nc)woB=L = vec![]; for handle in handles { // TODO: a struct is returned from thread::spawn, can you use it? + let a = handle.join().unwrap(); + results.push(a) } if results.len() != 10 { diff --git a/exercises/threads/threads1.rs~ b/exercises/threads/threads1.rs~ new file mode 100644 index 000000000..47800da06 --- /dev/null +++ b/exercises/threads/threads1.rs~ @@ -0,0 +1,40 @@ +// threads1.rs +// +// This program spawns multiple threads that each run for at least 250ms, and +// each thread returns how much time they took to complete. The program should +// wait until all the spawned threads have finished and should collect their +// return values into a vector. +// +// Execute `rustlings hint threads1` or use the `hint` watch subcommand for a +// hint. + +use std::thread; +use std::time::{Duration, Instant}; + +fn main() { + let mut handles = vec![]; + for i in 0..10 { + handles.push(thread::spawn(move || { + let start = Instant::now(); + thread::sleep(Duration::from_millis(250)); + println!("thread {} is complete", i); + start.elapsed().as_millis() + })); + } + + let mut results: Vec = vec![]; + for handle in handles { + // TODO: a struct is returned from thread::spawn, can you use it? + let a = handle.join().unwrap(); + results.push(a) + } + + if results.len() != 10 { + panic!("Oh no! All the spawned threads did not finish!"); + } + + println!(); + for (i, result) in results.into_iter().enumerate() { + println!("thread {} took {}ms", i, result); + } +} diff --git a/exercises/threads/threads2.rs b/exercises/threads/threads2.rs index 62dad80d6..0a7eed564 100644 --- a/exercises/threads/threads2.rs +++ b/exercises/threads/threads2.rs @@ -7,24 +7,25 @@ // Execute `rustlings hint threads2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::sync::Arc; +use std::sync::Mutex; use std::thread; use std::time::Duration; +#[derive(Debug)] struct JobStatus { jobs_completed: u32, } fn main() { - let status = Arc::new(JobStatus { jobs_completed: 0 }); + let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 })); let mut handles = vec![]; for _ in 0..10 { let status_shared = Arc::clone(&status); let handle = thread::spawn(move || { thread::sleep(Duration::from_millis(250)); // TODO: You must take an action before you update a shared value + let mut status_shared = status_shared.lock().unwrap(); status_shared.jobs_completed += 1; }); handles.push(handle); @@ -34,6 +35,6 @@ fn main() { // TODO: Print the value of the JobStatus.jobs_completed. Did you notice // anything interesting in the output? Do you have to 'join' on all the // handles? - println!("jobs completed {}", ???); } + println!("jobs completed {:?}", *status.lock().unwrap() ) ; } diff --git a/exercises/threads/threads2.rs~ b/exercises/threads/threads2.rs~ new file mode 100644 index 000000000..0a7eed564 --- /dev/null +++ b/exercises/threads/threads2.rs~ @@ -0,0 +1,40 @@ +// threads2.rs +// +// Building on the last exercise, we want all of the threads to complete their +// work but this time the spawned threads need to be in charge of updating a +// shared value: JobStatus.jobs_completed +// +// Execute `rustlings hint threads2` or use the `hint` watch subcommand for a +// hint. + +use std::sync::Arc; +use std::sync::Mutex; +use std::thread; +use std::time::Duration; + +#[derive(Debug)] +struct JobStatus { + jobs_completed: u32, +} + +fn main() { + let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 })); + let mut handles = vec![]; + for _ in 0..10 { + let status_shared = Arc::clone(&status); + let handle = thread::spawn(move || { + thread::sleep(Duration::from_millis(250)); + // TODO: You must take an action before you update a shared value + let mut status_shared = status_shared.lock().unwrap(); + status_shared.jobs_completed += 1; + }); + handles.push(handle); + } + for handle in handles { + handle.join().unwrap(); + // TODO: Print the value of the JobStatus.jobs_completed. Did you notice + // anything interesting in the output? Do you have to 'join' on all the + // handles? + } + println!("jobs completed {:?}", *status.lock().unwrap() ) ; +} diff --git a/exercises/threads/threads3.rs b/exercises/threads/threads3.rs index db7d41ba6..ba34e64f7 100644 --- a/exercises/threads/threads3.rs +++ b/exercises/threads/threads3.rs @@ -3,8 +3,6 @@ // Execute `rustlings hint threads3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::sync::mpsc; use std::sync::Arc; use std::thread; @@ -31,10 +29,11 @@ fn send_tx(q: Queue, tx: mpsc::Sender) -> () { let qc1 = Arc::clone(&qc); let qc2 = Arc::clone(&qc); + let tx1 = tx.clone(); thread::spawn(move || { for val in &qc1.first_half { println!("sending {:?}", val); - tx.send(*val).unwrap(); + tx1.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); diff --git a/exercises/threads/threads3.rs~ b/exercises/threads/threads3.rs~ new file mode 100644 index 000000000..ba34e64f7 --- /dev/null +++ b/exercises/threads/threads3.rs~ @@ -0,0 +1,65 @@ +// threads3.rs +// +// Execute `rustlings hint threads3` or use the `hint` watch subcommand for a +// hint. + +use std::sync::mpsc; +use std::sync::Arc; +use std::thread; +use std::time::Duration; + +struct Queue { + length: u32, + first_half: Vec, + second_half: Vec, +} + +impl Queue { + fn new() -> Self { + Queue { + length: 10, + first_half: vec![1, 2, 3, 4, 5], + second_half: vec![6, 7, 8, 9, 10], + } + } +} + +fn send_tx(q: Queue, tx: mpsc::Sender) -> () { + let qc = Arc::new(q); + let qc1 = Arc::clone(&qc); + let qc2 = Arc::clone(&qc); + + let tx1 = tx.clone(); + thread::spawn(move || { + for val in &qc1.first_half { + println!("sending {:?}", val); + tx1.send(*val).unwrap(); + thread::sleep(Duration::from_secs(1)); + } + }); + + thread::spawn(move || { + for val in &qc2.second_half { + println!("sending {:?}", val); + tx.send(*val).unwrap(); + thread::sleep(Duration::from_secs(1)); + } + }); +} + +fn main() { + let (tx, rx) = mpsc::channel(); + let queue = Queue::new(); + let queue_length = queue.length; + + send_tx(queue, tx); + + let mut total_received: u32 = 0; + for received in rx { + println!("Got: {}", received); + total_received += 1; + } + + println!("total numbers received: {}", total_received); + assert_eq!(total_received, queue_length) +} diff --git a/exercises/traits/.traits1.rs.un~ b/exercises/traits/.traits1.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..6a58c703d81b064829c3b53b5e72b980b2c9f71d GIT binary patch literal 8173 zcmeI%zfY4v7{Kut=nwo20zyqRmnIro5GDp=95gUE2n>p2Q)3|}P-_8Wf)30k&ThJy zm^i!WAK>O-qJz2_jRTA6jL-LaPrXoV7mw+l;|?|n~t zf9@0uJGspLxhD^n-Y+h`e0uBGqc7QSzh68netMmGcri(m3(`&-7v-ti=K4lyeWN~} zzgn*63zuZ{q_ktwdfaO{*gpDc$x7q=WQx&rQu;uLL~rw8|1xw)&vzy4TWLo;{^ty= zG|oM?96d>6Oy0X+nxR6CLO6Clva=iO_n+pI_s)~<1&yqKfF?$yTEclT88uJM;1bc_`U7ww_I)d;i9`SCmHm4N-sMSFY76)jOrz<+|Bw)gl*ap$@iP=n522 zTa0ofz>dH+6$kN0fIsd9rUoaZ{R`O1A!WBgH%}Civ$sHTX?0l%cIYNI(pGWf1+(Ss zu;MmI14rye>4UeqVh*UG^sB zLs>QZ@gwYBsH3c@dS3(BVa{EE$+~-#^9V>5LWThDb^;u3@)@&Q*)U~u*-(CN?S$%x zH#r!gzzvxGA81ts&}T=>#HAE_Ub#$&hkrBg>) zSasP#yPX2P1UD^u=9|EQE}1bf}!(@Zwff155mJbj0E#3n4@NMy+3O z^HH{LZMyO8>t}y+a*L-v-quNCY4IC~53}k%=S(4PlzFOzHjC$qv8G&ussA F^#?uvCPM%K literal 0 HcmV?d00001 diff --git a/exercises/traits/.traits2.rs.un~ b/exercises/traits/.traits2.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..6e82618033818e5dafe8ae35609309ea271f7e21 GIT binary patch literal 25554 zcmeI4&u8ft^e9qi6z3(w^-tfk8bx(48Pv^~>d-;BP?!9yF z4CgLiegE0%lQX|pT8F;B@!B&-PQB6d+@ZgAjn1Fhx%l$C?>+VB&kLV?@yo4Gzqwhd zRQ5^PefjF_mE&i}q7$>T6Vn$T9iNM$$(gz6+{8;9y)LJ8N!c!?Rm!LojM_?N>hBAm zx3$QTEtT`%@u}DfDICK1;u`hj$3J4pCw4H@|Dgg?OZ{VtqouO6MXtMAipdWOtn1*x z=<(>p)6uEZXQPv+PdzrWsOb2-P0xsbfN{P39?+Q*Wz~Z2NkvzQ(II`0l$}zDrY@q@ z3)Sli*v{JF&RQXGlMlM(AkkZKgdy6_@6MpjIckBhDN$A}grD~bGq^%{7Y!;jU?fKz zG$5_y3}*o3yxsgBprJyUCeU6;gNFQsWrR&mN8>t&p1&|YH!weOWpXeY8jH?|bIf4` z+bXZ4APpEjLCSU0Fm8}0BPn3)ZGbU~hg(9HuNnQ_4Zh~!1G__t8Gi`C*JB}uO_s81 zfq%)5VWi(ErB4d*JD`XqgD{MHrP#~~FxFCLfa4rp9|eFWOIfu5e9H&O90|ZZQUKVc z^yJ6*@a(nuO9O*0?!aWrUvU*7*a+h=cOpWm)(Bfq4Ys~M14pc__4)=xz-{7Kh&NOy z(*)exS@E{17M$b`5_Yia^m+%!z|Iq-TvyoLP3?*#|k8gRD zSInPU+TZSvnYGxq*5q$2)f!!Q{NS`ziWw|vi8{=Ah)~1|^V?pB-*L&5JA#nf=5-R9 zw5ti85P_aD&A538c4S3hUp<0n7UnKbPmL{u1e_*LT|a?J^W@?}C?Y};OF}{}f^TaL zhEnxqDD6~`9qBV*Zv&8Cvc@J(TiZaAT)7#PSp#u58OS0+sU~E5mF()6tlh}l+Gca= zjfLetMPr=4iv8 zaqKpZwlio;P)^wIbqR*y7T*)3keev!RJFZ4mZ0iSEe#*`Cqc`W8n;1i@sGR2jQ7-= zWlfWhEcXV#0k6-nO_B>C4n1X>ar5vT$>P~KW#h(ExD9$;glXXD2~x<-!*Mi=V^k;g zW|3;)2(|-WS3w#udV&;k^JDCer^VXgbz2>b%PDYx4N1ArbrhHZpcA8Tl_=>{wHrp} zNA+cXT*!*UhP#RI8ut1LOIi)PiJmA;yLtFsQ+_?^0hnVq5n>0u9zv6L+c*|hG^kL( z@(_GID*|`a8AA2dDYuvb*&(l!;0y>oK?=Ef5Wbm(a3=`Qrrlle`kP}2vj@C>!ZR@R z1S#a^VYryZFi#kQ?6B8Oa0Y~)AcfpK2;-->H>S^py9h&hjHb?OsG9z!5%%)Q4_Nve zj1Nh9kYi#X<~)6JBTSG;Qo!u8@*oa##g9~c>RQEpy&xw$jw9XE2X$8D>&0% z5?`Jqf%dT1QGn8PJI6vOqCx@71M%CeP}C>i>b&XSFHdJIg9O|Wud6_%d0xl}AQ7R6 zh%|}bRj&C>WR{{n<(j2)ty`M$>FFk|2M|RSy8z! zftkAYsb=X1C0&LqJqXzV)F^6+l5!z@9qy!trTW71GiA9YJuvrYv#d>z`!|#WMV_|t}iWI5yV0%%qb){q5$lw`We0ADO0a*HtM}>90 zB6TE%M}`SkjpGn;qC^oxN#-34Kkb?CsyhpN#*N3GTBPi)dA=r|=#CzpoSV5iFsKi_ zB~N{W&KeL`vC^o%j}cHJNde1)@&|v?t3|md3uQG)3rOoORB1orKp=?<1uPHAAC=^q zcs#W)5R~zeTDF;C8naEpv{No}kLy0GDBdSdhWG&2DN|Y{uYZ5whba>snQt3$bL<>L z%+|d06PgeVd;h3Wx+MhLs+T)PFwd5iA+yec6NGIX2tkMnWtt%TFe?ZfY+1Rj4WKbL zn*op#ZaYkoQtJd_dwLw^+@OLOYh(st45EReO7VaE5Q@KMh2owh^Ol|x_a5bd9BCdi zs6sMqZkQsa)nl(J88$XNQJQv9vcZ3K)BlGLk}ud2 zHGQaE-nXi|)#1gdAEW#$KusI^)^S+;AV~qsgZH-LU6l^=uJ)~Hjk{5d@t407j)gUl zh)}-Cm|K)su*oY*m_%i>@-b<~9$Wvp=%y@;>uslf|&Sv!L>ozasUm zZTVAn{ol`*Q-@t6bNL_R!NKnLz3rv9zcvO>4}ZT9LiAI%NE7Rup{kZt*3Z$=hm=n! z8z}EnA~14_;z{r|jk6iC@&{)rQnf+<#i?fAKcmpM;sb8H>j!(;(**7vjJM((@v!(-8W8``8`3IDJIOgb3g?a{c(uAfHH9EA|BTBR( zXngc%pkygrE2ynd6<0zPRQ%^#g;J1{gJW{ON}XGjA2d8)?VGFn?5-X)a{=~gN)F5m zUJKk@;HuPZq`5E^oeO9~%mpmemLgK#+Xx%U?dv2vSu*Q;msVCo2r~Ro;Q*&2%+;WO4BnTV9FS-dc@q+Cv7}tVF`~LxK&i7mZ literal 0 HcmV?d00001 diff --git a/exercises/traits/.traits4.rs.un~ b/exercises/traits/.traits4.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..bd1c22fc2ef30c477bece9faef60b4bf0295e422 GIT binary patch literal 8171 zcmeI1&uddb5XU!Zj6bUZ1%F)@dQq_Er1%3&BdMbO5o~Nd2HU*E2T5K?LQC-=y?GY} zFM5@p{R0FKUi}BelXwzO=34i=c`I9A+zw9A%MNUI-oD4n&U|KOH`$f2^?JEoioS?+ z>U(GIZTtPZ&)=@xt9>Y5e)Ht|=Jc~y+b;@}FS|>hc7zal)o#|?axH3g9(IFjGh7SW zy`b9P>;%1Yy{O*bP{Y?`p>RQ(t7?BE!pM0!eM7EBQByuvZ#kvflxiu}a;ibln2qq98oH!3`9yqi_Jp|P&?t9W5!(8y_YVuM+gZ3{&X~zQ%N#KGoGpj2R0`)4F3vLq z&J@hRii%cuZAr#>2u5@2v zrn|ktOJ+M@AF<3sAOL;|V;(-dzz_=jEf;)Bt>0D8f8WBp>4Wy9WgjBJ)3+SLQrYw= zslO-v__tj$^#S{+Wgr3p@MkdQQy*Sn2nGIAo%)&43;i;o?(YeIc-)d?57x&l>ktQi z&9@xFQVHzCi~q6ggSI(RgQ187pZV~_IOJCzsh2^=DGCI~Em~Ixm$O{@VXM=W^TWf{ z8gbFr$8wmFIolEOKRk9Nz)TSvcy0j~ekFhx7($7MTRI-HqgR3&VI^?J!>*fu+!21= F{s~7Tp2GkD literal 0 HcmV?d00001 diff --git a/exercises/traits/.traits5.rs.un~ b/exercises/traits/.traits5.rs.un~ new file mode 100644 index 0000000000000000000000000000000000000000..bfa6abc36c2db99c4862b96d73d3455814050800 GIT binary patch literal 2945 zcmWH`%$*;a=aT=Ff$7E4hbj}*t6pzVKiD#J-NO78@8?^;4PANQwc+uzle4rhGcYiy z0kK_Lo*IfQ^C) zjM7vN0bq1wfun+a<4RF*kK%!0#Xqf^KgEBHGY80?!W_x?2>&g;q2$65oR(kqNa#RR>xKDkY7vL?WT)5l|by0uW$EHgawS z`3My8pvYDRaYiE>6bcjoP)LH}4Fuq!3S^f7F*t;Qk^LJS*(|7$4a>0 Self; } impl AppendBar for String { // TODO: Implement `AppendBar` for type `String`. + fn append_bar(self) -> Self { + let mut a = self; + a.push_str("Bar"); + a + } } fn main() { diff --git a/exercises/traits/traits1.rs~ b/exercises/traits/traits1.rs~ new file mode 100644 index 000000000..f77c1fa0d --- /dev/null +++ b/exercises/traits/traits1.rs~ @@ -0,0 +1,45 @@ +// traits1.rs +// +// Time to implement some traits! Your task is to implement the trait +// `AppendBar` for the type `String`. The trait AppendBar has only one function, +// which appends "Bar" to any object implementing this trait. +// +// Execute `rustlings hint traits1` or use the `hint` watch subcommand for a +// hint. + +trait AppendBar { + fn append_bar(self) -> Self; +} + +impl AppendBar for String { + // TODO: Implement `AppendBar` for type `String`. + fn append_bar(self) -> Self { + let mut a = self; + a.push_str("Bar"); + a + } +} + +fn main() { + let s = String::from("Foo"); + let s = s.append_bar(); + println!("s: {}", s); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_foo_bar() { + assert_eq!(String::from("Foo").append_bar(), String::from("FooBar")); + } + + #[test] + fn is_bar_bar() { + assert_eq!( + String::from("").append_bar().append_bar(), + String::from("BarBar") + ); + } +} diff --git a/exercises/traits/traits2.rs b/exercises/traits/traits2.rs index 3e35f8e11..6fc34222a 100644 --- a/exercises/traits/traits2.rs +++ b/exercises/traits/traits2.rs @@ -8,13 +8,21 @@ // // Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - trait AppendBar { fn append_bar(self) -> Self; } // TODO: Implement trait `AppendBar` for a vector of strings. +impl AppendBar for Vec { + fn append_bar(self) -> Self { + let mut a = self; + let b = "Bar".to_string(); + a.push(b); + a + + } + +} #[cfg(test)] mod tests { diff --git a/exercises/traits/traits2.rs~ b/exercises/traits/traits2.rs~ new file mode 100644 index 000000000..6fc34222a --- /dev/null +++ b/exercises/traits/traits2.rs~ @@ -0,0 +1,37 @@ +// traits2.rs +// +// Your task is to implement the trait `AppendBar` for a vector of strings. To +// implement this trait, consider for a moment what it means to 'append "Bar"' +// to a vector of strings. +// +// No boiler plate code this time, you can do this! +// +// Execute `rustlings hint traits2` or use the `hint` watch subcommand for a hint. + +trait AppendBar { + fn append_bar(self) -> Self; +} + +// TODO: Implement trait `AppendBar` for a vector of strings. +impl AppendBar for Vec { + fn append_bar(self) -> Self { + let mut a = self; + let b = "Bar".to_string(); + a.push(b); + a + + } + +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_vec_pop_eq_bar() { + let mut foo = vec![String::from("Foo")].append_bar(); + assert_eq!(foo.pop().unwrap(), String::from("Bar")); + assert_eq!(foo.pop().unwrap(), String::from("Foo")); + } +} diff --git a/exercises/traits/traits3.rs b/exercises/traits/traits3.rs index 4e2b06b0e..2e0545427 100644 --- a/exercises/traits/traits3.rs +++ b/exercises/traits/traits3.rs @@ -8,10 +8,10 @@ // Execute `rustlings hint traits3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - pub trait Licensed { - fn licensing_info(&self) -> String; + fn licensing_info(&self) -> String { + "Some information".to_string() + } } struct SomeSoftware { diff --git a/exercises/traits/traits3.rs~ b/exercises/traits/traits3.rs~ new file mode 100644 index 000000000..2e0545427 --- /dev/null +++ b/exercises/traits/traits3.rs~ @@ -0,0 +1,42 @@ +// traits3.rs +// +// Your task is to implement the Licensed trait for both structures and have +// them return the same information without writing the same function twice. +// +// Consider what you can add to the Licensed trait. +// +// Execute `rustlings hint traits3` or use the `hint` watch subcommand for a +// hint. + +pub trait Licensed { + fn licensing_info(&self) -> String { + "Some information".to_string() + } +} + +struct SomeSoftware { + version_number: i32, +} + +struct OtherSoftware { + version_number: String, +} + +impl Licensed for SomeSoftware {} // Don't edit this line +impl Licensed for OtherSoftware {} // Don't edit this line + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn is_licensing_info_the_same() { + let licensing_info = String::from("Some information"); + let some_software = SomeSoftware { version_number: 1 }; + let other_software = OtherSoftware { + version_number: "v2.0.0".to_string(), + }; + assert_eq!(some_software.licensing_info(), licensing_info); + assert_eq!(other_software.licensing_info(), licensing_info); + } +} diff --git a/exercises/traits/traits4.rs b/exercises/traits/traits4.rs index 4bda3e571..4f3e19dce 100644 --- a/exercises/traits/traits4.rs +++ b/exercises/traits/traits4.rs @@ -7,8 +7,6 @@ // Execute `rustlings hint traits4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - pub trait Licensed { fn licensing_info(&self) -> String { "some information".to_string() @@ -23,7 +21,7 @@ impl Licensed for SomeSoftware {} impl Licensed for OtherSoftware {} // YOU MAY ONLY CHANGE THE NEXT LINE -fn compare_license_types(software: ??, software_two: ??) -> bool { +fn compare_license_types(software: impl Licensed, software_two: impl Licensed) -> bool { software.licensing_info() == software_two.licensing_info() } diff --git a/exercises/traits/traits4.rs~ b/exercises/traits/traits4.rs~ new file mode 100644 index 000000000..4f3e19dce --- /dev/null +++ b/exercises/traits/traits4.rs~ @@ -0,0 +1,47 @@ +// traits4.rs +// +// Your task is to replace the '??' sections so the code compiles. +// +// Don't change any line other than the marked one. +// +// Execute `rustlings hint traits4` or use the `hint` watch subcommand for a +// hint. + +pub trait Licensed { + fn licensing_info(&self) -> String { + "some information".to_string() + } +} + +struct SomeSoftware {} + +struct OtherSoftware {} + +impl Licensed for SomeSoftware {} +impl Licensed for OtherSoftware {} + +// YOU MAY ONLY CHANGE THE NEXT LINE +fn compare_license_types(software: impl Licensed, software_two: impl Licensed) -> bool { + software.licensing_info() == software_two.licensing_info() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn compare_license_information() { + let some_software = SomeSoftware {}; + let other_software = OtherSoftware {}; + + assert!(compare_license_types(some_software, other_software)); + } + + #[test] + fn compare_license_information_backwards() { + let some_software = SomeSoftware {}; + let other_software = OtherSoftware {}; + + assert!(compare_license_types(other_software, some_software)); + } +} diff --git a/exercises/traits/traits5.rs b/exercises/traits/traits5.rs index df1838054..07bb20682 100644 --- a/exercises/traits/traits5.rs +++ b/exercises/traits/traits5.rs @@ -7,8 +7,6 @@ // Execute `rustlings hint traits5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - pub trait SomeTrait { fn some_function(&self) -> bool { true @@ -30,7 +28,7 @@ impl SomeTrait for OtherStruct {} impl OtherTrait for OtherStruct {} // YOU MAY ONLY CHANGE THE NEXT LINE -fn some_func(item: ??) -> bool { +fn some_func(item: impl SomeTrait + OtherTrait) -> bool { item.some_function() && item.other_function() } diff --git a/exercises/traits/traits5.rs~ b/exercises/traits/traits5.rs~ new file mode 100644 index 000000000..07bb20682 --- /dev/null +++ b/exercises/traits/traits5.rs~ @@ -0,0 +1,38 @@ +// traits5.rs +// +// Your task is to replace the '??' sections so the code compiles. +// +// Don't change any line other than the marked one. +// +// Execute `rustlings hint traits5` or use the `hint` watch subcommand for a +// hint. + +pub trait SomeTrait { + fn some_function(&self) -> bool { + true + } +} + +pub trait OtherTrait { + fn other_function(&self) -> bool { + true + } +} + +struct SomeStruct {} +struct OtherStruct {} + +impl SomeTrait for SomeStruct {} +impl OtherTrait for SomeStruct {} +impl SomeTrait for OtherStruct {} +impl OtherTrait for OtherStruct {} + +// YOU MAY ONLY CHANGE THE NEXT LINE +fn some_func(item: impl SomeTrait + OtherTrait) -> bool { + item.some_function() && item.other_function() +} + +fn main() { + some_func(SomeStruct {}); + some_func(OtherStruct {}); +} From 2fd4df7c02fe16479325ab6b2d230ab268c68677 Mon Sep 17 00:00:00 2001 From: humpwhale Date: Sun, 20 Apr 2025 16:23:30 +0800 Subject: [PATCH 2/2] upd --- ..gitignore.un~ | Bin 0 -> 1411 bytes .gitignore | 2 ++ .gitignore~ | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 ..gitignore.un~ create mode 100644 .gitignore~ diff --git a/..gitignore.un~ b/..gitignore.un~ new file mode 100644 index 0000000000000000000000000000000000000000..fd7e113d9e66446226b5b1a0f89affe5b359e99f GIT binary patch literal 1411 zcmWH`%$*;a=aT=FfvGPy1I0eWXvBd+ftCOm zaW3G9V}L{)EIL3DhY*29B`nfFd}IL1mLRdwNJ9=4nz4bA<_0bN!1)RmX`mt$#D)~3 Jrj5^60RZmjI643T literal 0 HcmV?d00001 diff --git a/.gitignore b/.gitignore index 88bf2b6c7..3a99923ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +*.rs~ +*.rs.un~ *.swp target/ **/*.rs.bk diff --git a/.gitignore~ b/.gitignore~ new file mode 100644 index 000000000..fd3c60ead --- /dev/null +++ b/.gitignore~ @@ -0,0 +1,18 @@ +*.rs~ +*.swp +target/ +**/*.rs.bk +.DS_Store +*.pdb +exercises/clippy/Cargo.toml +exercises/clippy/Cargo.lock +rust-project.json +.idea +.vscode/* +!.vscode/extensions.json +*.iml +*.o +public/ + +# Local Netlify folder +.netlify