c - 519
(veya çerçeve için bana kredi verirseniz 137 ...)
Sadece bu tek operasyonu çözmek yerine, tüm kalıcılık sorunlarını çözmek için bir çerçeve üretmeye karar verdim .
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}
Yalnızca iki satır char*b
bu soruna özgüdür.
Girişi dize olarak ele alır, yani önde gelen "0" lar çıkış aşamasından önce şerit değildir.
Yukarıdaki açıklamalar, hata kontrolü ve raporlaması ve dosya okuması (girdi standart girdiden gelmelidir) aşağıdakilerden çıkarılmıştır:
/* persistence.c
*
* A general framework for finding the "persistence" of input strings
* on opperations.
*
* Persistence is defined as the number of times we must apply
*
* value_n+1 <-- Opperation(value_n)
*
* before we first reach a fixed point.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"
/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
* + Accept the signature above
* + return a point to a newly allocated buffer containing the updated str
*/
char* addop(char*s){
int i,l=0;
long long int v=0;
char *t=NULL;
/* protect against bad input */
if (NULL==s) return s;
/* allocate the new buffer */
l = strlen(s);
t = malloc(l+2);
if (NULL==t) return t;
/* walk the characters of the original adding as we go */
for (i=0; i<l; i++) v += s[i]-'0';
//fprintf(stderr," '%s' (%d) yields %lld\n",s,l,v);
snprintf(t,l+2,"%lld",v);
//fprintf(stderr," %lld is converted to '%s'\n",v,t);
return t;
}
/* Apply op(str), return true if the argument is a fixed point fo
* falsse otherwise,
*/
int apply(char**str, op_ptr op){
int r;
char*nstr;
/* protect against bad input */
if ( NULL==op ) exit(1);
if ( NULL==*str ) exit(4);
/* apply */
nstr = op(*str);
/* test for bad output */
if ( NULL==nstr ) exit(2);
r = !strcmp(*str,nstr);
/* free previous buffer, and reasign the new one */
free(*str);
*str = nstr;
return r;
}
int main(int argc, char**argv){
size_t len, llen=0;
char *c,*line=NULL;
op_ptr op=addop;
FILE *f=stdin;
if (argc > 1) f = fopen(argv[1],"r");
while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
int i=0;
line=strsep(&line,"\n"); // Strip the ending newline
/* keep a copy for later */
c = strdup(line);
/* count necessary applications */
while(!apply(&line,op)) i++;
printf("%s %d\n",c,i);
/* memory management */
free(c);
free(line);
line=NULL;
llen=0;
}
}
Bir elek gibi hafızayı sızdırmaya istekli olsaydık biraz daha tasarruf edilebilirdi. Aynı şekilde #define
dönüş ve benzeri ing, ama bu noktada daha çirkin yapmak umurumda değil.