Défi de programmation
Ya longtemps, avec Gamo, Batchy et compagnie, on se lançait des défis de programmation sur un thème bien précis, ça donnais parfois des trucs genre « programme moi un serveur http en 2h », ou bien des défis un peu plus tendus, basés sur l'élaboration d'un algorithme un peu tordu, mais toujours très intéressant.
Vu que moi ça me manque, et qu'on avait dit un jour que l'on recommencerais, et ben voilà !
Pour ce premier défi (depuis longtemps), je vais commencer par un truc assez simple, que Gamo nous avait déjà fait découvrir : les fonctions récursives. Je n'en dit pas plus, je vous laisse chercher si vous avez besoin de plus d'informations.
Le but du jeu va être de programmer une fonction qui aura le comportement suivant :
vagues(5, 3)
Affichera :
S
SS
SSS
SSSS
SSSSS
SSSS
SSS
SS
S
SS
SSS
SSSS
SSSSS
SSSS
SSS
SS
S
SS
SSS
SSSS
SSSSS
SSSS
SSS
SS
S
Le premier argument est la hauteur des vagues (en nombre de caractères), le second argument est le nombre de vagues
Le truc, c'est que vous n'avez pas le droit d'utiliser de structures de boucles dans votre programme (et la, je vous renvois 2 paragraphes plus haut). Vous ne devez pas non plus utiliser des spécificités de votre langage qui pourraient vous aider à résoudre ce problème.
Pour les règles, y'en a pas vraiment. Vous utilisez le langage que vous voulez, il n'y a rien à gagner, et je vous encourage à partager toute la doc utile que vous trouverez. Pour le code, le mieux est de l'héberger sur des sites de collage, sur un repository (cvs, svn, hg, ce que vous voulez tant qu'on peut accéder au code facilement avec un navigateur), ou encore sur votre hébergeur préféré. En fait, ce qu'il ne faut surtout pas, c'est le poster dans les commentaires, car vous perdriez l'indentation et la chasse fixe.
Pour ma part, je vais le faire en python (et peut être aussi en perl, on verra :))
Bon alors, voila les propositions, d'abbord, celle de Sunny en ruby:
#!/usr/bin/ruby
# Vagues, de Sunny Ripert
# implémentation ruby de http://inaps.org/journal/defiprog-1
# Sous licence WTFGL - http://sam.zoy.org/wtfpl/
class Vague
def initialize height, count
@maxheight, @maxcount = height.to_i, count.to_i
raise ArgumentError, \"Height must be bigger than 2\" if @maxheight < 2
raise ArgumentError, \"Count must be bigger than 1\" if @maxcount < 1
@count, @height = 0, 1
@output = \"\"
crest
waves
end
def waves
@height = 1
@count += 1
wave
waves unless @count == @maxcount
end
def wave
@height += 1
crest
wave unless @height == @maxheight
@height -= 1
crest
end
def crest
@h = 0
oscillation
@output += \"\\n\"
end
def oscillation
@h += 1
@output += \"S\"
oscillation unless @h == @height
end
def to_s
@output
end
end
if __FILE__ == $0
abort \"Usage: #{$0} height count\" if ARGV.size < 2
puts Vague.new(ARGV[0], ARGV[1]) rescue puts($!)
end
Ou par ici en couleur. Ensuite, celle de Batchy, en C(kipu :))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* waves_backend(int depth, int times) {
char *ret = NULL ,*othret;
if (times > 0) {
printf(\"%s\", ret = waves_backend(depth,times-1));
} else if (times == 0) {
puts(\"S\");
ret = calloc(((depth + 2) * depth - 2 ), sizeof *ret);
strcat(ret, othret = waves_backend(depth - 1, -1));
free(othret);
strcat(ret, othret = waves_backend(depth - 2, -2));
free(othret);
} else if (depth > 0) {
ret= calloc((((depth + 4) * (depth + 1)) / 2 + 1), sizeof *ret);
if (times == -2)
strcat(strcpy(ret, othret=waves_backend(-depth, -1)),\"\\n\");
else
strcpy(ret, othret = waves_backend(depth - 1, -3));
free(othret);
if (times == -2)
strcat(ret, othret = waves_backend(depth - 1,-2));
else
strcat(strcat(ret, othret = waves_backend(-depth, -1)),\"\\n\");
free(othret);
} else if (depth == 0) {
ret=calloc(3, sizeof *ret);
if (times != -3)
strcpy(ret, \"S\\n\");
} else {
ret=calloc(2 - depth, sizeof *ret);
strcpy(ret, othret = waves_backend(depth + 1, -1));
ret[-depth] = \'S\';
free(othret);
}
return ret;
}
void waves(int depth, int times) {
if (depth > 1 && times > 0)
free(waves_backend(depth, times));
}
int main(int argc, char *argv[]) {
if (argc < 3)
puts(\"usage: <depth of waves> <number of waves>\");
else
waves(atoi(argv[1]), atoi(argv[2]));
return 0;
}
Ou par ici en couleur. La mienne, en python :
#!/usr/bin/env python
from sys import stdout
def row(size, i=0):
if i != size:
stdout.write(\'S\')
row(size, i+1)
def aWave(size, i=1, d=1):
if i == size:
row(i)
stdout.write(\'\\n\')
aWave(size, i=i-1, d=0)
elif i==0:
return
elif d:
row(i)
stdout.write(\'\\n\')
aWave(size, i=i+1)
else:
row(i)
stdout.write(\'\\n\')
aWave(size, i=i-1, d=0)
def waves(size, number, i=0):
if i != number:
aWave(size)
waves(size, number, i=i+1)
vagues = waves
vagues(5, 2)
Et enfin, la version de gamo, en bash, très gore :
#!/bin/sh
# !!! the script must be chmod +x !!!
# at least i think so
if [ ${#*} -lt 3 ]; then
$0 $* $(($1 -1)) -
exit
fi
maxc=$1; wave=$2; curr=$3; op=$4
ndisp=$(($maxc - $curr))
seq -w -s\" \" $ndisp | sed -e \'s/[0-9]*/#/g\' -e \'s/ //g\'
if [ $ndisp -eq $maxc ]; then
op=\"+\"
elif [ $ndisp -eq 1 ]; then
op=\"-\"; wave=$(($wave - 1))
if [ $wave -lt 0 ]; then exit; fi
fi
. $0 $maxc $wave $(expr $curr $op 1) $op
Encore une de gamo, en C :
/* be a nazi and compile with:
* gcc -Wall -ansi -posix -pedantic cwaves.c -o toto
*
* OFC!
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void tibal(unsigned int n)
{
if (n)
{
write(1, \"\\x23\", 1);
tibal(--n);
}
else
write(1, \"\\x0a\", 1);
}
unsigned char cwaves(unsigned int maxc, unsigned int wave,
unsigned int curr, char op)
{
unsigned int ndisp = maxc - curr;
/* hi2u2 :) */
tibal(ndisp);
if (!(ndisp ^ maxc))
op = 1;
else if (ndisp == 1)
{
op = -1;
wave -= 1;
if (!wave)
return EXIT_SUCCESS;
}
cwaves(maxc, wave, curr+op, op);
/* never happens but nazi gcc stfu with this */
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
return (argc != 3)?EXIT_FAILURE:cwaves(atoi(argv[1]), atoi(argv[2]) + 1,
atoi(argv[1]) - 1, -1);
}


Commentaires
Antoine — inaps.org
le 23 décembre 2007 02:33<strong>Bon, j'ai la flemme de migrer tous les commentaires alors voici un copier->coller :</strong>
<blockquote cite="Multiples auteurs">commentaire de webs
lifeisdead.net/
Le mardi 2 octobre 2007 à 19h23
Moi, ruby.
commentaire de TibaL
tibal.info
Le mardi 2 octobre 2007 à 19h23
Moi, C.
commentaire de Sunny
sunfox.org/
Le mardi 2 octobre 2007 à 19h26
ruby: http://toothpaste.escaline.org/code/64
commentaire de webs
lifeisdead.net/
Le mardi 2 octobre 2007 à 19h30
En fait non c'est sunny qui fait le ruby.
commentaire de Antoine
inaps.org
Le mardi 2 octobre 2007 à 19h38
Sauf que sunny il a faux la, il utilise une spécificité de ruby qui lui simplifie les choses.
(Faut vraiment que je foutte cette case à cocher pour sauver les informations quand on envois un commentaie :x)
commentaire de Sunny
sunfox.org/
Le mardi 2 octobre 2007 à 19h45
Ok, voilà sans la "spécificité" : http://toothpaste.escaline.org/code/66
commentaire de Sunny
sunfox.org/
Le mardi 2 octobre 2007 à 20h3
Ajouté à mon dépot sous http://code.sunfox.org/vagues/trunk/?vagues.rb
Vive le ruby \o/
commentaire de BatchyX
Le mardi 2 octobre 2007 à 21h28
en Ckipu : http://toothpaste.escaline.org/code/67
attention code crade : prendre des gants.
commentaire de gamo
Le mercredi 3 octobre 2007 à 21h29
en bash version moche, qui peux l'etre encore plus (j'ai mon idee mais je suis bourré): http://pong.polio.be/~matth/vague.sh.txt
commentaire de gamo
www.polio.be
Le jeudi 4 octobre 2007 à 13h26
encore du laid, mais en C cette fois :p
http://pong.polio.be/~matth/cwaves.c.txt
commentaire de TibaL
tibal.info
Le jeudi 4 octobre 2007 à 23h33
Mon code en C: http://toothpaste.escaline.org/code/68
Je finis par le poster mais toujours sans comprendre pourquoi ça plante avec des grandes valeurs, par exemple amplitude=10 et 99999 vagues.
Ce n'est pas lié aux types des variables en tout cas...
commentaire de TibaL
tibal.info
Le vendredi 5 octobre 2007 à 21h16
Nouvelle version en C++ : http://toothpaste.escaline.org/code/69
ça m'a fait gagner une ligne de code \o/ (potentiellement deux, mais je n'ai pas encore réussi)
Le bug précédent persiste toujours, probablement à cause d'une récursion trop profonde (call stack trop petite ?).
commentaire de BatchyX
Le samedi 6 octobre 2007 à 10h59
celui de gamo plante aussi avec des grandes valeurs, c'est juste un dépassement de stack ;)
mais le mien il plante pas :p (enfin si, avec 180000 vagues de 10 de hauteurs ... je laisse l'exercice au lecteur pour augmenter cette limite, c'est pas compliqué)
</blockquote>
Araen
le 21 février 2008 19:21Et voilà le mien en python :
http://pastebin.com/f2f21931e
J'ai pas mis de vérification, c'est juste pour l'algorithme ;)
JeromeJ — www.olissea.com
le 01 mars 2008 13:27Et en PHP ?
function wave($height, $nb_wave, $str = 'S')
{
for($i = 0; $i < $nb_wave; $i++)
{
for($a = 1, $count = ($height*2)-1; $a < $count; $a++)
{
if($a <= $height) echo str_repeat($str, $a);
else echo str_repeat($str, ($count-$a+1));
echo '',"\n";
}
}
}
wave(6, 3);
JeromeJ — www.olissea.com
le 01 mars 2008 13:28Zut ;O on voit pas l'identation ni le br ... Désolé.
BatchyX
le 01 mars 2008 18:12Ouais mais ça va pas du tout !
on à dit pas de boucle ni de fonction préfaites du langage. exit donc les for(;;) et les str_repeat()
BatchyX
le 01 mars 2008 18:17et pareil, pas le droit au chaine*nombre du python/ruby.
wumzi — www.wumzi.info
le 22 avril 2010 23:46Encore un autre en Python (quel magnifique language pour se concentrer sur la logique pure ...)
http://ideone.com/weF01
Laisser un commentaire