Skip to content

Instantly share code, notes, and snippets.

@qlkzy
Last active December 29, 2015 09:09
Show Gist options
  • Select an option

  • Save qlkzy/7648785 to your computer and use it in GitHub Desktop.

Select an option

Save qlkzy/7648785 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
static int palindromic(uint64_t x)
{
/* C version for reference
uint64_t rev = 0;
for (uint64_t tmp = x; tmp; tmp /= 10) {
rev *= 10;
rev += tmp % 10;
}
return x == rev;
*/
__asm__ goto (
// initialise
" mov $10, %%r13 \n" // need 10 in a reg for mul/div
" mov $0, %%r14 \n" // build reversed x into r14 [rev]
" mov %0, %%r15 \n" // copy x into a temp [tmp]
"Lrun: \n"
// break when r15 becomes zero
" test %%r15, %%r15 \n"
" jz Ldone \n"
// rev *= 10
" xchg %%rax, %%r14 \n"
" mul %%r13 \n"
" xchg %%rax, %%r14 \n"
// rev += tmp%10; tmp /= 10
" xchg %%rax, %%r15 \n"
" mov $0, %%rdx \n"
" div %%r13 \n"
" xchg %%rax, %%r15 \n"
" add %%rdx, %%r14 \n"
// if r14 doesn't become nonzero immediately,
// x has a trailing zero & is therefore not palindromic
" jz %l2 \n" // no
// round the loop again
" jmp Lrun \n"
"Ldone: \n"
" cmp %%r14, %0 \n"
" je %l1 \n" // yes
:
: "r" (x)
: "rax", "rdx", "r13", "r14", "r15", "cc"
: yes, no
);
no:
return 0;
yes:
return 1;
}
int main()
{
uint64_t max = 0;
uint64_t f_a, f_b, f_c, f_d;
for (uint64_t r = 10000; r > 0; --r)
for (uint64_t a = 99; a > 10; --a) {
for (uint64_t b = a; b > 10; --b) {
uint64_t ab = a*b;
for (uint64_t c = b; c > 10; --c) {
uint64_t abc = ab*c;
for (uint64_t d = c; d > 10; --d) {
uint64_t curr = abc*d;
if (curr < max) break;
if (!palindromic(curr)) continue;
max = curr;
f_a = a;
f_b = b;
f_c = c;
f_d = d;
}
}
}
}
printf("%lu * %lu * %lu * %lu = %lu\n", f_a, f_b, f_c, f_d, max);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment