Undulating numbers

You are encouraged to solve this task according to the task description, using any language you may know.
An Undulating number in some base is a number which has the digit form ABABAB... where A and B are digits in that base.
For the purposes of this task, we shall only consider a number to be undulating if it has at least 3 digits in a given base and A != B.
- Examples
The numbers: 101 and 9898 are undulating numbers in base 10.
The numbers: 50 and 2350 are undulating numbers in base 7 because their base 7 representations are: 101 and 6565 respectively.
- Task
For base 10, find and show on this page:
1. All three digit undulating numbers.
2. All four digit undulating numbers.
3. All three digit undulating numbers which are primes.
4. The 600th undulating number.
5. How many undulating numbers are less than 2^53 and the largest such number.
- Bonus
Do the same for base 7 expressing the results in base 10 apart from 4. and 5. which should be expressed in base 7 also.
Note that undulating numbers with a given number of digits in base 7 may, of course, have less digits when expressed in base 10 and are unlikely to be still undulating. However, 121 (or 232 in base 7) is an exception to this.
- References
- Wikipedia article : Undulating number
- OEIS sequence A046075: Non-trivial undulants
ALGOL 68
As undulating numbers are relatively sparse, this counts the numbers by enumerating them.
BEGIN # show some Undulating numbers - numbers whose digits form the pattern #
# ABAB... #
LONG INT max number = LONG 2 ^ 53; # maximum number we will consider #
STRING max name = "2^53"; # "name" of max number #
# returns TRUE if n is prime, FALSE otherwise - uses trial division #
PROC is prime = ( LONG INT n )BOOL:
IF n < 3 THEN n = 2
ELIF n MOD 3 = 0 THEN n = 3
ELIF NOT ODD n THEN FALSE
ELSE
BOOL is a prime := TRUE;
INT f := 5;
INT f2 := 25;
INT to next := 24;
WHILE f2 <= n AND is a prime DO
is a prime := n MOD f /= 0;
f +:= 2;
f2 +:= to next;
to next +:= 8
OD;
is a prime
FI # is prime # ;
# returns s with comma separators #
PROC commatise = ( STRING s )STRING:
BEGIN
STRING result := "";
INT r pos := -1;
FOR s pos FROM UPB s BY -1 TO LWB s DO
IF ( r pos +:= 1 ) = 3 THEN
r pos := 0;
"," +=: result
FI;
s[ s pos ] +=: result
OD;
result
END # commatise # ;
# returns a string representation of the undulating number in base b #
# with first digit f and second digit s with d digits in total #
PROC undulating string = ( INT d, f, s, b )STRING:
BEGIN
STRING un := "";
CHAR fc = REPR ( f + ABS "0" );
CHAR sc = REPR ( s + ABS "0" );
FOR digit FROM d BY -1 TO 1 DO
IF ODD digit THEN fc ELSE sc FI +=: un
OD;
commatise( un )
END # undulating string # ;
# shows various Undulating numbers in base b #
PROC print undulation = ( INT b )VOID:
BEGIN
LONG INT un := 0;
INT un count := 0;
INT p count := 0;
INT last d := 0;
INT last f := 0;
INT last s := 0;
LONG INT last un := 0;
[ 1 : ( b - 1 ) * ( b - 1 ) ]LONG INT prime un;
FOR digits FROM 3 WHILE un < max number DO
IF digits = 3 OR digits = 4 THEN
print( ( whole( digits, 0 ), " digit Undulating Numbers in base " ) );
print( ( whole( b, 0 ) ) );
IF b /= 10 THEN print( ( " (shown in base 10)" ) ) FI;
print( ( ":", newline ) )
FI;
FOR f TO b - 1 WHILE un < max number DO
FOR s FROM 0 TO b - 1 WHILE un < max number DO
IF f /= s THEN
un := 0;
FOR d TO digits DO
un *:= b
+:= IF ODD d THEN f ELSE s FI
OD;
IF un < max number THEN
un count +:= 1;
last un := un;
last d := digits;
last f := f;
last s := s;
IF digits = 3 OR digits = 4 THEN
print( ( " ", whole( un, -digits ) ) );
IF digits = 3 THEN
IF is prime( un ) THEN
prime un[ p count +:= 1 ] := un
FI
FI
ELIF un count = 600 THEN
print( ( "Undulating number 600 in base ", whole( b, 0 ), ": " ) );
print( ( undulating string( digits, f, s, b ) ) );
IF b /= 10 THEN
print( ( newline, " which is: " ) );
print( ( commatise( whole( un, 0 ) ) ) );
print( ( " in base 10", newline ) )
FI;
print( ( newline ) )
FI
FI
FI
OD;
IF digits = 3 OR digits = 4 THEN print( ( newline ) ) FI
OD;
IF digits = 3 OR digits = 4 THEN
print( ( newline ) );
IF digits = 4 THEN
print( ( "Prime 3 digit Undulating Numbers in base " ) );
print( ( whole( b, 0 ) ) );
IF b /= 10 THEN print( ( " (shown in base 10)" ) ) FI;
print( ( ":", newline ) );
FOR i TO p count DO
print( ( whole( prime un[ i ], -4 ) ) );
IF i MOD b = ( b - 1 ) THEN print( ( newline ) ) FI
OD;
IF p count MOD b /= ( b - 1 ) THEN print( ( newline ) ) FI;
print( ( newline ) )
FI
FI
OD;
print( ( "There are ", whole( un count, 0 ) ) );
print( ( " Undulating nnumbers in base ", whole( b, 0 ), " before ", max name, newline ) );
print( ( "The last is: ", undulating string( last d, last f, last s, b ), newline ) );
IF b /= 10 THEN
print( ( " which is: ", commatise( whole( last un, 0 ) ), " in base 10", newline ) )
FI
END # print undulation # ;
print undulation( 10 ); # base 10 undulating numbers #
print( ( newline ) );
print undulation( 7 ) # base 7 undulating numbers #
END
- Output:
3 digit Undulating Numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 4 digit Undulating Numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 Prime 3 digit Undulating Numbers in base 10: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 Undulating number 600 in base 10: 4,646,464,646 There are 1125 Undulating nnumbers in base 10 before 2^53 The last is: 8,989,898,989,898,989 3 digit Undulating Numbers in base 7 (shown in base 10): 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 4 digit Undulating Numbers in base 7 (shown in base 10): 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 Prime 3 digit Undulating Numbers in base 7 (shown in base 10): 71 107 157 257 271 307 Undulating number 600 in base 7: 4,646,464,646,464,646,464 which is: 8,074,217,422,972,642 in base 10 There are 603 Undulating nnumbers in base 7 before 2^53 The last is: 5,252,525,252,525,252,525 which is: 8,786,648,372,058,464 in base 10
C++
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>
bool is_prime(uint64_t n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
for (uint64_t p = 5; p * p <= n; p += 4) {
if (n % p == 0)
return false;
p += 2;
if (n % p == 0)
return false;
}
return true;
}
class undulating_number_generator {
public:
explicit undulating_number_generator(int base) : base_(base) {}
uint64_t next() {
uint64_t n = 0;
for (int d = 0; d < digits_; ++d)
n = n * base_ + (d % 2 == 0 ? a_ : b_);
++b_;
if (a_ == b_)
++b_;
if (b_ == base_) {
++a_;
b_ = 0;
if (a_ == base_) {
a_ = 1;
++digits_;
}
}
return n;
}
private:
int base_;
int a_ = 1;
int b_ = 0;
int digits_ = 3;
};
std::string to_string(uint64_t n, int base) {
assert(base > 1 && base <= 16);
const char digits[] = "0123456789ABCDEF";
std::string str;
for (; n > 0; n /= base)
str += digits[n % base];
reverse(str.begin(), str.end());
return str;
}
void undulating(int base) {
undulating_number_generator gen(base);
uint64_t n = gen.next();
int i = 1;
uint64_t limit = base * base * base;
std::vector<uint64_t> primes;
std::cout << "3-digit undulating numbers in base " << base << ":\n";
for (; n < limit; ++i) {
std::cout << std::setw(3) << n << (i % 9 == 0 ? '\n' : ' ');
if (is_prime(n))
primes.push_back(n);
n = gen.next();
}
limit *= base;
std::cout << "\n4-digit undulating numbers in base " << base << ":\n";
for (; n < limit; ++i) {
std::cout << std::setw(4) << n << (i % 9 == 0 ? '\n' : ' ');
n = gen.next();
}
std::cout << "\n3-digit undulating numbers in base " << base
<< " which are prime:\n";
for (auto prime : primes)
std::cout << prime << ' ';
std::cout << '\n';
for (; i != 600; ++i)
n = gen.next();
std::cout << "\nThe 600th undulating number in base " << base << " is "
<< n;
if (base != 10) {
std::cout << "\nor expressed in base " << base << ": "
<< to_string(n, base);
}
std::cout << ".\n";
for (;; ++i) {
uint64_t next = gen.next();
if (next >= (1ULL << 53))
break;
n = next;
}
std::cout << "\nTotal number of undulating numbers < 2^53 in base " << base
<< ": " << i << "\nof which the largest is " << n;
if (base != 10) {
std::cout << "\nor expressed in base " << base << ": "
<< to_string(n, base);
}
std::cout << ".\n";
}
int main() {
undulating(10);
std::cout << '\n';
undulating(7);
}
- Output:
3-digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 4-digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 3-digit undulating numbers in base 10 which are prime: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is 4646464646. Total number of undulating numbers < 2^53 in base 10: 1125 of which the largest is 8989898989898989. 3-digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 4-digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 3-digit undulating numbers in base 7 which are prime: 71 107 157 257 271 307 The 600th undulating number in base 7 is 8074217422972642 or expressed in base 7: 4646464646464646464. Total number of undulating numbers < 2^53 in base 7: 603 of which the largest is 8786648372058464 or expressed in base 7: 5252525252525252525.
EasyLang
func isprim num .
i = 2
while i <= sqrt num
if num mod i = 0
return 0
.
i += 1
.
return 1
.
subr init
a_ = 1
b_ = 0
digits_ = 3
max_ = pow 2 53 - 1
.
func nxtundul .
for d = 1 to digits_
if d mod 2 = 1
n = n * 10 + a_
else
n = n * 10 + b_
.
if n > max_
return 0
.
.
b_ += 1
if a_ = b_
b_ += 1
.
if b_ = 10
a_ += 1
b_ = 0
if a_ = 10
a_ = 1
digits_ += 1
.
.
return n
.
init
while digits_ = 3
write nxtundul & " "
.
print "\n"
while digits_ = 4
write nxtundul & " "
.
print "\n"
init
while digits_ = 3
h = nxtundul
if isprim h = 1
write h & " "
.
.
print "\n"
init
for i to 600
h = nxtundul
.
print h
print ""
init
repeat
last = h
h = nxtundul
until h = 0
cnt += 1
.
print cnt & " " & last
- Output:
101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 4646464646 1125 8989898989898989
FreeBASIC
#include "isprime.bas"
Function convertToBase (n As Uinteger, b As Uinteger) As String
If n < 2 Orelse b < 2 Orelse b = 10 Orelse b > 36 Then Return Str(n)
Dim result As String = ""
Dim digit As Integer
While n > 0
digit = n Mod b
result = iIf(digit < 10, digit & result, Chr(digit + 87) & result)
n \= b
Wend
Return result
End Function
Sub PrintArray(arr() As Uinteger, ancho As Uinteger)
For i As Uinteger = 0 To Ubound(arr)
Print Using "#### "; arr(i);
If (i + 1) Mod ancho = 0 Then Print
Next
Print
End Sub
Sub Undulating(base_ As Uinteger, n As Uinteger)
Dim As Uinteger mpow = 53
Dim As Uinteger limit = 2 ^ mpow - 1
Dim As Uinteger u3(), u4(), primes(), un()
Dim As Uinteger bsquare = base_ * base_
Dim As Uinteger a, b, u, v, i
For a = 1 To base_ - 1
For b = 0 To base_ - 1
If b = a Then Continue For
u = a * bsquare + b * base_ + a
Redim Preserve u3(Ubound(u3) + 1)
u3(Ubound(u3)) = u
v = a * base_ + b
Redim Preserve u4(Ubound(u4) + 1)
u4(Ubound(u4)) = v * bsquare + v
Next
Next
Print Using "All 3 digit undulating numbers in base ##:"; base_
PrintArray(u3(), 9)
Print Using "All 4 digit undulating numbers in base ##:"; base_
PrintArray(u4(), 9)
Print Using "All 3 digit undulating numbers which are primes in base ##:"; base_
For i = 0 To Ubound(u3)
If u3(i) Mod 2 = 1 And u3(i) Mod 5 <> 0 And isPrime(u3(i)) Then
Redim Preserve primes(Ubound(primes) + 1)
primes(Ubound(primes)) = u3(i)
End If
Next
PrintArray(primes(), 10)
For i = 0 To Ubound(u3)
Redim Preserve un(Ubound(un) + 1)
un(Ubound(un)) = u3(i)
Next
For i = 0 To Ubound(u4)
Redim Preserve un(Ubound(un) + 1)
un(Ubound(un)) = u4(i)
Next
Dim unc As Uinteger = Ubound(un) + 1
Dim As Uinteger j = 0
Dim As Boolean done = False
While Not done
For i = 0 To unc - 1
u = un(j * unc + i) * bsquare + un(j * unc + i) Mod bsquare
If u > limit Then
done = True
Exit For
End If
Redim Preserve un(Ubound(un) + 1)
un(Ubound(un)) = u
Next
If done Then Exit While
j += 1
Wend
Print Using !"\nThe ###th undulating number in base & is: #,###,###,###,###,###"; n; base_; un(n - 1)
If base_ <> 10 Then Print Using "or expressed in base # : #,###,###,###,###,###,###"; base_; Cint(convertToBase(un(n-1), base_)) ''Hex(un(n - 1))
Print Using !"\nTotal number of undulating numbers in base & < 2^& = &"; base_; mpow; Ubound(un) + 1
Print Using "of which the largest is: #,###,###,###,###,###,###"; un(Ubound(un))
If base_ <> 10 Then Print Using "or expressed in base # : #,###,###,###,###,###,###"; base_; Cint(convertToBase(un(n), base_)) ''Hex(un(Ubound(un)))
Print
End Sub
Dim bases(1) As Uinteger = {10, 7}
For i As Integer = 0 To Ubound(bases)
Undulating(bases(i), 600)
Next
Sleep
- Output:
All 3 digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 All 4 digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 All 3 digit undulating numbers which are primes in base 10: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is: 4,646,464,646 Total number of undulating numbers in base 10 < 2^53 = 1125 of which the largest is: 8,989,898,989,898,989 All 3 digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 All 4 digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 All 3 digit undulating numbers which are primes in base 7: 71 107 157 257 271 307 The 600th undulating number in base 7 is: 8,074,217,422,972,642 or expressed in base 7 : 4,646,464,646,464,646,464 Total number of undulating numbers in base 7 < 2^53 = 603 of which the largest is: 8,786,648,372,058,464 or expressed in base 7 : 5,050,505,050,505,050,505
J
Inspection shows that there are 81 undulating numbers (base 10) for any given digit count, and 36 for base 7. (In other words two times the number of two digit combinations of the base minus the number of non-zero digits (or: the square of one less than the base).)
So, given:
require'stats'
undul=: {{ /:~ m #. y$"1(<:m)}.(,|."1)2 comb m }}
und10=: 10 undul
und7=: 7 undul
fmt7=: 7{{' '-.~":m&#.inv y}}
As an aside, undul could have been made more efficient, if speed was a concern, precalculating and sorting the digit pairs when the base was choosen:
undul=: {{ m {{ m #. y$"1 n}} (/:~ (<:m)}.(,|."1)2 comb m) }}
We get:
9 9$und10 3
101 121 131 141 151 161 171 181 191
202 212 232 242 252 262 272 282 292
303 313 323 343 353 363 373 383 393
404 414 424 434 454 464 474 484 494
505 515 525 535 545 565 575 585 595
606 616 626 636 646 656 676 686 696
707 717 727 737 747 757 767 787 797
808 818 828 838 848 858 868 878 898
909 919 929 939 949 959 969 979 989
9 9$und10 4
1010 1212 1313 1414 1515 1616 1717 1818 1919
2020 2121 2323 2424 2525 2626 2727 2828 2929
3030 3131 3232 3434 3535 3636 3737 3838 3939
4040 4141 4242 4343 4545 4646 4747 4848 4949
5050 5151 5252 5353 5454 5656 5757 5858 5959
6060 6161 6262 6363 6464 6565 6767 6868 6969
7070 7171 7272 7373 7474 7575 7676 7878 7979
8080 8181 8282 8383 8484 8585 8686 8787 8989
9090 9191 9292 9393 9494 9595 9696 9797 9898
(#~ 1 p:])und10 3
101 131 151 181 191 313 353 373 383 727 757 787 797 919 929
(<:600){;und10&.>3+i.>.600%81
4646464646
(#,{:)(#~ (2^53)>:]);und10&.>3+i.>.10^.2^53
1125 8989898989898989
6 7$ und7 3
50 64 71 78 85 92 100
107 121 128 135 142 150 157
164 178 185 192 200 207 214
221 235 242 250 257 264 271
278 292 300 307 314 321 328
335 50 64 71 78 85 92
6 7$ und7 4
350 450 500 550 600 650 700
750 850 900 950 1000 1050 1100
1150 1250 1300 1350 1400 1450 1500
1550 1650 1700 1750 1800 1850 1900
1950 2050 2100 2150 2200 2250 2300
2350 350 450 500 550 600 650
(#~ 1 p:])und7 3
71 107 157 257 271 307
fmt7(<:600){;und7&.>3+i.>.600%36
4646464646464646464
(#,&":' ',fmt7@{:)(#~ (2^53)>:]);und7&.>3+i.>.7^.2^53
603 5252525252525252525
Java
public final class UndulatingNumbers {
public static void main(String[] args) {
// Task - Part 1
UndulatingNumberIterator iterator = new UndulatingNumberIterator(3, 3, 10);
System.out.println("Three digit undulating numbers in base 10:");
int count = 0;
while ( iterator.hasNext() ) {
count += 1;
System.out.print(String.format("%3d%s", iterator.next(), ( ( count % 9 == 0 ) ? "\n" : " " )));
}
System.out.println();
// Task - Part 2
iterator = new UndulatingNumberIterator(4, 4, 10);
System.out.println("Four digit undulating numbers in base 10:");
count = 0;
while ( iterator.hasNext() ) {
count += 1;
System.out.print(String.format("%3d%s", iterator.next(), ( ( count % 9 == 0 ) ? "\n" : " " )));
}
System.out.println();
// Task - Part 3
iterator = new UndulatingNumberIterator(3, 3, 10);
System.out.println("Three digit undulating numbers in base 10 which are prime numbers:");
while ( iterator.hasNext() ) {
long undulatingNumber = iterator.next();
if ( isPrime(undulatingNumber) ) {
System.out.print(undulatingNumber + " ");
}
}
System.out.println(System.lineSeparator());
// Task - Part 4
iterator = new UndulatingNumberIterator(3, 100, 10);
count = 0;
while ( count < 599 && iterator.hasNext() ) {
count += 1;
iterator.next();
}
System.out.println("The 600th undulating number in base 10 is " + iterator.next());
System.out.println();
// Task - Part 5
final long TWO_POWER_53 = (long) Math.pow(2, 53);
final int maxDigitsBase10 = String.valueOf(TWO_POWER_53).length();
long number = 0;
long largest = 0;
count = 0;
iterator = new UndulatingNumberIterator(3, maxDigitsBase10, 10);
while ( iterator.hasNext() && ( number = iterator.next() ) < TWO_POWER_53 ) {
count += 1;
largest = number;
}
System.out.println("The number of undulating numbers in base 10 less than 2^53 is " + count);
System.out.println("The last undulating number in base 10 less than 2^53 is " + largest);
System.out.println();
// Bonus - Part 1
System.out.println("Three digit numbers, written in base 10, which are undulating in base 7:");
iterator = new UndulatingNumberIterator(3, 3, 7);
count = 0;
while ( iterator.hasNext() ) {
count += 1;
System.out.print(String.format("%3d%s", iterator.next(), ( ( count % 9 == 0 ) ? "\n" : " " )));
}
System.out.println();
// Bonus - Part 2
System.out.println("Four digit numbers, written in base 10, which are undulating in base 7:");
iterator = new UndulatingNumberIterator(4, 4, 7);
count = 0;
while ( iterator.hasNext() ) {
count += 1;
System.out.print(String.format("%3d%s", iterator.next(), ( ( count % 9 == 0 ) ? "\n" : " " )));
}
System.out.println();
// Bonus - Part 3
iterator = new UndulatingNumberIterator(3, 3, 7);
System.out.println("Three digit prime numbers, written in base 10, which are undulating in base 7:");
while ( iterator.hasNext() ) {
long undulatingNumber = iterator.next();
if ( isPrime(undulatingNumber) ) {
System.out.print(undulatingNumber + " ");
}
}
System.out.println(System.lineSeparator());
// Bonus - Part 4
iterator = new UndulatingNumberIterator(3, 100, 7);
count = 0;
while ( count < 599 && iterator.hasNext() ) {
count += 1;
iterator.next();
}
final long undulatingNumber = iterator.next();
System.out.println("The 600th undulating number in base 7 is " + convertToBase(7, undulatingNumber));
System.out.println("which is " + undulatingNumber + " written in base 10");
System.out.println();
// Task - Part 5
final int maxDigitsBase7 = convertToBase(7, TWO_POWER_53).length();
number = 0;
largest = 0;
count = 0;
iterator = new UndulatingNumberIterator(3, maxDigitsBase7, 7);
while ( iterator.hasNext() && ( number = iterator.next() ) < TWO_POWER_53 ) {
count += 1;
largest = number;
}
System.out.println("The number of undulating numbers in base 7 less than 2^53 is " + count);
System.out.println("The last undulating number in base 7 less than 2^53 is " + convertToBase(7, largest));
System.out.println("which is " + largest+ " written in base 10");
System.out.println();
}
private static final class UndulatingNumberIterator {
public UndulatingNumberIterator(int aMinDigits, int aMaxDigits, int aBase) {
minDigits = aMinDigits;
maxDigits = aMaxDigits;
base = aBase;
}
public boolean hasNext() {
return minDigits <= maxDigits;
}
public long next() {
long result = 0;
for ( int digit = 0; digit < minDigits; digit++ ) {
result = result * base + ( digit % 2 == 0 ? a : b );
}
b += 1;
if ( a == b ) {
b += 1;
}
if ( b == base ) {
b = 0;
a += 1;
if ( a == base ) {
a = 1;
minDigits += 1;
}
}
return result;
}
private int minDigits;
private int a = 1;
private int b = 0;
private final int base;
private final int maxDigits;
}
private static String convertToBase(int base, long number) {
if ( base < 2 || base > 10 ) {
throw new AssertionError("Base should be in the range: 2 << base << 10");
}
if ( number == 0 ) {
return "0";
}
StringBuilder result = new StringBuilder();
while ( number != 0 ) {
result.append(number % base);
number /= base;
}
return result.reverse().toString();
}
private static boolean isPrime(long number) {
if ( number < 2 ) {
return false;
}
if ( number % 2 == 0 ) {
return number == 2;
}
if ( number % 3 == 0 ) {
return number == 3;
}
for ( long p = 5; p * p <= number; p += 4 ) {
if ( number % p == 0 ) {
return false;
}
p += 2;
if ( number % p == 0 ) {
return false;
}
}
return true;
}
}
- Output:
Three digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 Four digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 Three digit undulating numbers in base 10 which are prime numbers: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is 4646464646 The number of undulating numbers in base 10 less than 2^53 is 1125 The last undulating number in base 10 less than 2^53 is 8989898989898989 Three digit numbers, written in base 10, which are undulating in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 Four digit numbers, written in base 10, which are undulating in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 Three digit prime numbers, written in base 10, which are undulating in base 7: 71 107 157 257 271 307 The 600th undulating number in base 7 is 4646464646464646464 which is 8074217422972642 written in base 10 The number of undulating numbers in base 7 less than 2^53 is 603 The last undulating number in base 7 less than 2^53 is 5252525252525252525 which is 8786648372058464 written in base 10
jq
Adapted from Wren
Also works with gojq, the Go implementation of jq.
## For the sake of gojq:
def _nwise($n):
def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
n;
## Generic functions
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
def tobase($b):
def digit: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[.:.+1];
def mod: . % $b;
def div: ((. - mod) / $b);
def digits: recurse( select(. > 0) | div) | mod ;
# For jq it would be wise to protect against `infinite` as input, but using `isinfinite` confuses gojq
select( (tostring|test("^[0-9]+$")) and 2 <= $b and $b <= 36)
| if . == 0 then "0"
else [digits | digit] | reverse[1:] | add
end;
# tabular print
def tprint(columns; wide):
reduce _nwise(columns) as $row ("";
. + ($row|map(lpad(wide)) | join(" ")) + "\n" );
def is_prime:
. as $n
| if ($n < 2) then false
elif ($n % 2 == 0) then $n == 2
elif ($n % 3 == 0) then $n == 3
elif ($n % 5 == 0) then $n == 5
elif ($n % 7 == 0) then $n == 7
elif ($n % 11 == 0) then $n == 11
elif ($n % 13 == 0) then $n == 13
elif ($n % 17 == 0) then $n == 17
elif ($n % 19 == 0) then $n == 19
else sqrt as $s
| 23
| until( . > $s or ($n % . == 0); . + 2)
| . > $s
end;
## Undulating numbers
def undulating($base; $n):
53 as $mpow
| (pow(2;$mpow) - 1) as $limit
| ($base * $base) as $bsquare
| { u3: [], u4: [] }
| reduce range(1; $base) as $a (.;
reduce range(0; $base) as $b (.;
if $b == $a then .
else ($a * $bsquare + $b * $base + $a) as $u
| .u3 += [$u]
| ($a * $base + $b) as $v
| .u4 += [$v * $bsquare + $v]
end) )
| "All 3-digit undulating numbers in base \($base):",
(.u3 | tprint(9; 4)),
"All 4-digit undulating numbers in base \($base):",
(.u4 | tprint(9; 5)),
"All 3-digit undulating numbers which are primes in base \($base):",
( .primes = []
| reduce .u3[] as $u (.;
if $u % 2 == 1 and $u % 5 != 0 and ($u | is_prime)
then .primes += [$u]
else .
end)
| (.primes | tprint(10; 4))),
( .un = (.u3 + .u4)
| (.un|length) as $unc
| .j = 0
| .i = 0
| .done = false
| until(.done;
.i = 0
| until(.i >= $unc;
(.un[.j * $unc + .i] * $bsquare + (.un[.j * $unc + .i] % $bsquare)) as $u
| if $u > $limit then .done = true | .i = $unc
else .un += [$u]
| .i += 1
end )
| .j += 1 )
| "\nThe \($n)th undulating number in base \($base) is: \(.un[$n-1])",
(select($base != 10) | "or expressed in base \($base): \(.un[$n-1] | tobase($base))"),
"\nTotal number of undulating numbers in base \($base) < 2^\($mpow) = \(.un|length)",
"of which the largest is: \(.un[-1])",
(select($base != 10) | "or expressed in base \($base): \(.un[-1]| tobase($base))")
) ;
(10, 7) as $base
| undulating($base; 600), ""
- Output:
Essentially as for Wren.
Julia
using Primes
""" An undulating number is an integer which has the digit form ABABAB... """
struct UndulatingInteger
ubase::Int
min_digits::Int
end
""" Iterate undulating numbers """
function Base.iterate(u::UndulatingInteger, state = (1, 0, u.min_digits))
a, b, n = state
i = foldl((i, j) -> u.ubase * i + (iseven(j) ? b : a), 1:n, init = 0)
b += 1
if b == a
b += 1
end
if b >= u.ubase
b = 0
a += 1
if a >= u.ubase
a = 1
n += 1
end
end
return i, (a, b, n)
end
""" Run tests on the sequence in a given base `ubase` """
function test_undulating(ubase)
println("Three digit undulating numbers in base $ubase:")
for (i, n) in enumerate(UndulatingInteger(ubase, 3))
n >= ubase^3 - 1 && break
print(lpad(n, 5), i % 9 == 0 ? "\n" : " ")
end
println("\nFour digit undulating numbers in base $ubase:")
for (i, n) in enumerate(UndulatingInteger(ubase, 4))
n >= ubase^4 - 1 && break
print(lpad(n, 5), i % 9 == 0 ? "\n" : " ")
end
println("\nThree digit undulating numbers in base $ubase which are primes:")
for (i, n) in enumerate(Iterators.filter(isprime, UndulatingInteger(ubase, 3)))
n >= ubase^3 - 1 && break
print(n, i % 20 == 0 ? "\n" : " ")
end
lastn = 0
for (i, n) in enumerate(UndulatingInteger(ubase, 3))
if i == 600
print("\n\nThe 600th undulating number in base $ubase is $n.")
elseif n > 2^53
print("\n\nNumber of undulating numbers in base $ubase less than 2^53 is ",
i - 1, "\n with the largest such number $lastn.\n\n")
break
end
lastn = n
end
end
test_undulating(10)
test_undulating(7)
- Output:
Three digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 Four digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 Three digit undulating numbers in base 10 which are primes: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is 4646464646. Number of undulating numbers in base 10 less than 2^53 is 1125 with the largest such number 8989898989898989. Three digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 Four digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 Three digit undulating numbers in base 7 which are primes: 71 107 157 257 271 307 The 600th undulating number in base 7 is 8074217422972642. Number of undulating numbers in base 7 less than 2^53 is 603 with the largest such number 8786648372058464.
Nim
import std/[algorithm, math, strutils]
func isPrime(n: Natural): bool =
## Return true if "n" is prime.
if n < 2: return false
if (n and 1) == 0: return n == 2
if n mod 3 == 0: return n == 3
var k = 5
var delta = 2
while k * k <= n:
if n mod k == 0: return false
inc k, delta
delta = 6 - delta
result = true
func toBase(n, base: Natural): string =
## Return the string representation of "n" in given base.
assert base in 2..10
var n = n
var s: seq[int]
if n == 0: return "0"
while n != 0:
s.add n mod base
n = n div base
result = reversed(s).join()
func buildNumber (a, b, n, base: int): int =
## Build an undulating number of length "n" in
## given base, returning its value in base 10.
var digits = [a, b]
var idx = 0
for i in 1..n:
result = base * result + digits[idx]
idx = 1 - idx
iterator undulatingNumbers(nStart, nEnd: Positive; base = 10): int =
## Yield the successive undulating numbers in given base (expressed in
## base 10), starting with "nStart" digits and ending with "nEnd" digits.
assert nStart >= 3, "need at least three digits."
var n = nStart
while n <= nEnd :
for a in 1..<base:
for b in 0..<base:
if b == a: continue
yield buildNumber(a, b, n, base)
inc n
### Task - Part 1 ###
echo "Three digits undulating numbers in base 10:"
var count = 0
for unum in undulatingNumbers(3, 3):
inc count
stdout.write unum
stdout.write if count mod 9 == 0: '\n' else: ' '
### Task - Part 2 ###
echo "\nFour digits undulating numbers in base 10:"
count = 0
for unum in undulatingNumbers(4, 4):
inc count
stdout.write unum
stdout.write if count mod 9 == 0: '\n' else: ' '
### Task - Part 3 ###
echo "\nThree digits undulating numbers in base 10 which are primes:"
count = 0
for unum in undulatingNumbers(3, 3):
if unum.isPrime:
inc count
stdout.write unum
stdout.write if count == 15: '\n' else: ' '
### Task - Part 4 ###
count = 0
for unum in undulatingNumbers(3, 10):
inc count
if count == 600:
echo "\nThe 600th undulating number in base 10 is ", unum
break
### Task - Part 5 ###
const N = 2^53
count = (D10 - 3) * 81 # For each number of digits, there are 9 × 9 undulating numbers.
count = (D10 - 3) * 81
var last: int
for unum in undulatingNumbers(D10, D10):
if unum < N:
inc count
last = unum
else: break
echo "\nNumber of undulating numbers in base 10 less than 2^53: ", count
echo "The last undulating number in base 10 less than 2^53 is ", last
### Bonus - Part 1 ###
echo "\nThree digits undulating numbers in base 7 (shown in base 10):"
count = 0
for unum in undulatingNumbers(3, 3, 7):
inc count
stdout.write align($unum, 3)
stdout.write if count mod 9 == 0: '\n' else: ' '
### Bonus - Part 2 ###
echo "\nFour digits undulating numbers in base 7 (shown in base 10):"
count = 0
for unum in undulatingNumbers(4, 4, 7):
inc count
stdout.write align($unum, 4)
stdout.write if count mod 9 == 0: '\n' else: ' '
### Bonus - Part 3 ###
echo "\nThree digits undulating numbers in base 7 which are primes:"
count = 0
for unum in undulatingNumbers(3, 3, 7):
if unum.isPrime:
inc count
stdout.write unum
stdout.write if count == 6: '\n' else: ' '
### Bonus - Part 4 ###
count = 0
for unum in undulatingNumbers(3, 19, 7):
inc count
if count == 600:
echo "\nThe 600th undulating number in base 7 is ", unum.toBase(7)
echo "which is ", unum, " in base 10."
break
### Bonus - Part 5 ###
const D7 = int(ln(N.toFloat) / ln(7.0)) + 1
count = (D7 - 3) * 36 # For each number of digits, there are 6 × 6 undulating numbers.
last = 0
for unum in undulatingNumbers(D7, D7, 7):
if unum < N:
inc count
last = unum
else: break
echo "\nNumber of undulating numbers in base 7 less than 2^53: ", count
echo "The last undulating number in base 7 less than 2^53 is ", last.toBase(7)
echo "which is ", last, " in base 10."
- Output:
Three digits undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 Four digits undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 Three digits undulating numbers in base 10 which are primes: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is 4646464646 Number of undulating numbers in base 10 less than 2^53: 1125 The last undulating number in base 10 less than 2^53 is 8989898989898989 Three digits undulating numbers in base 7 (shown in base 10): 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 Four digits undulating numbers in base 7 (shown in base 10): 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 Three digits undulating numbers in base 7 which are primes: 71 107 157 257 271 307 The 600th undulating number in base 7 is 4646464646464646464 which is 8074217422972642 in base 10. Number of undulating numbers in base 7 less than 2^53: 603 The last undulating number in base 7 less than 2^53 is 5252525252525252525 which is 8786648372058464 in base 10.
Perl
use v5.36;
use bigint;
use experimental <builtin for_list>;
use ntheory <is_prime vecfirstidx>;
sub X ($a, $b) { my @c; for my $aa (0..$a) { for my $bb (0..$b) { push @c, $aa, $bb } } @c }
sub table ($c, @V) { my $t = $c * (my $w = 6); ( sprintf( ('%'.$w.'d')x@V, @V) ) =~ s/.{1,$t}\K/\n/gr }
my $max = 2**53;
my(@pairs,@U);
for my($i,$j) ( X(9,9) ) { push @pairs, $i . $j unless $i == 0 || $i == $j }
for my $l (3..length $max) {
if (0 == $l%2) { push @U, "$_"x( $l /2) for @pairs }
else { push @U, "$_"x(($l+1)/2) and chop $U[-1] for @pairs }
}
say "All 3 digit undulating numbers:"; say table 9, grep { 3 == length $_ } @U;
say "All 3 digit undulating primes:"; say table 9, grep { 3 == length $_ and is_prime $_ } @U;
say "All 4 digit undulating numbers:"; say table 9, grep { 4 == length $_ } @U;
my $fmt = "%34s: %d\n";
printf $fmt, 'The 600th undulating number is', $U[599];
printf $fmt, 'Undulating numbers less than 2**53', (my $i = vecfirstidx { $_ >= $max } @U);
printf $fmt, 'That number is', $U[$i-1];
- Output:
All 3 digit undulating numbers: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 All 3 digit undulating primes: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 All 4 digit undulating numbers: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 The 600th undulating number is: 4646464646 Undulating numbers less than 2**53: 1125 That number is: 8989898989898989
Phix
with javascript_semantics for base in {10,7} do integer n = 600, mpow = 53, bsquare = base * base atom limit = power(2,53)-1 sequence u3 = {}, u4 = {} for a=1 to base-1 do for b=0 to base-1 do if b!=a then integer u = a * base + b, v = u * base + a, w = v * base + b u3 &= v u4 &= w end if end for end for for d,u in {{u3,"%3d"},{u4,"%4d"}} do printf(1,"All %d digit undulating numbers in base %d:\n%s\n", {d+2,base,join_by(u[1],1,9," ",fmt:=u[2])}) end for printf(1,"All 3 digit undulating numbers which are primes in base %d:\n%s\n", {base,join_by(filter(u3,is_prime),1,10," ",fmt:="%3d")}) sequence un = u3 & u4 integer start = 1, done = false while not done do integer finish = length(un) for i=start to finish do atom u = un[i] * bsquare + remainder(un[i],bsquare) if u>limit then done = true; exit end if un &= u end for start = finish+1 end while printf(1,"The %,d%s undulating number in base %d is: %,d\n", {n,ord(n),base,un[n]}) if base!=10 then printf(1,"or expressed in base %d : %,a\n", {base,{base,un[n]}}) end if printf(1,"\nTotal number of undulating numbers in base %d < 2^%d = %,d\n",{base,mpow,length(un)}) printf(1,"of which the largest is: %,d\n", un[$]) if base!=10 then printf(1,"or expressed in base %d : %,a\n", {base,{base,un[$]}}) end if printf(1,"\n") end for
Output same as Wren, except for "⁵³"->"^53". Note that comma-fill on %a under p2js needs a trivial fix ("df".indexOf->"aAdf".indexOf)/1.0.3 or later.
Python
from sympy import isprime
from collections import deque
def to_base(n: int, base: int):
digits = deque()
while n > 0:
digits.appendleft(str(n % base))
n //= base
return int(''.join(digits))
def t_print(nums: list[int], cols: int):
for i, n in enumerate(nums):
if i % cols == 0 and i != 0:
print()
print('%d' % n, end=' ')
print()
def undulating(base: int, n: int):
mpow = 53
limit = pow(2, mpow) - 1
u3 = []
u4 = []
bsquare = base * base
for a in range(1, base):
for b in range(0, base):
if (b == a):
continue
u = a * bsquare + b * base + a
u3.append(u)
v = a * base + b
u4.append(v * bsquare + v)
print(f"All 3 digit undulating numbers in base {base}:")
t_print(u3, 9)
print(f"\nAll 4 digit undulating numbers in base {base}:")
t_print(u4, 9)
print(f"\nAll 3 digit undulating numbers which are primes in base {base}:")
primes = [
u
for u in u3
if u % 2 == 1 and u % 5 != 0 and isprime(u)
]
t_print(primes, 9)
un = u3 + u4
unc = len(un)
j = 0
done = False
while True:
for i in range(0, unc):
u = un[j * unc + i] * bsquare + un[j * unc + i] % bsquare
if u > limit:
done = True
break
un.append(u)
if done:
break
j += 1
print("\nThe {:,} undulating number in base {:} is: {:,}".format(n, base, un[n-1]))
if (base != 10):
print("or expressed in base {:} : {:,}".format(base, to_base(un[n-1], base)))
print("\nTotal number of undulating numbers in base {:} < {:} = {:,} ".format(base, mpow, len(un)), end='')
print("of which the largest is: {:,}".format(un[-1]))
if (base != 10):
print("or expressed in base {:} : {:,}".format(base, to_base(un[-1], base)))
def main():
for base in [10, 7]:
undulating(base, 600)
if __name__ == '__main__':
main()
- Output:
All 3 digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 All 4 digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 All 3 digit undulating numbers which are primes in base 10: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600 undulating number in base 10 is: 4,646,464,646 Total number of undulating numbers in base 10 < 53 = 1,125 of which the largest is: 8,989,898,989,898,989 All 3 digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 All 4 digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 All 3 digit undulating numbers which are primes in base 7: 71 107 157 257 271 307 The 600 undulating number in base 7 is: 8,074,217,422,972,642 or expressed in base 7 : 4,646,464,646,464,646,464 Total number of undulating numbers in base 7 < 53 = 603 of which the largest is: 8,786,648,372,058,464 or expressed in base 7 : 5,252,525,252,525,252,525
Raku
# 20230602 Raku programming solution
sub undulating ($base, \n) {
my \limit = 2**(my \mpow = 53) - 1;
my (\bsquare,@u3,@u4) = $base*$base;
for 1..^$base X 0..^$base -> (\a,\b) {
next if b == a;
@u3.push(a * bsquare + b * $base + a);
@u4.push((my \v = a * $base + b) * bsquare + v)
}
say "\nAll 3 digit undulating numbers in base $base:";
.fmt('%3d').say for @u3.rotor: 9;
say "\nAll 4 digit undulating numbers in base $base:";
.fmt('%4d').say for @u4.rotor: 9;
say "\nAll 3 digit undulating numbers which are primes in base $base:";
my @primes = @u3.grep: *.is-prime;
.fmt('%3d').say for @primes.rotor: 10, :partial;
my \unc = (my @un = @u3.append: @u4).elems;
my ($j, $done) = 0, False;
loop {
for 0..^unc {
my \u = @un[$j * unc + $_] * bsquare + @un[$j * unc + $_] % bsquare;
u > limit ?? ( $done = True and last ) !! ( @un.push: u );
}
$done ?? ( last ) !! $j++
}
say "\nThe {n} undulating number in $base $base is: @un[n-1]";
say "or expressed in base $base : {@un[n-1].base($base)}" unless $base == 10;
say "\nTotal number of undulating numbers in base $base < 2**{mpow} = {+@un}";
say "of which the largest is: ", @un[*-1];
say "or expressed in base $base : {@un[*-1].base($base)}" unless $base == 10;
}
undulating $_, 600 for 10, 7;
You may Try it online!
RPL
Once found the direct formula, the code is fairly simple to write.
« 1 - → n « n 81 MOD 9 / FLOOR 1 + @ A = mod(N-1,81)//9 + 1 n 9 MOD DUP2 ≤ + @ B = mod(N-1,9) + (A ≤ mod(N-1,9)) →STR + n 81 / FLOOR 3 + SWAP WHILE DUP2 SIZE > REPEAT DUP + END 1 ROT SUB STR→ @ reduce # of digits to N//81 + 3 » » 'N→UND' STO « « n N→UND » 'n' 1 81 1 SEQ « n N→UND » 'n' 82 162 1 SEQ { } 1 4 PICK SIZE FOR j PICK3 j GET IF DUP ISPRIME? THEN + ELSE DROP END NEXT 625 N→UND 2 53 ^ 0 DO 1 + UNTIL DUP2 N→UND < END 1 - NIP DUP N→UND » 'TASK' STO
- Output:
6: { 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 } 5: { 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 } 4: { 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 } 3: 4646464646 2: 1125 1: 8989898989898989
Rust
// [dependencies]
// radix_fmt = "1.0"
fn is_prime(n: u64) -> bool {
if n < 2 {
return false;
}
if n % 2 == 0 {
return n == 2;
}
if n % 3 == 0 {
return n == 3;
}
let mut p: u64 = 5;
while p * p <= n {
if n % p == 0 {
return false;
}
p += 2;
if n % p == 0 {
return false;
}
p += 4;
}
true
}
fn undulating_numbers(base: u64) -> impl std::iter::Iterator<Item = u64> {
let mut a = 1;
let mut b = 0;
let mut digits = 3;
std::iter::from_fn(move || {
let mut n = 0;
for d in 0..digits {
n = n * base + if d % 2 == 0 { a } else { b };
}
b += 1;
if a == b {
b += 1;
}
if b == base {
a += 1;
b = 0;
if a == base {
a = 1;
digits += 1;
}
}
Some(n)
})
}
fn undulating(base: u64) {
let mut count = 0;
let limit3 = base * base * base;
let limit4 = base * limit3;
let mut u3 = Vec::new();
let mut u4 = Vec::new();
let mut umax = 0;
let mut u600 = 0;
for n in undulating_numbers(base).take_while(|x| *x < 1u64 << 53) {
if n < limit3 {
u3.push(n);
} else if n < limit4 {
u4.push(n);
}
count += 1;
umax = n;
if count == 600 {
u600 = n;
}
}
println!("3-digit undulating numbers in base {}:", base);
for (i, n) in u3.iter().enumerate() {
print!("{:3}{}", n, if (i + 1) % 9 == 0 { '\n' } else { ' ' });
}
println!("\n4-digit undulating numbers in base {}:", base);
for (i, n) in u4.iter().enumerate() {
print!("{:4}{}", n, if (i + 1) % 9 == 0 { '\n' } else { ' ' });
}
println!(
"\n3-digit undulating numbers in base {} which are prime:",
base
);
for n in u3 {
if is_prime(n) {
print!("{} ", n);
}
}
println!();
print!("\nThe 600th undulating number in base {} is {}", base, u600);
if base != 10 {
print!(
"\nor expressed in base {}: {}",
base,
radix_fmt::radix(u600, base as u8)
);
}
println!(".");
print!(
"\nTotal number of undulating numbers < 2^53 in base {}: {}\nof which the largest is {}",
base, count, umax
);
if base != 10 {
print!(
"\nor expressed in base {}: {}",
base,
radix_fmt::radix(umax, base as u8)
);
}
println!(".");
}
fn main() {
undulating(10);
println!();
undulating(7);
}
- Output:
3-digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 4-digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 3-digit undulating numbers in base 10 which are prime: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is 4646464646. Total number of undulating numbers < 2^53 in base 10: 1125 of which the largest is 8989898989898989. 3-digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 4-digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 3-digit undulating numbers in base 7 which are prime: 71 107 157 257 271 307 The 600th undulating number in base 7 is 8074217422972642 or expressed in base 7: 4646464646464646464. Total number of undulating numbers < 2^53 in base 7: 603 of which the largest is 8786648372058464 or expressed in base 7: 5252525252525252525.
Uiua
More of a script than a program, and only for base 10 as there's no built-in support for other radixes in Uiua yet.
# Generate all distinct two digit numbers as strings.
≡(°⋕)▽≡(≠0◿11).↘10⇡100
&p≡(⋕⊂⟜⊢) . &pf "Three digits: "
&p≡(⋕⊂.) . &pf "Four digits: "
≡(⋕⊂⟜⊢) . &pf "Three digit primes: "
# Primes by sieve.
⇌◌⍢(▽≠0◿⊃⊢(.↘1)⟜(⊂⊢)|>0⧻)↘2⇡1000[]
&p▽:⟜(/+⍉⊞⌕):
# Collect all 3 and 4 digit numbers.
⊂⊃≡(⋕⊂⟜⊢)≡(⋕⊂.)
# Double-up last two digits of each and remove the ensuing duplicates.
F ← ◴⊂⟜≡(⋕⊂⟜(↙¯2)°⋕)
# Repeat until length is okay.
⍢(F|<600⧻)
&p⊡599 . &pf "Six hundredth: "
# Repeat until last is larger than target.
⍢(F|<ⁿ53 2⊡¯1)
&p⧻.▽<ⁿ53 2. &pf "Count less than 2^53: "
&p⊡¯1⊏⍏. &pf "Last one less than 2^53: "
- Output:
Three digits: [101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989] Four digits: [1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898] Three digit primes: [101 131 151 181 191 313 353 373 383 727 757 787 797 919 929] Six hundredth: 4646464646 Count less than 2^53: 1125 Last one less than 2^53: 8989898989898989
Wren
import "./fmt" for Fmt, Conv
import "./math" for Int
var undulating = Fn.new { |base, n|
var mpow = 53
var limit = 2.pow(mpow) - 1
var u3 = []
var u4 = []
var bsquare = base * base
for (a in 1...base) {
for (b in 0...base) {
if (b == a) continue
var u = a * bsquare + b * base + a
u3.add(u)
var v = a * base + b
u4.add(v * bsquare + v)
}
}
System.print("All 3 digit undulating numbers in base %(base):")
Fmt.tprint("$3d ", u3, 9)
System.print("\nAll 4 digit undulating numbers in base %(base):")
Fmt.tprint("$4d ", u4, 9)
System.print("\nAll 3 digit undulating numbers which are primes in base %(base):")
var primes = []
for (u in u3) {
if (u % 2 == 1 && u % 5 != 0 && Int.isPrime(u)) primes.add(u)
}
Fmt.tprint("$3d ", primes, 10)
var un = u3 + u4
var unc = un.count
var j = 0
var done = false
while (true) {
for (i in 0...unc) {
var u = un[j * unc + i] * bsquare + un[j * unc + i] % bsquare
if (u > limit) {
done = true
break
}
un.add(u)
}
if (done) break
j = j + 1
}
Fmt.print("\nThe $,r undulating number in base $d is: $,d", n, base, un[n-1])
if (base != 10) Fmt.print("or expressed in base $d : $,s", base, Conv.itoa(un[n-1], base))
Fmt.print("\nTotal number of undulating numbers in base $d < 2$S = $,d", base, mpow, un.count)
Fmt.print("of which the largest is: $,d", un[-1])
if (base != 10) Fmt.print("or expressed in base $d : $,s", base, Conv.itoa(un[-1], base))
System.print()
}
for (base in [10, 7]) undulating.call(base, 600)
- Output:
All 3 digit undulating numbers in base 10: 101 121 131 141 151 161 171 181 191 202 212 232 242 252 262 272 282 292 303 313 323 343 353 363 373 383 393 404 414 424 434 454 464 474 484 494 505 515 525 535 545 565 575 585 595 606 616 626 636 646 656 676 686 696 707 717 727 737 747 757 767 787 797 808 818 828 838 848 858 868 878 898 909 919 929 939 949 959 969 979 989 All 4 digit undulating numbers in base 10: 1010 1212 1313 1414 1515 1616 1717 1818 1919 2020 2121 2323 2424 2525 2626 2727 2828 2929 3030 3131 3232 3434 3535 3636 3737 3838 3939 4040 4141 4242 4343 4545 4646 4747 4848 4949 5050 5151 5252 5353 5454 5656 5757 5858 5959 6060 6161 6262 6363 6464 6565 6767 6868 6969 7070 7171 7272 7373 7474 7575 7676 7878 7979 8080 8181 8282 8383 8484 8585 8686 8787 8989 9090 9191 9292 9393 9494 9595 9696 9797 9898 All 3 digit undulating numbers which are primes in base 10: 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929 The 600th undulating number in base 10 is: 4,646,464,646 Total number of undulating numbers in base 10 < 2⁵³ = 1,125 of which the largest is: 8,989,898,989,898,989 All 3 digit undulating numbers in base 7: 50 64 71 78 85 92 100 107 121 128 135 142 150 157 164 178 185 192 200 207 214 221 235 242 250 257 264 271 278 292 300 307 314 321 328 335 All 4 digit undulating numbers in base 7: 350 450 500 550 600 650 700 750 850 900 950 1000 1050 1100 1150 1250 1300 1350 1400 1450 1500 1550 1650 1700 1750 1800 1850 1900 1950 2050 2100 2150 2200 2250 2300 2350 All 3 digit undulating numbers which are primes in base 7: 71 107 157 257 271 307 The 600th undulating number in base 7 is: 8,074,217,422,972,642 or expressed in base 7 : 4,646,464,646,464,646,464 Total number of undulating numbers in base 7 < 2⁵³ = 603 of which the largest is: 8,786,648,372,058,464 or expressed in base 7 : 5,252,525,252,525,252,525