Improve Vampire Number (#6110)

This commit is contained in:
Stanislav Belogolov
2025-01-01 23:43:00 +01:00
committed by GitHub
parent 2da56d6ee4
commit 14db275c2b
2 changed files with 54 additions and 52 deletions

View File

@ -1,78 +1,48 @@
package com.thealgorithms.maths; package com.thealgorithms.maths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
/** /**
* n number theory, a vampire number (or true vampire number) is a composite * In number theory, a vampire number (or true vampire number) is a composite
* natural number with an even number of digits, that can be factored into two * natural number with an even number of digits, that can be factored into two
* natural numbers each with half as many digits as the original number and not * natural numbers each with half as many digits as the original number and not
* both with trailing zeroes, where the two factors contain precisely all the * both with trailing zeroes, where the two factors contain precisely all the
* digits of the original number, in any order, counting multiplicity. The first * digits of the original number, in any order, counting multiplicity. The first
* vampire number is 1260 = 21 × 60. * * vampire number is 1260 = 21 × 60.
* *
* <p> * @see <a href='https://en.wikipedia.org/wiki/Vampire_number'>Vampire number on Wikipedia</a>
* link: https://en.wikipedia.org/wiki/Vampire_number *
*
* <p>
*/ */
public final class VampireNumber { public final class VampireNumber {
// Forbid instantiation.
private VampireNumber() { private VampireNumber() {
} }
public static void main(String[] args) { static boolean isVampireNumber(int a, int b, boolean ignorePseudoVampireNumbers) {
test(10, 1000); // Pseudo vampire numbers don't have to be of n/2 digits. E.g., 126 = 6 x 21 is such a number.
} if (ignorePseudoVampireNumbers && String.valueOf(a).length() != String.valueOf(b).length()) {
return false;
static void test(int startValue, int stopValue) {
int countofRes = 1;
StringBuilder res = new StringBuilder();
for (int i = startValue; i <= stopValue; i++) {
for (int j = i; j <= stopValue; j++) {
// System.out.println(i+ " "+ j);
if (isVampireNumber(i, j, true)) {
countofRes++;
res.append("").append(countofRes).append(": = ( ").append(i).append(",").append(j).append(" = ").append(i * j).append(")").append("\n");
}
}
}
System.out.println(res);
}
static boolean isVampireNumber(int a, int b, boolean noPseudoVamireNumbers) {
// this is for pseudoVampireNumbers pseudovampire number need not be of length n/2 digits
// for example 126 = 6 x 21
if (noPseudoVamireNumbers) {
if (a * 10 <= b || b * 10 <= a) {
return false;
}
} }
String mulDigits = splitIntoDigits(a * b, 0); String mulDigits = splitIntoSortedDigits(a * b);
String faktorDigits = splitIntoDigits(a, b); String factorDigits = splitIntoSortedDigits(a, b);
return mulDigits.equals(faktorDigits); return mulDigits.equals(factorDigits);
} }
// methode to Split the numbers to Digits // Method to split a pair of numbers to digits and sort them in the ascending order.
static String splitIntoDigits(int num, int num2) { static String splitIntoSortedDigits(int... nums) {
StringBuilder res = new StringBuilder(); // Collect all digits in a list.
ArrayList<Integer> digits = new ArrayList<>(); ArrayList<Integer> digits = new ArrayList<>();
while (num > 0) { for (int num : nums) {
digits.add(num % 10); while (num > 0) {
num /= 10; digits.add(num % 10);
} num /= 10;
while (num2 > 0) { }
digits.add(num2 % 10);
num2 /= 10;
}
Collections.sort(digits);
for (int i : digits) {
res.append(i);
} }
// Sort all digits and convert to String.
StringBuilder res = new StringBuilder();
digits.stream().sorted().forEach(res::append);
return res.toString(); return res.toString();
} }
} }

View File

@ -0,0 +1,32 @@
package com.thealgorithms.maths;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class VampireNumberTest {
@Test
void areVampireNumbers() {
Assertions.assertTrue(VampireNumber.isVampireNumber(15, 93, true));
Assertions.assertTrue(VampireNumber.isVampireNumber(135, 801, true));
Assertions.assertTrue(VampireNumber.isVampireNumber(201, 600, true));
}
@Test
void arePseudoVampireNumbers() {
Assertions.assertTrue(VampireNumber.isVampireNumber(150, 93, false));
Assertions.assertTrue(VampireNumber.isVampireNumber(546, 84, false));
Assertions.assertTrue(VampireNumber.isVampireNumber(641, 65, false));
}
@Test
void areNotVampireNumbers() {
Assertions.assertFalse(VampireNumber.isVampireNumber(51, 39, false));
Assertions.assertFalse(VampireNumber.isVampireNumber(51, 39, true));
}
@Test
void testSplitIntoSortedDigits() {
Assertions.assertEquals("123", VampireNumber.splitIntoSortedDigits(321));
Assertions.assertEquals("02234", VampireNumber.splitIntoSortedDigits(20, 324));
}
}