Решение на Network Packets от Стефан Чолаков
Резултати
- 15 точки от тестове
- 0 бонус точки
- 15 точки общо
- 11 успешни тест(а)
- 4 неуспешни тест(а)
Код
Лог от изпълнението
Compiling solution v0.1.0 (/tmp/d20200111-2173579-iutls9/solution) Finished test [unoptimized + debuginfo] target(s) in 3.68s Running target/debug/deps/solution-a73e64ec87929bd0 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/solution_test-38971695424b36d5 running 15 tests test solution_test::test_construct_packet_from_unicode ... ok test solution_test::test_construct_packet_no_remainder ... ok test solution_test::test_construct_packet_with_remainder ... ok test solution_test::test_construct_packet_with_remainder_cyrillic ... ok test solution_test::test_consuming_packets ... thread '<unnamed>' panicked at 'assertion failed: `(left == right)` left: `"bazbar foo "`, right: `"foo bar baz"`', tests/solution_test.rs:204:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. FAILED test solution_test::test_deserialize_invalid_packet ... ok test solution_test::test_deserialize_packet ... ok test solution_test::test_deserialize_unicode_packet ... ok test solution_test::test_full_roundtrip ... thread '<unnamed>' panicked at 'assertion failed: `(left == right)` left: `"foo bar baz"`, right: `"foo bar ba"`', tests/solution_test.rs:215:9 FAILED test solution_test::test_full_roundtrip_for_zero_size_string ... thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidPacket', src/libcore/result.rs:1165:5 FAILED test solution_test::test_invalid_packet_combination ... ok test solution_test::test_iterating_packets ... thread '<unnamed>' panicked at 'assertion failed: `(left == right)` left: `[98, 97, 122]`, right: `[102, 111, 111, 32]`', tests/solution_test.rs:178:9 FAILED test solution_test::test_iterating_packets_for_zero_size_string ... ok test solution_test::test_serialize_packet ... ok test solution_test::test_zero_size ... ok failures: ---- solution_test::test_consuming_packets stdout ---- thread 'main' panicked at 'assertion failed: `(left == right)` left: `"bazbar foo "`, right: `"foo bar baz"`', tests/solution_test.rs:197:5 ---- solution_test::test_full_roundtrip stdout ---- thread 'main' panicked at 'assertion failed: `(left == right)` left: `"foo bar baz"`, right: `"foo bar ba"`', tests/solution_test.rs:210:5 ---- solution_test::test_full_roundtrip_for_zero_size_string stdout ---- thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidPacket', tests/solution_test.rs:221:5 ---- solution_test::test_iterating_packets stdout ---- thread 'main' panicked at 'assertion failed: `(left == right)` left: `[98, 97, 122]`, right: `[102, 111, 111, 32]`', tests/solution_test.rs:172:5 failures: solution_test::test_consuming_packets solution_test::test_full_roundtrip solution_test::test_full_roundtrip_for_zero_size_string solution_test::test_iterating_packets test result: FAILED. 11 passed; 4 failed; 0 ignored; 0 measured; 0 filtered out error: test failed, to rerun pass '--test solution_test'
История (6 версии и 4 коментара)
Стефан качи решение на 28.11.2019 22:46 (преди почти 6 години)
Стефан качи решение на 29.11.2019 11:54 (преди почти 6 години)
Стефан качи решение на 29.11.2019 16:51 (преди почти 6 години)
Стефан качи решение на 29.11.2019 16:52 (преди почти 6 години)
Стефан качи решение на 02.12.2019 18:13 (преди почти 6 години)
Това е ок, и работи, но можеше да използваш стандартната функция u32::from_be_bytes()
.
Единия от бъговете ти идва тук -- метода pop
премахва елемент от края на вектора, а метода push
добавя елементи към края. Ти използваш тези два метода, което кара вектора ти да се държи като стек, и резултата излиза наобратно.
Тук би могъл да викнеш .remove(0)
и да минат още 3 теста. Ако искаш да поддържаш ефективност, можеш да използваш std::collections::VecDeque
вместо вектор.
Тук е другия ти бъг, но честно казано не мога да го намеря, понеже кода е твърде сложен :). Off-by-one грешка е, което е често срещана ситуация. Наистина, най-лесния начин да избягваш бъгове е да пишеш прост код, но може да е предизвикателно, admittedly.
Целта на Packet::from_source
беше да се използва итеративно. Ако вместо да пазиш вектор от пакети, си пазеше slice-а от байтове, можеше да си улесниш доста живота като го викаш в цикъл върху това, което връща като "остатък". Ето моята имплементация:
impl<'a> Iterator for PacketSerializer<'a> {
type Item = Packet<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.source.len() == 0 {
return None;
}
let (packet, remainder) = Packet::from_source(self.source, self.packet_size);
self.source = remainder;
Some(packet)
}
}
Оттам нататък, .to_packets
се свежда просто до:
fn to_packets(&self, packet_size: u8) -> PacketSerializer {
PacketSerializer { source: self.as_bytes(), packet_size }
}
Дори да предпочиташ да си направиш вектор, който да подадеш на итератора, това пак щеше да може да се направи със същата логика преместена в .to_packets
.
Разбира се, не искаме всички да пишат едни и същи решения, и не очакваме да "познаете" как сме решили ние проблема. Но в някои отношения е добре да се вгледаш в инструментите, които ти дава интерфейса и да се възползваш от тях. Ти конструираш пакет, но остатъка който се връща го игнорираш напълно. Опитваш се да изчислиш "истинския" packet size, но метода .from_source
вече го прави.
Имаш някои бъгове, но повечето код работи. Главния проблем според мен е, че не си се възползвал от функциите, които вече имаш, било то от собствения си код, било то от стандартната библиотека. Опитал си се да решиш много проблеми "на ръка" които можеше да решиш по-лесно. Огледай останалите решения за вдъхновение.
Това е ок, и работи, но можеше да използваш стандартната функция
u32::from_be_bytes()
.Единия от бъговете ти идва тук -- метода
pop
премахва елемент от края на вектора, а методаpush
добавя елементи към края. Ти използваш тези два метода, което кара вектора ти да се държи като стек, и резултата излиза наобратно.Тук би могъл да викнеш
.remove(0)
и да минат още 3 теста. Ако искаш да поддържаш ефективност, можеш да използвашstd::collections::VecDeque
вместо вектор.Тук е другия ти бъг, но честно казано не мога да го намеря, понеже кода е твърде сложен :). Off-by-one грешка е, което е често срещана ситуация. Наистина, най-лесния начин да избягваш бъгове е да пишеш прост код, но може да е предизвикателно, admittedly.
Целта на
Packet::from_source
беше да се използва итеративно. Ако вместо да пазиш вектор от пакети, си пазеше slice-а от байтове, можеше да си улесниш доста живота като го викаш в цикъл върху това, което връща като "остатък". Ето моята имплементация:Оттам нататък,
.to_packets
се свежда просто до:Дори да предпочиташ да си направиш вектор, който да подадеш на итератора, това пак щеше да може да се направи със същата логика преместена в
.to_packets
.Разбира се, не искаме всички да пишат едни и същи решения, и не очакваме да "познаете" как сме решили ние проблема. Но в някои отношения е добре да се вгледаш в инструментите, които ти дава интерфейса и да се възползваш от тях. Ти конструираш пакет, но остатъка който се връща го игнорираш напълно. Опитваш се да изчислиш "истинския" packet size, но метода
.from_source
вече го прави.