Steady squares: Difference between revisions

From Rosetta Code
Content added Content deleted
m (fix)
(add fermat)
Line 108: Line 108:
625^2 = 390,625
625^2 = 390,625
9376^2 = 87,909,376
9376^2 = 87,909,376
</pre>

=={{header|Fermat}}==
<lang fermat>Func Isstead( n ) =
m:=n;
d:=1;
while m>0 do
d:=d*10;
m:=m\10;
od;
if n^2|d=n then Return(1) else Return(0) fi.;

for i = 1 to 9999 do
if Isstead(i) then !!(i,'^2 = ',i^2) fi;
od;</lang>
{{out}}<pre>
1^2 = 1
5^2 = 25
6^2 = 36
25^2 = 625
76^2 = 5776
376^2 = 141376
625^2 = 390625
9376^2 = 87909376
</pre>
</pre>



Revision as of 22:22, 21 December 2021

Steady squares 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.
Euler Project #284
Task


The 3-digit number 376 in the decimal numbering system is an example of numbers with the special property that its square ends with the same digits: 376*376 = 141376. Let's call a number with this property a steady square. Find steady squares under 10.000

C

<lang c>#include <stdio.h>

  1. include <stdbool.h>

bool steady(int n) {

   int mask=1;
   for (int d=n; d; d/=10) mask*=10;
   return (n*n)%mask == n;

}

int main() {

   for (int i=1; i<10000; i++)
       if (steady(i))
           printf("%4d^2 = %8d\n", i, i*i);
   return 0;

}</lang>

Output:
   1^2 =        1
   5^2 =       25
   6^2 =       36
  25^2 =      625
  76^2 =     5776
 376^2 =   141376
 625^2 =   390625
9376^2 = 87909376

CLU

<lang clu>n_digits = proc (n: int) returns (int)

   i: int := 0
   while n>0 do
       i := i+1
       n := n/10
   end
   return(i)

end n_digits

