In number theory, a weird number is a natural number that is abundant but not semiperfect. In other words, the sum of the proper divisors (divisors including 1 but not itself) of the number is greater than the number, but no subset of those divisors sums to the number itself.
Given a number N, the task is to check if the number is weird or not.
Examples:
Input: 40
Output: The number is not weird
1+4+5+10+20=40, hence it is not weird.
Input: 70
Output: The number is Weird
The smallest weird number is 70. Its proper divisors are 1, 2, 5, 7, 10, 14, and 35; these sum to 74, but no subset of these sums to 70.
The number 12, for example, is abundant but not weird, because the proper divisors of 12 are 1, 2, 3, 4, and 6, which sum to 16; but 2+4+6 = 12. The first few weird numbers are 70, 836, 4030, 5830, 7192, 7912, 9272, 10430, 10570, 10792, 10990, 11410, 11690, 12110, 12530, 12670, 13370, 13510, …
Approach: Check if the number is abundant or not. The approach has been discussed here. Once the checking has been done, check if the number is semiperfect or not. The approach for checking semiperfect numbers has been discussed here.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors( int n)
{
vector< int > v;
v.push_back(1);
for ( int i = 2; i <= sqrt (n); i++) {
if (n % i == 0) {
v.push_back(i);
if (n / i != i) {
v.push_back(n / i);
}
}
}
return v;
}
bool checkAbundant( int n)
{
vector< int > v;
int sum = 0;
v = factors(n);
for ( int i = 0; i < v.size(); i++) {
sum += v[i];
}
if (sum > n)
return true ;
else
return false ;
}
bool checkSemiPerfect( int n)
{
vector< int > v;
v = factors(n);
sort(v.begin(), v.end());
int r = v.size();
bool subset[r + 1][n + 1];
for ( int i = 0; i <= r; i++)
subset[i][0] = true ;
for ( int i = 1; i <= n; i++)
subset[0][i] = false ;
for ( int i = 1; i <= r; i++) {
for ( int j = 1; j <= n; j++) {
if (j < v[i - 1])
subset[i][j] = subset[i - 1][j];
else {
subset[i][j] = subset[i - 1][j] ||
subset[i - 1][j - v[i - 1]];
}
}
}
if ((subset[r][n]) == 0)
return false ;
else
return true ;
}
bool checkweird( int n)
{
if (checkAbundant(n) == true &&
checkSemiPerfect(n) == false )
return true ;
else
return false ;
}
int main()
{
int n = 70;
if (checkweird(n))
cout << "Weird Number" ;
else
cout << "Not Weird Number" ;
return 0;
}
|
Java
import java.util.*;
class GFG
{
static ArrayList<Integer> factors( int n)
{
ArrayList<Integer> v = new ArrayList<Integer>();
v.add( 1 );
for ( int i = 2 ;
i <= Math.sqrt(n); i++)
{
if (n % i == 0 )
{
v.add(i);
if (n / i != i)
{
v.add(n / i);
}
}
}
return v;
}
static boolean checkAbundant( int n)
{
ArrayList<Integer> v;
int sum = 0 ;
v = factors(n);
for ( int i = 0 ; i < v.size(); i++)
{
sum += v.get(i);
}
if (sum > n)
return true ;
else
return false ;
}
static boolean checkSemiPerfect( int n)
{
ArrayList<Integer> v;
v = factors(n);
Collections.sort(v);
int r = v.size();
boolean subset[][] = new boolean [r + 1 ][n + 1 ];
for ( int i = 0 ; i <= r; i++)
subset[i][ 0 ] = true ;
for ( int i = 1 ; i <= n; i++)
subset[ 0 ][i] = false ;
for ( int i = 1 ; i <= r; i++)
{
for ( int j = 1 ; j <= n; j++)
{
if (j < v.get(i - 1 ))
subset[i][j] = subset[i - 1 ][j];
else {
subset[i][j] = subset[i - 1 ][j] ||
subset[i - 1 ][j -
v.get(i - 1 )];
}
}
}
if ((subset[r][n]) == false )
return false ;
else
return true ;
}
static boolean checkweird( int n)
{
if (checkAbundant(n) == true &&
checkSemiPerfect(n) == false )
return true ;
else
return false ;
}
public static void main(String args[])
{
int n = 70 ;
if (checkweird(n))
System.out.println( "Weird Number" );
else
System.out.println( "Not Weird Number" );
}
}
|
Python3
from math import sqrt
def factors(n):
v = []
v.append( 1 )
for i in range ( 2 , int (sqrt(n)) + 1 , 1 ):
if (n % i = = 0 ):
v.append(i);
if ( int (n / i) ! = i):
v.append( int (n / i))
return v
def checkAbundant(n):
sum = 0
v = factors(n)
for i in range ( len (v)):
sum + = v[i]
if ( sum > n):
return True
else :
return False
def checkSemiPerfect(n):
v = factors(n)
v.sort(reverse = False )
r = len (v)
subset = [[ 0 for i in range (n + 1 )]
for j in range (r + 1 )]
for i in range (r + 1 ):
subset[i][ 0 ] = True
for i in range ( 1 , n + 1 ):
subset[ 0 ][i] = False
for i in range ( 1 , r + 1 ):
for j in range ( 1 , n + 1 ):
if (j < v[i - 1 ]):
subset[i][j] = subset[i - 1 ][j]
else :
subset[i][j] = (subset[i - 1 ][j] or
subset[i - 1 ][j - v[i - 1 ]])
if ((subset[r][n]) = = 0 ):
return False
else :
return True
def checkweird(n):
if (checkAbundant(n) = = True and
checkSemiPerfect(n) = = False ):
return True
else :
return False
if __name__ = = '__main__' :
n = 70
if (checkweird(n)):
print ( "Weird Number" )
else :
print ( "Not Weird Number" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static List< int > factors( int n)
{
List< int > v = new List< int >();
v.Add(1);
for ( int i = 2;
i <= Math.Sqrt(n); i++)
{
if (n % i == 0)
{
v.Add(i);
if (n / i != i)
{
v.Add(n / i);
}
}
}
return v;
}
static Boolean checkAbundant( int n)
{
List< int > v;
int sum = 0;
v = factors(n);
for ( int i = 0; i < v.Count; i++)
{
sum += v[i];
}
if (sum > n)
return true ;
else
return false ;
}
static Boolean checkSemiPerfect( int n)
{
List< int > v;
v = factors(n);
v.Sort();
int r = v.Count;
Boolean [,]subset = new Boolean[r + 1,n + 1];
for ( int i = 0; i <= r; i++)
subset[i,0] = true ;
for ( int i = 1; i <= n; i++)
subset[0,i] = false ;
for ( int i = 1; i <= r; i++)
{
for ( int j = 1; j <= n; j++)
{
if (j < v[i-1])
subset[i,j] = subset[i - 1,j];
else {
subset[i,j] = subset[i - 1,j] ||
subset[i - 1,j -
v[i-1]];
}
}
}
if ((subset[r,n]) == false )
return false ;
else
return true ;
}
static Boolean checkweird( int n)
{
if (checkAbundant(n) == true &&
checkSemiPerfect(n) == false )
return true ;
else
return false ;
}
public static void Main(String []args)
{
int n = 70;
if (checkweird(n))
Console.WriteLine( "Weird Number" );
else
Console.WriteLine( "Not Weird Number" );
}
}
|
Javascript
<script>
function factors(n)
{
var v = [];
v.push(1);
for ( var i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
v.push(i);
if (n / i != i) {
v.push(n / i);
}
}
}
return v;
}
function checkAbundant(n)
{
var v = [];
var sum = 0;
v = factors(n);
for ( var i = 0; i < v.length; i++) {
sum += v[i];
}
if (sum > n)
return true ;
else
return false ;
}
function checkSemiPerfect(n)
{
var v = [];
v = factors(n);
v.sort()
var r = v.length;
var subset = Array.from(Array(r+1), ()=>Array(n+1));
for ( var i = 0; i <= r; i++)
subset[i][0] = true ;
for ( var i = 1; i <= n; i++)
subset[0][i] = false ;
for ( var i = 1; i <= r; i++) {
for ( var j = 1; j <= n; j++) {
if (j < v[i - 1])
subset[i][j] = subset[i - 1][j];
else {
subset[i][j] = subset[i - 1][j] ||
subset[i - 1][j - v[i - 1]];
}
}
}
if ((subset[r][n]) == 0)
return false ;
else
return true ;
}
function checkweird(n)
{
if (checkAbundant(n) == true &&
checkSemiPerfect(n) == false )
return true ;
else
return false ;
}
var n = 70;
if (checkweird(n))
document.write( "Weird Number" );
else
document.write( "Not Weird Number" );
</script>
|
Time Complexity: O(N * number of factors)
Auxiliary Space: O(N * number of factors)
Efficient approach : Space optimization
In previous approach the current value subset[i][j] is only depend upon the current and previous row values of subset matrix. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors( int n)
{
vector< int > v;
v.push_back(1);
int sqrtN = sqrt (n);
for ( int i = 2; i <= sqrtN; i++) {
if (n % i == 0) {
v.push_back(i);
if (n / i != i) {
v.push_back(n / i);
}
}
}
return v;
}
bool checkAbundant( int n)
{
vector< int > v;
v = factors(n);
int sum = 0;
for ( int i = 0; i < v.size(); i++) {
sum += v[i];
}
return sum > n;
}
bool checkSemiPerfect( int n)
{
vector< int > v;
v = factors(n);
sort(v.begin(), v.end());
int r = v.size();
vector< bool > subset(n + 1, false );
subset[0] = true ;
for ( int i = 0; i < r; i++) {
for ( int j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
return subset[n];
}
bool checkWeird( int n)
{
return checkAbundant(n) && !checkSemiPerfect(n);
}
int main()
{
int n = 70;
if (checkWeird(n))
cout << "Weird Number" ;
else
cout << "Not Weird Number" ;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.Collections;
public class Main {
static ArrayList<Integer> factors( int n) {
ArrayList<Integer> v = new ArrayList<>();
v.add( 1 );
int sqrtN = ( int ) Math.sqrt(n);
for ( int i = 2 ; i <= sqrtN; i++) {
if (n % i == 0 ) {
v.add(i);
if (n / i != i) {
v.add(n / i);
}
}
}
return v;
}
static boolean checkAbundant( int n) {
ArrayList<Integer> v;
v = factors(n);
int sum = 0 ;
for ( int i = 0 ; i < v.size(); i++) {
sum += v.get(i);
}
return sum > n;
}
static boolean checkSemiPerfect( int n) {
ArrayList<Integer> v;
v = factors(n);
Collections.sort(v);
int r = v.size();
boolean [] subset = new boolean [n + 1 ];
subset[ 0 ] = true ;
for ( int i = 0 ; i < r; i++) {
for ( int j = n; j >= v.get(i); j--) {
subset[j] = subset[j] || subset[j - v.get(i)];
}
}
return subset[n];
}
static boolean checkWeird( int n) {
return checkAbundant(n) && !checkSemiPerfect(n);
}
public static void main(String[] args) {
int n = 70 ;
if (checkWeird(n))
System.out.println( "Weird Number" );
else
System.out.println( "Not Weird Number" );
}
}
|
Python3
import math
def factors(n):
v = [ 1 ]
sqrtN = int (math.sqrt(n))
for i in range ( 2 , sqrtN + 1 ):
if n % i = = 0 :
v.append(i)
if n / / i ! = i:
v.append(n / / i)
return v
def checkAbundant(n):
v = factors(n)
sum_factors = sum (v)
return sum_factors > n
def checkSemiPerfect(n):
v = factors(n)
v.sort()
r = len (v)
subset = [ False ] * (n + 1 )
subset[ 0 ] = True
for i in range (r):
for j in range (n, v[i] - 1 , - 1 ):
subset[j] = subset[j] or subset[j - v[i]]
return subset[n]
def checkWeird(n):
return checkAbundant(n) and not checkSemiPerfect(n)
n = 70
if checkWeird(n):
print ( "Weird Number" )
else :
print ( "Not Weird Number" )
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
static List< int > Factors( int n)
{
List< int > v = new List< int >{ 1 };
int sqrtN = ( int )Math.Sqrt(n);
for ( int i = 2; i <= sqrtN; i++) {
if (n % i == 0) {
v.Add(i);
if (n / i != i) {
v.Add(n / i);
}
}
}
return v;
}
static bool CheckAbundant( int n)
{
List< int > v = Factors(n);
int sumFactors = v.Sum();
return sumFactors > n;
}
static bool CheckSemiPerfect( int n)
{
List< int > v = Factors(n);
v.Sort();
int r = v.Count;
bool [] subset = new bool [n + 1];
subset[0] = true ;
for ( int i = 0; i < r; i++) {
for ( int j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
return subset[n];
}
static bool CheckWeird( int n)
{
return CheckAbundant(n) && !CheckSemiPerfect(n);
}
static void Main()
{
int n = 70;
if (CheckWeird(n)) {
Console.WriteLine( "Weird Number" );
}
else {
Console.WriteLine( "Not Weird Number" );
}
}
}
|
Javascript
function GFG(n) {
const v = [1];
const sqrtN = Math.sqrt(n);
for (let i = 2; i <= sqrtN; i++) {
if (n % i === 0) {
v.push(i);
if (n / i !== i) {
v.push(n / i);
}
}
}
return v;
}
function checkAbundant(n) {
const v = GFG(n);
let sum = 0;
for (let i = 0; i < v.length; i++) {
sum += v[i];
}
return sum > n;
}
function checkSemiPerfect(n) {
const v = GFG(n).sort();
const r = v.length;
const subset = new Array(n + 1).fill( false );
subset[0] = true ;
for (let i = 0; i < r; i++) {
for (let j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
return subset[n];
}
function checkWeird(n) {
return checkAbundant(n) && !checkSemiPerfect(n);
}
function main() {
const n = 70;
if (checkWeird(n)) {
console.log( "Weird Number" );
} else {
console.log( "Not Weird Number" );
}
}
main();
|
Time Complexity: O(N * number of factors)
Auxiliary Space: O(N)
Last Updated :
29 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...