CY's Take on The Weekly Challenge #118 Task 1
If you want to challenge yourself on programming, especially on Perl and/or Raku, go to https://perlweeklychallenge.org, code the latest challenges, submit codes on-time (by GitHub or email).
Do tell me, if I am wrong or you strongly oppose my statements!
It's time for challenges in Week #118 !
Task 1: Binary Palindrome
Task statement in one-line: Given a positive integer $N in base-10, determine whether it is a palindrome in base-2.
Looking at others' codes on Week #117, I have also learn the oct for a handy transform integer to base-2 string! I referred to the Perl Cookbook and use pack-unpack, which I have still not understood. Oooooops...
Let's come back to the Task 1 of this week. I implemented a &divmod similar to that in Ruby(but not OO, a big difference as Ruby is pure-OO language) and think it's useful and tiddying stuff, well.
Without testing, I proceeded to write other code components, and the codes are:
my $r = $ARGV[0] || 0; print binpali($r),"\n"; sub binpali { my @d = dec2binarr($_[0])->@*; return (join "", @d) eq (join "", reverse @d) ? 1 : 0; }sub dec2binarr { my $s = $_[0]; my $i = 0; my @digit; while ($s != 0) { ($s, $digit[$i] ) = divmod($s)->@*; $i++; } return [@digit]; }
Started test with the integer 3. The terminal output is negative. So I modified the code to see what happens. I decided to print $i in &dec2binarr and printed the binary string. The terminal gave me this string:
00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000011
And the $i ran to as large as 1077. How about $N = 2? $i ran to 1076 and also something with many zeros and end with 10. What happens?
Then I checked $digit[$i]:
# $i $digit[$i] 1 1 2 0.5 3 0.25 4 0.125 5 0.0625 #... 1066 2.52961610670718e-321 1067 1.26480805335359e-321 1068 6.32404026676796e-322 1069 3.16202013338398e-322 1070 1.58101006669199e-322 1071 7.90505033345994e-323 1072 3.95252516672997e-323 1073 1.97626258336499e-323 1074 9.88131291682493e-324 1075 4.94065645841247e-324 1076 0 00000000000000000000000 ... 00000000000000000000000 000000000 #end with 10
I think the readers are able to guess where goes wrong on my first attempt.
Initial &divmod:
sub divmod { my $num = $_[0]; return [$num / 2 , $num % 2]; }
Corrected &divmod:
sub divmod { my $num = $_[0]; return [int $num / 2 , $num % 2]; }
Finally I am back to the practice of providing test cases with Perl standard test suite (here: Test::More), for reviewers or other coders to validate my code. Initially, I tried many times with oct 0b1001001 before realizing it should be oct "0b1001001".
Stay alert and healthy! □
link for full codes: ch-1.pl
link to blogpost for Task 2 "Adventure of Knight"
Contact on twitter: @e7_87.
Created Date: 26th June, 2021; last updated: 27th June, 2021.