steady = proc (n: int) returns (bool)

   sq: int := n ** 2
   return (sq // 10**n_digits(n) = n)

end steady

start_up = proc ()

   po: stream := stream$primary_output()
   for i: int in int$from_to(1, 10000) do
       if ~steady(i) then continue end
       stream$putright(po, int$unparse(i), 4)
       stream$puts(po, "^2 = ")
       stream$putright(po, int$unparse(i**2), 8)
       stream$putl(po, "")
   end

end start_up</lang>

Output:
   1^2 =        1
   5^2 =       25
   6^2 =       36
  25^2 =      625
  76^2 =     5776
 376^2 =   141376
 625^2 =   390625
9376^2 = 87909376

F#

<lang fsharp> // Steady Squares. Nigel Galloway: December 21st., 2021 let rec fG n g=match g with 0->true |g when n%10=g%10->fG(n/10)(g/10) |_->false [for n in 0..999 do for g in [1;5;6]->10*n+g]|>List.filter(fun n->fG(n*n)n)|>List.iter(printf "%d ") </lang>

Output:
1 
5 
6 
25 
76 
376 
625 
9376

Factor

Only checking numbers that end with 1, 5, and 6. See Talk:Steady_Squares for more details.

Works with: Factor version 0.99 2021-06-02

<lang factor>USING: formatting kernel math math.functions math.functions.integer-logs prettyprint sequences tools.memory.private ;

steady? ( n -- ? )
   [ sq ] [ integer-log10 1 + 10^ mod ] [ = ] tri ;

1000 <iota> { 1 5 6 } [

   [ 10 * ] dip + dup steady?
   [ dup sq commas "%4d^2 = %s\n" printf ] [ drop ] if

] cartesian-each</lang>

Output:
   1^2 = 1
   5^2 = 25
   6^2 = 36
  25^2 = 625
  76^2 = 5,776
 376^2 = 141,376
 625^2 = 390,625
9376^2 = 87,909,376

Fermat

<lang fermat>Func Isstead( n ) =

   m:=n;
   d:=1;
   while m>0 do
       d:=d*10;
       m:=m\10;
   od;
   if n^2|d=n then Return(1) else Return(0) fi.;

for i = 1 to 9999 do

   if Isstead(i) then !!(i,'^2 = ',i^2) fi;

od;</lang>

Output:

1^2 =  1
5^2 =  25
6^2 =  36
25^2 =  625
76^2 =  5776
376^2 =  141376
625^2 =  390625
9376^2 =  87909376

FreeBASIC

<lang freebasic>function numdig( byval n as uinteger ) as uinteger

   'number of decimal digits in n
   dim as uinteger d=0
   while n
       d+=1
       n\=10
   wend
   return d

end function

function is_steady_square( n as const uinteger ) as boolean

   dim as integer n2 = n^2
   if n2 mod 10^numdig(n) = n then return true else return false

end function

for i as uinteger = 1 to 10000

   if is_steady_square(i) then print using "####^2 = ########";i;i^2

next i</lang>

Output:

  1^2 =        1
  5^2 =       25
  6^2 =       36
 25^2 =      625
 76^2 =     5776
376^2 =   141376
625^2 =   390625

9376^2 = 87909376

jq

Works with: jq

Works with gojq, the Go implementation of jq <lang jq># Input: an upper bound, or null for infinite def steady_squares:

 range(0; . // infinite)
 | tostring as $i
 | select( .*. | tostring | endswith($i));

10000 | steady_squares</lang>

Output:
0
1
5
6
25
76
376
625
9376

GW-BASIC

<lang gwbasic>10 FOR N = 1 TO 10000 20 M$ = STR$(N) 30 M2#=N*N 40 M$ = RIGHT$(M$,LEN(M$)-1) 50 N2$ = STR$(M2#) 60 A = LEN(M$) 70 IF RIGHT$(N2$,A)= M$ THEN PRINT M$,N2$ 80 NEXT N</lang>

Output:

1 1 5 25 6 36 25 625 76 5776 376 141376 625 390625 9376 87909376

MAD

<lang MAD> NORMAL MODE IS INTEGER

           VECTOR VALUES FMT = $I4,7H **2 = ,I8*$
           THROUGH LOOP, FOR I=1, 1, I.G.10000
           THROUGH POW, FOR MASK=1, 0, MASK.G.I

POW MASK = MASK*10

           SQ = I*I
           WHENEVER SQ-SQ/MASK*MASK.E.I
               PRINT FORMAT FMT, I, SQ
           END OF CONDITIONAL

LOOP CONTINUE

           END OF PROGRAM</lang>
Output:
   1**2 =        1
   5**2 =       25
   6**2 =       36
  25**2 =      625
  76**2 =     5776
 376**2 =   141376
 625**2 =   390625
9376**2 = 87909376

Phix

A number n ending in 2,3,4,7,8, or 9 will have a square ending in 4,9,6,9,4 or 1 respectively.
Further a number ending in k 0s will have a square ending in 2*k 0s, and hence always fail, so all possible candidates must end in 1, 5, or 6.
Further, the square of any k-digit number n will end in the same k-1 digits as the square of the number formed from the last k-1 digits of n,
in other words every successful 3-digit n must end with one of the previously successful answers (maybe zero padded), and so on for 4 digits, etc.
I stopped after 8 digits to avoid the need to fire up gmp. Finishes near-instantly, of course.

with javascript_semantics
sequence success = {1,5,6}  -- (as above)
atom p10 = 10
for digits=2 to 8 do
    for d=1 to 9 do
        for i=1 to length(success) do
            atom cand = d*p10+success[i]
            if remainder(cand*cand,p10*10)=cand then
                success &= cand
            end if
        end for
    end for
    p10 *= 10
end for
printf(1,"%d such numbers < 100,000,000 found:\n",length(success))
for i=1 to length(success) do
    atom si = success[i]
    printf(1,"%,11d^2 = %,21d\n",{si,si*si})
end for
Output:
15 such numbers < 100,000,000 found:
          1^2 =                     1
          5^2 =                    25
          6^2 =                    36
         25^2 =                   625
         76^2 =                 5,776
        376^2 =               141,376
        625^2 =               390,625
      9,376^2 =            87,909,376
     90,625^2 =         8,212,890,625
    109,376^2 =        11,963,109,376
    890,625^2 =       793,212,890,625
  2,890,625^2 =     8,355,712,890,625
  7,109,376^2 =    50,543,227,109,376
 12,890,625^2 =   166,168,212,890,625
 87,109,376^2 = 7,588,043,387,109,376

mpz

Obsessed with the idea the series could in fact be finite, I wheeled out gmp anyway and found all n all the way up to a (quite random) 548-digit n, so here it is.
(In other words I am now reasonably confident the series is indeed probably infinite, which would have been a pretty sensible prediction in the first place...)

with javascript_semantics
include mpfr.e
sequence success = {"1","5","6"}    -- (as above)
sequence squared = {"1","25","36"}  -- (kiss)
mpz p10 = mpz_init(10), {d10,sqr,r10} = mpz_inits(3)
--for digits=2 to 8 do
for digits=2 to 48 do
--for digits=2 to 548 do    -- (no real reason...)
    for d=1 to 9 do
        for i=1 to length(success) do
            mpz_mul_si(d10,p10,d)
            mpz cand = mpz_init(success[i])
            mpz_add(cand,d10,cand)
            mpz_mul_si(d10,p10,10)
            mpz_mul(sqr,cand,cand)
            mpz_fdiv_r(r10,sqr,d10)
            if mpz_cmp(cand,r10)=0 then
                success = append(success,mpz_get_str(cand))
                squared = append(squared,mpz_get_str(sqr))
            end if
        end for
    end for
    mpz_mul_si(p10,p10,10)
end for
printf(1,"%d such numbers found:\n",length(success))
for i=1 to length(success) do
    string si = shorten(success[i]),
           sq = shorten(squared[i])
    printf(1,"%12s^2 = %21s\n",{si,sq})
end for

Output is the same as the above, except for the number of them found and lots more output that no-one here should have any interest in seeing.

Python

<lang python> print("working...") print("Steady squares under 10.000 are:") limit = 10000

for n in range(1,limit):

   nstr = str(n)
   nlen = len(nstr)
   square = str(pow(n,2))
   rn = square[-nlen:]
   if nstr == rn:
      print(str(n) + " " + str(square))

print("done...") </lang>

Output:
working...
Steady squares under 10.000 are:
1 1
5 25
6 36
25 625
76 5776
376 141376
625 390625
9376 87909376
done...

Raku

<lang perl6>.say for ({$++²}…*).kv.grep( {$^v.ends-with: $^k} )[1..10]</lang>

Output:
(1 1)
(5 25)
(6 36)
(25 625)
(76 5776)
(376 141376)
(625 390625)
(9376 87909376)
(90625 8212890625)
(109376 11963109376)


Ring

<lang ring> see "working..." +nl see "Steady squatres under 10.000 are:" + nl limit = 10000

for n = 1 to limit

   nstr = string(n)
   len = len(nstr)
   square = pow(n,2)
   rn = right(string(square),len)
   if nstr = rn
      see "" + n + " -> " + square + nl
   ok

next

see "done..." +nl </lang>

Output:
working...
Steady numbers under 10.000 are:
1 -> 1
5 -> 25
6 -> 36
25 -> 625
76 -> 5776
376 -> 141376
625 -> 390625
9376 -> 87909376
done...

Tiny BASIC

Because TinyBASIC is limited to signed 16-bit integers, we need to perform the squaring by repeated addition and then take modulus. That makes for a pretty inefficient solution.

<lang tinybasic>REM N = THE NUMBER TO BE SQUARED REM D = 10^THE NUMBER OF DIGITS IN N REM M = THE SQUARE OF N, MODULO D REM T = TEMP COPY OF N

    LET N = 1
    LET D = 10
 10 IF N > 9 THEN LET D = 100
    IF N > 99 THEN LET D = 1000
    IF N > 999 THEN LET D = 10000
    LET M = 0
    LET T = N
 20 LET M = M + N
    LET M = M - (M/D)*D
    LET T = T - 1
    IF T > 0 THEN GOTO 20
    rem PRINT N, "  ", M
    IF M  = N THEN PRINT N
    LET N = N + 1
    IF N < 10000 THEN GOTO 10
    END</lang>
Output:

1 5 6 25 76 376 625

9376

Wren

Library: Wren-fmt

Although it hardly matters for a small range such as this, one can cut down the numbers to be examined by observing that a steady square must end in 1, 5 or 6. <lang ecmascript>import "./fmt" for Fmt

System.print("Steady squares under 10,000:") var finalDigits = [1, 5, 6] for (i in 1..9999) {

   if (!finalDigits.contains(i % 10)) continue
   var sq = i * i
   if (sq.toString.endsWith(i.toString)) Fmt.print("$,5d -> $,10d", i, sq)

}</lang>

Output:
Steady squares under 10,000:
    1 ->          1
    5 ->         25
    6 ->         36
   25 ->        625
   76 ->      5,776
  376 ->    141,376
  625 ->    390,625
9,376 -> 87,909,376

XPL0

<lang XPL0>int N, P; [for N:= 0 to 10000-1 do

   [P:= 1;
   repeat P:= P*10 until P>N;
   if rem(N*N/P) = N then
       [IntOut(0, N);
       Text(0, "^^2 = ");
       IntOut(0, N*N);
       CrLf(0);
       ];
   ];

]</lang>

Output:
0^2 = 0
1^2 = 1
5^2 = 25
6^2 = 36
25^2 = 625
76^2 = 5776
376^2 = 141376
625^2 = 390625
9376^2 = 87909376