Data update

This commit is contained in:
Ingy döt Net 2024-07-13 15:19:22 -07:00
parent 29a5eea0d4
commit 5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions

View file

@ -1,5 +1,4 @@
Given a zero or positive integer, the task is to generate the next largest
integer using only the given digits<sup>*1</sup>.
Given a zero or positive integer, the task is to generate the next largest integer with the same digits<sup>*1</sup>.
* &nbsp; Numbers will not be padded to the left with zeroes.
* &nbsp; Use all given digits, with their given multiplicity. (If a digit appears twice in the input number, it should appear twice in the result).
@ -22,8 +21,8 @@ digits, but should be easy to reason about its correctness.
;Algorithm 2:
# &nbsp; Scan right-to-left through the digits of the number until you find a digit with a larger digit somewhere to the right of it.
# &nbsp; Exchange that digit with the digit on the right that is ''both'' more than it, and closest to it.
# &nbsp; Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right. (I.e. so they form the lowest numerical representation)
# &nbsp; Exchange that digit with the smallest digit on the right that is greater than it.
# &nbsp; Order the digits to the right of this position, after the swap; lowest-to-highest, left-to-right. (that is, so they form the lowest numerical representation)
'''E.g.:'''
@ -47,7 +46,7 @@ algorithms for random numbers generated from a range that the first algorithm ca
;Task requirements:
Calculate the next highest int from the digits of the following numbers:
Calculate the next highest integer from the digits of the following numbers:
:* &nbsp; 0
:* &nbsp; 9
:* &nbsp; 12

View file

@ -0,0 +1,125 @@
-- Next highest integer with same digits
-- J. Carter 2024 June
-- Uses the PragmAda Reusable Components (https://github.com/jrcarter/PragmARC)
with Ada.Text_IO;
with PragmARC.Permutations;
with PragmARC.Sorting.Insertion;
procedure Next_Highest is
package Permutations is new PragmARC.Permutations (Element => Character);
procedure Sort is new PragmARC.Sorting.Insertion (Element => Character, Index => Positive, Sort_Set => String);
subtype Digit is Character range '0' .. '9';
function Valid (S : in String) return Boolean is
(S'First = 1 and S'Length > 0 and (for all C of S => C in Digit) );
function Next_P (Value : in String) return String with
Pre => Valid (Value);
-- Returns the smallest integer > Value that can be produced from Value's decimal digits, using permutations
-- Returns zero if there is no such integer
function Next_S (Value : in String) return String with
Pre => Valid (Value);
-- Returns the smallest integer > Value that can be produced from Value's decimal digits, using the Scan, Sort, Scan, and Swap
-- (SSSS) algorithm
-- Returns zero if there is no such integer
function Next_P (Value : in String) return String is
procedure Check (Image : in Permutations.Sequence; Stop : in out Boolean);
-- Checks if Image represents an integer > Value and smaller than Smallest
-- If so, sets Found to True and Smallest to the represented value
Found : Boolean := False;
Smallest : String := (Value'Range => '9');
procedure Check (Image : in Permutations.Sequence; Stop : in out Boolean) is
Number : constant String := String (Image);
begin -- Check
if Number > Value then
Found := True;
Smallest := (if Number < Smallest then Number else Smallest);
end if;
end Check;
begin -- Next_P
if Value'Length < 2 or (Value'Length = 2 and Value < "12") then
return "0";
end if;
Permutations.Generate (Initial => Permutations.Sequence (Value), Process => Check'Access);
return (if Found then Smallest else "0");
end Next_P;
function Next_S (Value : in String) return String is
Work : String := Value;
Found : Boolean := False;
Lower : Positive;
Higher : Positive;
begin -- Next_S
Scan_Lower : for I in reverse 1 .. Work'Last - 1 loop
if (for some C of Work (I + 1 .. Work'Last) => Work (I) < C) then
Found := True;
Lower := I;
exit Scan_Lower;
end if;
end loop Scan_Lower;
if not Found then
return "0";
end if;
Sort (Set => Work (Lower + 1 .. Work'Last) );
Scan_Higher : for I in Lower + 1 .. Work'Last loop -- The Found test above ensures that this will always assign to Higher
if Work (I) > Work (Lower) then
Higher := I;
exit Scan_Higher;
end if;
end loop Scan_Higher;
Swap : declare
Temp : constant Character := Work (Lower);
begin -- Swap
Work (Lower) := Work (Higher);
Work (Higher) := Temp;
end Swap;
return Work;
end Next_S;
Test_1 : constant String := "0";
Test_2 : constant String := "9";
Test_3 : constant String := "12";
Test_4 : constant String := "21";
Test_5 : constant String := "12453";
Test_6 : constant String := "738440";
Test_7 : constant String := "45072010";
Test_8 : constant String := "95322020";
Stretch : constant String := "9589776899767587796600";
begin -- Next_Highest
Ada.Text_IO.Put_Line (Item => "Using permutations");
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_1'Length => ' ') & Test_1 & ' ' & Next_P (Test_1) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_2'Length => ' ') & Test_2 & ' ' & Next_P (Test_2) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_3'Length => ' ') & Test_3 & ' ' & Next_P (Test_3) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_4'Length => ' ') & Test_4 & ' ' & Next_P (Test_4) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_5'Length => ' ') & Test_5 & ' ' & Next_P (Test_5) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_6'Length => ' ') & Test_6 & ' ' & Next_P (Test_6) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_7'Length => ' ') & Test_7 & ' ' & Next_P (Test_7) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_8'Length => ' ') & Test_8 & ' ' & Next_P (Test_8) );
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line (Item => "Using SSSS");
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_1'Length => ' ') & Test_1 & ' ' & Next_S (Test_1) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_2'Length => ' ') & Test_2 & ' ' & Next_S (Test_2) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_3'Length => ' ') & Test_3 & ' ' & Next_S (Test_3) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_4'Length => ' ') & Test_4 & ' ' & Next_S (Test_4) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_5'Length => ' ') & Test_5 & ' ' & Next_S (Test_5) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_6'Length => ' ') & Test_6 & ' ' & Next_S (Test_6) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_7'Length => ' ') & Test_7 & ' ' & Next_S (Test_7) );
Ada.Text_IO.Put_Line (Item => (1 .. 8 - Test_8'Length => ' ') & Test_8 & ' ' & Next_S (Test_8) );
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line (Item => Stretch & ' ' & Next_S (Stretch) );
end Next_Highest;

View file

@ -1,21 +1,19 @@
(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)))</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">permute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rfind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function nigh(string n)
sequence p = repeat("",factorial(length(n)))
for i=1 to length(p) do
p[i] = permute(i,n)
end for
p = sort(p)
integer k = rfind(n,p)
return iff(k=length(p)?"0",p[k+1])
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"21"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12453"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"738440"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"45072010"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"95322020"</span><span style="color: #0000FF;">}</span>
<span style="color: #000080;font-style:italic;">-- (crashes on) "9589776899767587796600"}</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%22s =&gt; %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--
constant tests = {"0","9","12","21","12453",
"738440","45072010","95322020"}
-- (crashes on) "9589776899767587796600"}
atom t0 = time()
for i=1 to length(tests) do
string t = tests[i]
printf(1,"%22s => %s\n",{t,nigh(t)})
end for
?elapsed(time()-t0)

View file

@ -1,28 +1,26 @@
(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">hi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[$]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ni</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ni</span><span style="color: #0000FF;"><</span><span style="color: #000000;">hi</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">sr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">..$])</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rfind</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ni</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sr</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">sr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sr</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">hi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">hi</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ni</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #008000;">"0"</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function nigh(string n)
integer hi = n[$]
for i=length(n)-1 to 1 by -1 do
integer ni = n[i]
if ni<hi then
string sr = sort(n[i..$])
integer k = rfind(ni,sr)+1
n[i] = sr[k]
sr[k..k] = ""
n[i+1..$] = sr
return n
end if
hi = max(hi,ni)
end for
return "0"
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"9"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"21"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"12453"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"738440"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"45072010"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"95322020"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"9589776899767587796600"</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%22s =&gt; %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">t</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nigh</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--
constant tests = {"0","9","12","21","12453",
"738440","45072010","95322020",
"9589776899767587796600"}
atom t0 = time()
for i=1 to length(tests) do
string t = tests[i]
printf(1,"%22s => %s\n",{t,nigh(t)})
end for
?elapsed(time()-t0)