A sub-unit square is a square number (product of two identical non-negative integers) that remains a square after having a 1 subtracted from each digit in the square.

Task
Sub-unit squares
You are encouraged to solve this task according to the task description, using any language you may know.


E.G.

The number 1 is a sub-unit square. 1 - 1 is 0, which is also a square, though it's kind-of a degenerate case.

The number 3136 is a sub-unit square. 3136 (56²) with unit 1 subtracted from each digit is 2025 (45²).


A sub-unit square cannot contain a digit zero (0) since zero minus one is negative one. Every known sub-unit square, with the exception of 1, ends with the digits 36.


Task
  • Find and display at least the first five sub-unit squares.


See also


Assumes LONG INT is at least 64 bit (as in ALGOL 68G version 2 or 3). Uses the optimisations in the J sample, based on Wherra's observation that the squares (other than 1) must end in 36 (see the Discussion page).

BEGIN # find some sub-unit squares: squares which are still squares when 1 #
      # is subtracted from each of their digits                            #
      # the sub-unit squares must end in 36 (see task discussion) and so   #
      # the square formed by subtracting 1 from each digit must end in 25  #
      # so, as with the J sample, we start with the "25" square and test   #
      # the incremented square                                             #
    # find the sub unit squares - note that 1 is a special case            #
    print( ( "1" ) );
    INT      su count    :=  1;
    LONG INT add ones    :=  1;
    LONG INT power of 10 := 10;
    FOR n FROM 5 BY 10 WHILE su count < 7 DO
        LONG INT sq = ( LENG n ) * ( LENG n );
        WHILE sq > power of 10 DO
            # the square has more digits than the previous one             #
            power of 10 *:= 10;
            add ones    *:= 10 +:= 1
        OD;
        IF  LONG INT add unit sq = sq + add ones;
            add unit sq < power of 10
        THEN
            # squaring the number with one added to the digits has the     #
            # same number of digits as the original square                 #
            IF  LONG INT root        = ENTIER long sqrt( add unit sq );
                root * root = add unit sq
            THEN
                # the add unit square is actually a square                 #
                # make sure there are no 0s in the add unit square as they #
                # can't be decremented to a positive digit                 #
                IF  BOOL no zeros := TRUE;
                    LONG INT v    := add unit sq;
                    WHILE v > 0 AND no zeros DO
                        no zeros := v MOD 10 /= 0;
                        v OVERAB 10
                    OD;
                    no zeros
                THEN
                    print( ( " ", whole( add unit sq, 0 ) ) );
                    su count +:= 1
                FI
            FI
        FI
    OD
END
Output:
1 36 3136 24336 5973136 71526293136 318723477136
Translation of: Oberon-07
begin % find some sub-unit squares: squares which are still squares when 1 %
      % is subtracted from each of their digits                            %
      % the sub-unit squares must end in 36 (see task discussion) and so   %
      % the square formed by subtracting 1 from each digit must end in 25  %
      % so, as with the J sample, we start with the "25" square and test   %
      % the incremented square                                             %

    integer suCount, addOnes, powerOf10, n;

    % find the sub unit squares - note that 1 is a special case            %
    writeon( "1" );
    suCount   :=  1;
    addOnes   :=  1;
    powerOf10 := 10;
    n         := -5;
    while suCount < 5 do begin
        integer sq, addUnitSq;
        n  := n + 10;
        sq := n * n;
        while sq > powerOf10 do begin
            % the square has more digits than the previous one             %
            powerOf10 := powerOf10 * 10;
            addOnes   := ( addOnes * 10 ) + 1
        end;
        addUnitSq := sq + addOnes;
        if addUnitSq < powerOf10 then begin
            integer root;
            % squaring the number with one added to the digits has the     %
            % same number of digits as the original square                 %
            root := entier( sqrt( addUnitSq ) );
            if root * root = addUnitSq then begin
                logical noZeros;
                integer v;
                % the add unit square is actually a square                 %
                % make sure there are no 0s in the add unit square as they %
                % can't be decremented to a positive digit                 %
                noZeros := true;
                v       := addUnitSq;
                while noZeros and v > 0 do begin
                    noZeros := v rem 10 not = 0;
                    v := v div 10
                end;
                if noZeros then begin
                    writeon( i_w := 1, s_w := 0, " ", addUnitSq );
                    suCount := suCount + 1
                end if_noZeros
            end if_addUnitSq_is_a_square
        end if_addUnitSq_lt_powerOf10
    end while_suCount_lt_5
end.
Output:
1 36 3136 24336 5973136
allSquares:  map 1..1000000 'x -> x^2
subUnits: allSquares | select 'z -> not? some? digits z 'w -> w=0 
                     | select 'x -> contains? allSquares to :integer join map digits x 'k -> k-1

print ["The first" size subUnits "sub-unit squares:"]
print subUnits
Output:
The first 10 sub-unit squares:
36 3136 24336 118336 126736 5973136 71526293136 113531259136 137756776336 318723477136
# syntax: GAWK -f SUB-UNIT_SQUARES.AWK
# converted from FreeBASIC
BEGIN {
    n = 1
    while (count <= 7) {
      n2 = n * n
      if (!has_zero(n2)) {
        m2 = dec_digits(n2)
        m = int(sqrt(m2))
        if (m * m == m2) {
          printf("%d ",n2)
          count++
        }
      }
      n++
    }
    printf("\n")
    exit(0)
}
function dec_digits(n,  m,t) {
    m = 11111111111
    while (1) {
      t = n - m
      m = int(m/10)
      if (t >= 0) {
        break
      }
    }
    return(t)
}
function has_zero(n) {
    return(n ~ "0" ? 1 : 0)
}
Output:
1 36 3136 24336 118336 126736 5973136 71526293136
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>

std::vector<uint32_t> find_digits(uint64_t number) {
	std::vector<uint32_t> result;
	while ( number != 0 ) {
		result.emplace(result.begin(), number % 10);
		number /= 10;
	}
	return result;
}

uint64_t find_sub_unit(const std::vector<uint32_t>& digits) {
	uint64_t result = 0;
	for ( const uint32_t& digit : digits ) {
		result = 10 * result + ( digit - 1 );
	}
	return result;
}

bool is_square(const uint64_t& number) {
	const uint64_t squareRoot = std::sqrt(number);
	return number == squareRoot * squareRoot;
}

bool contains(const std::vector<uint32_t>& digits, uint32_t digit) {
	return std::find(digits.begin(), digits.end(), digit) != digits.end();
}

int main() {
	const uint32_t sub_units_required = 7;
	std::cout << "The first " << sub_units_required << " sub-unit squares are:" << std::endl;
	std::cout << 1 << std::endl;
	uint64_t number = 2;
	uint32_t count = 1;
	while ( count < sub_units_required ) {
		const uint64_t square = number * number;
		std::vector<uint32_t> digits = find_digits(square);
		if ( ! contains(digits, 0) && digits[0] != 1 ) {
			const uint64_t sub_unit = find_sub_unit(digits);
			if ( is_square(sub_unit) ) {
				std::cout << square << std::endl;
				count++;
			}
		}
		number++;
	}
}
Output:
The first 7 sub-unit squares are:
1
36
3136
24336
5973136
71526293136
318723477136
Works with: Delphi version 6.0


function IsSubUnitSquare(SQ: integer): boolean;
{Returns true if you subtract one from each digit}
{and it is still square. Assume SQ is square}
var I,J: integer;
var IA: TIntegerDynArray;
begin
Result:=False;
{Get all digits}
GetDigits(SQ,IA);
{Subtract one from each digit}
for J:=0 to High(IA) do
	begin
	{Zeros not allowed = they would cause negative digits}
	if IA[J]=0 then exit;
	IA[J]:=IA[J]-1;
	end;
{Turn digits into number again}
SQ:=DigitsToInt(IA);
{Test if it is square}
if Frac(Sqrt(SQ))<>0 then exit;
Result:=True;
end;

procedure ShowSubUnitSquares(Memo: TMemo);
var I,SQ,Cnt: integer;
begin
Cnt:=0;

for I:=1 to high(Integer) do
	begin
	SQ:=I*I;
	if IsSubUnitSquare(SQ) then
		begin
		Inc(Cnt);
		Memo.Lines.Add(Format('%d %8.0n',[Cnt,SQ+0.0]));
		if Cnt>=7 then break;
		end;
	end;
end;
Output:
1        1
2       36
3    3,136
4   24,336
5  118,336
6  126,736
7 5,973,136
Elapsed Time: 6.899 ms.

func has9 v .
   while v > 0
      if v mod 10 = 9
         return 1
      .
      v = v div 10
   .
   return 0
.
ones = 1
pow10 = 10
while count < 5
   while n * n > pow10
      pow10 *= 10
      ones = ones * 10 + 1
   .
   if has9 (n * n) = 0
      sq = n * n + ones
      if sqrt sq mod 1 = 0
         write " " & sq
         count += 1
      .
   .
   n += 1
.
Output:
 1 36 3136 24336 5973136

see Talk:Sub-unit_squares#Our_friend_the_digital_root

//Sub-unit squares. Nigel Galloway: March 4th., 2026
let dr=[|[1UL;4UL;7UL;9UL];[1UL];[9UL];[1UL;4UL;7UL];[4UL];[9UL];[1UL;4UL;7UL];[7UL];[9UL]|]
let start numD dr=((pown 10UL numD)-1UL)/9UL+dr-uint64(numD%9)
let rec zFree n=match System.Math.DivRem(n,10UL)
                with _,0UL->false |0UL,_->true |n,_->zFree n
let izSq (n:uint64)=let g=sqrt(float n)|>uint64 in n=g*g
let rec fG n g=seq{let r=n*100UL+36UL in if zFree n && izSq r then yield r
                   let n=n+9UL in if n<g then yield! fG n g}
let fN numD=
  let s=((pown 10UL numD)-1UL)/9UL
  dr[numD%9]|>Seq.collect(fun n->fG(start(numD-2) n)(pown 10UL(numD-2))|>Seq.filter(fun n->izSq(n-s)))
seq{yield 1UL; yield 36UL; yield! Seq.initInfinite((+)3)|>Seq.collect(fun g->fN g)}|>Seq.iter(printfn "%d")
Output:
1
36
3136
24336
118336
126736
5973136
71526293136
113531259136
137756776336
318723477136
Function HasZero(n As Uinteger) As Boolean
    Return Iif(Instr(Str(n), "0"), True, False)
End Function

Function DecDigits(n As Uinteger) As Uinteger
    Dim As Integer t, m = 1111111111
    Do
        t = n - m
        m /= 10
    Loop Until t >= 0
    Return t
End Function

Dim As Uinteger n = 1, c = 0
Dim As Uinteger n2, m, m2
Do
    n2 = n*n
    If Not HasZero(n2) Then
        m2 = DecDigits(n2)
        m = Sqr(m2)
        If m*m = m2 Then
            Print n2 & "  ";
            c += 1
        End If
    End If
    n += 1
Loop Until c >= 7

Sleep
Output:
Same as XPL0 entry.
import Data.Char ( digitToInt , intToDigit )

isSquareNumber :: Int -> Bool 
isSquareNumber n = root * root == n
 where
  root :: Int
  root = floor $ sqrt $ fromIntegral n

isSubunitSquare :: Int -> Bool
isSubunitSquare n 
   |elem '0' numstr = False
   |otherwise = isSquareNumber n && isSquareNumber subunitnum
   where
    numstr :: String
    numstr = show n
    subunitnum :: Int
    subunitnum = read $ map (intToDigit . pred . digitToInt ) numstr 

solution :: [Int]
solution = take 7 $ filter isSubunitSquare [1,2..]
Output:
[1,36,3136,24336,118336,126736,5973136]

J

   digits=: 10&#.inv
   idigs=: >:&.digits"0
   (#~ 1-(0 e. digits)"0) (#~ (=<.)@%:)idigs*:5*i.2e5
1 36 3136 24336 5973136 71526293136 318723477136

Here we work in the reverse direction. Since these sub-unit squares always end in 36, their decremented digit version must always end in 25 and the square roots must always end in 5. So, we start with a sequence of multiples of 5, square them, increment their digits and discard those which are not exact squares. Finally, we discard those which contain a 0 digit. (The method used to increment digits here maps 99 to 1010. Arguably, that should instead be 110, but it would get discarded, regardless. (With a little more complexity we could discard anything with a 9 digit while generating the initial sequence, this would provide only a minor gain.))

import java.util.ArrayList;
import java.util.List;

public class Sub_unitSquares {

	public static void main(String[] args) {
		final int sub_unitsRequired = 7;
		System.out.println("The first " + sub_unitsRequired + " sub-unit squares are:");
		System.out.println(1);
		long number = 2;
		int count = 1;
		while ( count < sub_unitsRequired ) {
		    final long square = number * number;
		    List<Integer> digits = digits(square);		    
		    if ( ! digits.contains(0) && digits.get(0) != 1 ) {
		    	final long sub_unit = sub_unit(digits);
		        if ( isSquare(sub_unit) ) {
		            System.out.println(square);
		            count += 1;
		        }
		    }		    
		    number += 1;
		}
		
	}
	
	private static boolean isSquare(long number) {
		final long squareRoot =(long) Math.sqrt(number);
		return number == squareRoot * squareRoot;
	}
	
	private static long sub_unit(List<Integer> digits) {
		long result = 0;
        for ( int digit : digits ) {
        	result = 10 * result + ( digit - 1 );
        }
        return result;
	}
	
	private static List<Integer> digits(long number) {
		List<Integer> result = new ArrayList<Integer>();
		while ( number != 0 ) {
			result.add(0, (int) ( number % 10 ) );
	        number /= 10;
	    }
		return result;
	}

}
Output:
The first 7 sub-unit squares are:
1
36
3136
24336
5973136
71526293136
318723477136

This doesn't include 1, as if numbers with leading ones are disallowed then 1 being an exception doesn't really make sense to me. Uses the fact that all real sub-unit squares (i.e. not 1) end in 36.

function is_square(n) {
  return Number.isInteger(Math.sqrt(n));
}

function is_subunit(n) s (i.e.{
  const s = [...String(n)].map(Number);
  if (s.includes(0) || s[0] === 1) {
    return false;
  }
  const nsub = Number(s.map(x => x - 1).join(""));
  if (is_square(n) && is_square(nsub)) {
    console.log(`${n} = ${Math.sqrt(n)}^2 and ${nsub} = ${Math.sqrt(nsub)}^2`);
    return true;
  }
  return false;
}

let count = 0, n = 36;
while (count < 4) {
  if (is_subunit(n)) {
    count++;
  }
  n += 100;
}
Output:
36 = 6^2 and 25 = 5^2
3136 = 56^2 and 2025 = 45^2
24336 = 156^2 and 13225 = 115^2
5973136 = 2444^2 and 4862025 = 2205^2

The following jq program closely follows the task description and thus includes squares greater than 1 that begin with "1", even though A061844 excludes them.

Since gojq, the Go implementation of jq, uses unbounded-precision integer arithmetic, the program can be expected to produce reliable results when used with that implementation.

By contrast, the C implementation of jq uses IEEE 754 64-bit arithmetic, and so cannot be expected to produce reliable values beyond the first few, though in fact the results using the C-implementation are accurate through at least the first 11 sub-unit squares.

# The following is sufficiently accurate for the task:
def is_square: sqrt | . == floor;

# Emit a stream of "sub-unit squares"
def subunitSquares:
  def sub1:
    tostring | explode
    | if any(. == 48) then null
      else map(.-1) | implode | tonumber
      end;

  foreach range(1; infinite) as $i ( null;
    ($i * $i) as $sq
    | ($sq|sub1)
    | if . == null or (tostring[-1:] | IN("3", "7", "8")) then null
      elif is_square then $sq
      else null
      end;
      select(.) ) ;

11 as $count
| "The first \($count) sub-unit squares are:",
  limit($count; subunitSquares)
Output:
"The first 11 sub-unit squares are:"
1
36
3136
24336
118336
126736
5973136
71526293136
113531259136
137756776336
318723477136
""" Rosetta Code task rosettacode.org/wiki/Sub-unit_squares """

issquare(n::Integer) = isqrt(n)^2 == n
from_subsquare(n) = (d = digits(n); all( x -> x < 9, d) && issquare(evalpoly(10, d .+ 1)))
println("Subunit squares up to 10^12: ",
   pushfirst!([evalpoly(10, digits(i^2) .+ 1) for i in 5:10:10^6 if from_subsquare(i^2)], 1))
Output:
Subunit squares up to 10^12: [1, 36, 3136, 24336, 5973136, 71526293136, 318723477136]

Alternative procedural version.

Translation of: Lua
# find some sub-unit squares: squares which are still squares when 1
# is subtracted from each of their digits
# the sub-unit squares must end in 36 (see task discussion) and so
# the square formed by subtracting 1 from each digit must end in 25
# so, as with the J sample, we start with the "25" square and test
# the incremented square

begin # find the sub unit squares - note that 1 is a special case
    local maxCount  =  7
    local suSquares = collect( 1 : maxCount ) # array initially 1, 2, 3, ...
    local suCount   =  1
    local addOnes   =  1
    local powerOf10 = 10
    local n         = -5
    while suCount < maxCount
        n += 10
        sq = n^2
        while sq > powerOf10
            # the square has more digits than the previous one
            powerOf10 *= 10
            addOnes   *= 10
            addOnes   +=  1
        end
        addUnitSq = sq + addOnes
        if addUnitSq < powerOf10
            # squaring the number with one added to the digits has the
            # same number of digits as the original square
            local root = isqrt( addUnitSq )
            if root^2 == addUnitSq
                # the addUnitSquare is actually a square
                # make sure there are no 0s in the addUnitSquare as they
                # can't be decremented to a positive digit
                if all( x -> x != 0, digits( addUnitSq ) )
                    suCount += 1
                    suSquares[ suCount ] = addUnitSq
                end
            end
        end
    end
    println( suSquares )
end
Output:
[1, 36, 3136, 24336, 5973136, 71526293136, 318723477136]
Translation of: ALGOL 68

Tested with Lua 5.2.4

do  --[[ find some sub-unit squares: squares which are still squares when 1
         is subtracted from each of their digits
         the sub-unit squares must end in 36 (see task discussion) and so
         the square formed by subtracting 1 from each digit must end in 25
         so, as with the J sample, we start with the "25" square and test
         the incremented square
    --]]
    -- find the sub unit squares - note that 1 is a special case
    io.write( "1" )
    local suCount   =  1
    local addOnes   =  1
    local powerOf10 = 10
    local n         = -5
    while suCount < 7 do
        n = n + 10
        local sq = n * n
        while sq > powerOf10 do
            -- the square has more digits than the previous one
            powerOf10 = powerOf10 * 10
            addOnes   = ( addOnes * 10 ) + 1
        end
        local addUnitSq = sq + addOnes
        if addUnitSq < powerOf10
        then
            -- squaring the number with one added to the digits has the
            -- same number of digits as the original square
            local root = math.floor( math.sqrt( addUnitSq ) )
            if root * root == addUnitSq
            then
                -- the addUnitSquare is actually a square
                -- make sure there are no 0s in the addUnitSquare as they
                -- can't be decremented to a positive digit
                local noZeros = true
                local v       = addUnitSq
                while v > 0 and noZeros do
                    noZeros = v % 10 ~= 0
                    v = math.floor( v / 10 )
                end
                if noZeros
                then
                    io.write( " ", addUnitSq )
                    suCount = suCount + 1
                end
            end
        end
    end
end
Output:
1 36 3136 24336 5973136 71526293136 318723477136
subUnitSquare[1] = True;
subUnitSquare[n_] := With[{dig = IntegerDigits[n]},
    IntegerQ[Sqrt[n]] &&
    Min[dig] > 0 &&
    First[dig] != 1 &&
    IntegerQ[Sqrt[FromDigits[dig - 1]]]];

res = {};
n = 1;
While[Length[res] < 5,
    If[subUnitSquare[n^2], AppendTo[res, n^2]];
    n++;
];
res // TableForm
Output:
1      
36     
3136   
24336  
5973136
ctr = 1
tt = time
while ctr < 1000000
	a = ctr ^ 2
	aa = str(a)
	if a == 1 or (a % 100 == 36 and aa.indexOf("0") == null) then
		b = a - ("1" * aa.len).val
		c = b ^ 0.5
		if floor(c) == c then print a
	end if
	ctr +=1
	while not (ctr % 10 == 4 or ctr % 10 == 6)
		ctr += 1
	end while
end while
Output:
1
36
3136
24336
118336
126736
5973136
71526293136
113531259136
137756776336
318723477136
import std/[algorithm, math, strutils]

func digits(n: Positive): seq[int] =
  ## Return the sequence of digits of "n".
  var n = n.Natural
  while n != 0:
    result.add n mod 10
    n = n div 10
  result.reverse()

func toInt(digits: seq[int]): int =
  ## Convert a sequence of digits to an integer.
  for d in digits:
    result = 10 * result + d

func isSquare(n: int): bool =
  ## Return true if "n" is square.
  let r = sqrt(n.toFloat).int
  result = r * r == n

echo "First eight sub-unit squares:"
echo 1
var n = 0
var count = 1
while count < 8:
  inc n, 5
  block Check:
    var digs = digits(n * n)
    for d in digs.mitems:
      if d == 9: break Check
      inc d
    let s = digs.toInt
    if s.isSquare:
      inc count
      echo s
Output:
First eight sub-unit squares:
1
36
3136
24336
5973136
71526293136
318723477136
264779654424693136
Translation of: ALGOL 68

...but only finding 5 sub-unit squares as integers are 32-bit in oberonc and OBNC.

MODULE SubUnitSquares;
    (* find some sub-unit squares: squares which are still squares when 1   *)
    (* is subtracted from each of their digits                              *)
    (* the sub-unit squares must end in 36 (see task discussion) and so     *)
    (* the square formed by subtracting 1 from each digit must end in 25    *)
    (* so, as with the J sample, we start with the "25" square and test     *)
    (* the incremented square                                               *)

    IMPORT Out, Math;

VAR suCount, addOnes, powerOf10, n, sq, addUnitSq, root, v   : INTEGER;
    noZeros                                                  : BOOLEAN;

BEGIN
    (* find the sub unit squares - note that 1 is a special case            *)
    Out.String( "1" );
    suCount   :=  1;
    addOnes   :=  1;
    powerOf10 := 10;
    n         := -5;
    WHILE suCount < 5 DO
        INC( n, 10 );
        sq := n * n;
        WHILE sq > powerOf10 DO
            (* the square has more digits than the previous one             *)
            powerOf10 := powerOf10 * 10;
            addOnes   := ( addOnes * 10 ) + 1
        END;
        addUnitSq := sq + addOnes;
        IF addUnitSq < powerOf10 THEN
            (* squaring the number with one added to the digits has the     *)
            (* same number of digits as the original square                 *)
            root := FLOOR( Math.sqrt( FLT( addUnitSq ) ) );
            IF root * root = addUnitSq THEN
                (* the add unit square is actually a square                 *)
                (* make sure there are no 0s in the add unit square as they *)
                (* can't be decremented to a positive digit                 *)
                noZeros := TRUE;
                v       := addUnitSq;
                WHILE noZeros & ( v > 0 ) DO
                    noZeros := v MOD 10 # 0;
                    v := v DIV 10
                END;
                IF noZeros THEN
                    Out.String( " " );Out.Int( addUnitSq, 0 );
                    INC( suCount )
                END
            END
        END
    END
END SubUnitSquares.
Output:
1 36 3136 24336 5973136

simple brute force.

program SubUnitSquares;
{$OPTIMIZATION ON,ALL}
procedure CheckForZero(n,i,j:NativeUint);
var
  q,dgt: NativeUint;
begin
  repeat
    q := n DIV 10;
    dgt := n-10*q;
    if dgt = 0 then
      EXIT;
    n := q
  until q = 0;
  j := (j-1) SHR 1;i := (i-1) SHR 1;   
  writeln(j:10,sqr(j):20,' -> ',sqr(i):20,i:10);
end;

var
  sqI,sqJ,dSqrI,dSqrJ,Pot10Limit,RepUnit : NativeUInt;
BEGIN
   Pot10Limit := 10;      
   RepUnit := 1;

   sqj := 1;      // 1*1
   sqI := RepUnit;// 0+RepUnit
   dSqrI := 1;
   dSqrJ := 2*1+1;
   
   repeat
     if sqJ = sqI then
       CheckForZero(sqj,dSqrI,dSqrJ); 
   
     repeat
       sqJ += dSqrJ;
       inc(dSqrJ,2);       
     until sqJ>=sqI;
           
     //one more digit
     if sqJ >= Pot10Limit then
     begin
//     choose dSqrI and sqJ so, that next sqJ starts with digit 2
       RepUnit += Pot10Limit;
       dSqrI := trunc(sqrt(2*Pot10Limit-RepUnit));              
       dSqrJ := trunc(sqrt(2*Pot10Limit));       
       Pot10Limit *= 10;
       sqI := dSqrI*dSqrI+RepUnit;
       dSqrI := 2*dSqrI+1;
       sqJ := dSqrJ*dSqrJ;
       dSqrJ := 2*dSqrJ+1;
     end;
     
     repeat
       sqI += dSqrI;
       inc(dSqrI,2);
     until sqI>=sqJ;
   until dSqrJ >2*514567445; //2*2*1000*1000*1000;//
END.
@TIO.RUN:
         1                   1 ->                    0         0
         6                  36 ->                   25         5
        56                3136 ->                 2025        45
       156               24336 ->                13225       115
      2444             5973136 ->              4862025      2205
    267444         71526293136 ->          60415182025    245795
    564556        318723477136 ->         207612366025    455645
 514567444  264779654424693136 ->   153668543313582025 392005795
@home 0.22user before 0.34
@TIO.RUN Real time: 0.979 s before Real time: 0.871 s

Like Raku, but without the laziness.

use v5.36;

sub U ($n) { $n>1 ? (2*$n)**2 : 1 }
sub L ($n) { $n**2 }
sub R ($n) { 1 x $n }

my($l,$u,$c) = (-1);

while (++$u) {
    next if U($u) =~ /0/;
    my $chars = length U($u);
    while ($l++) {
        next if U($u) - L($l) > R($chars);
        last if U($u) - L($l) < R($chars);
        say U($u) and ++$c == 7 and exit
    }
}
Output:
1
36
3136
24336
5973136
71526293136
318723477136

A more efficient approach:

Translation of: Sidef
Library: ntheory
use 5.036;
use bigint try => 'GMP';
use ntheory qw(:all);

sub difference_of_two_squares_solutions ($n) {

    my @solutions;
    my $limit = sqrtint($n);

    foreach my $divisor (divisors($n)) {

        last if $divisor > $limit;

        my $p = $divisor;
        my $q = $n / $divisor;

        ($p + $q) % 2 == 0 or next;

        my $x = ($q + $p) >> 1;
        my $y = ($q - $p) >> 1;

        unshift @solutions, [$x, $y];
    }

    return @solutions;
}

my $N    = 20;         # how many terms to compute
my %seen = (1 => 1);

my $index = 1;
say($index, ': ', 1);

OUTER: for (my $n = 1 ; ; ++$n) {

    my $r = (10**$n - 1) / 9;

    foreach my $xy (difference_of_two_squares_solutions($r)) {

        my $xsqr = $xy->[0]**2;
        my @d    = todigits($xsqr);

        next if $d[0] == 1;
        next if !vecall { $_ } @d;
        next if !is_square(fromdigits([map { $_ - 1 } @d]));

        if (!$seen{$xsqr}++) {
            say(++$index, ': ', $xsqr);
            last OUTER if ($index >= $N);
        }
    }
}
Output:
1: 1
2: 36
3: 3136
4: 24336
5: 5973136
6: 71526293136
7: 318723477136
8: 264779654424693136
9: 24987377153764853136
10: 31872399155963477136
11: 58396845218255516736
12: 517177921565478376336
13: 252815272791521979771662766736
14: 518364744896318875336864648336
15: 554692513628187865132829886736
16: 658424734191428581711475835136
17: 672475429414871757619952152336
18: 694688876763154697414122245136
19: 711197579293752874333735845136
20: 975321699545235187287523246336
Library: Phix/online

Uses the much faster method from the OEIS page.

with javascript_semantics
function sub_unit_squares(integer digits, atom d1s)
    -- d1s is eg 1111 for digits==4
    sequence res = {}
    for f in factors(d1s,1) do
        atom g = d1s/f,
             a = (f+g)/2,
             b = (f-g)/2
        if a*a-b*b=d1s then
            string a2 = sprintf("%d",a*a)
            if length(a2)=digits
--          and (digits=1 or a2[1]!='1')
            and not find('0',a2) then
                res = append(res,a2)
            end if
        end if
    end for
    res = unique(res)
    return res
end function

atom n = 1, t0 = time()
sequence res = {}
for digits=1 to iff(machine_bits()=32?12:18) do
    res &= sub_unit_squares(digits,n)
    n = n*10+1
end for
printf(1,"Found %d sub-unit squares in %s:\n%s\n",{length(res),elapsed(time()-t0),join(res,"\n")})

As per the Julia jq entry, while A061844 explicitly excludes squares beginning with 1 apart from 1 itself, this task does not.
It would of course be trivial to exclude them using either and a2[1]!='1', or and length(sprintf("%d",b*b))=digits.
Technically 32 bit will go to 16 digits and 64 bit to 19, but it won't find any more answers, so there's no point.

Output:

(64 bit - 32bit only shows the first 11, in 0s)

Found 15 sub-unit squares in 2.2s:
1
36
3136
24336
118336
126736
5973136
71526293136
113531259136
137756776336
318723477136
118277763838638336
118394723955598336
126825269186126736
264779654424693136

Should you uncomment the additional test so the output matches A061844, it'll only show 8 (or 7 under 32-bit).

gmp version

You can run this online here.

with javascript_semantics
include mpfr.e
constant match_A061844 = true
function sub_unit_squares(integer digits)
    progress("sub_unit_squares(%d)\r",{digits})
    mpz d1s = mpz_init(repeat('1',digits))
    sequence res = {}
    mpz {g,a,b,t} = mpz_inits(4)
    atom t1 = time()+1
    sequence fs = mpz_factors({"mpz",d1s},1,false)
    for i,f in fs do
        mpz_fdiv_q(g,d1s,f)             -- g = d1s/f
        mpz_add(a,f,g)
        mpz_sub(b,f,g)
        assert(mpz_fdiv_q_ui(a,a,2)=0)  -- a = (f+g)/2
        assert(mpz_fdiv_q_ui(b,b,2)=0)  -- b = (f-g)/2
        mpz_mul(a,a,a)
        mpz_mul(b,b,b)
        mpz_sub(b,a,b)
        if mpz_cmp(b,d1s)=0 then        -- a*a-b*b = d1s
            string a2 = mpz_get_str(a)  -- (a*a by now)
            if length(a2)=digits
            and (not match_A061844 or digits=1 or a2[1]!='1')
            and not find('0',a2) then
                res = append(res,a2)
            end if
        end if
        if time()>t1 then
            progress("sub_unit_squares(%d): factor %d/%d...\r",{digits,i,length(fs)})
            t1 = time()+1
        end if
    end for
    progress("")
    res = unique(res)
    return res
end function

atom t = time()
sequence res = {}, tests = tagset(32)
--tests &= {40,42,54,60,64,66,72,84,90,96} -- see below
for digits in tests do
    res &= sub_unit_squares(digits)
end for
printf(1,"Found %d sub-unit squares in %s:\n%s\n",{length(res),elapsed(time()-t),join(res,"\n")})
Output:
Found 23 sub-unit squares in 0.5s:
1
36
3136
24336
5973136
71526293136
318723477136
264779654424693136
24987377153764853136
31872399155963477136
58396845218255516736
517177921565478376336
252815272791521979771662766736
518364744896318875336864648336
554692513628187865132829886736
658424734191428581711475835136
672475429414871757619952152336
694688876763154697414122245136
711197579293752874333735845136
975321699545235187287523246336
23871973274358556957126877486736
25347159162241162461433882565136
34589996454813135961785697637136

Should you set match_A061844 to false, ie include numbers >1 that begin with 1, it'll find another 27 bringing the total to 50.

While sub_unit_squares(38) exceeded my patience, let alone sub_unit_squares(180), at a push and cheating slightly but at least matching/verifying A061844, extending tests with {40,42,54,60,64,66,72,84,90,96} gets (or 156 when match_A061844 is false):

Found 77 sub-unit squares in 11 minutes and 26s:
1
36
3136
24336
5973136
71526293136
318723477136
264779654424693136
24987377153764853136
31872399155963477136
58396845218255516736
517177921565478376336
252815272791521979771662766736
518364744896318875336864648336
554692513628187865132829886736
658424734191428581711475835136
672475429414871757619952152336
694688876763154697414122245136
711197579293752874333735845136
975321699545235187287523246336
23871973274358556957126877486736
25347159162241162461433882565136
34589996454813135961785697637136
2858541763747552538199941619545257144336
214785886789716796533667464535274377236736
233292528132679183463629157143235636286736
244671849793441155421899813243325528686736
271571567929448516411695557685613529966736
322388381596588665613523969581347191316736
385414415625146742626881165526237149942336
494827714874767379344736911473964125592336
729191918879671448289782722539515523333136
739265858539339252384919139328667324488336
451616391374794616993675837721511769881724292768597136
225155131198959884498111695266319246921397575282262981916736
235533149167838594417145126422746861139269181233838789763136
247165591495471317848341556972927924777146487462821199752336
253185584977741571193838716134142968698828866536879387589136
255118517389891411837338761327472341665993165261943933973136
258794681328961385589665886866946129315831982462313647221136
264638279877394985436962113298797369525794994152638329716736
274993879679611537524346229892753979256782689558714439941136
317227344555757949695298635797266762327152673658761948316736
322778753177461749385975279423679631448585894831889496126736
359789363125538627844318913392816245152758765579763311486736
393441389391373434369197686452869535953373734343532842366736
414994447929493177987216182314238968483589993433234743387136
425694769821125433165871546269244331365369797668913817432336
432644594437123781553749497955531461492791463379194125966736
437562512527813432113133967677338524499138828662399714286736
449852946468284983783199424761436133724851432965597753717136
482134751872773928421842374421611988974497596294794558126736
521975939684451673253113662113934173792645168416634454516736
527522135343484614696922441512961219362733539657782899395136
562641631377938237248318531478861249592277376289475543144336
571185124453583434863858314331338695842867554344647955413136
572684988569547784165849427621699664494716729842793127896336
614898423328697552174926774454594881158921253578236236792336
633696482563387284528138567949516822355885534948846913486736
643289923123766413527889349998824883237881684711852761436736
667191497411655246112479559487494956367164427966476793774336
687676275633214498821343918455779943946116536644394167797136
738581581372137137454777164721328295342861142971169656536336
762742925841272953426291121719451613531524131158969765243136
775543441492587483465982446818139435456241975693619925238336
848683965199869214645864196533185358672353998728624638126736
947138642349237674483499271295327433171899196661387174341136
964891172337149147689484881922848848795484622547192848916736
5569531161785335471834187656758668584186145889911322362616238336
392218699139394917429267256144352916588419663779199636243639414336
848357125461439331518387328465823399571373158999455173816177975229891136
416423361382974375988119796395668527245964353555414577638838888367828457388415992336
479474784622574743882185337518915188918922331343493318921536469363248612788886766736
241835624857156131887688175431621247512542273949817527242228179562863761282638896774325136
398574359223975871554875716496874244751857937743666637999272258371878627497383572366715136
917299545663587142783558195917968989124276866721326391286476151415422729817578418459766336
689912968699291934123339418659749956627118749536638166817937181829315824413919788889194395285136

I will note that in sub_unit_squares(96), mpz_factors() takes 7 mins, vs. mpz_pollard_rho() 3 mins, and builds a list of 4,194,304 factors, of which we're only really interested in a middle block of just 171,710, so there may be a potential two-fold or more speedup in there, somewhere. Alas the needed mpz_pollard_rho() [as occurs within mpz_factors] of sub_unit_squares(38|180) also exceeded my patience, so it wouldn't help with that.

Translation of: Wren
Library: Pluto-int
local int = require "int"

print("The first 7 sub-unit squares are:")
print(1)
local i = 2
local count = 1
while count < 7 do
    local sq = i * i
    local digits = int.digits(sq)
    if digits[1] != 1 and !digits:contains(0) then
        local sum = digits[1] - 1
        for j = 2, #digits do sum = sum * 10  + digits[j] - 1 end
        if int.issquare(sum) then
            print(sq)
            count += 1
        end
    end
    i +=1
end
Output:
The first 7 sub-unit squares are:
1
36
3136
24336
5973136
71526293136
318723477136
Library: gmpy2
# sub-unit_squares.py by Xing216
from gmpy2 import is_square
def digits(n: int) -> list[int]:
    return [int(d) for d in str(n)]
def get_sub_unit(digits_n: list[int], n: int) -> int:
    return int(''.join([str(d-1) for d in digits_n]))
def is_sub_unit_square(n: int) -> bool:
    if not is_square(n): return False
    digits_n = digits(n)
    if 0 in digits_n: return False
    sub_unit = get_sub_unit(digits_n, n)
    if len(str(sub_unit)) != len(str(n)): return False
    return is_square(sub_unit)
res = []
i = 1
while len(res) < 5:
    if is_sub_unit_square(i): res.append(i)
    i += 1
print(res)
Output:
[1, 36, 3136, 24336, 5973136]

R

Translation of: JavaScript
digits <- function(n, nd) rev((n %/% (10^(1:nd - 1))) %% 10)

recombine <- function(v) Reduce(function(x, y) 10*x + y, v)

is_square <- function(n) sqrt(n) %% 1 == 0

is_subunit <- function(n, nd) {
  digs <- digits(n, nd)
  if (0 %in% digs || digs[1] == 1) return(list(result = FALSE))
  nsub <- recombine(digs - 1)
  res <- is_square(n) && is_square(nsub)
  list(result = res, n = n, rn = sqrt(n), nsub = nsub, rnsub = sqrt(nsub))
}

nd <- 2
count <- 0
n <- 36
while (count < 4) {
  test <- is_subunit(n, nd)
  if (test$result) {
    do.call(sprintf, c("%i = %i^2 and %i = %i^2", tail(test, -1))) |> cat("\n")
    count <- count + 1
  }
  n <- n + 100
  if (n > 10^(nd)) nd <- nd + 1
}
Output:
36 = 6^2 and 25 = 5^2 
3136 = 56^2 and 2025 = 45^2 
24336 = 156^2 and 13225 = 115^2 
5973136 = 2444^2 and 4862025 = 2205^2 

First seven take about 5 seconds with this implementation. The eighth would take several hours at least.

my @upper = 1,|(1 .. *).map((* × 2)²);
my @lower = (^∞).map: *²;
my \R = [\+] 0, 1, 10, 100 … *;

my $l = 0;

.say for (gather {
    (^∞).map: -> $u {
        next if @upper[$u].contains: 0;
        my $chars = @upper[$u].chars;
        loop {
            $l++ and next   if @upper[$u] - @lower[$l]  > R[$chars];
            take @upper[$u] if @upper[$u] - @lower[$l] == R[$chars];
            last;
        }
    }
})[^7]
Output:
1
36
3136
24336
5973136
71526293136
318723477136
Rebol [
    title: "Rosetta code: Sub-unit squares"
    file: %Sub-unit_squarese.r3
    url: https://rosettacode.org/wiki/Sub-unit_squares
]
;; A "sub-unit square" is a perfect square where:
;;   1. No digit is 0 (since subtracting 1 would produce a -1 digit)
;;   2. Its last two digits are "36" (necessary condition — see note below)
;;   3. Subtracting 1 from every digit yields another perfect square

sub-unit-square?: function [
    "Return true if the number is a sub-unit square."
    num [integer!]
][
    ;; Convert the number to a mutable string of digit characters
    str: append clear "" num
    all [
        ;; Reject any number containing a 0 digit — subtracting 1 would be invalid
        not find str #"0"
        ;; Fast pre-filter: sub-unit squares must end in "36"
        ;; (only squares ending in 36 can produce a square when each digit is decremented)
        "36" == skip tail str -2
        ;; Decrement every digit character in-place by 1
        ;; (e.g. "149" becomes "038", which as an integer is 38)
        forall str [str/1: str/1 - 1]
        ;; Parse the modified string back into an integer
        num: to integer! str
        ;; Compute the integer square root of the decremented number
        sqr: to integer! square-root num
        ;; Confirm it is a perfect square (guards against floating-point rounding)
        sqr * sqr == num
    ]
]

;; Collect the first 10 sub-unit squares
sub-unit-squares: copy []
n: 1
while [10 > length? sub-unit-squares][
    num: n * n
    ;; Test the current square and collect it if it qualifies
    if sub-unit-square? num [ append sub-unit-squares num ]
    ;; Advance to the next integer so we test the next perfect square
    ++ n
]

print "The first 10 sub-unit squares:"
print sub-unit-squares
Output:
The first 10 sub-unit squares:
36 3136 24336 118336 126736 5973136 71526293136 113531259136 137756776336 318723477136

Since brute force is not an option for 4-bit computer languages, we use the method described in the OEIS page, based on the resolution of x² - y² = 11..1 The line OVER →STR 1 1 SUB "1" ≠ AND can be removed to obtain the OEIS sequence. FACTS is defined at Factors of an integer

RPL code Comment
IFERR FP NOT THEN DROP 0 END ≫ ‘INT?’ STO
 
≪ 
   ALOG 1 - 9 /
   DUP FACTS 1 OVER SIZE 2 / CEIL SUB → ones factors
   ≪ { } 1 factors SIZE FOR j
        factors j GET ones OVER / + 2 / SQ
        IF 
           DUP XPON ones XPON ==
           OVER →STR "0" POS NOT AND
           OVER →STR 1 1 SUB "1" ≠ AND
           OVER ones - √ INT? AND 
        THEN + ELSE DROP END
     NEXT
≫ ≫ ‘SUBUNITS’ STO
INT? ( x → boolean ) 

SUBUNITS ( n → { SUS } ) 
ones = (10^n-1)/9
factors = half of the full FACTS list is enough
for each factor
   x = ((factor+factor/ones)/2)^2
   if
    x has same number of digits as ones
    and x does not contain any zero
    and x does not start with 1
    and x's sub-unit square is an integer
   then append x to list
next
return list
≪ 2 { 1 } WHILE DUP SIZE 5 < REPEAT OVER SUBUNITS + SWAP 1 + SWAP END SWAP DROP ≫ EVAL
Output:
1: { 1 36 3136 24336 5973136 }

Returned in 41 seconds on a basic HP-48SX... but finding the following SUS (71526293136) took one hour and a half, essentially to factor 11111111111 = 21649 x 513239

fn is_square_number( number : u64 ) -> bool {
   let root : f64 = (number as f64).sqrt( ).floor( ) ;
   (root as u64) * (root as u64) == number 
}

fn is_subunit_square( number : u64 ) -> bool {
   let numberstring = number.to_string( ) ;
   let numstring : &str = numberstring.as_str( ) ;
   if numstring.contains( '0' ) {
      return false ;
   }
   else {
      if number < 10 {
         is_square_number( number ) && is_square_number( number - 1 )
      }
      else {
         let mut digits : Vec<u64> = Vec::new( ) ;
         let mut num : u64 = number ;
         while num != 0 {
            digits.push( num % 10 ) ;
            num /= 10 ;
         }
         for n in digits.iter_mut( ) {
            *n -= 1 ;
         }
         let mut sum : u64 = 0 ;
         let mut factor : u64 = 1 ;
         for d in digits {
            sum += d * factor ;
            factor *= 10 ;
         }
         is_square_number( sum ) && is_square_number( number )
      }
   }
}

fn main() {
   let mut solution : Vec<u64> = Vec::new( ) ;
   let mut current : u64 = 1 ;
   while solution.len( ) != 7 {
      if is_subunit_square( current ) {
         solution.push( current ) ;
      }
      current += 1 ;
   }
   println!("{:?}" , solution ) ;
}
Output:
[1, 36, 3136, 24336, 118336, 126736, 5973136]

Using the method described in the OEIS entry, representing (10^n - 1)/9 as a difference of squares x^2 - y^2 and checking x^2 to see if it satisfies the conditions.

var N   = 20      # how many terms to compute
var arr = Set(1)

for n in (1..Inf) {
    var r = (10**n - 1)/9
    arr << r.diff_of_squares.map{.head}.map{.sqr.digits}.grep {|d|
        (d[-1] != 1) && d.none{.is_zero} && d.map{.dec}.digits2num.is_square
    }.map{.digits2num}...
    break if (arr.len >= N)
}

arr.sort.first(N).each_kv {|k,n|
    say "#{'%2d' % k+1}: #{n}"
}
Output:
 1: 1
 2: 36
 3: 3136
 4: 24336
 5: 5973136
 6: 71526293136
 7: 318723477136
 8: 264779654424693136
 9: 24987377153764853136
10: 31872399155963477136
11: 58396845218255516736
12: 517177921565478376336
13: 252815272791521979771662766736
14: 518364744896318875336864648336
15: 554692513628187865132829886736
16: 658424734191428581711475835136
17: 672475429414871757619952152336
18: 694688876763154697414122245136
19: 711197579293752874333735845136
20: 975321699545235187287523246336

Square candidates, check for zeros, check for sub-unit squares.

▽=⊸⁅√⊸⍜°⋕-₁▽⊸≡(≤˜⨂@0⟜⧻°⋕)ⁿ2↘1⇡1000000
Output:
[1 36 3136 24336 118336 126736 5973136 71526293136 113531259136 137756776336 318723477136]  
Library: Wren-math

Apart from the number '1' itself, it looks like the first digit can't be '1' either. In other words, the number of digits in the transformed number must remain unchanged.

import "./math" for Int

System.print("The first 7 sub-unit squares are:")
System.print(1)
var i = 2
var count = 1
while (count < 7) {
    var sq = i * i
    var digits = Int.digits(sq)
    if (digits[0] != 1 && !digits.contains(0)) {
        var sum = digits[0] - 1
        for (i in 1...digits.count) sum = sum * 10  + digits[i] - 1
        if (Int.isSquare(sum)) {
            System.print(sq)
            count = count + 1
        }
    }
    i = i + 1
}
Output:
The first 7 sub-unit squares are:
1
36
3136
24336
5973136
71526293136
318723477136
func HasZero(N);        \Return 'true' if N contains a zero digit
int  N;
[repeat N:= N/10;
        if rem(0) = 0 then return true;
until   N=0;
return false;
];

func DecDigits(N);      \Decrement each digit of N
int  N, M, T;
[M:= 1_111_111_111;
repeat  T:= N-M;
        M:= M/10;
until   T >= 0;
return T;
];

int  N, C, N2, M, M2;
[N:= 1;  C:= 0;
repeat  N2:= N*N;
        if not HasZero(N2) then
            [M2:= DecDigits(N2);
            M:= sqrt(M2);
            if M*M = M2 then
                [IntOut(0, N2);
                ChOut(0, ^ );
                C:= C+1;
                ];
            ];
        N:= N+1;
until   C >=7;
]
Output:
1 36 3136 24336 118336 126736 5973136 
Translation of: Wren
import "std/vec.zc"
import "std/math.zc"

fn digits<T>(n: T) -> Vec<int> {
    let digs = Vec<int>::new();
    if n == 0 {
        digs << 0;
        return digs;
    }
    while n > 0 {
        digs << (n % 10);
        n /= 10;
    }
    digs.reverse();
    return digs;
}

fn is_square<T>(n: T) -> bool {
    let sqrt = (T)Math::round(Math::sqrt((f64)n));
    return sqrt * sqrt == n;
}

fn main() {
    println "The first 7 sub-unit squares are:";
    println "1";
    let count = 1;
    for let i: u64 = 2; count < 7; i++ {
        let sq = i * i;
        let digs = digits(sq);
        if digs[0] != 1 && !digs.contains(0) {
            let sum: u64 = digs[0] - 1;
            for j in 1..digs.length() { sum = sum * 10 + digs[j] - 1; }
            if is_square(sum) {
                println "{sq}";
                count++;
            }
        }
    }
}
Output:
The first 7 sub-unit squares are:
1
36
3136
24336
5973136
71526293136
318723477136