Smallest square that begins with n: Difference between revisions

Add Refal
(→‎{{header|Perl}}: prepend Free Pascal version. Extreme reduced runtime.)
(Add Refal)
 
(16 intermediate revisions by 7 users not shown)
Line 1,780:
484 is 22²
49 is 7²
</pre>
 
=={{header|JavaScript}}==
{{Trans|Julia}}
Procedural, uses console.log to show the numbers.
<syntaxhighlight lang="javascript">
{ // find the smallest square that begins with n for n in 1..49
'use strict'
const smsq = function( n ) {
let results = [], found = 0, square = 1, delta = 3
while( found < n ) {
let k = square
while( k > 0 ) {
if( k <= n && results[ k ] == null ) {
results[ k ] = square
found += 1
}
k = Math.floor( k / 10 )
}
square = square + delta
delta = delta + 2
}
return results
} // smsq
 
const seq = smsq( 49 )
let out = ""
for( let i = 1; i < seq.length; i ++ ) {
out += seq[ i ].toString().padStart( 6 )
if( i % 10 == 0 ){ out += "\n" }
}
console.log( out )
}
</syntaxhighlight>
{{out}}
<pre>
1 25 36 4 529 64 729 81 9 100
1156 121 1369 144 1521 16 1764 1849 196 2025
2116 225 2304 2401 25 2601 2704 289 2916 3025
3136 324 3364 3481 35344 36 3721 3844 3969 400
41209 4225 4356 441 45369 4624 4761 484 49
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">functionusing squaresstartingupto(n, verbose=true)BenchmarkTools
 
res, numfound = zeros(Int, n), 0
function smsq(n = 49)
p_int = collect(1:n)
p_stringresults = string.zeros(p_intInt, n)
found, square, delta = 0, 1, 3
for i in 1:typemax(Int)
while found < sq = i * in
sq_sk = string(sq)square
forwhile (j,k s) in enumerate(p_string)> 0
if res[j]k =<= 0n && length(sq_s) >= length(s) && sq_sresults[1:length(s)k] == s0
resresults[jk] = sqsquare
numfoundfound += 1
end
k ÷= 10
end
ifsquare numfound =+= ndelta
delta += if verbose2
for p in enumerate(res)
print(rpad(p[2], 6), p[1] % 10 == 0 ? "\n" : "")
end
end
break
end
end
return resresults
end
 
foreach(p -> print(rpad(p[2], 6), p[1] % 10 == 0 ? "\n" : ""), enumerate(smsq()))
squaresstartingupto(49)
println()
@btime smsq(1_000_000)
</syntaxhighlight>{{out}}
<pre>
1 25 36 4 529 64 729 81 9 100
1156 121 1369 144 1521 16 1764 1849 196 2025
2116 225 2304 2401 25 2601 2704 289 2916 3025
3136 324 3364 3481 35344 36 3721 3844 3969 400
41209 4225 4356 441 45369 4624 4761 484 49
27.356 ms (2 allocations: 7.63 MiB)
</pre>
 
=={{header|Lua}}==
{{Trans|Julia}}
<syntaxhighlight lang="lua">
do -- find the smallest square that begins with n for n in 1..49
local function smsq( n )
local results, found, square, delta = {}, 0, 1, 3
while found < n do
local k = square
while k > 0 do
if k <= n and results[ k ] == nil then
results[ k ] = square
found = found + 1
end
k = math.floor( k / 10 )
end
square = square + delta
delta = delta + 2
end
return results
end
 
local seq = smsq( 49 )
for i = 1, #seq do
io.write( " ", string.format( "%5d", seq[ i ] ) )
if i % 10 == 0 then io.write( "\n" ) end
end
end
</syntaxhighlight>
{{out}}
<pre>
1 25 36 4 529 64 729 81 9 100
1156 121 1369 144 1521 16 1764 1849 196 2025
2116 225 2304 2401 25 2601 2704 289 2916 3025
3136 324 3364 3481 35344 36 3721 3844 3969 400
41209 4225 4356 441 45369 4624 4761 484 49
</pre>
 
Line 1,956 ⟶ 2,032:
484
49</pre>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE SmallestSquareWithPrefix;
FROM InOut IMPORT WriteCard, WriteLn;
 
VAR n: CARDINAL;
 
PROCEDURE prefix(n, m: CARDINAL): BOOLEAN;
BEGIN
IF n>=m
THEN RETURN n=m
ELSE RETURN prefix(n, m DIV 10)
END
END prefix;
 
PROCEDURE firstPrefixSquare(n: CARDINAL): CARDINAL;
VAR
sq, sqr: CARDINAL;
BEGIN
sqr := 0;
REPEAT
INC(sqr);
sq := sqr*sqr
UNTIL prefix(n, sq);
RETURN sq
END firstPrefixSquare;
 
BEGIN
FOR n := 0 TO 49 DO
WriteCard(firstPrefixSquare(n), 7);
IF n MOD 10 = 9 THEN WriteLn END
END
END SmallestSquareWithPrefix.</syntaxhighlight>
{{out}}
<pre> 1 1 25 36 4 529 64 729 81 9
100 1156 121 1369 144 1521 16 1764 1849 196
2025 2116 225 2304 2401 25 2601 2704 289 2916
3025 3136 324 3364 3481 35344 36 3721 3844 3969
400 41209 4225 4356 441 45369 4624 4761 484 49</pre>
 
=={{header|Nim}}==
Line 2,032 ⟶ 2,147:
</pre>
 
<syntaxhighlight lang="perlpascal">
program LowSquareStartN;
uses
sysutils;
 
function LowSquareStartN(N: Uint32): Uint32;
const
dez = 10.0;
{Find lowest square that matches N}
var
sqrtN,sqrtN_10,dez : double;
mySqr : Uint64;
Pow10 : int64;
begin
dez := 10;
Pow10:= 1;
sqrtN := sqrt(n);
//to stay more accurate, instead *sqrt(10);
sqrtN_10 := sqrt(n*dez);// one more decimal digit
mySqr := n;
repeat
result := Trunc(sqrtN);
mySqr := result*result;
while mySqr > n do mySqr := mySqr DIV 10Pow10;
if mySqr = n then EXIT;
//test only next number
inc(result);
mySqr := (result*result);
while mySqr > n do mySqr := mySqr DIV 10pow10;
if mySqr = n then EXIT;
 
pow10 *= 10;
result := Trunc(sqrtN_10);
mySqr := result*result;
while mySqr > n do mySqr := mySqr DIV 10pow10;
if mySqr = n then EXIT;
inc(result);
mySqr := result*result;
while mySqr > n do mySqr := mySqr DIV 10pow10;
if mySqr = n then EXIT;
 
pow10 *= 10;
sqrtN *= dez;
sqrtN_10 *=dez;
until sqrtN > dez*nUint32(-1);
exit(0);readln;
readln;
end;
 
procedure SquareStartsN();
{Find smallest square that begins with N}
var
T : Uint64;
i : Uint32;
begin
writeln('Test 1 .. 49');
for I:=1 to 49 do //1*1000*1000 do
begin
T:=LowSquareStartN(I);
Line 2,088 ⟶ 2,206:
end;
writeln;
writeln;
writeln('Test 999,991 .. 1,000,000');
for I:= 999991 to 1000*1000-9 doto //1000*1000 do
begin
T:= LowSquareStartN(I);
writeln(i:10,':',T:1011,'->',t*t:1420);
end;
writeln;
T := GetTickCount64;
for I:= 1 to 10*1000*1000-10 do
LowSquareStartN(I);
T := GetTickCount64-T;
writeln('check 1..1E7 in ', T,' ms');
end;
 
