Skip to content
Snippets Groups Projects
Commit 11bdfc58 authored by Jocelyne's avatar Jocelyne
Browse files

pfn2 c

parent d37ca5c2
No related branches found
No related tags found
No related merge requests found
Showing
with 889 additions and 0 deletions
1
3
4
7
9
10
13
15
19
.PHONY:test
CC?=clang
CFLAGS=-g -m64 -Wall -Werror -Wunused-parameter -Wunused-variable -O3
FILE_BASE=enumM
all:${FILE_BASE}.x
%.x:%.c
${CC} ${CFLAGS} -o $@ $<
README:Makefile
@echo "Die Loesung zu dieser Aufgabe muss in der Datei ${FILE_BASE}.c implementiert werden" > $@
test:test_Enum test_fit
@echo "Congratulations. $@ passed"
test_Enum:test_Enum20 test_Enum100 test_Enum1000
@echo "Congratulations. $@ passed"
test_Enum20:${FILE_BASE}.x
@./${FILE_BASE}.x 20 | diff -I '^#' - M20.tsv
@echo "Congratulations. $@ passed"
test_Enum100:${FILE_BASE}.x
@./${FILE_BASE}.x 100 | diff -I '^#' - M100.tsv
@echo "Congratulations. $@ passed"
test_Enum1000:${FILE_BASE}.x
@./${FILE_BASE}.x 1000 | diff -I '^#' - M1000.tsv
@echo "Congratulations. $@ passed"
steps.tsv:${FILE_BASE}.x
@./steps.sh 500 > $@
# You need to provide your own values for a and b, such that runs with success
value_a=120
value_b=9
test_fit:steps.tsv
@./fit_linear.py -a ${value_a} -b ${value_b} --inputfile steps.tsv
@echo "Congratulations. $@ passed"
.PHONY:clean
clean:
${RM} ${FILE_BASE}.[ox]
${RM} -r ${FILE_BASE}.x.dSYM steps.tsv
Die Loesung zu dieser Aufgabe muss in der Datei enumM.c implementiert werden
File added
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
unsigned long n;
unsigned long steps = 4;
if (argc != 2 || (sscanf(argv[1], "%ld" , &n) != 1)) {
fprintf(stderr, \
"Usage <%s>: Insert a positive whole number!\n", argv[0]);
return EXIT_FAILURE;
}
steps += 5;
int i = 1;
bool menge[n+1];
menge[i] = true;
for (int multiples_2 = 2; multiples_2 <= n; multiples_2++){
steps += 5;
menge[multiples_2] = 5;
}
while (i < n) {
steps += 3;
if (menge[i]){
steps += 3;
if (i * 2 < n){
steps += 4;
menge[(i * 2 ) + 1] = true;
}
else{
steps += 2;
for (int multiples_2 = 1; multiples_2 <= n; multiples_2++){
steps += 4;
if (menge[multiples_2] == true){
steps += 1;
printf("%d\n",multiples_2);
}
}
printf("%lu\t%lu\t",n,steps);
return EXIT_SUCCESS;
}
steps += 3;
if (i * 3 < n){
steps += 4;
menge[(i * 3) + 1] = true;
}
}
steps += 2;
i += 1;
}
}
/* unsigned long *ptr;
ptr = (unsigned long*)malloc(n * sizeof(unsigned long));
unsigned long i=0, j=1;
if (ptr == NULL){
exit (0);
}
else {
while (i <= n){
ptr[i] = 2*i + 1;
ptr[j] = 3*i + 1;
}
printf("%lu\n%lu\n",ptr[i],ptr[j]);
return EXIT_SUCCESS;
}
}
for(i = 1; i <= n; i++)
{ int n, elem[] = {1}, *ptr;
if(i % 3 == 1)
{
printf("%d\n",i);
}
else if(i % 2 == 1)
{
printf("%d\n",i);
}
else if(i == 1){
printf("%d\n",i);
}
else if(i == 3){
printf("%d\n",i);
}
else if(i == 4){
printf("%d\n",i);
}
}
int i = 1, next_2 = (2*i)+1, next=3;
while(i <= n)
{
if(i == 1)
{
printf("%d\n",i);
}
else if (next % i == 1)
{
printf("%d",next_2);
i = next_2;
}
}*/
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.enumM</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
File added
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.enumM.x</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
#!/usr/bin/env python3
import argparse, sys, math
import numpy as np
def fit_linear(n_vec,steps_vec):
def func(x, a, b):
return a + b * x
(a, b) , _ = opt.curve_fit(func, n_vec, steps_vec)
return a, b
def parse_arguments():
p = argparse.ArgumentParser(description='fit data to linear function')
p.add_argument('-a','--avalue',metavar='<float>',type=float,default=None,
help='specify value of a')
p.add_argument('-b','--bvalue',type=float,metavar='<float>',default=None,
help='specify value of b')
p.add_argument('-i','--inputfile',type=str,default='steps.tsv',
help='specify input file')
return p.parse_args()
args = parse_arguments()
''' read the data from the tab separated file '''
steps_for_n = np.loadtxt(args.inputfile,dtype=int)
'''
transform matrix (i.e. array of rows, each of length 2) into
matrix of two 2 rows, one with the x-value, and the other with the
y-value. This is just a transposition, expressed by .T
'''
n_vec, steps_vec = steps_for_n.T
'''
if user gives values for a and b, then take these. Otherwise,
use values which are determined by the curve_fit function of SciPy.
The latter should give some good estimate of a and b which however
does not always provide an upper bound. One should therefore
try values slightly larger, until all steps-values are upperbounded.
'''
fitted = False
if args.avalue and args.bvalue:
a = args.avalue
b = args.bvalue
else:
import scipy.optimize as opt
a, b = fit_linear(n_vec,steps_vec)
fitted = True
sum_difference = 0
upper_bound = True
for n, steps in zip(n_vec,steps_vec):
steps_upper = int(math.ceil(a + n * b))
if steps > steps_upper:
sys.stderr.write(('no upper bound: steps = {} > {} = {:.2f} + {:.2f} * {} '
'= a + b * n\n').format(steps,steps_upper,a,b,n))
upper_bound = False
else:
sum_difference += (steps_upper - steps)
if upper_bound:
print('''# values for a and b such that s(n) <= a + b * n for all pairs
# n where s(n) is the number of steps required by your program to compute
# set M for given parameter n.
# So a and b are the constants such that the linear function f(n)=a+b*n
# is an upper bound for the number of steps in the range of values considered.
# Last value is sum of positive differences f(n) - s(n) for all n.''')
print('{}\t{}\t{}'.format(a,b,sum_difference))
else:
if fitted:
sys.stderr.write('fitted:\ta={:.2f}\tb={:.2f}\n'.format(a,b))
exit(1)
#!/bin/sh
if test $# -ne 1
then
echo "Usage: $0 <maximum value of n>"
exit 1
fi
n=1
max_n=$1
while test ${n} -le ${max_n}
do
./enumM.x ${n} | grep '^#' | cut -d '#' -f 2
n=`expr ${n} + 1`
done
# Zuerst tragen Sie bitte f"ur den Platzhalter
# h unten die Anzahl der Stunden, die sie f"ur die
# Aufgabe aufgewendet haben, ein. Das k"onnen auch Flie"spunkt-Werte sein,
# also z.B. 1.5, wenn Sie 1 Stunde und 30 Minuten ben"otigt haben.
Bearbeitungszeit: h Stunden
# Als n"achstes tragen Sie bitte ein, wie schwierig
# Sie die Aufgabe fanden. Die m"oglichen Werte sind vorgegeben. Bitte
# die Werte streichen, die nicht zutreffen:
Schwierigkeitsgrad: leicht, mittelschwer, genau richtig, schwer, sehr schwer
# Schliesslich tragen Sie bitte ein, wie verst"andlich die
# Aufgabenstellung formuliert war. Die m"oglichen Werte sind vorgegeben.
# Bitte die Werte streichen, die nicht zutreffen.
Aufgabenstellung: vollkommen klar, weitgehend klar, weniger klar, unklar
# Falls eine der beiden letzten Kategorien zutrifft, bitte
# kurz angeben, worin die Unklarheiten bestehen.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c, *string, string2[3] = {0}, **strings;
int num, *nump, a, *b;
string = "Hallo Welt";
c = string[6];
string2[0] = 'A';
string2[1] = 'B';
strings = malloc(sizeof (*strings) * 3);
strings[0] = &c;
strings[1] = string2;
strings[2] = "third string";
a = 7;
nump = &a;
*nump = 5;
b = &a;
num = (int) (*(strings + 1))[1];
}
/*
c = char
*string = (pointer) int
string2[3] = static array
**strings = char (pointer of pointers (Oberklasse))
num = int
*nump = (pointer) int
a = int
*b = (pointer) int
*/
/*
c = W
*strings = WAB
string2 = AB
strings[2][2] = Adresse (105)
string2[0] = Adresse (65)
num = 66
*/
/*
*strings[0] == *(string + 6): Wahr
*b == *nump: Wahr
b == nump: Wahr
string == strings[1]: Falsch
*/
# Zuerst tragen Sie bitte f"ur den Platzhalter
# h unten die Anzahl der Stunden, die sie f"ur die
# Aufgabe aufgewendet haben, ein. Das k"onnen auch Flie"spunkt-Werte sein,
# also z.B. 1.5, wenn Sie 1 Stunde und 30 Minuten ben"otigt haben.
Bearbeitungszeit: h Stunden
# Als n"achstes tragen Sie bitte ein, wie schwierig
# Sie die Aufgabe fanden. Die m"oglichen Werte sind vorgegeben. Bitte
# die Werte streichen, die nicht zutreffen:
Schwierigkeitsgrad: leicht, mittelschwer, genau richtig, schwer, sehr schwer
# Schliesslich tragen Sie bitte ein, wie verst"andlich die
# Aufgabenstellung formuliert war. Die m"oglichen Werte sind vorgegeben.
# Bitte die Werte streichen, die nicht zutreffen.
Aufgabenstellung: vollkommen klar, weitgehend klar, weniger klar, unklar
# Falls eine der beiden letzten Kategorien zutrifft, bitte
# kurz angeben, worin die Unklarheiten bestehen.
File added
.PHONY:test
CC?=clang
CFLAGS=-g -m64 -Wall -Werror -Wunused-parameter -Wunused-variable -O3
FILE_BASE=queens
MAIN=./${FILE_BASE}.x
all:${FILE_BASE}.x
%.x:%.c
${CC} ${CFLAGS} -o $@ $<
test:test_13 test_i13 test_d5
@echo "Congratulations. $@ passed"
.PHONY:test_13
test_13:${FILE_BASE}.x
@./queens_test.sh 13 ${MAIN} | diff - queens1-13.tsv
@echo "Congratulations. $@ passed"
.PHONY:test_i13
test_i13:${FILE_BASE}.x
@./queens_test.sh 13 '${MAIN} -i' | diff - queens1-13.tsv
@echo "Congratulations. $@ passed"
.PHONY:test_d5
test_d5:${FILE_BASE}.x
@./queens.x -d 5 | diff - queens-d5.txt
@echo "Congratulations. $@ passed"
.PHONY:clean
clean:
${RM} ${FILE_BASE}.[ox]
${RM} -r ${FILE_BASE}.x.dSYM
Q . . . .
. . Q . .
. . . . Q
. Q . . .
. . . Q .
---------
Q . . . .
. . . Q .
. Q . . .
. . . . Q
. . Q . .
---------
. Q . . .
. . . Q .
Q . . . .
. . Q . .
. . . . Q
---------
. Q . . .
. . . . Q
. . Q . .
Q . . . .
. . . Q .
---------
. . Q . .
Q . . . .
. . . Q .
. Q . . .
. . . . Q
---------
. . Q . .
. . . . Q
. Q . . .
. . . Q .
Q . . . .
---------
. . . Q .
Q . . . .
. . Q . .
. . . . Q
. Q . . .
---------
. . . Q .
. Q . . .
. . . . Q
. . Q . .
Q . . . .
---------
. . . . Q
. Q . . .
. . . Q .
Q . . . .
. . Q . .
---------
. . . . Q
. . Q . .
Q . . . .
. . . Q .
. Q . . .
---------
5 10
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
static void usage(const char *progname,bool show_options)
{
const char *optionsmsg =
" -d\tdisplay placement of queens on chessboard\n"
" -i\tuse iterative implementation\n"
" -h\tshow this usage message";
fprintf(stderr, "Usage: %s [options] number\ncount and possibly "
"display soliutions of the n-Queens problem\n%s\n",
progname,
show_options ? optionsmsg : "Use -h for more information.");
}
typedef struct
{
size_t size, /* number of queens, rows, columns */
solutions; /* counter for found solutions */
int *columns,
valid;
bool *in_col, /* in_col[j] iff a queen in column j */
*on_a_diag, /* on_a_diag[q] iff a queen on antidiag q */
*on_diag, /* on_diag[d] iff a queen on diag d */
display;
} Board;
/*lst{queensIndexFunctions}*/
static int a_diag_idx(int i,int j)
{
return i + j;
}
static int diag_idx(int i,int j)
{
return j - i;
}
/*lstend*/
/*lst{queensPlacementPossible}*/
static bool is_placement_possible(const Board *bd,int i,int j)
{
return !bd->in_col[j] &&
!bd->on_a_diag[a_diag_idx(i,j)] &&
!bd->on_diag[diag_idx(i,j)];
}
/*lstend*/
/*lst{queensDoPlacement}*/
static void do_placement(Board *bd,int i,int j) {
bd->in_col[j] = bd->on_a_diag[a_diag_idx(i,j)]
= bd->on_diag[diag_idx(i,j)] = true;
/*lstend*/
bd->columns[i] = j;
bd->valid = i + 1;
/*lst{queensCloseDoPlacement}*/
}
/*lstend*/
/*lst{queensUnDoPlacement}*/
static void undo_placement(Board *bd,int i,int j) {
bd->in_col[j] = bd->on_a_diag[a_diag_idx(i,j)]
= bd->on_diag[diag_idx(i,j)] = false;
/*lstend*/
bd->columns[i] = (int) bd->size; /* undefined */
bd->valid = i;
/*lst{queensCloseUnDoPlacement}*/
}
/*lstend*/
/*lst{queensDisplayBoard}*/
static void display_board(const Board *bd)
{
int i;
for (i = 0; i < bd->size; i++)
{
int j;
assert(bd->columns[i] < bd->size);
for (j = 0; j < bd->size; j++)
{
printf("%c%c",j == bd->columns[i] ? 'Q' : '.',
j < bd->size - 1 ? ' ' : '\n');
}
}
for (i=0; i < 2 * bd->size; i++) /* ----- line */
printf("%c",i < 2 * bd->size - 1 ? '-' : '\n');
}
/*lstend*/
/*lst{queensRecursive}*/
static void queens_rec(int i,Board *bd)
{
if (i < bd->size)
{
int j;
for (j = 0; j < bd->size; j++)
{
if (is_placement_possible(bd,i,j))
{
do_placement(bd,i,j);
queens_rec(i+1,bd);
undo_placement(bd,i,j);
}
}
} else
{
/*lstend*/
/*lst{queensCallDisplayBoard}*/
if (bd->display) display_board(bd);
/*lstend*/
/*lst{queensRestRecursive}*/
bd->solutions++;
}
}
/*lstend*/
static void queens_itrv(Board *bd)
{
int i = 0, j = 0;
while (true)
{
while (j < bd->size)
{
if (is_placement_possible(bd,i,j))
{
do_placement(bd,i,j);
i++;
j = 0;
break;
}
j++;
}
if (j == bd->size || i == bd->size)
{
int prev_column;
if (i == bd->size)
{
if (bd->display)
{
display_board(bd);
}
bd->solutions++;
#define WITH_OPTIMIZATION
#ifdef WITH_OPTIMIZATION
prev_column = bd->columns[bd->valid-1];
undo_placement(bd,bd->valid-1,prev_column);
i--;
#endif
}
if (bd->valid == 0)
{
break;
}
prev_column = bd->columns[bd->valid-1];
undo_placement(bd,bd->valid-1,prev_column);
i--;
j = 1 + prev_column;
}
}
}
/*lst{queensfunction}*/
static size_t queens(size_t size,bool display,bool iterative)
{
size_t row;
Board bd;
bd.size = size;
bd.solutions = 0;
bd.in_col = calloc(5 * bd.size - 2,sizeof *bd.in_col);
bd.on_a_diag = bd.in_col + bd.size;
bd.on_diag = bd.on_a_diag + 2 * bd.size - 1 + bd.size - 1;
/*lstend*/
bd.columns = malloc(sizeof *bd.columns * bd.size);
for (row = 0; row < bd.size; row++)
{
bd.columns[row] = bd.size;
}
bd.display = display;
bd.valid = 0;
/*lst{queenscallrealmethods}*/
if (iterative)
queens_itrv(&bd); /* call iterative method. not shown */
else
queens_rec(0,&bd); /* call recursive method, see below */
free(bd.in_col); /* only one calloc => only one free */
/*lstend*/
free(bd.columns);
/*lst{queensfunctionreturn}*/
return bd.solutions;
}
/*lstend*/
typedef struct
{
bool display,
iterative;
size_t size;
} Options;
static Options *options_new(int argc, char *const *argv)
{
int opt;
Options *options = malloc(sizeof *options);
bool haserr = false;
assert(options != NULL);
options->display = false;
options->iterative = false;
options->size = 0;
while ((opt = getopt(argc, argv, "dih")) != -1)
{
switch ((char) opt)
{
case 'd':
options->display = true;
break;
case 'i':
options->iterative = true;
break;
case 'h':
usage(argv[0], true);
haserr = true;
break;
default:
assert((char) opt == '?');
usage(argv[0], false);
haserr = true;
break;
}
}
if (!haserr && optind < argc - 1)
{
fprintf(stderr,"%s: superfluous argument %s\n",argv[0],argv[optind]);
haserr = true;
}
if (!haserr && optind > argc - 1)
{
fprintf(stderr,"%s: missing argument\n",argv[0]);
haserr = true;
}
if (!haserr)
{
int readint;
if (sscanf(argv[optind],"%d",&readint) != 1 || readint < 1)
{
fprintf(stderr,"%s: last parameter must be positive integert\n",argv[0]);
haserr = true;
}
options->size = (size_t) readint;
}
if (haserr)
{
free(options);
return NULL;
}
return options;
}
static void options_delete(Options *options)
{
if (options != NULL)
{
free(options);
}
}
int main(int argc,char *argv[])
{
Options *options = options_new(argc,(char *const *) argv);
if (options == NULL)
{
return EXIT_FAILURE;
}
printf("%lu\t%lu\n",options->size,
queens(options->size,options->display,
options->iterative));
options_delete(options);
return EXIT_SUCCESS;
}
#!/usr/bin/env python3
# from https://www.sanfoundry.com/python-program-solve-n-queen-problem-without-recursion/
import argparse
class QueenChessBoard:
def __init__(self, size):
# board has dimensions size x size
self.size = size
# columns[r] is a number c if a queen is placed at row r and column c.
# columns[r] is out of range if no queen is place in row r.
# Thus after all queens are placed, they will be at positions
# (columns[0], 0), (columns[1], 1), ... (columns[size - 1], size - 1)
self.columns = list()
def place_in_next_row(self, column):
self.columns.append(column)
def is_empty(self):
return len(self.columns) == 0
def remove_in_current_row(self):
return self.columns.pop()
def is_this_column_safe_in_next_row(self, column):
# index of next row
row = len(self.columns)
# check column
for queen_column in self.columns:
if column == queen_column:
return False
# check diagonal
diag = column - row
for queen_row, queen_column in enumerate(self.columns):
if queen_column - queen_row == diag:
return False
# check antidiagonal
anti_diag = column + row
for queen_row, queen_column in enumerate(self.columns):
if queen_column + queen_row == anti_diag:
return False
return True
def display(self):
for row in range(self.size):
line = list()
for column in range(self.size):
if column == self.columns[row]:
line.append('Q')
else:
line.append('.')
print(' '.join(line))
def solve_queens(size,with_display):
"""Display a chessboard for each possible configuration of placing n queens
on an n x n chessboard and print the number of such configurations."""
board = QueenChessBoard(size)
number_of_solutions = 0
row = 0
column = 0
# iterate over rows of board
while True:
# place queen in next row
while column < size:
if board.is_this_column_safe_in_next_row(column):
board.place_in_next_row(column)
row += 1
column = 0
break
else:
column += 1
# if could not find column to place in or if board is full
if column == size or row == size:
# if board is full, we have a solution
if row == size:
if with_display:
board.display()
print('-' * (2 * size - 1))
number_of_solutions += 1
# small optimization:
# In a board that already has queens placed in all rows except
# the last, we know there can only be at most one position in
# the last row where a queen can be placed. In this case, there
# is a valid position in the last row. Thus we can backtrack two
# times to reach the second last row.
#board.remove_in_current_row()
#row -= 1
# now backtrack
if board.is_empty():
# all queens removed, thus no more possible configurations
break
prev_column = board.remove_in_current_row()
# try previous row again
row -= 1
# start checking at column = (1 + value of column in previous row)
column = 1 + prev_column
return number_of_solutions
def parse_arguments():
p = argparse.ArgumentParser(description='show number of solutions to '
'n-queens problem')
p.add_argument('-d','--display',action='store_true',default=False,
help='show the possible solutions')
p.add_argument('size',type=int,
help='specify number of rows/columns of chessboard')
return p.parse_args()
args = parse_arguments()
num_solutions = solve_queens(args.size,args.display)
print("{}\t{}".format(args.size,num_solutions))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment