Mean Brazilians
Weekly challenge 157 — 21 March 2022
Week 157: 21 Mar 2022
You are given a number $n > 3
.
Write a script to output 1 if the given number is a Brazilian Number or 0 if it isn't.
A Brazilian number is a positive integer N for which a base B exists where N written in that base consists of repetitions of the same digit - excluding 11. (See Wikipedia for more info.)
Example 1: Input: $n = 7 Output: 1 Since 7 in base 2 is 111. Example 2: Input: $n = 6 Output: 0 Since 6 in base 2 is 110, 6 in base 3 is 20 and 6 in base 4 is 12. Example 3: Input: $n = 8 Output: 1 Since 8 in base 3 is 22.
My solution simply checks $n
in every base up to $n / 2
. You can stop there, because any higher base will give representations between 1x
(where x is the representation of (base - 1), eg 9 in decimal) down to 11. That means that I don't quite replicate Mohammad's example output because, for example, I don't check 6 base 4 because I know it won't be a repeating number.
And another reason for not going beyond base $n/2
is that for base $n
you need $n
symbols to represent a number. I used 0-9, A-Z, a-z
and then various symbols, giving 100 symbols and - using my algorithm - the ability to check $n
up to 301.
#!/usr/bin/perl # Peter Campbell Smith - 2022-03-22 # PWC 157 task 1 use v5.28; use strict; use warnings; use utf8; my (@tests, $n, $base, $based, $brazilian, $reason); # tests as stated in the challenge and then some more @tests = (7, 6, 8, 9, 10, 97, 98, 99, 100); # loop over numbers to be tested for $n (@tests) { $reason = ''; # loop over possible bases (see blog for why we can stop at $n / 2) for $base (2 .. int($n / 2)) { $based = base($n, $base); $brazilian = $based =~ m|^(.)\1+$|; # succeeds if the first character is followed by 1+ repeats of the same # it is, and we can stop looking if ($brazilian) { say qq[\nInput: \$n = $n\nOutput: 1\nSince $n in base $base is $based]; last; } $reason .= qq[\n $n in base $base is $based]; } # so we've been through all the bases and it isn't brazilian say qq[\nInput: \$n = $n\nOutput: 0\nSince] . substr($reason, 6) unless $brazilian; } sub base { my ($base, $digit, $digits, $integer, $result); # converts $integer to 123AB representation in base $base # nicked from week 149 task 2 ($integer, $base) = @_; $digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"£$%^&*()'; $result = ''; # strip digits 1 at a time while ($integer) { $digit = $integer % $base; $integer = ($integer - $digit) / $base; $result = substr($digits, $digit, 1) . $result; } return $result; }
Input: $n = 7 Output: 1 Since 7 in base 2 is 111 Input: $n = 6 Output: 0 Since 6 in base 2 is 110 6 in base 3 is 20 Input: $n = 8 Output: 1 Since 8 in base 3 is 22 Input: $n = 9 Output: 0 Since 9 in base 2 is 1001 9 in base 3 is 100 9 in base 4 is 21 Input: $n = 10 Output: 1 Since 10 in base 4 is 22 Input: $n = 97 Output: 0 Since 97 in base 2 is 1100001 97 in base 3 is 10121 97 in base 4 is 1201 97 in base 5 is 342 97 in base 6 is 241 97 in base 7 is 166 97 in base 8 is 141 97 in base 9 is 117 97 in base 10 is 97 97 in base 11 is 89 97 in base 12 is 81 97 in base 13 is 76 97 in base 14 is 6D 97 in base 15 is 67 97 in base 16 is 61 97 in base 17 is 5C 97 in base 18 is 57 97 in base 19 is 52 97 in base 20 is 4H 97 in base 21 is 4D 97 in base 22 is 49 97 in base 23 is 45 97 in base 24 is 41 97 in base 25 is 3M 97 in base 26 is 3J 97 in base 27 is 3G 97 in base 28 is 3D 97 in base 29 is 3A 97 in base 30 is 37 97 in base 31 is 34 97 in base 32 is 31 97 in base 33 is 2V 97 in base 34 is 2T 97 in base 35 is 2R 97 in base 36 is 2P 97 in base 37 is 2N 97 in base 38 is 2L 97 in base 39 is 2J 97 in base 40 is 2H 97 in base 41 is 2F 97 in base 42 is 2D 97 in base 43 is 2B 97 in base 44 is 29 97 in base 45 is 27 97 in base 46 is 25 97 in base 47 is 23 97 in base 48 is 21 Input: $n = 98 Output: 1 Since 98 in base 13 is 77 Input: $n = 99 Output: 1 Since 99 in base 10 is 99 Input: $n = 100 Output: 1 Since 100 in base 19 is 55
Any content of this website which has been created by Peter Campbell Smith is in the public domain