From ef8b789d18ba128f34a00ed8e789e664395e43ad Mon Sep 17 00:00:00 2001 From: tomsmeding Date: Mon, 25 Dec 2017 11:27:04 +0100 Subject: Christmas! 🎄 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2017/25.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2017/25.in | 62 +++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 2017/25.c create mode 100644 2017/25.in (limited to '2017') diff --git a/2017/25.c b/2017/25.c new file mode 100644 index 0000000..46680d4 --- /dev/null +++ b/2017/25.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include + + +const char* next_word(void){ + static char buf[1024]; + int len=0; + char c=getchar(); + while(isspace(c))c=getchar(); + if(feof(stdin))return NULL; + if(!isalnum(c)){ + buf[0]=c; + buf[1]='\0'; + return buf; + } + while(isalnum(c)&&!feof(stdin)){ + buf[len++]=c; + c=getchar(); + } + if(!feof(stdin))ungetc(c,stdin); + buf[len]='\0'; + return buf; +} + +struct rule { + int state; + int direction; // right = 1, left = -1 + bool value; +}; + +struct rules { + struct rule table[8][2]; + int start; + int stopcount; +}; + + +#define EQ(s1_,s2_) (strcmp((s1_),(s2_))==0) +#define READ(dest_) assert((dest_)=next_word()) +#define READ_EOF(dest_) ((dest_)=next_word()) +#define READSTATE(dest_) ((dest_)=next_word()[0]-'A') +#define READINT(dest_) ((dest_)=strtol(next_word(),NULL,10)) +#define EXPECT(s_) assert(EQ(next_word(),(s_))) + +static struct rules parse(void){ + struct rules R; + int curstate=0,curval=0; + const char *word; + while(true){ + READ_EOF(word); + if(!word)break; + if(EQ(word,"Begin")){ + EXPECT("in"); EXPECT("state"); + READSTATE(R.start); + EXPECT("."); + } else if(EQ(word,"Perform")){ + EXPECT("a"); EXPECT("diagnostic"); EXPECT("checksum"); EXPECT("after"); + READINT(R.stopcount); + EXPECT("steps"); EXPECT("."); + } else if(EQ(word,"In")){ + EXPECT("state"); + READSTATE(curstate); + EXPECT(":"); + } else if(EQ(word,"If")){ + EXPECT("the"); EXPECT("current"); EXPECT("value"); EXPECT("is"); + READINT(curval); + EXPECT(":"); + } else if(EQ(word,"-")){ + READ(word); + if(EQ(word,"Write")){ + EXPECT("the"); EXPECT("value"); + READINT(R.table[curstate][curval].value); + EXPECT("."); + } else if(EQ(word,"Move")){ + EXPECT("one"); EXPECT("slot"); EXPECT("to"); EXPECT("the"); + READ(word); + if(EQ(word,"right"))R.table[curstate][curval].direction=1; + else if(EQ(word,"left"))R.table[curstate][curval].direction=-1; + else assert(false); + EXPECT("."); + } else if(EQ(word,"Continue")){ + EXPECT("with"); EXPECT("state"); + READSTATE(R.table[curstate][curval].state); + EXPECT("."); + } else { + assert(false); + } + } else { + assert(false); + } + } + return R; +} + +#undef EQ +#undef EXPECT + +static void printrules(const struct rules R){ + printf("start=%c\nstopcount=%d\n",R.start+'A',R.stopcount); + for(int i=0;i<8;i++){ + printf("%c: %d,%c,%c %d,%c,%c\n", + 'A'+i, + R.table[i][0].value,"<>"[R.table[i][0].direction],R.table[i][0].state+'A', + R.table[i][1].value,"<>"[R.table[i][1].direction],R.table[i][1].state+'A'); + } +} + +int main(void){ + freopen("25.in","r",stdin); + struct rules R=parse(); + // printrules(R); + + assert(sizeof(bool)==1); + + int tapesize=4096; + bool *tape=calloc(tapesize,1); + + int state=R.start,ptr=tapesize/2; + + for(int iter=0;itervalue; + ptr+=rule->direction; + state=rule->state; + } + + int total=0; + for(int i=0;i