/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * palindrome26.c
 * Copyright (C) 2021 drdev <gualtieri@ieee.org>
 * 
 * palindrome26 is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * palindrome26 is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//finds palindrome primes in base 26

//to compile using gcc: gcc -o pp26 palindrome26.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

 /* Prototypes */
int strcmp (const char* str1, const char* str2);
char *strcpy(char *dest, const char *src);
char *strrev(char *str);
int factor_sum(int n);
void dec2base26(int n, char* dest);
/* end of prototypes */

int i;
int p;
long int rev_p;
#define limit 100000
char str1[32]="";
char str2[32]="";
char dest[16]=""; //placeholder for base-26 string
char rev_dest[16]=""; //placeholder for base-26 string
FILE *outdata;

char *strrev(char *str)
{
//recreates the strrev function once present in string.h
      char *ptr1, *ptr2;

      if (! str || ! *str)
            return str;
      for (ptr1 = str, ptr2 = str + strlen(str) - 1; ptr2 > ptr1; ++ptr1, --ptr2)
      {
            *ptr1 ^= *ptr2;
            *ptr2 ^= *ptr1;
            *ptr1 ^= *ptr2;
      }
      return str;
}

int factor_sum(int n)
// find prime factors of n; returns the sum of their digits, or zero if the number 
// is a prime number
{
int t;  //  t is the factor that's tested; start small, work bigger
int sum = 0; // sum of factor digits
int factor_count = 0;
t= 2;
sum=0;
factor_count =0;
if(n < 2) return 0;
/* while the test factor t is lower than the number to be factored */
while(t < n)
{
/* if t is a valid prime factor */
if(n % t == 0) 
{
factor_count++;
sum = sum+t;
n /= t;
}
/* else, prime factor is not valid */
else
{
if(t== 2)
{
t = 3;
}
else t += 2;
}
}
factor_count++;
sum = sum+t;
if(factor_count <2)
{
sum=0; // prime number returns a zero
}
return sum;
}

void dec2base26(int n, char* dest)
{
//converts an integer to a reversed base-16 string
//strrev() can be used to extract proper digit order
    char arr[26]="0123456789abcdefghijklmnop";
    int k=0; //character position
    dest[0]='\0'; //null string
    while(n>25)
    {
    dest[k] = arr[n%26];
    k++;
    n /= 26;
    }
    dest[k] = arr[n];
    k++;
    dest[k] = '\0';
}


int main(void)
{

  if ((outdata = fopen ("data.txt", "w")) == NULL)
    {
      printf ("\nOutput datafile cannot be opened.\n");
      exit (1);
    }

for(p=2;p<=limit;p++)
{
if (factor_sum(p)==0)
{
    dec2base26(p,dest);
    strcpy(rev_dest,dest);
    if(strcmp(dest,strrev(rev_dest))==0)
    {
    printf("%d\t%s\t%s\n",p,strrev(rev_dest),dest);
    fprintf(outdata,"%d\t%s\t%s\n",p,strrev(rev_dest),dest);
    }
}
}

//fflush(outdata);

fclose (outdata);

  return (0);
}
