initial commit
This commit is contained in:
commit
ce41fdc97c
|
@ -0,0 +1,16 @@
|
|||
CC = gcc
|
||||
CFLAGS = -Wall -Wpedantic -Wextra
|
||||
SRC = src
|
||||
BINDIR = bin
|
||||
BIN = skomb
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN):
|
||||
$(CC) $(CFLAGS) -O2 -DNDEBUG -Funroll-loops -march=native -s $(SRC)/$(BIN).c -o $(BINDIR)/$@
|
||||
|
||||
debug:
|
||||
$(CC) $(CFLAGS) -O0 -g $(SRC)/$(BIN).c -o $(BINDIR)/$(BIN)
|
||||
|
||||
clean:
|
||||
$(RM) -r $(BINDIR)/*
|
|
@ -0,0 +1,115 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "skomb.h"
|
||||
|
||||
#define VERSION "1.1"
|
||||
#define ERROR_MSG(msg) fprintf(stderr, "error: "msg"\n")
|
||||
#define HELPMSG printf("skomb is a program that returns the possible combinations for a given number and cells it spans in a sudoku killer board\nthis current version only supports numbers in the same column or line, or in the same 9x9, although this may change in future versions\nusage: skomb\n skomb [-h|--help] shows this message\n skomb [-v|--version] shows version number\n")
|
||||
|
||||
int main(int argc, char **argv){
|
||||
if (argc >= 2 && (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0)){
|
||||
printf(VERSION"\n");
|
||||
return 0;
|
||||
}
|
||||
if (argc >= 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)){
|
||||
HELPMSG;
|
||||
return 0;
|
||||
}
|
||||
while (1){
|
||||
printf("Insert number to solve for > ");
|
||||
/* number can only be two digits at most + space for null character */
|
||||
char *numberc = malloc(sizeof(char) * 3);
|
||||
readline(numberc, 3);
|
||||
if (numberc[0] == '\0'){
|
||||
free(numberc);
|
||||
break;
|
||||
}
|
||||
int number = atoi(numberc);
|
||||
free(numberc);
|
||||
/* cells can only be one digit at most + space for null character */
|
||||
printf("Insert cells it takes up > ");
|
||||
char *cellsc = malloc(sizeof(char) * 2);
|
||||
readline(cellsc, 2);
|
||||
int cells = atoi(cellsc);
|
||||
free(cellsc);
|
||||
printf("Insert numbers that can't be in the group separated by spaces > ");
|
||||
char *not_allowedc = malloc(sizeof(char) * 20);
|
||||
readline(not_allowedc, 20);
|
||||
int *not_allowed = malloc(sizeof(int) * 9);
|
||||
int *not_allowed_len = malloc(sizeof(int)*1);
|
||||
*not_allowed_len = splitc_toi(not_allowedc, ' ', not_allowed);
|
||||
free(not_allowedc);
|
||||
switch (cells){
|
||||
case 2:
|
||||
if (number >= 3 && number <= 17){
|
||||
pair *pairs = malloc(sizeof(pair) * 4);
|
||||
int len = perm2(number, not_allowed, not_allowed_len, pairs);
|
||||
printf("%d:\n", number);
|
||||
for (int i = 0; i < len; i++){
|
||||
printf("\t%d + %d\n", pairs[i].x, pairs[i].y);
|
||||
}
|
||||
free(pairs);
|
||||
break;
|
||||
}
|
||||
ERROR_MSG("number too small or big for ammount of cells");
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
return 3;
|
||||
case 3:
|
||||
if (number >= 6 && number <= 24){
|
||||
trio *trios = malloc(sizeof(trio) * 9);
|
||||
int len = perm3(number, not_allowed, not_allowed_len, trios);
|
||||
printf("%d:\n", number);
|
||||
for (int i = 0; i < len; i++){
|
||||
printf("\t%d + %d + %d\n", trios[i].x, trios[i].y, trios[i].z);
|
||||
}
|
||||
free(trios);
|
||||
break;
|
||||
}
|
||||
ERROR_MSG("number too small or big for ammount of cells");
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
return 3;
|
||||
case 4:
|
||||
if (number >= 10 && number <= 30){
|
||||
quartet *quartets = malloc(sizeof(quartet) * 12);
|
||||
int len = perm4(number, not_allowed, not_allowed_len, quartets);
|
||||
printf("%d:\n", number);
|
||||
for (int i = 0; i < len; i++){
|
||||
printf("\t%d + %d + %d + %d\n", quartets[i].x, quartets[i].y, quartets[i].z, quartets[i].w);
|
||||
}
|
||||
free(quartets);
|
||||
break;
|
||||
}
|
||||
ERROR_MSG("number too small or big for ammount of cells");
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
return 3;
|
||||
case 5:
|
||||
if (number >= 15 && number <= 35){
|
||||
quintet *quintets = malloc(sizeof(quintet) * 12);
|
||||
int len = perm5(number, not_allowed, not_allowed_len, quintets);
|
||||
printf("%d:\n", number);
|
||||
for (int i = 0; i < len; i++){
|
||||
printf("\t%d + %d + %d + %d + %d\n", quintets[i].x, quintets[i].y, quintets[i].z, quintets[i].w, quintets[i].v);
|
||||
}
|
||||
free(quintets);
|
||||
break;
|
||||
}
|
||||
ERROR_MSG("number too small or big for ammount of cells");
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
return 3;
|
||||
default:
|
||||
ERROR_MSG("invalid ammount of cells");
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
HELPMSG;
|
||||
return 4;
|
||||
}
|
||||
free(not_allowed);
|
||||
free(not_allowed_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
#ifndef STDIO_H
|
||||
#define STDIO_H
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef STRING_H
|
||||
#define STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifndef STDLIB_H
|
||||
#define STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef SKOMBLIB_H
|
||||
#define SKOMBLIB_H
|
||||
|
||||
typedef struct pair{
|
||||
int x;
|
||||
int y;
|
||||
} pair;
|
||||
|
||||
typedef struct trio{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
} trio;
|
||||
|
||||
typedef struct quartet{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
} quartet;
|
||||
|
||||
typedef struct quintet{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
int v;
|
||||
} quintet;
|
||||
|
||||
void readline(char *line, int len);
|
||||
int splitc_toi(char *line, int sep, int *dest);
|
||||
int perm2(int number, int *not_allowed, int* not_allowed_len, pair *pairs);
|
||||
int perm3(int number, int *not_allowed, int* not_allowed_len, trio *trios);
|
||||
int perm4(int number, int *not_allowed, int* not_allowed_len, quartet *quartets);
|
||||
int perm5(int number, int *not_allowed, int* not_allowed_len, quintet *quintets);
|
||||
|
||||
void readline(char *line, int len){
|
||||
int i = 0;
|
||||
int c;
|
||||
while ((c = getchar()) != '\n' && i < len){
|
||||
line[i] = c;
|
||||
i++;
|
||||
}
|
||||
line[i] = '\0';
|
||||
}
|
||||
|
||||
int splitc_toi(char *line, int sep, int *dest){
|
||||
int i, j;
|
||||
i = j = 0;
|
||||
char temp[2];
|
||||
temp[1] = '\0';
|
||||
while (line[i] != '\0'){
|
||||
if (line[i] == sep){
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
temp[0] = line[i];
|
||||
dest[j] = atoi(temp);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
int perm2(int number, int* not_allowed, int* not_allowed_len, pair* dest){
|
||||
int i, j, k;
|
||||
int skip;
|
||||
k = 0;
|
||||
for (i = 1; i < 10; i++){
|
||||
for (j = 0; j < *not_allowed_len; j++){
|
||||
if (i == not_allowed[j] || number - i == not_allowed[j]){
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip == 1){
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
if (i != number && i < number - i && number - i < 10){
|
||||
dest[k].x = i;
|
||||
dest[k].y = number - i;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
int perm3(int number, int *not_allowed, int *not_allowed_len, trio *trios){
|
||||
int i, j, k;
|
||||
int skip, len;
|
||||
k = 0;
|
||||
pair *pairs = malloc(sizeof(pair) * 4);
|
||||
for (i = 1; i < 10; i++){
|
||||
for (j = 0; j < *not_allowed_len; j++){
|
||||
if (i == not_allowed[j]){
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip == 1){
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
if (i != number && number - i < 18 && number - i > 2
|
||||
&& i < number){
|
||||
not_allowed[*not_allowed_len] = i;
|
||||
(*not_allowed_len)++;
|
||||
len = perm2(number-i, not_allowed, not_allowed_len, pairs);
|
||||
if (len > 0){
|
||||
for (j = 0; j < len; j++){
|
||||
if (i < pairs[j].x && i < pairs[j].y){
|
||||
trios[k].x = i;
|
||||
trios[k].y = pairs[j].x;
|
||||
trios[k].z = pairs[j].y;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*not_allowed_len)--;
|
||||
not_allowed[*not_allowed_len] = 0;
|
||||
}
|
||||
}
|
||||
free(pairs);
|
||||
return k;
|
||||
}
|
||||
|
||||
int perm4(int number, int *not_allowed, int *not_allowed_len, quartet *quartets){
|
||||
int i, j, k;
|
||||
int skip, len;
|
||||
k = 0;
|
||||
trio *trios = malloc(sizeof(pair) * 8);
|
||||
for (i = 1; i < 10; i++){
|
||||
for (j = 0; j < *not_allowed_len; j++){
|
||||
if (i == not_allowed[j]){
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip == 1){
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
if (i != number && number - i < 25 && number - i > 5){
|
||||
not_allowed[*not_allowed_len] = i;
|
||||
(*not_allowed_len)++;
|
||||
len = perm3(number - i, not_allowed, not_allowed_len, trios);
|
||||
if (len > 0){
|
||||
for (j = 0; j < len; j++){
|
||||
if (i < trios[j].x && i < trios[j].y && i < trios[j].z){
|
||||
quartets[k].x = i;
|
||||
quartets[k].y = trios[j].x;
|
||||
quartets[k].z = trios[j].y;
|
||||
quartets[k].w = trios[j].z;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*not_allowed_len)--;
|
||||
not_allowed[*not_allowed_len] = 0;
|
||||
}
|
||||
}
|
||||
free(trios);
|
||||
return k;
|
||||
}
|
||||
|
||||
int perm5(int number, int *not_allowed, int* not_allowed_len, quintet *quintets){
|
||||
int i, j, k;
|
||||
int skip, len;
|
||||
k = 0;
|
||||
quartet *quartets = malloc(sizeof(pair) * 12);
|
||||
for (i = 1; i < 10; i++){
|
||||
for (j = 0; j < *not_allowed_len; j++){
|
||||
if (i == not_allowed[j]){
|
||||
skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip == 1){
|
||||
skip = 0;
|
||||
continue;
|
||||
}
|
||||
if (i != number && number - i < 31 && number - i > 9){
|
||||
not_allowed[*not_allowed_len] = i;
|
||||
(*not_allowed_len)++;
|
||||
len = perm4(number-i, not_allowed, not_allowed_len, quartets);
|
||||
if (len > 0){
|
||||
for (j = 0; j < len; j++){
|
||||
if (i < quartets[j].x && i < quartets[j].y && i < quartets[j].z && i < quartets[j].w){
|
||||
quintets[k].x = i;
|
||||
quintets[k].y = quartets[j].x;
|
||||
quintets[k].z = quartets[j].y;
|
||||
quintets[k].w = quartets[j].z;
|
||||
quintets[k].v = quartets[j].w;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
(*not_allowed_len)--;
|
||||
not_allowed[*not_allowed_len] = 0;
|
||||
}
|
||||
}
|
||||
free(quartets);
|
||||
return k;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue