Numbers which are not the sum of distinct squares: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
No edit summary
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(13 intermediate revisions by 4 users not shown)
Line 32:
* [[oeis:A001422|OEIS: A001422 Numbers which are not the sum of distinct squares]]
 
 
=={{header|ALGOL 68}}==
Recursive brute force (tempting though it is to use 9 nested loops... :) ), using the proof that if 129-324 can be expressed as the sum of distinct squares, then all integers greater than 128 can be so expressed - see the link in the Wren sample.
<syntaxhighlight lang="algol68">
CO find the integers that can't be expressed as the sum of distinct squares
it can be proved that if 120-324 can be expressed as the sum of distinct
squares then all integers greater than 129 can be so expressed
(see the link in the Wren sample) so we need to check that 129-324 can
be so expressed and find the numbers below 129 that can't be so expressed
CO
BEGIN
INT max number = 324;
[ 0 : max number ]BOOL is sum; FOR i FROM LWB is sum TO UPB is sum DO is sum[ i ] := FALSE OD;
INT max square = ENTIER sqrt( 324 );
[ 0 : max square ]INT square; FOR i FROM LWB square TO UPB square DO square[ i ] := i * i OD;
 
PROC flag sum = ( INT curr sum, sq pos )VOID:
IF INT next sum = curr sum + square[ sq pos ];
next sum <= UPB is sum
THEN
is sum[ next sum ] := TRUE;
FOR i FROM sq pos + 1 TO UPB square DO
flag sum( next sum, i )
OD
FI # flag sum # ;
 
FOR i FROM LWB square TO UPB square DO
flag sum( 0, i )
OD;
# show the numbers that can't be formed from a sum of distinct squares #
# and check 129-324 can be so formed #
INT unformable := 0;
FOR i FROM LWB is sum TO UPB is sum DO
IF NOT is sum[ i ] THEN
print( ( whole( i, -4 ) ) );
IF ( unformable +:= 1 ) MOD 12 = 0 THEN print( ( newline ) ) FI;
IF i > 128 THEN
print( ( newline, "**** unexpected unformable number: ", whole( i, 0 ), newline ) )
FI
FI
OD
END
</syntaxhighlight>
{{out}}
<pre>
2 3 6 7 8 11 12 15 18 19 22 23
24 27 28 31 32 33 43 44 47 48 60 67
72 76 92 96 108 112 128
</pre>
 
=={{header|ALGOL W}}==
{{Trans|ALGOL 68}}
<syntaxhighlight lang="algolw">
begin comment find the integers that can't be expressed as the sum of distinct squares
it can be proved that if 120-324 can be expressed as the sum of distinct
squares then all integers greater than 129 can be so expressed
(see the link in the Wren sample) so we need to check that 129-324 can
be so expressed and find the numbers below 129 that can't be so expressed
;
integer MAX_NUMBER, MAX_SQUARE;
MAX_NUMBER := 324;
MAX_SQUARE := entier( sqrt( MAX_NUMBER ) );
 
begin
logical array isSum ( 0 :: MAX_NUMBER );
integer array square ( 0 :: MAX_SQUARE );
integer unformable;
 
procedure flagSum ( integer value currSum, sqPos ) ; begin
integer nextSum;
nextSum := currSum + square( sqPos );
if nextSum <= MAX_NUMBER then begin
isSum( nextSum ) := true;
for i := sqPos + 1 until MAX_SQUARE do flagSum( nextSum, i )
end of_nextSum_le_MAX_NUMBER
end flagSum ;
 
for i := 0 until MAX_NUMBER do isSum( i ) := false;
for i := 0 until MAX_SQUARE do square( i ) := i * i;
for i := 0 until MAX_SQUARE do flagSum( 0, i );
% show the numbers that can't be formed from a sum of distinct squares %
% and check 129-324 can be so formed %
unformable := 0;
for i := 0 until MAX_NUMBER do
if not isSum( i ) then begin
writeon( i_w := 4, s_w := 0, i );
unformable := unformable + 1;
if unformable rem 12 = 0 then write();
if i > 128 then write( i_w := 1, s_w := 0, "**** unexpected unformable number: ", i )
end if_not_isSum__i
end
end.
</syntaxhighlight>
{{out}}
<pre>
2 3 6 7 8 11 12 15 18 19 22 23
24 27 28 31 32 33 43 44 47 48 60 67
72 76 92 96 108 112 128
</pre>
 
=={{header|C#|CSharp}}==
Line 196 ⟶ 295:
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <numeric>
#include <vector>
 
void print_vector(const std::vector<int32_t>& list) {
std::cout << "[";
for ( uint64_t i = 0; i < list.size() - 1; ++i ) {
std::cout << list[i] <<", ";
}
std::cout << list.back() << "]" << std::endl;
}
 
bool sum_of_distinct_squares(const int32_t& n, const std::vector<int32_t>& squares) {
if ( n <= 0 ) {
return false;
}
if ( find(squares.begin(), squares.end(), n) != squares.end() ) {
return true;
}
 
const int32_t sum = std::accumulate(squares.begin(), squares.end(), 0);
if ( n > sum ) {
return false;
}
if ( n == sum ) {
return true;
}
 
std::vector<int32_t> reversed_squares(squares);
reversed_squares.erase(reversed_squares.end() - 1);
std::reverse(reversed_squares.begin(), reversed_squares.end());
 
return sum_of_distinct_squares(n - squares[squares.size() - 1], reversed_squares)
|| sum_of_distinct_squares(n, reversed_squares);
}
 
int main() {
std::vector<int32_t> squares;
std::vector<int32_t> result;
int32_t test_number = 1;
int32_t previous_test_number = 1;
while ( previous_test_number >= ( test_number >> 1 ) ) {
const int32_t square_root = static_cast<int32_t>(std::sqrt(test_number));
if ( square_root * square_root == test_number ) {
squares.emplace_back(test_number);
}
if ( ! sum_of_distinct_squares(test_number, squares) ) {
result.emplace_back(test_number);
previous_test_number = test_number;
}
test_number++;
}
 
std::cout << "Numbers which are not the sum of distinct squares:" << std::endl;
print_vector(result);
std::cout << "\n" << "Stopped checking after finding " << ( test_number - previous_test_number )
<< " sequential non-gaps after the final gap of " << previous_test_number << std::endl;
std::cout << "Found " << result.size() << " numbers in total" << std::endl;
}
</syntaxhighlight>
{{ out }}
<pre>
Numbers which are not the sum of distinct squares:
[2, 3, 6, 7, 8, 11, 12, 15, 18, 19, 22, 23, 24, 27, 28, 31, 32, 33, 43, 44, 47, 48, 60, 67, 72, 76, 92, 96, 108, 112, 128]
 
Stopped checking after finding 130 sequential non-gaps after the final gap of 128
Found 31 numbers in total
</pre>
 
=={{header|Delphi}}==
Line 309 ⟶ 482:
</pre>
 
 
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight lang=easylang>
maxNumber = 324
len isSum[] maxNumber
maxSquare = floor sqrt maxNumber
#
proc flagSum currSum sqPos . .
nextSum = currSum + sqPos * sqPos
if nextSum <= maxNumber
isSum[nextSum] = 1
for i = sqPos + 1 to maxSquare
flagSum nextSum i
.
.
.
for i = 1 to maxSquare
flagSum 0 i
.
for i = 1 to maxNumber
if isSum[i] = 0
write i & " "
.
.
</syntaxhighlight>
 
=={{header|Go}}==
Line 405 ⟶ 604:
<syntaxhighlight lang=J> task''
2 3 6 7 8 11 12 15 18 19 22 23 24 27 28 31 32 33 43 44 47 48 60 67 72 76 92 96 108 112 128</syntaxhighlight>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
public final class NumbersNotSumDistinctSquares {
 
public static void main(String[] aArgs) {
List<Integer> squares = new ArrayList<Integer>();
List<Integer> result = new ArrayList<Integer>();
int testNumber = 1;
int previousTestNumber = 1;
while ( previousTestNumber >= ( testNumber >> 1 ) ) {
final int squareRoot = (int) Math.sqrt(testNumber);
if ( squareRoot * squareRoot == testNumber ) {
squares.add(testNumber);
}
if ( ! sumOfDistinctSquares(testNumber, squares) ) {
result.add(testNumber);
previousTestNumber = testNumber;
}
testNumber += 1;
}
System.out.println("Numbers which are not the sum of distinct squares:");
System.out.println(result);
System.out.println();
System.out.println("Stopped checking after finding " + ( testNumber - previousTestNumber )
+ " sequential non-gaps after the final gap of " + previousTestNumber);
System.out.println("Found " + result.size() + " numbers in total");
}
private static boolean sumOfDistinctSquares(int aN, List<Integer> aSquares) {
if ( aN <= 0 ) {
return false;
}
if ( aSquares.contains(aN) ) {
return true;
}
final int sum = aSquares.stream().mapToInt(Integer::intValue).sum();
if ( aN > sum ) {
return false;
}
if ( aN == sum ) {
return true;
}
List<Integer> reversedSquares = new ArrayList<Integer>(aSquares);
reversedSquares.remove(reversedSquares.size() - 1);
Collections.reverse(reversedSquares);
return sumOfDistinctSquares(aN - aSquares.get(aSquares.size() - 1), reversedSquares)
|| sumOfDistinctSquares(aN, reversedSquares);
}
 
}
</syntaxhighlight>
{{ out }}
<pre>
Numbers which are not the sum of distinct squares:
[2, 3, 6, 7, 8, 11, 12, 15, 18, 19, 22, 23, 24, 27, 28, 31, 32, 33, 43, 44, 47, 48, 60, 67, 72, 76, 92, 96, 108, 112, 128]
 
Stopped checking after finding 130 sequential non-gaps after the final gap of 128
Found 31 numbers in total
</pre>
 
=={{header|jq}}==
Line 497 ⟶ 764:
<pre>
[2, 3, 6, 7, 8, 11, 12, 15, 18, 19, 22, 23, 24, 27, 28, 31, 32, 33, 43, 44, 47, 48, 60, 67, 72, 76, 92, 96, 108, 112, 128]
</pre>
 
=={{header|Lua}}==
{{Trans|ALGOL 68}}
<syntaxhighlight lang="lua">
do --[[ find the integers that can't be expressed as the sum of distinct squares
it can be proved that if 120-324 can be expressed as the sum of distinct squares
then all integers greater than 129 can be so expressed (see the link in
the Wren sample) so we need to check that 129-324 can be so expressed
and find the numbers below 129 that can't be so expressed
--]]
local maxNumber = 324
local isSum = {}
local maxSquare = math.floor( math.sqrt( 324 ) )
local square = {} for i = 0,maxSquare do square[ i ] = i * i end
 
local function flagSum ( currSum, sqPos )
local nextSum = currSum + square[ sqPos ]
if nextSum <= maxNumber then
isSum[ nextSum ] = true
for i = sqPos + 1, maxSquare do
flagSum( nextSum, i )
end
end
end
 
for i = 0,maxSquare do
flagSum( 0, i )
end
--[[ show the numbers that can't be formed from a sum of distinct squares
and check 129-324 can be so formed
--]]
local unformable = 0
for i = 0, maxNumber do
if not isSum[ i ] then
io.write( string.format( "%4d", i ) )
unformable = unformable + 1
if unformable % 12 == 0 then io.write( "\n" ) end
if i > 128 then
io.write( "\n", "**** unexpected unformable number: ", i, "\n" )
end
end
end
end
</syntaxhighlight>
{{out}}
<pre>
2 3 6 7 8 11 12 15 18 19 22 23
24 27 28 31 32 33 43 44 47 48 60 67
72 76 92 96 108 112 128
</pre>
 
Line 807 ⟶ 1,124:
2 3 6 7 8 ... 92 96 108 112 128 (31 numbers which are not the sum of distinct squares)
</pre>
 
=={{header|Quackery}}==
 
<code>from</code>, <code>index</code>, <code>end</code>, and <code>incr</code> are defined at [[Loops/Increment loop index within loop body#Quackery]].
 
'''Method'''
 
We generate numbers which are the Sum Of Distinct Squares (SODS) up to N<sup>2</sup> by generating a list of the SODS up to (N-1)<sup>2</sup>, then adding each of those numbers + N<sup>2</sup> to the list. For N=0 the list is [0]. This method produces some duplicates along the way so after each iteration we remove any duplicates using <code>sort unique</code>. (<code>unique</code> requires a sorted list.)
 
As noted in other solutions, once there is a run longer than (N+1)<sup>2</sup>, all the subsequent numbers will be SODS. <code>missing</code> returns the length and position of the longest run. (After the last iteration, some SODS will be missing from the list after the longest run, but we can be confident that they will be found in further iterations as noted in other task solutions.) The length is used to test for when we can stop iterating, and the position tells us where we can trim the list.
 
Finally, <code>missing</code> generates a list of the numbers which are not SODS from the list of SODS. (This is why we need to trim the list; so it does not include the numbers which are SODS but had not yet been added to the list.)
 
<syntaxhighlight lang="Quackery"> [ [] swap
behead swap
witheach
[ 2dup = iff
drop done
dip join ]
join ] is unique ( [ --> [ )
 
[ stack ] is cut ( --> s )
 
[ -1 cut put
1 temp put
1 swap
behead swap
witheach
[ tuck - -1 = iff
[ dip 1+
over temp share
> if
[ over temp replace
i^ cut replace ] ]
else
[ nip 1 swap ] ]
2drop
temp take cut take ] is maxrun ( [ --> n n )
 
[ [] swap 0 over
witheach [ bit | ]
swap -1 peek times
[ dup i^ bit & not if
[ dip [ i^ join ] ] ]
drop ] is missing ( [ --> [ )
 
1 temp put
' [ 0 ]
1 from
[ dup witheach
[ temp share +
join ]
sort unique
dup maxrun drop
index 2 + temp tally
temp share > iff
end done
2 incr ]
temp release
dup maxrun
nip split
drop missing
say "Numbers that are not the sum of distinct squares:"
cr echo</syntaxhighlight>
 
{{out}}
 
<pre>Numbers that are not the sum of distinct squares:
[ 2 3 6 7 8 11 12 15 18 19 22 23 24 27 28 31 32 33 43 44 47 48 60 67 72 76 92 96 108 112 128 ]</pre>
 
=={{header|Raku}}==
Line 832 ⟶ 1,218:
===Brute force===
This uses a brute force approach to generate the relevant numbers, similar to Julia, except using the same figures as the above proof. Still slow in Wren, around 20 seconds.
<syntaxhighlight lang="ecmascriptwren">var squares = (1..18).map { |i| i * i }.toList
var combs = []
var results = []
Line 887 ⟶ 1,273:
{{libheader|Wren-fmt}}
Hugely quicker in fact - only 24 ms, the same as C# itself.
<syntaxhighlight lang="ecmascriptwren">import "./math" for Nums
import "./fmt" for Fmt
 
9,476

edits