BEGIN
SquareStartsN();
END.</syntaxhighlight>
END.
 
</syntaxhighlight>
{{out|@home}}
<pre>Test 1 .. 49
Test 1 .. 49
1 25 36 4 529 64 729 81 9 100
1156 121 1369 144 1521 16 1764 1849 196 2025
Line 2,112 ⟶ 2,234:
 
Test 999,991 .. 1,000,000
999991: 3162264-> 9999913605696
999992: 999996-> 999992000016
999993: 3162267-> 9999932579289
999994: 999997-> 999994000009
999995: 316227-> 99999515529
999996: 999998-> 999996000004
999997: 3162273-> 9999970526529
999998: 999999-> 999998000001
999999: 3162277-> 9999995824729
1000000: 1000-> 1000000
 
check 1..1E7 in 328 ms
real 0m0,001s
TIO.RUN-> check 1..1E7 in 2540 ms ( old compiler version 3.0.4/3.2.3 and 2.3 vs 4.4 Ghz )
</pre>
===={{trans|Julia}}====
Storing only the root ( n_running ) of the square so Uint32 suffices for the result.<br>
Improved version ->335 ms<br>
Stop searching as early as possible->minimize count of divisions (~ n*(1+3.162=sqrt(10)) ) -> 71 ms<br>
increment as long the testsqr didn't change in last digit. Divisions (~ n*(1+1.8662 )) -> 53 ms :-)
<syntaxhighlight lang="pascal">
program smsq;
{$IFDEF FPC}{$MODE DELPHI}{$OPTIMIZATION ON,ALL}{$ENDIF}
uses
sysutils;
type
tRes = array of Uint32;
 
var
maxTestVal : Uint32;
function smsq(n:Uint32):tRes;
// limit n is ~ 1.358E9
var
square,nxtSqr,Pow10 : Uint64;
n_run,testSqr,found : Uint32;
begin
setlength(result,n+1);
fillchar(result[0],length(result)*Sizeof(result[0]),#0);
found := 0;
square := 0;
n_run := 0;
Pow10 := 1;
nxtSqr := 1;//sqr(n_run)+1;
while found < n do
begin
repeat
n_run +=1;
square := sqr(n_run);
until square >= nxtSqr;
//bring square into the right place
testSqr := square div pow10;
while testSqr > n do
Begin
pow10 *=10;
testSqr := testSqr div 10;
end;
//next square must increase by one digit
nxtSqr := (testSqr+1)*pow10;
repeat
//no need to test any more
//if found ex. 4567 than 456,45 and 4 already marsquareed
if result[testSqr] <> 0 then
BREAK;
result[testSqr] := n_run;
found += 1;
testSqr := testSqr div 10;
until testSqr = 0;
end;
maxTestVal := n_run;
end;
 
var
t0 : Int64;
n,i : Uint32;
results : tRes;
BEGIN
n := 49;
results := smsq(n);
For i := 1 to n do
begin
write(sqr(results[i]):6);
if i mod 10 = 0 then
Writeln;
end;
writeln;
writeln('Max test value : ',maxTestVal); ;
writeln;
 
n := 10*1000*1000;
// speed up cpu
smsq(n);
t0 := GetTickCount64;
smsq(n);
t0 := GetTickCount64-t0;
writeln('check 1..',n,' in ', T0,' ms. Max test value : ',maxTestVal);
END.
</syntaxhighlight>
{{out|@home}}
<pre>
1 25 36 4 529 64 729 81 9 100
1156 121 1369 144 1521 16 1764 1849 196 2025
2116 225 2304 2401 25 2601 2704 289 2916 3025
3136 324 3364 3481 35344 36 3721 3844 3969 400
41209 4225 4356 441 45369 4624 4761 484 49
Max test value : 213
 
check 1..10000000 in 53 ms. Max test value : 31622776
....
check 1..1000000000 in 5174 ms. Max test value : 3162277656
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
Line 2,174 ⟶ 2,393:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<syntaxhighlight lang="phix">
<span style="color: #008080;">constant</span> <span style="color: #000000;">lim</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">49</span>
with javascript_semantics
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">)</span>
constant lim = 49
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
sequence res = repeat(0,lim)
<span style="color: #008080;">while</span> <span style="color: #000000;">found</span><span style="color: #0000FF;"><</span><span style="color: #000000;">lim</span> <span style="color: #008080;">do</span>
integer n = 1, found = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">n2</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">n</span>
while found<lim do
<span style="color: #008080;">while</span> <span style="color: #000000;">n2</span> <span style="color: #008080;">do</span>
integer n2 = n*n
<span style="color: #008080;">if</span> <span style="color: #000000;">n2</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">lim</span> <span style="color: #008080;">and</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n2</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
while n2 do
<span style="color: #000000;">found</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
if n2<=lim and res[n2]=0 then
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
found += 1
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res[n2] = n
<span style="color: #000000;">n2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n2</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
n2 = floor(n2/10)
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
n += 1
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">sq_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">,{{</span><span style="color: #008000;">"(%d^2)"</span><span style="color: #0000FF;">},</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})})</span>
end while
<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;">"Smallest squares that begin with 1..%d:\n%s\n"</span><span style="color: #0000FF;">,</span>
res = columnize({tagset(lim),sq_power(res,2),apply(true,sprintf,{{"(%d^2)"},res})})
<span style="color: #0000FF;">{</span><span style="color: #000000;">lim</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">apply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">,{{</span><span style="color: #008000;">"%2d: %5d %-8s"</span><span style="color: #0000FF;">},</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}),</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)})</span>
printf(1,"Smallest squares that begin with 1..%d:\n%s\n",
<!--</syntaxhighlight>-->
{lim,join_by(apply(true,sprintf,{{"%2d: %5d %-8s"},res}),10,5)})
</syntaxhighlight>
{{out}}
<pre>
Line 2,207 ⟶ 2,428:
10: 100 (10^2) 20: 2025 (45^2) 30: 3025 (55^2) 40: 400 (20^2)
</pre>
{{trans|Pascal}}
Same output as the Pascal entry, slight tidy
<syntaxhighlight lang="phix">
with javascript_semantics
function LowSquareStartN(integer n)
-- Find lowest square that matches n
atom sqrtN = sqrt(n),
sqrtN_10 = sqrt(n*10)
integer pow10 = 1
do
for res in {trunc(sqrtN),trunc(sqrtN_10)} do
for plus01=0 to 1 do
if floor(res*res/pow10)=n then return res end if
res += 1
end for
pow10 *= 10
end for
sqrtN *= 10
sqrtN_10 *= 10
until sqrtN > 10*n
?9/0
end function
 
procedure SquareStartsN()
-- Find smallest square that begins with N
integer t
printf(1,"Test 1 .. 49\n")
for i=1 to 49 do
t := LowSquareStartN(i)
printf(1,"%7d%n",{t*t,mod(i,10)=0})
end for
printf(1,"\n\nTest 999,991 .. 1,000,000\n")
for i=999991 to 1000*1000 do
t := LowSquareStartN(i)
printf(1,"%10d:%11d->%20d\n",{i,t,t*t})
end for
puts(1,"\n")
end procedure
 
SquareStartsN()
</syntaxhighlight>
 
=={{header|Picat}}==
Line 2,655 ⟶ 2,917:
 
Same output.
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Table (7 7) <Each FirstPrefixSquare <Iota 1 49>>>;
};
 
Cell {
s.W s.N, <Repeat s.W ' '> <Symb s.N>: e.C,
<Last s.W e.C>: (e.X) e.CI = e.CI;
}
 
Repeat {
0 s.C = ;
s.N s.C = s.C <Repeat <- s.N 1> s.C>;
};
 
Table {
(s.Cols s.CW) e.X = <Table () (s.Cols s.Cols s.CW) e.X>;
(e.Row) (s.Cols s.N s.CW), e.Row: {
= ;
e.Row = <Prout e.Row>;
};
(e.Row) (s.Cols 0 s.CW) e.X =
<Prout e.Row>
<Table () (s.Cols s.Cols s.CW) e.X>;
(e.Row) (s.Cols s.N s.CW) s.I e.X =
<Table (e.Row <Cell s.CW s.I>) (s.Cols <- s.N 1> s.CW) e.X>;
};
 
Each {
s.F = ;
s.F s.I e.X = <Mu s.F s.I> <Each s.F e.X>;
};
 
Iota {
s.End s.End = s.End;
s.Start s.End = s.Start <Iota <+ 1 s.Start> s.End>;
};
 
FirstPrefixSquare {
s.N = <FirstPrefixSquare s.N 1>;
s.N s.Sqr, <* s.Sqr s.Sqr>: s.Sq,
<Symb s.N>: e.Pfx,
<Symb s.Sq>: e.Pfx e.X = s.Sq;
s.N s.Sqr = <FirstPrefixSquare s.N <+ 1 s.Sqr>>;
};
</syntaxhighlight>
{{out}}
<pre> 1 25 36 4 529 64 729
81 9 100 1156 121 1369 144
1521 16 1764 1849 196 2025 2116
225 2304 2401 25 2601 2704 289
2916 3025 3136 324 3364 3481 35344
36 3721 3844 3969 400 41209 4225
4356 441 45369 4624 4761 484 49</pre>
 
=={{header|REXX}}==
Line 3,013 ⟶ 3,330:
(return-from search)))
((set k (trunc k 10)))))))</syntaxhighlight>
 
 
=={{header|Uiua}}==
{{works with|Uiua|0.10}}
 
In best YAGNI style, just calculate sufficient squares for the task as specced (up to 220^2)
 
<syntaxhighlight lang="Uiua">
IsPrefix ← =⧻⟜(/+⬚@.=)
⊞◇IsPrefix °⋕↘1⇡50 °⋕.ⁿ2+1⇡220
⊏≡(⊢⊚)
</syntaxhighlight>
{{out}}
<pre>
[1 25 36 4 529 64 729 81 9 100 1156 ...etc...]
</pre>
 
=={{header|VTL-2}}==
Line 3,044 ⟶ 3,377:
=={{header|Wren}}==
{{libheader|Wren-fmt}}
===Version 1===
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
Line 3,085 ⟶ 3,419:
3136 324 3364 3481 35344 36 3721 3844 3969 400
41209 4225 4356 441 45369 4624 4761 484 49
</pre>
 
===Version 2===
{{trans|Pascal}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var lowSquareStartN = Fn.new { |n|
var sqrtN = n.sqrt
var sqrtN10 = (n * 10).sqrt
var pow10 = 1
while (true) {
for (i in [sqrtN.truncate, sqrtN10.truncate]) {
for (j in 0..1) {
var mySqr = (i * i / pow10).floor
if (mySqr == n) return i
i = i + 1
}
pow10 = pow10 * 10
}
sqrtN = sqrtN * 10
sqrtN10 = sqrtN10 * 10
if (sqrtN > 10 * n) break
}
}
 
System.print("Test 1 .. 49")
for (i in 1..49) {
var t = lowSquareStartN.call(i)
Fmt.write("$7d", t * t)
if (i % 10 == 0) System.print()
}
System.print("\n")
System.print("Test 999,991 .. 1,000,000")
for (i in 999991..1e6) {
var t = lowSquareStartN.call(i)
Fmt.print("$10d : $10d -> $14d", i, t, t * t)
}</syntaxhighlight>
 
{{out}}
<pre>
Similar to Pascal entry.
</pre>
 
2,093

edits