Jump to content

Upside-down numbers: Difference between revisions

→‎{{header|Free Pascal}}: added direct calculation of n-th Upside-Down numbers
(→‎{{header|Free Pascal}}: added direct calculation of n-th Upside-Down numbers)
Line 212:
=={{header|Pascal}}==
==={{header|Free Pascal}}===
extended to 50E6. Added direct calculation of n-th Upside-Down number.
<syntaxhighlight lang="pascal">
program UpSideDownNumbers;
Line 219:
const
middle = 5;
type
tUpDown = record
UD_half : array[0..15] of Int32;
UD_Dgt : Int32;
end;
function CalcUpDownNumber(const UD :tUpDown):Uint64;
var
Upperhalfi,dc : array[0..15] of 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
idgtCnt,dci : Int32;
sum,
dSum : Int64;
begin
dcsum := (dgtCnt DIV 2) -10;
resultdgtCnt := 01;
For idsum := dc downto 0 do1;
repeat
result := result*10+Upperhalf[i];
if Odd(dgtCntsum>=n) then
result := result*10+middleBreak;
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;
 
procedure NextNumb(var dgtCntUD:UInt32tUpDown);
var
i,dc,dgt : Uint32;
begin
dc:=with DgtCnt;UD do
IF dc= 0 then
begin
dgtcnt dc:= 1UD_Dgt;
EXIT;if dc>1 then
end; Begin
IF dc= 1 then 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
Upperhalf[0] := 1inc(UD_Dgt);
dgtCntUD_half[0] := 21;
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
{$ALIGN 32}
dgtcnt,
UD1,Ud2 : tUpDown;
Count,
limit : UInt32UInt64;
Begin
Count := 0;
limit := 50;
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
NextNumb(dgtCntUD1);inc(Count);
until count inc(Count)>= limit;
NthUpDownNumber(count,UD2);
IF Count<= 50 then
writeln(' next ',UD1.UD_Dgt:3,count:10,CalcUpDownNumber(UD1):20);
Begin
writeln(' calc write(',UD2.UD_Dgt:3,count:10,CalcUpDownNumber(dgtCntUD2):520);
limit if Count MOD*= 10 = 0 then;
until Limit > 50*1000*1000 ;
writeln;
endwriteln;
repeat
until Count>= limit;
NthUpDownNumber(Limit,UD2);
if limit <> 50 then
writeln(limit' calc ',UD2.UD_Dgt:3,Limit:10,CalcUpDownNumber(dgtCntUD2):20);
elselimit *= 10;
until Limit > 500*1000*1000 ;
writeln;
writeln;
limit := limit*10;
until limit> 50*1000*1000;
end.
</syntaxhighlight>
Line 310 ⟶ 359:
3467 3557 3647 3737 3827 3917 4196 4286 4376 4466
 
digits 500 count 494616 value
next 4 5000 51 56546545 4556
calc 4 50000 51 6441469664 4556
next 6 500000 500 729664644183 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
 
UserReal time: 0.310282 s CPU share: 9998.3065 %
</pre>
 
132

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.