class Palindromes {
static generate(obj) {
const arr = [];
const arrPalindrome = [];
let j = obj.minFactor;
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i);
}
}
j ;
}
arr.forEach((el) => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el);
}
});
return arrPalindrome;
}
get smallest() {
return Palindromes.generate(obj);
//I am using the return value of the STATIC method above to do some calc here.
}
get largest() {}
}
const result = Palindromes.generate({ minFactor: 1, maxFactor: 9 });
console.log(result.smallest);
Here is the problem:
Detect palindrome products in a given range.
A palindromic number is a number that remains the same when its digits are reversed. For example, 121 is a palindromic number but 112 is not.
Given a range of numbers, find the largest and smallest palindromes which are products of two numbers within that range.
Your solution should return the largest and smallest palindromes, along with the factors of each within the range. If the largest or smallest palindrome has more than one pair of factors within the range, then return all the pairs.
Given the range [1, 9] (both inclusive)...
And given the list of all possible products within this range: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 15, 21, 24, 27, 20, 28, 32, 36, 25, 30, 35, 40, 45, 42, 48, 54, 49, 56, 63, 64, 72, 81]
The palindrome products are all single digit numbers (in this case): [1, 2, 3, 4, 5, 6, 7, 8, 9]
The smallest palindrome product is 1. Its factors are (1, 1). The largest palindrome product is 9. Its factors are (1, 9) and (3, 3).
CodePudding user response:
The result
of ...
Palindromes.generate({ minFactor: 1, maxFactor: 9 });
... as of the OP's current implementation is the following array ...
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Thus, there is no smallest
property on this array which is the reason of logging the undefined
value when doing ...
console.log(result.smallest);
The OP needs to think ...
either about the provided code
- e.g. a refactoring of the
smallest
/largest
getter implementations where at least the former features a forwarding call to the static (class) method while providing an unknown / undefinedobj
.
- e.g. a refactoring of the
and/or how to correctly use it
- e.g. by invoking a correctly implemented
smallest
method at an instance ofPalindromes
.
- e.g. by invoking a correctly implemented
class Palindromes {
static generate(obj) {
const arr = [];
const arrPalindrome = [];
let j = obj.minFactor;
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i);
}
}
j ;
}
arr.forEach((el) => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el);
}
});
return arrPalindrome;
}
smallest(config) {
const arrPalindrome = Palindromes.generate(config);
return arrPalindrome[0];
}
largest(config) {
const arrPalindrome = Palindromes.generate(config);
return arrPalindrome[arrPalindrome.length - 1];
}
}
const instance = new Palindromes;
const generated = Palindromes.generate({ minFactor: 1, maxFactor: 9 });
const smallest = instance.smallest({ minFactor: 1, maxFactor: 9 });
const largest = instance.largest({ minFactor: 1, maxFactor: 9 });
console.log({ generated, smallest, largest });
.as-console-wrapper { min-height: 100%!important; top: 0; }
CodePudding user response:
It seems that there are multiple things that could be improved here, as many different things are combined incorrectly (e.g.: getting .smallest
on an instance of Palindromes
currently throws a ReferenceError: obj is not defined
).
I'm not sure how this is intended to be used syntactically, whether this is meant to be a property accessor or if it's meant to be a method.
Property accessor:
Used on instances of Palindromes
:
const p = new Palindromes({ minFactor: 1, maxFactor: 9 })
const result = p.smallest // triggers getter
Used on the Palindromes
class:
const result = Palindromes.smallest // trigger getter
Method:
Used on instances of Palindromes
:
const p = new Palindromes()
const result = p.smallest({ minFactor: 1, maxFactor: 9 })
Used on the Palindromes
class:
const result = Palindromes.smallest({ minFactor: 1, maxFactor: 9 })
So I'll just give the fixes for all.
Property Accessor:
Class usage: WORST SOLUTION
There isn't a way to give arguments to a getter is JS Getter MDN. So this is the worst option, as it requires a getter function that uses environment state (i.e.: environment variables or class static properties) for the arguments to Palindromes.generate()
:
let environmentVariableObject = {}
class Palindromes {
// use default parameters when obj can't be given to generate()
static generate(obj = environmentVariableObject /* or Palindromes */) {
const arr = []
const arrPalindrome = []
let j = obj.minFactor
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i)
}
}
j
}
arr.forEach(el => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el)
}
})
return arrPalindrome
}
// static getter on class
static get smallest() {
return Palindromes.generate()
// or return Palindromes.generate(environmentVariableObject /* or Palindromes */)
// instead of using default parameter to generate()
}
}
environmentVariableObject.minFactor = 1 // or Palindromes.minFactor = 1
environmentVariableObject.maxFactor = 9 // or Palindromes.maxFactor = 9
const result = Palindromes.smallest // trigger getter
console.log(result)
This is BAD! Do not use this solution, it's horrible for readability and will be prone to all kinds of bugs! (e.g.: the properties obj.minFactor
and obj.maxFactor
can be changed or deleted from obj
between different calls to Palindromes.generate()
and triggers of Palindromes.prototype.smallest
, or even while the function is running.)
Instance usage: SOLUTION (but not improvement)
This is closest to what I think the question's code is trying to do.
class Palindromes {
// question's code was missing a constructor for instance of the class
constructor(obj){
this.minFactor = obj.minFactor
this.maxFactor = obj.maxFactor
}
static generate(obj) {
const arr = []
const arrPalindrome = []
let j = obj.minFactor
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i)
}
}
j
}
arr.forEach(el => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el)
}
})
return arrPalindrome
}
// instance getter on prototype of class instead of static getter on class
get smallest() {
return Palindromes.generate(this)
}
}
// create new instance of class
const p = new Palindromes({ minFactor: 1, maxFactor: 9 })
const result = p.smallest // trigger getter
console.log(result)
The problems with the question's code:
- Used argument
obj
which was not defined in getter or the surrounding variable scope. - Didn't create an instance of the
Palindromes
class. - The getter should use
return Palindromes.generate(this)
instead ofreturn Palindromes.generate(obj)
.
While this fixes those problems, it may not be ideal depending on the use case, (I'm still not sure how this is intended to be used). Given the logic the function needs to accomplish in the question, it could be a pure function.
Method:
Using a method makes much more sense given the intended usage in the question allows it to be a method instead of a getter (property accessor). And it should be much better for readability.
Class usage: Good Solution
class Palindromes {
// no constructor needed to create an instance of the class
// because no instances of the class are needed
static generate(obj) {
const arr = []
const arrPalindrome = []
let j = obj.minFactor
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i)
}
}
j
}
arr.forEach(el => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el)
}
})
return arrPalindrome
}
// static method of class
static smallest(obj) {
return Palindromes.generate(obj)
}
}
const result = Palindromes.smallest({ minFactor: 1, maxFactor: 9 }) // call method
console.log(result)
This is a very clean solution, as it doesn't need any new instances of the class to be created and its usage is very short and clear.
Instance usage: Best Solution
class Palindromes {
// no constructor needed to create an instance of the class
static generate(obj) {
const arr = []
const arrPalindrome = []
let j = obj.minFactor
while (j <= obj.maxFactor) {
for (let i = obj.minFactor; i <= obj.maxFactor; i ) {
if (!arr.includes(j * i)) {
arr.push(j * i)
}
}
j
}
arr.forEach(el => {
if (el === String(el).split("").reverse().join()) {
arrPalindrome.push(el)
}
})
return arrPalindrome
}
// instance method on prototype of class
smallest(obj) {
return Palindromes.generate(obj)
}
}
// create a new instance of class just by using new
const p = new Palindromes()
const result = p.smallest({ minFactor: 1, maxFactor: 9 }) // call method
console.log(result)
This is a lot better. It doesn't need any properties or environment variables, and it can set the needed results of the Palindromes.generate()
function (smallest multiple, greatest multiple, set of multiples for each product, etc.) as properties of the class instance: this
.
Revision
After reviewing and rewriting your code, it seems the Palindromes
class is supposed to have the following usage.
- Create palindromes within a given range or from a set of numbers. (NOTE: in it's current implementation it's extremely inefficient!)
- Find products in range (or from set) that are palindromes.
- Find set of multiples whose product are the smallest. (seems to be unimplemented...)
- Find set of multiples whose product are the largest. (also unimplemented...)
- Find the largest palindrome. (also unimplemented...)
- Find the smallest palindrome. (also unimplemented...)
This sounds a lot like an exam question (which is not the type of questions Stack Overflow can or should be used for), so I won't write the logic (just as a precaution, sorry if I misread things...).
But I am able to point in the general right direction!
- It think it would be helpful to reference the Mozilla Developer Network Web Docs and MDN JavaScript Guide
Also, here's why I didn't use semicolons MDN Automatic Semicolon Insertion
Have fun on your JavaSrcipt journey Afzal18!