Skip to content

Instantly share code, notes, and snippets.

@cpylua
Created August 17, 2011 03:22
Show Gist options
  • Save cpylua/1150740 to your computer and use it in GitHub Desktop.
Save cpylua/1150740 to your computer and use it in GitHub Desktop.
bestbefore
/* http://www.spotify.com/us/jobs/tech/best-before/ */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* process_raw(char *p);
char* process(char *pa, char *pb, char *pc);
char* process4(int *len ,int *num, size_t n);
char* process2(int *len ,int *num, size_t n);
void sort(int *arr, int *aux, size_t len);
void swap(int *arr, size_t i, size_t j);
int chkdate(int y, int m, int d);
int main(int argc, char **argv)
{
char buf[16] = {0};
char raw[16];
char *out = NULL;
int ret = scanf("%s", buf);
if (ret != 1) {
fprintf(stderr, "%s\n", "bad input");
return -1;
}
memcpy(raw, buf, sizeof(buf));
out = process_raw(buf);
if (out == NULL) {
printf("%s is illegal", raw);
}
else {
printf("%s", out);
free(out);
}
return 0;
}
char* process_raw(char *p)
{
char *pa, *pb, *pc;
char *best = NULL;
if (p == NULL)
return NULL;
pa = p;
pb = strchr(p, '/');
if (pb)
*pb++ = '\0';
pc = strchr(pb, '/');
if (pc)
*pc++ = '\0';
assert(pa && pb && pc);
return process(pa, pb, pc);
}
char* process(char *pa, char *pb, char *pc)
{
int num[3];
int len[3];
num[0] = atoi(pa);
num[1] = atoi(pb);
num[2] = atoi(pc);
len[0] = strlen(pa);
len[1] = strlen(pb);
len[2] = strlen(pc);
/* sort by length, descending */
sort(len, num, 3);
if (len[0] == 4 && len[1] < 3) {
return process4(len, num, 3);
} else if (len[0] < 3) {
return process2(len, num, 3);
}
return NULL;
}
void sort(int *arr, int *aux, size_t len)
{
size_t i, j;
for (i = 0; i < len ; i++) {
for (j = i + 1; j < len; j++) {
if (arr[i] < arr[j]) {
swap(arr, i, j);
swap(aux, i, j);
}
}
}
}
void swap(int *arr, size_t i, size_t j)
{
int x = arr[i];
arr[i] = arr[j];
arr[j] = x;
}
char* process4(int *len ,int *num, size_t n)
{
int y, m, d;
int valid;
if (num[0] > 2999 || num[0] < 2000) {
return NULL;
}
/* sort by value, descending */
sort(num, len, 3);
if (num[2] > 12 || num[1] < 1 || num[2] < 1) {
return NULL;
}
y = num[0];
m = num[2];
d = num[1];
valid =chkdate(y, m, d);
if (valid) {
char *p = malloc(11);
if (p) {
sprintf(p, "%04d-%02d-%02d", y, m, d);
return p;
}
}
return NULL;
}
char* process2(int *len ,int *num, size_t n)
{
int num1[3], len1[3];
char *p = NULL;
/* sort by value, descending */
sort(num, len, 3);
memcpy(num1, num, sizeof(num1));
memcpy(len1, len ,sizeof(len1));
num1[2] += 2000;
sort(num1, len1, 3);
p = process4(len1, num1, 3);
if (!p) {
memcpy(num1, num, sizeof(num1));
memcpy(len1, len ,sizeof(len1));
num1[1] += 2000;
sort(num1, len1, 3);
p = process4(len1, num1, 3);
if (!p) {
memcpy(num1, num, sizeof(num1));
memcpy(len1, len ,sizeof(len1));
num1[0] += 2000;
sort(num1, len1, 3);
return process4(len1, num1, 3);
}
}
return p;
}
int chkdate(int y, int m, int d)
{
static int lookup[13] = { 0,
31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31
};
int fix;
if (y % 400 == 0)
fix = 1;
else if (y % 100 == 0)
fix = 0;
else if (y % 4 == 0)
fix = 1;
else
fix = 0;
if (m != 2 && lookup[m] >= d)
return 1;
if (m == 2 && lookup[m] + fix >= d)
return 1;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment