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 1080 additions and 0 deletions
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include "pfn_file_info.h"
#include "pfn_line_store.h"
static void usage(const char *progname,bool show_options)
{
const char *optionsmsg =
"output number of lines and/or reverse lines of specified files\n"
" -l\toutput number of lines\n"
" -o\tshow lines in reverse order\n"
" -r\tshow characters of each line in reverse order\n"
" -h\tshow this usage message";
fprintf(stderr, "Usage: %s [options] ... filename1 [filename2...]\n%s\n",
progname,
show_options ? optionsmsg : "Use -h for more information.");
}
/* FRAGE 1: Wozu dient die Struktur PfNLineStoreOptions?
Die Struktur PfNLineStoreOptions dient als Parse Command Line
Argumente/Optionen, die vom Benutzer beim Ausf"uhren der Datei
verwendet werden k"onnen. */
typedef struct
{
bool show_num_lines,
show_rev_each_line,
show_reversed_order;
size_t num_of_files;
const char * const *filenames;
} PfNLineStoreOptions;
static PfNLineStoreOptions *pfn_line_store_options_new(int argc,
char *const *argv)
{
int opt;
PfNLineStoreOptions *options = malloc(sizeof *options);
bool haserr = false;
assert(options != NULL);
options->show_num_lines = false;
options->show_rev_each_line = false;
options->show_reversed_order = false;
/* FRAGE 2: Was passiert in der folgenden while-Schleife? Sie m"ussen
hier keine technischen Details beschreiben, und es ist nicht notwendig,
dass Sie das Manual zu getopt konsultieren. Die Antwort ergibt sich aus dem
Kontext.
Die while-Schleife verarbeitet alle Optionen der Command Line Options
(also -l, -o, -r und -h) und definiert die Vorgehensweise, wenn jede
Command Line Option aufgerufen wird. */
while ((opt = getopt(argc, argv, "lroh")) != -1)
{
switch ((char) opt)
{
case 'l':
options->show_num_lines = true;
break;
case 'o':
options->show_reversed_order = true;
break;
case 'r':
options->show_rev_each_line = true;
break;
case 'h':
usage(argv[0], true);
/* FRAGE 3: Wozu wird die Variable haserr verwendet?
haserr wird verwendet, um eine Usage Message im Falle
eines Usage Error zu generieren
(d.h. haserr ist true, wenn ein Usage Error auftritt).*/
haserr = true;
break;
default:
assert((char) opt == '?');
usage(argv[0], false);
haserr = true;
break;
}
}
if (!haserr)
{
/* FRAGE 4: Wo wird die Variable optind deklariert und
welche Bedeutung hat sie?
optind wird in getopt deklariert und stellt den Index des n"achsten
Elements im argv dar und wird vor dem ersten Aufruf von getopt auf
1 initialisiert.*/
if (optind < argc)
{
options->filenames = (const char * const *) (argv + optind);
options->num_of_files = (size_t) (argc - optind);
} else
{
fprintf(stderr,"%s: Error: filenames expected\n",argv[0]);
usage(argv[0], false);
haserr = true;
}
}
if (haserr)
{
free(options);
return NULL;
}
return options;
}
static void pfn_line_store_options_delete(PfNLineStoreOptions *options)
{
if (options != NULL)
{
free(options);
}
}
/* Diese Funktion gibt die Zeilen aus der PfNLineStore-Struktur
wieder aus.
FRAGE 5: Wie sieht in der folgenden Funktion die Ausgabe des
Dateiinhalts in Abh"angigkeit der beiden boolschen-Parameter aus?
Die boolschen-Parameter entscheiden, ob die Ausgabe normal ist (wenn
reversed_order = rev_each_line = false), Zeilen in umgekehrter Reihenfolge
sind (wenn reversed_order - true) oder die Zeichen in jeder Zeile in
umgekehrter Reihenfolge sind (wenn rev_each_line = true).
FRAGE 6: Welche Abstraktion wird in der folgenden Funktion verwendet,
damit man die "au"sere Schleife nur einmal schreiben muss?
Die Parameter "nothing" und "nocheck"
*/
static void show_lines_generic(const PfNLineStore *line_store,
bool reversed_order,
bool rev_each_line)
{
size_t idx, first_idx, last_idx,
num_lines = pfn_line_store_number(line_store);
int step;
const char sep = pfn_line_store_sep(line_store);
if (reversed_order)
{
first_idx = num_lines-1;
last_idx = 0;
step = -1;
} else
{
first_idx = 0;
last_idx = num_lines-1;
step = 1;
}
for (idx = first_idx; /* nocheck */; idx += step)
{
const char *line_ptr = pfn_line_store_access(line_store,idx);
const size_t line_length = strlen(line_ptr);
if (rev_each_line)
{
const char *ptr = line_ptr + line_length - 1;
for (/* Nothing */; ptr >= line_ptr; ptr--)
{
putchar(*ptr);
}
} else
{
/* write the memory of (line_length * sizeof *line_ptr) bytes referred
to by line_ptr to stdout */
fwrite(line_ptr,sizeof *line_ptr,line_length,stdout);
}
putchar(sep);
if (idx == last_idx)
{
break;
}
}
}
int main(int argc,char *argv[])
{
size_t idx, total_lines = 0;
PfNLineStoreOptions *options
= pfn_line_store_options_new(argc,(char *const *) argv);
bool haserr = false;
if (options == NULL)
{
return EXIT_FAILURE;
}
for (idx = 0; idx < options->num_of_files; idx++)
{
PfNFileInfo *file_info
= pfn_file_info_new(argv[0],options->filenames[idx]);
size_t file_size, num_lines = 0;
if (file_info == NULL)
{
return EXIT_FAILURE;
}
file_size = pfn_file_info_size(file_info);
if (file_size > 0)
{
PfNLineStore *line_store;
void *file_contents = pfn_file_info_contents(file_info);
line_store = pfn_line_store_new((unsigned char *) file_contents,
file_size,'\n');
if (line_store == NULL)
{
haserr = true;
} else
{
num_lines = pfn_line_store_number(line_store);
total_lines += num_lines;
if (options->show_reversed_order || options->show_rev_each_line)
{
show_lines_generic(line_store,
options->show_reversed_order,
options->show_rev_each_line);
}
}
pfn_line_store_delete(line_store);
}
if (!haserr && options->show_num_lines)
{
printf("%8lu %s\n",num_lines,options->filenames[idx]);
}
pfn_file_info_delete(file_info);
}
if (!haserr && options->show_num_lines)
{
/* Bei deutschen Versionen von wc steht hier das Wort 'insgesamt'.
Dieses wird nun im Test modifiziert, damit es zu der
erwateten Ausgabe passt. */
printf("%8lu total\n",total_lines);
}
pfn_line_store_options_delete(options);
return EXIT_SUCCESS;
}
a
ab
# 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: 3 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: 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
# 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))
1 1
2 0
3 0
4 2
5 10
6 4
7 40
8 92
9 352
10 724
11 2680
1 1
2 0
3 0
4 2
5 10
6 4
7 40
8 92
9 352
10 724
11 2680
12 14200
13 73712
#!/usr/bin/env python3
import operator as op
from functools import reduce
def binom(n, r):
r = min(r, n-r)
numer = reduce(op.mul, range(n, n-r, -1), 1)
denom = reduce(op.mul, range(1, r+1), 1)
return numer / denom
valid_combinations = [None,1,0,0,2,10,4,40,92,352,724,2680,14200,73712,365596,2279184]
for n in range(1,15+1):
print('{}\t{:.2e}\t{:.2e}'.format(n,binom(n*n,n),valid_combinations[n]))
#!/bin/sh
if test $# -ne 2
then
echo "Usage: $0 <maxn> <program>"
exit 1
fi
maxn=$1
program=$2
n=1
while test $n -le ${maxn}
do
${program} $n
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: 0.75 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: genau richtig
# 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
Frau Jakovljevic erkl"arte die Implementierung des Codes f"ur das
Queens Problem (in Bezug auf den Pseudocode, den wir in der
Peer-Teaching letzte Woche besprochen haben).
In ihrer Erkl"arung ging sie auch auf die L"osung der wichtige
"Uberlegungen im Pseudocode ein (n"amlich wie wir die G"ultigkeit
unserer Platzierungen "uberpr"ufen k"onnen und wie wir "undo" f"ur
unsere Platzierungen machen k"onnen).
# Falls eine der beiden letzten Kategorien zutrifft, bitte
# kurz angeben, worin die Unklarheiten bestehen.
.PHONY:test
CC?=clang
CFLAGS=-g -m64 -Wall -Werror -Wunused-parameter -Wunused-variable -O3
LDFLAGS=${CFLAGS}
FILE_BASE=fib_generator
MAIN=./${FILE_BASE}.x
OBJECTS=${FILE_BASE}_mn.o ${FILE_BASE}.o
all:${FILE_BASE}.x
${FILE_BASE}.x:${OBJECTS}
${CC} ${LDFLAGS} -o $@ ${OBJECTS} ${LDLIBS}
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS) -MT $@ -MMD -MP -MF $(@:.o=.d)
test:all
@${MAIN} | diff - fibonacci_first_94.tsv
@echo "Congratulations. $@ passed"
README:Makefile
@echo "Die Loesung zu dieser Aufgabe muss in der Datei ${FILE_BASE}.c implementiert werden" > $@
.PHONY:clean
clean:
@${RM} ${FILE_BASE}.[oxd] ${FILE_BASE}_mn.[od]
@${RM} -r ${FILE_BASE}.x.dSYM
#include <stdlib.h>
#include <assert.h>
#include "fib_generator.h"
struct FibGenerator {
size_t p, pp;
};
FibGenerator *fib_generator_new(void) {
FibGenerator *fibo = malloc(sizeof *fibo);
assert(fibo != NULL);
fibo->p = 0;
fibo->pp = 1;
return fibo;
}
void fib_generator_delete(FibGenerator *fib_generator) {
if (fib_generator != NULL)
free(fib_generator);
}
size_t fib_generator_next(FibGenerator *fib_generator) {
assert (fib_generator != NULL);
size_t first_term = fib_generator->p;
fib_generator->p = fib_generator->pp;
fib_generator->pp += first_term;
return first_term;
}
/*Antwort zur Frage: Der Integer/Zahlen-Typ von Python
erm"oglicht beliebig große Zahl, indem die Zahl nicht auf
eine bestimmte Anzahl von Bits beschr"ankt, wie es C ist.
In C m"ussen wir einen Type f"ur unsere Variable
deklarieren, die Gr"osse der Ganzzahl unserer Variable begrenzt.
In diesem Fall liegt die Fibonacci-Zahlen nach der ersten 94.
ausserhalb der "Grenze" des von uns deklarierten Typs */
#ifndef FIB_GENERATOR_H
#define FIB_GENERATOR_H
#include <stddef.h>
/* The name of the opaque datatyp which stores the state of the
generation of Fibonacci numbers. In the file fib_generator.c
one must add the declarion
struct FibGenerator
{
...
};
with appropriate components between { and }
*/
typedef struct FibGenerator FibGenerator;
/* dynamically create a space for a new FibGenerator structure,
initialze it and return a pointer to it */
FibGenerator *fib_generator_new(void);
/* free the dynamically allocated space referred to by the
passed pointer */
void fib_generator_delete(FibGenerator *fib_generator);
/* deliver the next Fibonacci number. So the i-th call of the
function delivers the i-th Fibonacci number */
size_t fib_generator_next(FibGenerator *fib_generator);
#endif
#!/usr/bin/env python
import sys, argparse
def parse_arguments(argv):
p = argparse.ArgumentParser(description='output fibonacci numbers')
p.add_argument('--max_idx',type=int,default=93,
help=('specify maximum index of Fibonacci number to be '
'generated, default: 93'))
return p.parse_args(argv)
args = parse_arguments(sys.argv[1:])
def fib_infinite():
pp, p = 0, 1 # pp = previous of previous, p = previous
while True:
yield pp # iteration will receive pp as value
current_sum = p + pp
pp = p
p = current_sum
for idx, f in enumerate(fib_infinite()):
print('{}\t{}'.format(idx,f))
if idx == args.max_idx: # args delivered by option parser
break
#include <stdio.h>
#include <stdlib.h>
#include "fib_generator.h"
int main(void)
{
FibGenerator *fib_generator = fib_generator_new();
for (size_t idx = 0; idx <= 93; idx++)
{
size_t fib_num = fib_generator_next(fib_generator);
printf("%lu\t%lu\n",idx,fib_num);
}
fib_generator_delete(fib_generator);
return EXIT_SUCCESS;
}
0 0
1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55
11 89
12 144
13 233
14 377
15 610
16 987
17 1597
18 2584
19 4181
20 6765
21 10946
22 17711
23 28657
24 46368
25 75025
26 121393
27 196418
28 317811
29 514229
30 832040
31 1346269
32 2178309
33 3524578
34 5702887
35 9227465
36 14930352
37 24157817
38 39088169
39 63245986
40 102334155
41 165580141
42 267914296
43 433494437
44 701408733
45 1134903170
46 1836311903
47 2971215073
48 4807526976
49 7778742049
50 12586269025
51 20365011074
52 32951280099
53 53316291173
54 86267571272
55 139583862445
56 225851433717
57 365435296162
58 591286729879
59 956722026041
60 1548008755920
61 2504730781961
62 4052739537881
63 6557470319842
64 10610209857723
65 17167680177565
66 27777890035288
67 44945570212853
68 72723460248141
69 117669030460994
70 190392490709135
71 308061521170129
72 498454011879264
73 806515533049393
74 1304969544928657
75 2111485077978050
76 3416454622906707
77 5527939700884757
78 8944394323791464
79 14472334024676221
80 23416728348467685
81 37889062373143906
82 61305790721611591
83 99194853094755497
84 160500643816367088
85 259695496911122585
86 420196140727489673
87 679891637638612258
88 1100087778366101931
89 1779979416004714189
90 2880067194370816120
91 4660046610375530309
92 7540113804746346429
93 12200160415121876738
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment