Upside-down numbers: Difference between revisions
Content added Content deleted
(→{{header|Python}}: prepend Free Pascal version) |
(Added Wren) |
||
Line 239: | Line 239: | ||
Five hundred thousandth: 729,664,644,183 |
Five hundred thousandth: 729,664,644,183 |
||
Five millionth: 82,485,246,852,682</pre> |
Five millionth: 82,485,246,852,682</pre> |
||
=={{header|Wren}}== |
|||
{{trans|Python}} |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="ecmascript">import "./fmt" for Fmt |
|||
var genUpsideDown = Fiber.new { |
|||
var wrappings = [ |
|||
[1, 9], [2, 8], [3, 7], [4, 6], [5, 5], |
|||
[6, 4], [7, 3], [8, 2], [9, 1] |
|||
] |
|||
var evens = [19, 28, 37, 46, 55, 64, 73, 82, 91] |
|||
var odds = [5] |
|||
var oddIndex = 0 |
|||
var evenIndex = 0 |
|||
var ndigits = 1 |
|||
var pow = 100 |
|||
while (true) { |
|||
if (ndigits % 2 == 1) { |
|||
if (odds.count > oddIndex) { |
|||
Fiber.yield(odds[oddIndex]) |
|||
oddIndex = oddIndex + 1 |
|||
} else { |
|||
// build next odds, but switch to evens |
|||
var nextOdds = [] |
|||
for (w in wrappings) { |
|||
for (i in odds) { |
|||
nextOdds.add(w[0] * pow + i * 10 + w[1]) |
|||
} |
|||
} |
|||
odds = nextOdds |
|||
ndigits = ndigits + 1 |
|||
pow = pow * 10 |
|||
oddIndex = 0 |
|||
} |
|||
} else { |
|||
if (evens.count > evenIndex) { |
|||
Fiber.yield(evens[evenIndex]) |
|||
evenIndex = evenIndex + 1 |
|||
} else { |
|||
// build next evens, but switch to odds |
|||
var nextEvens = [] |
|||
for (w in wrappings) { |
|||
for (i in evens) { |
|||
nextEvens.add(w[0] * pow + i * 10 + w[1]) |
|||
} |
|||
} |
|||
evens = nextEvens |
|||
ndigits = ndigits + 1 |
|||
pow = pow * 10 |
|||
evenIndex = 0 |
|||
} |
|||
} |
|||
} |
|||
} |
|||
var limit = 5000000 |
|||
var count = 0 |
|||
var ud50s = [] |
|||
var pow = 50 |
|||
while (count < limit) { |
|||
var n = genUpsideDown.call() |
|||
count = count + 1 |
|||
if (count < 50) { |
|||
ud50s.add(n) |
|||
} else if (count == 50) { |
|||
System.print("First 50 upside down numbers:") |
|||
Fmt.tprint("$,5d", ud50s + [n], 10) |
|||
System.print() |
|||
pow = 500 |
|||
} else if (count == pow) { |
|||
Fmt.print("$,r : $,d", pow, n) |
|||
pow = pow * 10 |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
First 50 upside down numbers: |
|||
5 19 28 37 46 55 64 73 82 91 |
|||
159 258 357 456 555 654 753 852 951 1,199 |
|||
1,289 1,379 1,469 1,559 1,649 1,739 1,829 1,919 2,198 2,288 |
|||
2,378 2,468 2,558 2,648 2,738 2,828 2,918 3,197 3,287 3,377 |
|||
3,467 3,557 3,647 3,737 3,827 3,917 4,196 4,286 4,376 4,466 |
|||
500th : 494,616 |
|||
5,000th : 56,546,545 |
|||
50,000th : 6,441,469,664 |
|||
500,000th : 729,664,644,183 |
|||
5,000,000th : 82,485,246,852,682 |
|||
</pre> |
Revision as of 11:18, 14 February 2023
Upside-down numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
An upside-down number is a positive base 10 integer whose i-th leftmost and i-th rightmost digits are complements, i.e., their sum is 10.
- For example
7165493 is an upside-down number. 7 + 3 = 10 1 + 9 = 10 6 + 4 = 10 5 + 5 = 10
From that definition it follows that an upside-down number cannot contain any zeros, and if there is an odd number of digits, then the center digit must be a 5.
- Task
- Write a routine to find (or generate) upside-down numbers.
- Find and show the first 50 upside-down numbers.
- Find and show the five hundredth upside-down number.
- Find and show the five thousandth upside-down number.
- Stretch
- Find and show the fifty thousandth, five hundred thousandth, five millionth upside-down number.
- See also
Pascal
Free Pascal
extended to 50E6
program UpSideDownNumbers;
{$IFDEF FPC}{$MODE DELPHI}{$Optimization ON,All}{$ENDIF}
{$IFDEF Windows}{$APPTYPE CONSOLE}{$ENDIF}
const
middle = 5;
var
Upperhalf : array[0..15] of Int32;
function CalcUpDownNumber(dgtCnt:Int32):Uint64;
var
i,dc : Int32;
begin
dc := (dgtCnt DIV 2) -1;
result := 0;
For i := dc downto 0 do
result := result*10+Upperhalf[i];
if Odd(dgtCnt) then
result := result*10+middle;
For i := 0 to dc do
result := result*10+(10-Upperhalf[i]);
end;
procedure NextNumb(var dgtCnt:UInt32);
var
i,dc,dgt : Uint32;
begin
dc:= DgtCnt;
IF dc= 0 then
begin
dgtcnt := 1;
EXIT;
end;
IF dc= 1 then
begin
Upperhalf[0] := 1;
dgtCnt := 2;
EXIT;
end;
i := 0;
dc := dc DIV 2-1;
repeat
dgt := Upperhalf[i]+1;
if dgt <10 then
begin
Upperhalf[i] := dgt;
BREAK;
end;
Upperhalf[i] := 1;
inc(i);
until i > dc;
if i > dc then
Begin
For i := 0 to dc+1 do
Upperhalf[i]:= 1;
inc(dgtcnt);
Upperhalf[i] :=1;
end;
end;
var
dgtcnt,
Count,
limit : UInt32;
Begin
Count := 0;
limit := 50;
Writeln('First fifty upside-downs:');
repeat
repeat
NextNumb(dgtCnt);
inc(Count);
IF Count<= 50 then
Begin
write(CalcUpDownNumber(dgtCnt):5);
if Count MOD 10 = 0 then
writeln;
end;
until Count>= limit;
if limit <> 50 then
writeln(limit:10,CalcUpDownNumber(dgtCnt):20)
else
writeln;
limit := limit*10;
until limit> 50*1000*1000;
end.
- @TIO.RUN:
First fifty upside-downs: 5 19 28 37 46 55 64 73 82 91 159 258 357 456 555 654 753 852 951 1199 1289 1379 1469 1559 1649 1739 1829 1919 2198 2288 2378 2468 2558 2648 2738 2828 2918 3197 3287 3377 3467 3557 3647 3737 3827 3917 4196 4286 4376 4466 500 494616 5000 56546545 50000 6441469664 500000 729664644183 5000000 82485246852682 50000000 9285587463255281 User time: 0.310 s CPU share: 99.30 %
""" rosettacode.org task Upside-down_numbers """
def gen_upside_down_number():
""" generate upside-down numbers (OEIS A299539) """
wrappings = [[1, 9], [2, 8], [3, 7], [4, 6],
[5, 5], [6, 4], [7, 3], [8, 2], [9, 1]]
evens = [19, 28, 37, 46, 55, 64, 73, 82, 91]
odds = [5]
odd_index, even_index = 0, 0
ndigits = 1
while True:
if ndigits % 2 == 1:
if len(odds) > odd_index:
yield odds[odd_index]
odd_index += 1
else:
# build next odds, but switch to evens
odds = sorted([hi * 10**(ndigits + 1) + 10 *
i + lo for i in odds for hi, lo in wrappings])
ndigits += 1
odd_index = 0
else:
if len(evens) > even_index:
yield evens[even_index]
even_index += 1
else:
# build next evens, but switch to odds
evens = sorted([hi * 10**(ndigits + 1) + 10 *
i + lo for i in evens for hi, lo in wrappings])
ndigits += 1
even_index = 0
print('First fifty upside-downs:')
for (udcount, udnumber) in enumerate(gen_upside_down_number()):
if udcount < 50:
print(f'{udnumber : 5}', end='\n' if (udcount + 1) % 10 == 0 else '')
elif udcount == 499:
print(f'\nFive hundredth: {udnumber: ,}')
elif udcount == 4999:
print(f'\nFive thousandth: {udnumber: ,}')
elif udcount == 49_999:
print(f'\nFifty thousandth: {udnumber: ,}')
elif udcount == 499_999:
print(f'\nFive hundred thousandth: {udnumber: ,}')
elif udcount == 4_999_999:
print(f'\nFive millionth: {udnumber: ,}')
break
- Output:
First fifty upside-downs: 5 19 28 37 46 55 64 73 82 91 159 258 357 456 555 654 753 852 951 1199 1289 1379 1469 1559 1649 1739 1829 1919 2198 2288 2378 2468 2558 2648 2738 2828 2918 3197 3287 3377 3467 3557 3647 3737 3827 3917 4196 4286 4376 4466 Five hundredth: 494,616 Five thousandth: 56,546,545 Fifty thousandth: 6,441,469,664 Five hundred thousandth: 729,664,644,183 Five millionth: 82,485,246,852,682
Raku
use Lingua::EN::Numbers;
sub udgen (@r) {
my @u = @r.hyper.map: { next if .contains: 0; ($_, (10 «-« .flip.comb).join) };
@u».join, @u».join(5)
}
my @upside-downs = lazy flat 5, (^∞).map({ udgen exp($_,10) .. exp(1+$_,10) });
say "First fifty upside-downs:\n" ~ @upside-downs[^50].batch(10)».fmt("%4d").join: "\n";
say '';
for 5e2, 5e3, 5e4, 5e5, 5e6 {
say "{.Int.&ordinal.tc}: " ~ comma @upside-downs[$_-1]
}
- Output:
First fifty upside-downs: 5 19 28 37 46 55 64 73 82 91 159 258 357 456 555 654 753 852 951 1199 1289 1379 1469 1559 1649 1739 1829 1919 2198 2288 2378 2468 2558 2648 2738 2828 2918 3197 3287 3377 3467 3557 3647 3737 3827 3917 4196 4286 4376 4466 Five hundredth: 494,616 Five thousandth: 56,546,545 Fifty thousandth: 6,441,469,664 Five hundred thousandth: 729,664,644,183 Five millionth: 82,485,246,852,682
Wren
import "./fmt" for Fmt
var genUpsideDown = Fiber.new {
var wrappings = [
[1, 9], [2, 8], [3, 7], [4, 6], [5, 5],
[6, 4], [7, 3], [8, 2], [9, 1]
]
var evens = [19, 28, 37, 46, 55, 64, 73, 82, 91]
var odds = [5]
var oddIndex = 0
var evenIndex = 0
var ndigits = 1
var pow = 100
while (true) {
if (ndigits % 2 == 1) {
if (odds.count > oddIndex) {
Fiber.yield(odds[oddIndex])
oddIndex = oddIndex + 1
} else {
// build next odds, but switch to evens
var nextOdds = []
for (w in wrappings) {
for (i in odds) {
nextOdds.add(w[0] * pow + i * 10 + w[1])
}
}
odds = nextOdds
ndigits = ndigits + 1
pow = pow * 10
oddIndex = 0
}
} else {
if (evens.count > evenIndex) {
Fiber.yield(evens[evenIndex])
evenIndex = evenIndex + 1
} else {
// build next evens, but switch to odds
var nextEvens = []
for (w in wrappings) {
for (i in evens) {
nextEvens.add(w[0] * pow + i * 10 + w[1])
}
}
evens = nextEvens
ndigits = ndigits + 1
pow = pow * 10
evenIndex = 0
}
}
}
}
var limit = 5000000
var count = 0
var ud50s = []
var pow = 50
while (count < limit) {
var n = genUpsideDown.call()
count = count + 1
if (count < 50) {
ud50s.add(n)
} else if (count == 50) {
System.print("First 50 upside down numbers:")
Fmt.tprint("$,5d", ud50s + [n], 10)
System.print()
pow = 500
} else if (count == pow) {
Fmt.print("$,r : $,d", pow, n)
pow = pow * 10
}
}
- Output:
First 50 upside down numbers: 5 19 28 37 46 55 64 73 82 91 159 258 357 456 555 654 753 852 951 1,199 1,289 1,379 1,469 1,559 1,649 1,739 1,829 1,919 2,198 2,288 2,378 2,468 2,558 2,648 2,738 2,828 2,918 3,197 3,287 3,377 3,467 3,557 3,647 3,737 3,827 3,917 4,196 4,286 4,376 4,466 500th : 494,616 5,000th : 56,546,545 50,000th : 6,441,469,664 500,000th : 729,664,644,183 5,000,000th : 82,485,246,852,682