NVidia GPU GEMS 1,2,3 available freely online
2014-10-28 13:28:31


So much knowledge for graphical programmer, gotta love it !

https://developer.nvidia.com/gpugems/GPUGems/gpugems_pref01.html
Ikaruga-style trails (sort of)
2014-09-03 23:26:48


While making my own shoot'em up game, the never ending Nicuga project, there's one graphic effect that I was always looking to mimic : the all out missile trails effect from Ikaruga, the best shooting game ever.
I think that it just looked gorgeous !

I've finally manage to make my own cheapo ones. It relies on my old particle manager class except that instead on rendering particles indivudally, the particle sprite would be extend horizontally and vertically to meet the neighbour particle from the same trail, the neighbour is found by looking at the particle with the closest lifetime and belonging to the trail.

Here is the code that handles it for each active particles
 
int head = -1;
int trailId = this->particles[i].trailId;
if (trailId != -1) {
for (int j = 0;j < 1000;j++) {
if ((this->particles[j].active == true) && (this->particles[j].trailId == trailId)&& (i!=j)) {
if (this->particles[i].currentLifeTime > this->particles[j].currentLifeTime) {
if (head == -1) {
head = j;
} else
if ((this->particles[i].currentLifeTime - this >particles[j].currentLifeTime)
< (this->particles[i].currentLifeTime - this->particles[head].currentLifeTime)){
head = j;
}                
}
 
}
}
}
 
if (head != -1) {
float xdest = this->particles[i].x > this->particles[head].x ?
-abs(this->particles[i].x - this->particles[head].x) : abs(this->particles[i].x - this->particles[head].x);
float ydest = this->particles[i].y > this->particles[head].y ?
-abs(this->particles[i].y - this->particles[head].y) : abs(this->particles[i].y - this->particles[head].y);
 
sprite->updateQuad(0,0,xdest,ydest,xdest+5.f,ydest+0.f,5.f,0.f);
}
sprite->draw();
 
Leek wars goodies
2014-08-15 21:34:24


I'm having so much fun currently with Leek wars http://leekwars.com

Sadly only in french.

Leek wars is a permanent AI programming contest that put you in control of a heavily armed and trained leek that fights against other AI programmed leek.

What is good about it is not so much of the idea, but the dense competition it had gather in only a few month time.
Competition is what drives me into alway improving my AI to keep it up to the game. I like it to a point where I'm finding myself coding more leekwars script than real code ! I hate fellow workers who got me into it !

So let's have a little code giveaway : here is a piece of code to do brute force path finding between two cells of the leek wars arena.
Parameters are cell1 : start, cell2 : destination and mp : the number of available movement points.
Currently isReachable only returns true if destination cell is reachable within mp points but it could easly be modified to gives a real path if needed.
 
function browse_square(@tab, x, y,w,h,current,mp) {
    //debug("bt "+"x="+x+",y="+y+",w="+w+",h="+h);
    if ((x < 0)||(x >= w)||(y<0)||(y>=h))
        return;
 
    if ((tab[x + y * w] == -1)||(tab[x + y * w] > current)) {
        return;
    }
 
    tab[x + y * w] = current;
 
    if (current == mp) {
        return;
    }
 
    browse_square(tab,x-1,y,w,h,current+1,mp);
    browse_square(tab,x,y-1,w,h,current+1,mp);
    browse_square(tab,x+1,y,w,h,current+1,mp);
    browse_square(tab,x,y+1,w,h,current+1,mp);
}
 
 
function isReachable(cell1, cell2, mp) {
    //setup grid
    var x1 = getCellX(cell1);
    var y1 = getCellY(cell1);
    var x2 = getCellX(cell2);
    var y2 = getCellY(cell2);
    var xSup = 0;
    var ySup = 0;
    var xLow = 0;
    var yLow = 0;    
    x1 > x2 ? xSup = x1 : xSup = x2;
    y1 > y2 ? ySup = y1 : ySup = y2;
    x1 < x2 ? xLow = x1 : xLow = x2;
    y1 < y2 ? yLow = y1 : yLow = y2;    
    xSup++;
    ySup++;
    xLow--;
    yLow--;
 
    var w = xSup - xLow + 1;
    var h = ySup - yLow + 1;
    var tab = [];
    for (var i = xLow;i <= xSup;i++) {
        for (var j = yLow;i <= ySup;i++) {
            var x = i - xLow;
            var y = j - yLow;
 
            var cell = getCellFromXY(i, j);
            if (cell == null) {
                tab[x + y * w] = -1;
            } else if (getCellContent(cell) == CELL_OBSTACLE) {
                tab[x + y * w] = -1;
            } else tab[x + y * w] = 1000;
        }
    }
 
    browse_square(tab,x1 - xLow, y1 - yLow,w,h, 0,mp);
    var x2t = x2 - xLow;
    var y2t = y2 - yLow;
    return tab[x2t + y2t * w] <= mp;
}
 
Coding contest : another fail
2014-06-29 01:21:51
I've failed heavily on Codingame june contest.

I didn't even complete the first exercise even though the solution was simple.


Unhappy with this performance, I've written the answer:

 
#include <stdlib.h>
#include <stdio.h>
 
void compute_move(int * xmove,int *ymove, char * s, int w,int h,int * x,int * y) {
if ((s[1] == 'R')||(s[0] == 'R')) {
*x = (*x) + (*xmove);
}
 
if ((s[1] == 'L')||(s[0] == 'L')) {
*x = (*x) - (*xmove);
}
 
if (s[0] == 'U') {
*y = (*y) - (*ymove);
}
 
if (s[0] == 'D') {
*y = (*y) + (*ymove);
}
 
*xmove = (int)(round(((float)(*xmove)) / 2.f));
*ymove = (int)(round(((float)(*ymove)) / 2.f));
}
 
 
int main() {
// Read init information from standard input, if any
int w,h;
int n;
int x,y;
scanf("%d %d", &w,&h);
 
scanf("%d", &n);
 
scanf("%d %d", &x,&y);
 
char s[3];
 
scanf("%s", s);
 
printf("%d %d\n",w/2,h/2);
 
int xmove = w/4;
int ymove = h/4;
x = w/2;
y = h/2;
while (1) {
// Read information from standard input
 
scanf("%s", &s);
// Compute logic here
 
// fprintf(stderr, "Debug messages...\n");
compute_move(&xmove,&ymove,s,w,h,&x,&y);
// Write action to standard output
if (x >= w) {
x = w - 1;
}
 
if (x < 0) {
x = 0;
}
 
if (y >= h) {
y = h - 1;
}
if (y < 0) {
y = 0;
}
 
printf("%d %d\n",x,y);
}
 
return 0;
}
 


I've lost 2 hours on this question because of bugs and failed implementation where I would keep state of the former state when it was so simple.
My contribution to the "All RGB" code challenge
2014-03-21 00:27:37


The All RGB challenge consists in displaying every rgb space colors in one picture, every color should appear one and only one time.

My algorithm is straight :
* generate palette color
* create seed pixels (at least one)
* find a colored pixel, crawl horizontally or vertically to find the first non-colored pixel, color the pixel with the closest available color (using norm 1 distance against the last visited color)

The results are certainly interesting.

Sourcecode available at GitHub : https://github.com/kobr4/MyAllRGB
Requires :
Apache Portable Runtime (multithreading)
FLTK (UI toolkit)

win32 build : http://www.nicolasmy.com/blog/uplodad/MyAllRGB-win32.zip


VBScript to recursively remove CVS meta-data directories
2014-03-03 14:23:50
Does not work too badly. One might remove "WScript.Echo" instructions on big projects.

 
Option Explicit
 
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
 
WScript.Quit Main()
 
Function Main()
Dim sDir : sDir = "CVS-REPOS\ANAH"
Dim oWorker : Set oWorker = New cWorker
Main = traverseDir(goFS.GetFolder(sDir), oWorker)
End Function
 
Class cWorker
Public Sub processFile(oFile)
End Sub
Public Function processFolder(oFolder)
WScript.Echo "looking at", oFolder.Path
processFolder = True
If "CVS" = oFolder.Name Then
WScript.Echo "will delete", oFolder.Path
oFolder.Delete
processFolder = False
End If
End Function
End Class
 
Function traverseDir(oDir, oWorker)
traverseDir = 0
Dim oF
For Each oF In oDir.Files
oWorker.processFile oF
Next
For Each oF In oDir.SubFolders
If oWorker.processFolder(oF) Then
traverseDir = traverseDir(oF, oWorker)
End If
Next
End Function
 
What did I learn porting Lincity-ng to Android
2014-02-23 22:47:20

Widely acknowledged open-source software are generally highly regarded for being nicely crafted by very skillful people. Lincity-ng while being only a confidential game does confirm this view.

Namely, it features a full fledged graphical user interface that handles draggable windows, button and text widget and even multi-language support, and thus while being entirely Opengl ES compatible and still allowing software rendering.
I think it's a great introduction on UI software design, stripped from all the fluff and optimisation.

While using native user interface components is alway interesting, especially for user acceptance. In order to have a consistent user experience across plaforms, one might consider writing it's own OpenGL ES/C++ gui for a cross platform app.

Here is the prototype of the Component class:
 
class Component
{
public:
/** Values for the flags bitfield. */
enum {
FLAG_RESIZABLE = 0x00000001
};
 
Component();
virtual ~Component();
 
virtual void draw(Painter& painter);
virtual void event(const Event& event);
virtual void resize(float width, float height);
 
/** Causes the component to layout it's child components again */
virtual void reLayout();
 
/**
* @return true if the component is opaque at this place.
*/

virtual bool opaque(const Vector2& pos) const
{
if(pos.x >= 0 && pos.y >= 0 && pos.x <= width && pos.y <= height)
return true;
 
return false;
}
 
float getWidth() const
{
return width;
}
 
float getHeight() const
{
return height;
}
 
const std::string& getName() const
{
return name;
}
 
void setName(const std::string& name)
{
this->name = name;
}
 
/** @return The component flags (this is a bitfield). */
int getFlags() const
{
return flags;
}
 
/**
* Get the current component parent.
* @return The parent component or 0 if the component has no parent. */

Component* getParent() const
{
return parent;
}
Component* findComponent(const std::string& name);
 
/**
* Maps a relative coordinate from this component to a global one.
*/

Vector2 relative2Global(const Vector2& pos);
 
protected:
Childs childs;
Child& addChild(Component* component);
void resetChild(Child& child, Component* component);
void drawChild(Child& child, Painter& painter);
bool eventChild(Child& child, const Event& event, bool visible = false);
void setChildDirty(Component* child, const Rect2D& area);
Child& findChild(Component* component);
void setDirty()
{
setDirty(Rect2D(0, 0, width, height));
}
virtual void setDirty(const Rect2D& area);
virtual bool parseAttribute(const char* attribute, const char* value);
void setFlags(int flags)
{
this->flags |= flags;
}
 
void clearFlags(int flags)
{
this->flags &= ~flags;
}
Component* parent;
int flags;
float width, height;
std::string name;
friend class ButtonPanel;
};
 


1. Component hierarchy
Every single component from Button to Scrollbar inherits from one base class : Component. A component has one parents and one to many childs.

3. Event dispatching
Components are receiving events and have to act accordingly (for instance user interaction like a mouse click). Event are dispatched from parent to every childs.

2. Layouts
Layouts are components that are used to arrange others components within : a table layout, will arrange child components in columns and rows.

3. XML configuration
Every user interface composite components are declared in an XML file. A "Component Loader" will load the XML file and call the right "component factory". Each component having its own factory but the Component loader having no knowledge of any particular component factory.

Here is the component factory class :
 
#ifndef __COMPONENT_FACTORY_HPP__
#define __COMPONENT_FACTORY_HPP__
 
#include <map>
#include <string>
#include <memory>
 
const char * GUI_TRANSLATE(const char * msgid);
std::string GUI_TRANSLATE(const std::string& msgid);
 
class Component;
class XmlReader;
 
/**
* @class Factory
*/

class Factory
{
public:
virtual ~Factory()
{ }
 
virtual Component* createComponent(XmlReader& reader) = 0;
};
 
typedef std::map<std::string, Factory*> ComponentFactories;
extern ComponentFactories* component_factories;
 
/**
* @note From Matze:
* Yes I know macros are evil, but in this specific case they save
* A LOT of typing and evil code duplication.
* I'll happily accept alternatives if someone can present me one that does
* not involve typing 4 or more lines for each object class
*/

#define DECLARE_COMPONENT_FACTORY(CLASS) \
class INTERN_##CLASS##Factory : public Factory \
{ \
public: \
INTERN_##CLASS##Factory() \
{ \
if(component_factories == 0) \
component_factories = new ComponentFactories; \
\
component_factories->insert(std::make_pair(#CLASS, this)); \
} \
\
virtual Component* createComponent(XmlReader& reader) \
{ \
std::auto_ptr<CLASS> component (new CLASS()); \
component->parse(reader); \
return component.release(); \
} \
};
#define IMPLEMENT_COMPONENT_FACTORY(CLASS) \
DECLARE_COMPONENT_FACTORY(CLASS) \
INTERN_##CLASS##Factory factory_##CLASS;
 
#endif
 

I like the little macro that allows to create any component factory in one single macro call (some sort of rudimentary compile-time introspection, one can say).
Codingame November #112
2013-11-25 01:16:26
I've been ranked #112 out of 1167 at the november contest, not bad, although I didn't complete the "Docteur Who - Partitions" exercise.

This exercise was about being able to translate music notes from a partition picture.
I've choosen an original approach : instead of going for purely geometrical method (detecting staff, then looking for the round shape), I went for a statistical approach which proved risky.

I would build the horizontal and vertical histograms, then I would try to find values that would looks like notes signatures. In a hurry, I've tied detection to reading a single value from histograms which is far insufficient to detect correctly all the notes.
After the contest, I've added a solution that checks for pattern signatures in the horizontal and vertica histograms.

This solution still is not complete : It doesn't work on scaled graphics, which appears in part of the mandatories unit tests.

 
// Read inputs from stdin. Write outputs to stdout.
 
#include <stdlib.h>
#include <stdio.h>
 
char output[255];
int ouput_count=0;
 
#define H_MARGIN 5
#define V_MARGIN 2
 
static int s_noire_interligne_tab[] = {149, 145, 143, 139, 139, 137, 136, 136, 136, 136, 136,
136, 136, 136, 136, 136, 137, 139, 139, 143, 108, 110};
static int s_noire_interligne_length = sizeof(s_noire_interligne_tab)/sizeof(int);
 
static int s_vnoire_interligne_tab[] = {10, 8, 4, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2,
2, 4, 6, 6, 10};
static int s_vnoire_interligne_length = sizeof(s_vnoire_interligne_tab)/sizeof(int);
 
static int s_noire_ligne_tab[] = {153, 149, 147, 143, 143, 141, 139, 139, 139,
139, 139, 139, 139, 139, 139, 139, 141, 143, 143, 147, 112, 114};
static int s_noire_ligne_length = sizeof(s_noire_ligne_tab)/sizeof(int);
 
static int s_vnoire_ligne_tab[] = {10, 8, 4, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2,
4, 6, 6, 10, 12};
static int s_vnoire_ligne_length = sizeof(s_vnoire_ligne_tab)/sizeof(int);
 
static int s_blanche_interligne_tab[] = {149, 145, 148, 148, 152, 152, 151, 153, 153,
153, 153, 153, 153, 153, 153, 151, 152, 152, 148, 148, 108, 110};
static int s_blanche_interligne_length = sizeof(s_blanche_interligne_tab)/sizeof(int);
 
static int s_vblanche_interligne_tab[] = {10, 8, 12, 16, 16, 15, 17, 16, 18, 18, 18, 18,
18, 16, 18, 16, 18, 18, 14, 10};
static int s_vblanche_interligne_length = sizeof(s_vblanche_interligne_tab)/sizeof(int);
 
static int s_blanche_ligne_tab[] = {153, 149, 152, 152, 156, 156, 154, 156, 156,
156, 156, 156, 156, 156, 156, 154, 156, 156, 152, 152, 112, 114};
static int s_blanche_ligne_length = sizeof(s_blanche_ligne_tab)/sizeof(int);
 
static int s_vblanche_ligne_tab[] = {10, 8, 12, 16, 16, 15, 17, 16, 18, 18, 18, 18,
18, 16, 18, 16, 18, 18, 14, 10, 12};
static int s_vblanche_ligne_length = sizeof(s_vblanche_ligne_tab)/sizeof(int);
 
 
static int const c_porteuse = 156;
static int s_porteuse_detection = 156;
 
void v_buffer_scan(char * pbuff,int w,int h,int h_start,int h_end, int q_flag);
 
int detect_pattern(int * tab,int tab_length, int offset, int * pattern, int p_length, int margin) {
    for (int i = offset;i < tab_length - p_length + 1;i++) {
        if ( abs( (tab[i]-s_porteuse_detection) - (pattern[0] - c_porteuse)) <= margin) {
            int exit = 0;
            for(int k = 1;(!exit) && (k < p_length);k++) {
                if (abs ( (tab[i+k]-s_porteuse_detection) - (pattern[k]- c_porteuse)) > margin) {
                    exit = 1;
                }
            }
            if (exit != 1) {
                return i;
            }
        }
    }
    return -1;
}
 
int detect_inverted_pattern(int * tab,int tab_length, int offset, int * pattern, int p_length, int margin) {
    for (int i = offset;i < tab_length - p_length + 1;i++) {
        if ( abs((tab[i]-s_porteuse_detection) - (pattern[p_length-1] - c_porteuse)) <= margin) {
            int exit = 0;
            for(int k = 1;(!exit) && (k < p_length);k++) {
                if (abs ((tab[i+k]-s_porteuse_detection) - (pattern[p_length-1-k] - c_porteuse)) > margin) {
                    exit = 1;
                }
            }
            if (exit != 1) {
                return i;
            }
        }
    }
    return -1;
}
 
 
void add_output(char note, char color){
if (ouput_count > 0) {
output[ouput_count]=' ';
ouput_count++;
}
output[ouput_count]=note;
ouput_count ++;
output[ouput_count]=color;
ouput_count++;
output[ouput_count] = 0;
}
 
void fill_buffer(char * pbuff, int w,int h,char col,int length,int offset) {
for (int i = offset;i < offset+length;i++) {
pbuff[i] = col;
}
}
 
char getpixel(char * pbuff,int w,int h,int i,int j) {
return pbuff[j*w+i];
}
 
void h_buffer_scan(char * pbuff,int w,int h) {
int * wBuff = (int*)malloc(sizeof(int)*w);
 
 
for (int i = 0;i < w;i++) {
wBuff[i] = 0;
for(int j = 0;j < h;j++) {
wBuff[i] += getpixel(pbuff,w,h,i,j);
}
}
 
 
/*
int val = 0;
val = wBuff[0];
 
for (int i = 0;i < w;i++) {
 
 
if (s_porteuse_detection == 0 && wBuff[i] != wBuff[0] ) {
s_porteuse_detection = wBuff[i];
}
 
 
}
*/

for (int i = 0;i < w;i++) {
printf("%d ",wBuff[i] - s_porteuse_detection);
}
 
for (int i = 0;i < w;i++) {
 
 
int a = detect_pattern(wBuff,w, i, s_noire_ligne_tab, s_noire_ligne_length, H_MARGIN);
if (a == i) {
v_buffer_scan(pbuff,w,h,i,a+s_noire_ligne_length,1);
i += s_noire_ligne_length;
continue;
}
a = detect_inverted_pattern(wBuff,w, i, s_noire_ligne_tab, s_noire_ligne_length, H_MARGIN);
if (a == i) {
v_buffer_scan(pbuff,w,h,i,a+s_noire_ligne_length,1);
i += s_noire_ligne_length;
continue;
}
 
int b = detect_pattern(wBuff,w, i, s_noire_interligne_tab, s_noire_interligne_length, H_MARGIN);
if (b == i) {
v_buffer_scan(pbuff,w,h,i,b+s_noire_interligne_length,1);
i += s_noire_interligne_length;
continue;
}
b = detect_inverted_pattern(wBuff,w, i, s_noire_interligne_tab, s_noire_interligne_length, H_MARGIN);
if (b == i) {
v_buffer_scan(pbuff,w,h,i,b+s_noire_interligne_length,1);
i += s_noire_interligne_length;
continue;
}
 
int c = detect_pattern(wBuff,w, i, s_blanche_ligne_tab, s_blanche_ligne_length, H_MARGIN);
if (c == i) {
v_buffer_scan(pbuff,w,h,i,c+s_blanche_ligne_length,0);
i += s_blanche_ligne_length;
continue;
}
c = detect_inverted_pattern(wBuff,w, i, s_blanche_ligne_tab, s_blanche_ligne_length, H_MARGIN);
if (c == i) {
v_buffer_scan(pbuff,w,h,i,c+s_blanche_ligne_length,0);
i += s_blanche_ligne_length;
continue;
}
 
int d = detect_pattern(wBuff,w, i, s_blanche_interligne_tab, s_blanche_interligne_length, H_MARGIN);
if (d == i) {
v_buffer_scan(pbuff,w,h,i,d+s_blanche_interligne_length,0);
i += s_blanche_interligne_length;
continue;
}
d = detect_inverted_pattern(wBuff,w, i, s_blanche_interligne_tab, s_blanche_interligne_length, H_MARGIN);
if (d == i) {
v_buffer_scan(pbuff,w,h,i,d+s_blanche_interligne_length,0);
i += s_blanche_interligne_length;
continue;
}
 
}
 
free(wBuff);
}
 
void v_buffer_scan(char * pbuff,int w,int h,int h_start,int h_end, int q_flag) {
printf("\nvertical scan at: %d\n",h_start);
 
int * hBuff = (int*)malloc(sizeof(int)*h);
 
int col = 'H';
if (q_flag == 1) {
col = 'Q';
}
 
for (int j = 0;j < h;j++) {
hBuff[j] = 0;
for(int i = h_start;i < h_end;i++) {
hBuff[j] += getpixel(pbuff,w,h,i,j);
}
}
 
/*
for (int i = 0;i < h;i++) {
printf("%d ",hBuff[i]);
}
 
puts("");
*/

for (int i = 0;i < h;i++) {
int a = detect_pattern(hBuff,h, i, s_vnoire_ligne_tab, s_vnoire_ligne_length, V_MARGIN);
 
if (a == i) {
//printf("noire ligne dected at %d\n",i);
char cout = 'A' + 6 - ((a/12) - 1)%7;
add_output(cout, col);
i += s_vnoire_ligne_length;
continue;
}
 
int b = detect_pattern(hBuff,h, i, s_vnoire_interligne_tab, s_vnoire_interligne_length, V_MARGIN);
if (b == i) {
//printf("noire interligne dected at %d\n",i);
char cout = 'A' + 6 - ((b/12) - 1)%7;
add_output(cout, col);
i += s_vnoire_interligne_length;
continue;
}
 
int c = detect_pattern(hBuff,h, i, s_vblanche_ligne_tab, s_vblanche_ligne_length, V_MARGIN);
if (c == i) {
//printf("blanche ligne dected at %d\n",i);
char cout = 'A' + 6 - ((c/12) - 1)%7;
add_output(cout, col);
i += s_vblanche_ligne_length;
continue;
}
 
int d = detect_pattern(hBuff,h, i, s_vblanche_interligne_tab, s_vblanche_interligne_length, V_MARGIN);
if (d == i) {
//printf("blanche interligne dected at %d\n",i);
char cout = 'A' + 6 - ((d/12) - 1)%7;
add_output(cout, col);
i += s_vblanche_interligne_length;
continue;
}
}
 
free(hBuff);
}
 
 
int main()
{
int w, h;
scanf("%d %d", &w, &h);
printf("w=%d h=%d\n",w,h);
char str_num[10];
int ind = 0;
char * pbuf = (char*)malloc(sizeof(char)*w*h);
int offset = 0;
char curr_c = 0;
int cr = getchar();
while ((cr != EOF)) {
//printf("%c",cr);
cr = getchar();
 
if (cr == 'W' || cr == 'B') {
if (curr_c != 0) {
str_num[ind] = 0;
int length = atoi(str_num);
//printf("l=%d %d\n",length,offset);
int col;
if (curr_c == 'W'){
col = 1;
} else {
col = 0;
}
fill_buffer(pbuf, w,h,col,length,offset);
offset += length;
}
curr_c = cr;
ind = 0;
 
} else {
if (cr != ' ') {
str_num[ind]=cr;
ind++;
}
}
}
 
 
str_num[ind] = 0;
int length = atoi(str_num);
int col;
if (curr_c == 'W'){
col = 1;
} else {
col = 0;
}
fill_buffer(pbuf, w,h,col,length,offset);
offset += length;
 
h_buffer_scan(pbuf, w, h);
 
free(pbuf);
printf("%s\n",output);
return 0;
}
 
CodingGame training
2013-11-23 01:39:58
My solution to "Dwarfs standing on the shoulders of giants"
http://www.codingame.com/cg/#!page:training

Solved in 83 minutes !
 
// Read inputs from stdin. Write outputs to stdout.
 
#include <stdlib.h>
#include <stdio.h>
 
 
int main()
{
int n;
scanf("%d", &n);
 
int * tab = (int*)malloc(sizeof(int)*n*2);
for (int i = 0;i < n;i++) {
scanf("%d %d",&tab[i*2], &tab[(i*2) + 1]);
}
 
int * tab2 = (int*)malloc(sizeof(int)*n);
 
 
 
int max = 0;
for (int k = 0;k < n;k++) {
int iterate = 1;
 
for (int i=0;i < n;i++) {
tab2[i] = 0;
}
 
while (iterate) {
int c_pos = tab[k<<1];
int count = 1;
int exit = 0;
int c_arc = 0;
//printf("tab2[c_arc]=%d\n",tab2[c_arc]);
while (!exit) {
int found = 0;
for (int i = 0;(found == 0)&&(i < n);i++) {
if (tab2[i]==0)
if ((tab[i<<1] == c_pos)&&(tab2[i]==0)) {
found = 1;
count++;
c_pos = tab[(i<<1) + 1];
c_arc = i;
//printf(" %d-%d (%d) ",tab[i<<1],tab[(i<<1)+1],i);
}
}
 
 
if (found == 0) {
tab2[c_arc]=1;
//printf(" = %d (%d %d)\n",count,c_arc,tab2[c_arc]);
exit = 1;
}
}
if (max < count) {
max = count;
}
 
if (c_arc == k) {
iterate = 0;
}
}
 
}
printf("%d\n",max);
free(tab);
free(tab2);
return 0;
}
 

Then I realized that graph traversal the iterative way is the hard way.
Coding contests
2013-11-22 00:38:34
http://www.codingame.com/

I like coding contests, far from design patterns, middleware or webservices, it bring programming back to what it meant to be : solve a real-life problem in an automated way.
The competition idea in programming is a nice idea as very rarely coding rely on competition in real life, but rather on cooperation, so being able to compare skills hardly happens.
If it can also helps coders finding a job where they can make right use of their skill that's even better.

I happen to learn things about myself:
* Overall I'd rather solve this kind of problems using C after all.
* I'm rusted in raw keyboard input, forgot that scanf("%s",s) won't catch "space".
* Writing algorithms is not only about instinct or skills but is a matter of training.

I'll be there November 23th, will you ?
See 10 older news | Back to the top