[Tous langages] Atelier de Noël : dessinons un sapin !

♪ Mon beau sapin, roi des forêts ♫

a marqué ce sujet comme résolu.

Salutation les agrumes !

Je vous propose un petit atelier de programmation pour les fêtes : dessiner un sapin !

Le programme à réaliser

Écrire un programme qui prends un nombre entier positif non-nul n en entrée, et qui dessine un sapin de cette taille.

Un sapin d’ordre n est constitué de n rangées de * disposées… ben, en sapin ; et d’un tronc #. Le sapin doit être bien droit et son tronc centré.

Parce que c’est mieux avec des exemples :

Sapin d’ordre 3 :

1
2
3
4
  *
 ***
*****
  #

Sapin d’ordre 5 :

1
2
3
4
5
6
    *
   ***
  *****
 *******
*********
    #

L’ordre du sapin peut être codé en dur dans le programme, tant qu’il est à un seul endroit et qu’on peut le modifier en changeant un simple chiffre.

La sortie peut se faire n’importe où (console, page web…) tant que les contraintes ci-dessus sont respectées.

N’oubliez pas de préciser le langage et la version utilisés !

Pour les débutants

Essayez simplement de réaliser le programme, c’est un exercice intéressant.

Pour les expérimentés

Réalisez ce programme de la façon la plus originale possible. Ça peut être le code le plus court, le plus étrange, le pire abus de votre langage, etc.

Dans tous les cas, expliquez à vos lecteurs quels sont les astuces utilisées.

À noter que les astuces suivantes sont trop classiques et donc ne devraient pas être utilisées :

  • Utiliser des caractères qui sont identiques graphiquement mais qui ne sont pas les mêmes.
  • Récupérer la solution depuis une source externe.
  • Coder la solution en dur.
  • En fait à peu près tout ce qui est dans cette liste.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
spacefox@spacefox-win:/mnt/c/Users/SpaceFox$ python sapin.py
  File "sapin.py", line 1
    for i in range(N):print(f'{"*"*(i*2+1):^{2*N}}')
                                                  ^
SyntaxError: invalid syntax
spacefox@spacefox-win:/mnt/c/Users/SpaceFox$ python3 sapin.py
  File "sapin.py", line 1
    for i in range(N):print(f'{"*"*(i*2+1):^{2*N}}')
                                                  ^
SyntaxError: invalid syntax

C’est bien comme ça qu’on utilise Haskell?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import Control.Monad

main :: IO ()
main = do
  putStrLn "Ordre du sapin?"
  n <- readLn
  -- Affiche le haut ligne par ligne
  forM_ [0..(n-1)] $ \i -> do
    forM_ [0..(n-i-2)] $ \_ -> do
      putStr " "
    forM_ [0..(2*i)] $ \_ -> do
      putStr "*"
    putStr "\n"
  -- Affiche le tronc
  forM_ [0..(n-2)] $ \_ -> do
    putStr " "
  putStrLn "#"

Et la version pas aussi courte que j’aurais voulu:

1
2
3
n=5
r=replicate
main=mapM putStrLn$[r(n-i)' '++r(2*i-1)'*'|i<-[0..n]]++[r(n-1)' '++"#"]

Une version en Kotlin qui tourne dans un navigateur : loriswit.github.io/sapin/

Code source :

import org.w3c.dom.HTMLInputElement
import kotlin.browser.document

fun main(args: Array<String>)
{
    val input = document.createElement("input") as HTMLInputElement
    input.type = "range"
    input.min = "2"
    input.max = "30"
    input.value = "10"
    input.addEventListener("input", { draw(input.value.toInt()) })
    
    val height = document.createElement("h1")
    height.id = "height"
    
    val canvas = document.createElement("pre")
    canvas.id = "canvas"
    
    document.body?.appendChild(height)
    document.body?.appendChild(input)
    document.body?.appendChild(canvas)
    
    draw(input.value.toInt())
}

fun draw(height: Int)
{
    val tree = StringBuilder()
    for(i in 0 until height)
        tree.append(" ".repeat(height - i - 1) + "*".repeat(i * 2 + 1) + "\n")
    tree.append(" ".repeat(height - 1) + "#")
    
    document.getElementById("height")?.innerHTML = "n = $height"
    document.getElementById("canvas")?.innerHTML = tree.toString()
}
+1 -0

Dyalog APL:

1
{⎕IO0⋄((¯1+2×)(∊↓⍉↑(⌽⍳)(1+2×⍳)(⌽⍳))/(3×)' ' '*' ' ')(' ' '#' ' '/⍨(-1),1,(-1))}

J’suis pas trop satisfait, y’a encore de la répétition…

edit: en plus court

1
{n('#',' '-1),{(' 'n-),('*'¯1+2×)}¨}
+4 -0

Un sapin et la fonction x -> |x|, c’est presque la même chose non ?

1
2
3
4
5
N = 7
lentab = N*2+1
mat = [[' ' if j < abs(i-(lentab)//2) or j == N else '*' for i in range(lentab)]for j in range(N+1)]
mat[-1][lentab//2] = '#'
for line in mat: print(''.join(line))
+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte