Upside-down numbers: Difference between revisions
Content added Content deleted
(→{{header|Free Pascal}}: added direct calculation of n-th Upside-Down numbers) |
|||
Line 212: | Line 212: | ||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
==={{header|Free Pascal}}=== |
==={{header|Free Pascal}}=== |
||
extended to 50E6 |
extended to 50E6. Added direct calculation of n-th Upside-Down number. |
||
<syntaxhighlight lang="pascal"> |
<syntaxhighlight lang="pascal"> |
||
program UpSideDownNumbers; |
program UpSideDownNumbers; |
||
Line 219: | Line 219: | ||
const |
const |
||
middle = 5; |
middle = 5; |
||
type |
|||
tUpDown = record |
|||
UD_half : array[0..15] of Int32; |
|||
UD_Dgt : Int32; |
|||
end; |
|||
function CalcUpDownNumber(const UD :tUpDown):Uint64; |
|||
var |
var |
||
i,dc : Int32; |
|||
begin |
|||
with UD do |
|||
Begin |
|||
dc := (UD_Dgt shr 1) -1; |
|||
result := 0; |
|||
For i := dc downto 0 do |
|||
result := result*10+UD_half[i]; |
|||
if Odd(UD_Dgt) then |
|||
result := result*10+middle; |
|||
For i := 0 to dc do |
|||
result := result*10+(10-UD_half[i]); |
|||
end; |
|||
end; |
|||
procedure NthUpDownNumber(n : Uint64;var UD:tUpDown); |
|||
function CalcUpDownNumber(dgtCnt:Int32):Uint64; |
|||
var |
var |
||
dgtCnt,i : Int32; |
|||
sum, |
|||
dSum : Int64; |
|||
begin |
begin |
||
sum := 0; |
|||
dgtCnt := 1; |
|||
dsum := 1; |
|||
repeat |
|||
result := result*10+Upperhalf[i]; |
|||
if |
if (sum>=n) then |
||
Break; |
|||
dgtCnt +=1; |
|||
For i := 0 to dc do |
|||
if Odd(dgtCnt) then |
|||
result := result*10+(10-Upperhalf[i]); |
|||
dSum *= 9; |
|||
sum += dSum; |
|||
until false; |
|||
dgtCnt -=1; |
|||
with UD do |
|||
begin |
|||
UD_Dgt := dgtCnt; |
|||
sum := n-(sum-dSum)-1;// -1 because of dgtcnt=1 |
|||
if dgtCnt > 1 then |
|||
begin |
|||
dgtCnt := dgtCnt SHR 1-1;// |
|||
i := dgtcnt; |
|||
repeat |
|||
UD_half[i-dgtcnt] := sum mod 9+1; |
|||
sum := sum div 9; |
|||
dec(dgtCnt); |
|||
until dgtCnt <0; |
|||
end; |
|||
end; |
|||
end; |
end; |
||
procedure NextNumb(var |
procedure NextNumb(var UD:tUpDown); |
||
var |
var |
||
i,dc,dgt : Uint32; |
i,dc,dgt : Uint32; |
||
begin |
begin |
||
with UD do |
|||
IF dc= 0 then |
|||
begin |
begin |
||
dc:= UD_Dgt; |
|||
if dc>1 then |
|||
Begin |
|||
i := 0; |
|||
dc := dc shr 1-1; |
|||
repeat |
|||
dgt := UD_half[i]+1; |
|||
if dgt <10 then |
|||
begin |
|||
UD_half[i] := dgt; |
|||
BREAK; |
|||
end; |
|||
UD_half[i] := 1; |
|||
inc(i); |
|||
until i > dc; |
|||
if i > dc then |
|||
Begin |
|||
UD_half[i]:= 1; |
|||
inc(UD_Dgt); |
|||
end; |
|||
end |
|||
else |
|||
begin |
begin |
||
inc(UD_Dgt); |
|||
UD_half[0] := 1; |
|||
EXIT; |
|||
end; |
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; |
||
end; |
end; |
||
var |
var |
||
{$ALIGN 32} |
|||
dgtcnt, |
|||
UD1,Ud2 : tUpDown; |
|||
Count, |
Count, |
||
limit : |
limit : UInt64; |
||
Begin |
Begin |
||
Count := 0; |
Count := 0; |
||
limit := 50; |
limit := 50; |
||
Writeln('First fifty upside-downs:'); |
Writeln('First fifty upside-downs:'); |
||
limit := 50; |
|||
repeat |
|||
NextNumb(UD1); |
|||
inc(Count); |
|||
write(CalcUpDownNumber(UD1):5); |
|||
if Count MOD 10 = 0 then |
|||
writeln; |
|||
until Count>=limit; |
|||
writeln; |
|||
writeln(' digits count value'); |
|||
repeat |
repeat |
||
repeat |
repeat |
||
NextNumb( |
NextNumb(UD1);inc(Count); |
||
until count >= limit; |
|||
NthUpDownNumber(count,UD2); |
|||
IF Count<= 50 then |
|||
writeln(' next ',UD1.UD_Dgt:3,count:10,CalcUpDownNumber(UD1):20); |
|||
Begin |
|||
writeln(' calc ',UD2.UD_Dgt:3,count:10,CalcUpDownNumber(UD2):20); |
|||
limit *= 10; |
|||
until Limit > 50*1000*1000 ; |
|||
writeln; |
|||
writeln; |
|||
repeat |
|||
until Count>= limit; |
|||
NthUpDownNumber(Limit,UD2); |
|||
if limit <> 50 then |
|||
writeln(' calc ',UD2.UD_Dgt:3,Limit:10,CalcUpDownNumber(UD2):20); |
|||
limit *= 10; |
|||
until Limit > 500*1000*1000 ; |
|||
writeln; |
|||
writeln; |
|||
limit := limit*10; |
|||
until limit> 50*1000*1000; |
|||
end. |
end. |
||
</syntaxhighlight> |
</syntaxhighlight> |
||
Line 310: | Line 359: | ||
3467 3557 3647 3737 3827 3917 4196 4286 4376 4466 |
3467 3557 3647 3737 3827 3917 4196 4286 4376 4466 |
||
digits count value |
|||
next 4 51 4556 |
|||
calc 4 51 4556 |
|||
next 6 500 494616 |
|||
calc 6 500 494616 |
|||
5000000 82485246852682 |
|||
next 8 5000 56546545 |
|||
50000000 9285587463255281 |
|||
calc 8 5000 56546545 |
|||
next 10 50000 6441469664 |
|||
calc 10 50000 6441469664 |
|||
next 12 500000 729664644183 |
|||
calc 12 500000 729664644183 |
|||
next 14 5000000 82485246852682 |
|||
calc 14 5000000 82485246852682 |
|||
next 16 50000000 9285587463255281 |
|||
calc 16 50000000 9285587463255281 |
|||
calc 19 500000000 1436368345672474769 |
|||
Real time: 0.282 s CPU share: 98.65 % |
|||
</pre> |
</pre> |
||