Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 32 additions & 70 deletions euler-0038.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,84 +41,46 @@
// The result may have either 8 or 9 digits and there is an upper limit for the start value.

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

bool isPandigital(const std::string& s, int K) {
if (s.length() != K) return false;
std::vector<bool> seen(K + 1, false); // index 0 to K

for (char c : s) {
int d = c - '0';
if (d == 0 || d > K || seen[d]) return false;
seen[d] = true;
}
return true;
}

int main()
{
unsigned int maxFactor, maxDigit; // 10000 and 9 for the original problem
std::cin >> maxFactor >> maxDigit;

// bitmask if all digits are used
unsigned int bitsAll = 0;
for (unsigned int i = 1; i <= maxDigit; i++)
bitsAll |= 1 << i;

#define ORIGINAL
#ifdef ORIGINAL
// largest pandigital number found so far
unsigned int largest = 0;
#endif

// try all numbers
for (unsigned int i = 2; i <= maxFactor; i++)
{
// the whole pandigital number
unsigned int pandigital = 0;

// multiply i by 1,2,3,...
unsigned int multiplier = 1;

// bitmask of used digits (nth bit is set if pandigital contains digit n)
unsigned int bitsUsed = 0;

while (bitsUsed < bitsAll)
{
// next step
unsigned int product = i * multiplier;
int main() {
int N, K;
std::cin >> N >> K;

// extract right-most digit
while (product > 0)
{
// extract right-most digit
unsigned int digit = product % 10;
// remove it
product /= 10;
std::vector<int> results;

// make room to add i*multiplier lateron
pandigital *= 10;
for (int M = 2; M < N; ++M) {
std::string concat = "";
int multiplier = 1;

// remember all digits we used
unsigned int bitMask = 1 << digit;
// we already had this digit ?
if (digit == 0 || (bitsUsed & bitMask) != 0)
{
bitsUsed = bitsAll + 1; // set to an invalid value
break;
while ((int)concat.length() < K) {
concat += std::to_string(M * multiplier);
++multiplier;
}

// mark current digit as "used"
bitsUsed |= bitMask;
}

// keep going in the sequence
pandigital += i * multiplier;
multiplier++;
if (isPandigital(concat, K)) {
results.push_back(M);
}
}

// enough digits generated ?
if (bitsUsed == bitsAll)
{
#ifdef ORIGINAL
if (largest < pandigital)
largest = pandigital;
#else
std::cout << i << std::endl;
#endif
for (int r : results) {
std::cout << r << std::endl;
}
}

#ifdef ORIGINAL
std::cout << largest << std::endl;
#endif

return 0;
return 0;
}