Écrivez le programme le plus court pour transformer n'importe quelle œuvre d'art ASCII en une scène de neige animée qui commence à se former à partir de la neige qui tombe ( exemple JavaScript non-golfé dernière mise à jour le 2011-12-19).
Spécification d'entrée : votre programme doit accepter des combinaisons arbitraires d'espaces, d'astérisques et de nouvelles lignes. L'entrée contiendra au maximum 23 lignes et 80 caractères par ligne. Il n'y aura pas de lignes vides, mais les lignes peuvent être constituées uniquement d'espaces. Une seule nouvelle ligne de fin sera incluse et doit être ignorée.
Sortie : affichez des caractères ASCII (espaces, astérisques) et des codes de contrôle (retours chariot, sauts de ligne, codes d'échappement ANSI, etc.) pour la console texte ou l'émulateur de terminal de votre système d'exploitation jusqu'à ce que l'utilisateur termine manuellement le programme. Vous pouvez supposer que la fenêtre du terminal contient 80 x 24 caractères si votre système d'exploitation autorise ce paramètre.
Règles :
- L'animation doit être fluide et rapide (15 ips de préférence).
- La densité de la neige doit être comprise entre 5% et 15%.
- Pas plus d'un écran de neige peut défiler par seconde. (Cela signifie qu'au plus 24 lignes de neige fraîche peuvent être ajoutées au cours d'une même période.)
- La neige ne doit présenter aucun motif évident lorsqu'elle pénètre en haut de l'écran; il doit avoir l'air aléatoire.
- Le programme doit remplir toutes les rangées de l'écran de neige le plus rapidement possible au démarrage; le remplissage initial des lignes individuelles de l'écran ne doit pas être évident pour le spectateur.
- Le coin inférieur gauche de l'art ASCII d'entrée doit être situé dans le coin inférieur gauche de l'écran (figure 1 pour plus de précisions).
- La zone à l'intérieur ou sous l'art ASCII ne doit pas être remplie en permanence d'astérisques. Cependant, les astérisques peuvent (mais ne sont pas obligatoires) faire défiler cette zone.
- La neige ne doit pas s'accumuler au bas de l'écran ou sur le dessus de la neige existante, sauf comme indiqué dans l'entrée.
- Les espaces inférieurs doivent être remplis avant les espaces supérieurs, car le remplissage des espaces dans l'ordre opposé rend l'animation de l'arbre de Noël très différente de la sortie de mon code d'origine. (ajouté le 2011-12-20)
Joyeuses fêtes!
Figure 1: zones étiquetées d'un écran 80x24
---------------------------New snow added on this line--------------------------
|
|
----------------------------------------------------------+ |
**** | |
Snow MUST fall Snow MAY fall ----------------> **** | |
through this through these **** **** | Snow MUST fall |
area. areas of a **** **** | through this |
completed \---------> **** ****| area. |
ASCII art scene. \ *** **** ****| |
area \ \ ******* **** ****| |
\ \ ******** *** ***| (ALL CAPS terms |
(located in \ \--> ********* *** | have standard |
lower left \ ******* ****** MAY | RFC 2119 |
corner of \ ************* ** fall | meanings.) |
screen) \ *********** here | |
*** +---> **** *** | |
*** | **************** *** | |
| Snow MUST fall *** | **************** *** | |
| through this *** +---> *** | |
| area. *** | **************** *** | |
--+---------------------+*** +---> ***+----+------------------+--
| Snow MUST NOT |****************************| Snow MUST NOT |
V accumulate here. |****************************| accumulate here. V
Exemples d'entrées
Code Golf Banner
****** ******* ******** ******** ****** ******* ** ********
** ** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ****** ** **** ** ** ** ******
** ** ** ** ** ** ** ** ** ** ** **
** ** ** ** ** ** ** ** ** ** ** ** **
****** ******* ******** ******** ****** ******* ******** **
Logo de débordement de pile
****
****
**** ****
**** ****
**** ****
*** **** ****
******* **** ****
******** *** ***
********* ***
******* ******
************* **
***********
*** **** ***
*** **************** ***
*** **************** ***
*** ***
*** **************** ***
*** ***
****************************
****************************
Arbres de Noël
*
*** *
* ***** ***
*** ******* * *****
***** ********* *** *
* *********** *****
* ************* *******
* *** *************** * *
*** ***** ***************** ***
***** ******* ******************* *****
******* * ********************* *******
********* * *********
* *
Réponses:
Perl, 196/239 caractères
Cette solution diffère de votre exemple JS en ce que le motif est rempli de haut en bas plutôt que de bas en haut, mais je suppose que c'est OK car vous n'avez rien dit à ce sujet dans les règles.
Une réduction triviale de 1 caractère peut être obtenue en remplaçant
\e
par un caractère ESC littéral, mais cela rend le code beaucoup plus difficile à lire et à modifier.Mise à jour: Je l' ai réussi à trouver une version qui remplit le modèle de bas en haut, et ne permet pas la neige de tomber à travers les parties remplies du modèle, comme dans l'exemple la mise en œuvre JS, au prix de 43 caractères supplémentaires:
Le remplacement
($s[$_]&=~$f[$_])
par juste$s[$_]
sauverait 11 caractères en laissant passer la neige qui tombe à travers les parties remplies du motif (ce qui correspond à la spécification, mais pas à l'exemple d'implémentation).OK, puisque je semble toujours mener la course après une semaine, je suppose que je devrais expliquer comment ma solution fonctionne pour encourager plus de compétition. (Remarque: cette explication concerne la version de remplissage descendante de 196 caractères. Je pourrai la modifier pour inclure l'autre version ultérieurement.)
Tout d'abord, la seule grosse astuce sur laquelle ma solution est basée est que, en raison de la façon dont les codes de caractères ASCII sont organisés, les 1 bits du code ASCII pour un espace se trouvent être un sous-ensemble de ceux du code pour un astérisque.
Ainsi, les expressions suivantes sont vraies:
" " & "*" eq " "
et" " | "*" eq "*"
. C'est ce qui me permet d'utiliser des opérations de chaîne au niveau du bit pour combiner les parties statiques et mobiles de la scène sans avoir à boucler sur des caractères individuels.Donc, avec cela à l'écart, passons en revue le code. En voici une version dé-golfée:
La première ligne configure les tableaux
@f
(pour "fixe") et@p
(pour "motif").@f
formera la partie fixe de l'affichage et commencera par ne contenir que des espaces, tandis que@p
, qui n'est pas affiché directement, contient le motif d'entrée; au fur et à mesure de l'animation, nous ajouterons de plus en plus d'astérisques@f
jusqu'à ce que cela ressemble finalement@p
.Plus précisément,
@f = ($" x 80) x 23
définit@f
24 chaînes de 80 espaces chacune. ($"
est une variable Perl spéciale dont la valeur par défaut se trouve être un espace.) Nous prenons ensuite cette liste, y ajoutons les lignes d'entrée à l'aide de l'opérateur readline<>
, prenons les 24 dernières lignes de cette liste combinée et l'affectons à@p
: c'est une façon compacte de remplir@p
avec des lignes vides afin que le motif apparaisse où il devrait. Enfin, nouschomp
introduisons les lignes d'entrée@p
pour supprimer tous les retours à la ligne afin qu'ils ne causent pas de problèmes plus tard.Maintenant, regardons la boucle principale. Il s'avère que
{...;redo}
c'est un moyen plus court d'écrire une boucle infinie quewhile(1){...}
ou mêmefor(;;){...}
, surtout si nous arrivons à omettre le point-virgule avantredo
car il suit immédiatement unif
bloc.La première ligne de la boucle principale présente le tableau
@s
(pour "snow", bien sûr), auquel il ajoute une chaîne aléatoire de 80 caractères de 90% d'espaces et 10% d'astérisques à chaque itération. (Pour enregistrer quelques caractères, je n’ajoute jamais de lignes supplémentaires à la fin du@s
tableau, donc il continue de s'allonger de plus en plus. prendra beaucoup plus de temps que la plupart des gens ne regarderaient jamais cette animation. L'ajout d'unepop@s;
déclaration avant leselect
corrigerait au prix de sept caractères.)Le reste de la boucle principale est enveloppé dans un
if
bloc, de sorte qu'il ne s'exécute qu'une fois que le@s
tableau contient au moins 24 lignes. C'est un moyen simple de se conformer à la spécification, qui nécessite que tout l'affichage soit rempli de neige tombante dès le début, et simplifie également un peu les opérations au niveau du bit.Vient ensuite une
foreach
boucle, qui dans la version golfée est en fait une seule déclaration avec unfor 0..23
modificateur. Puisque le contenu de la boucle a probablement besoin d'explications, je vais le décompresser un peu plus bas:Tout d'abord,
$_
c'est la variable de compteur de boucle par défaut en Perl sauf si une autre variable est spécifiée. Ici, il va de 0 à 23, c'est-à-dire sur les 24 lignes du cadre d'affichage.$foo[$_]
désigne l'élément indexé par$_
dans le tableau@foo
.Sur la première ligne de la boucle dé-golfée, nous imprimons soit une nouvelle ligne (obtenue commodément à partir de la
$/
variable spéciale) ou, lorsqu'elle$_
est égale à 0, la chaîne"\e[H"
, où\e
dénote un caractère ESC. C'est un code de contrôle de terminal ANSI qui déplace le curseur dans le coin supérieur gauche de l'écran. Techniquement, nous pourrions omettre cela si nous supposions une taille d'écran spécifique, mais je l'ai gardée dans cette version car cela signifie que je n'ai pas à redimensionner mon terminal pour exécuter l'animation.Sur la
$t = $f[$_]
ligne, nous enregistrons simplement la valeur actuelle de$f[$_]
dans une variable "temporaire" (donc$t
) avant de la changer potentiellement dans la ligne suivante, où$s[$_] & $p[$_]
donne l'intersection (au niveau du bit ET) de la neige qui tombe et le motif d'entrée, et l'|=
opérateur OU que dans la ligne de sortie fixe$f[$_]
.Sur la ligne ci-dessous,
$t ^ $f[$_]
donne le XOR au niveau du bit des valeurs précédentes et actuelles de$f[$_]
, c'est-à-dire une liste des bits que nous avons modifiés dans la ligne précédente, le cas échéant, et la négation de l'une des chaînes d'entrée avec~
annule la sortie. Ainsi, ce que nous obtenons est un masque de bits avec tous les bits mis à 1 à l' exception de ceux que nous venons d'ajouter à$f[$_]
la ligne précédente. ANDing ce bitmask sur en$s[$_]
supprime ces bits; en effet, cela signifie que lorsqu'un flocon de neige qui tombe remplit un trou dans le motif fixe, il est retiré du réseau de neige qui tombe.Enfin,
print $f[$_] | $s[$_]
(qui dans la version golfée est implémentée en effectuant simplement un OR des deux lignes précédentes ensemble) imprime simplement l'union (OR au niveau du bit) des flocons de neige fixes et mobiles sur la ligne actuelle.Une dernière chose à expliquer est le
select '', '', '', 0.1
dessous de la boucle intérieure. C'est juste une façon délicate de dormir 0,1 seconde en Perl; pour une raison historique stupide, lasleep
commande Perl standard a une résolution d'une seconde, et l'importation d'un meilleursleep
depuis leTime::HiRes
module prend plus de caractères que d'abuser de 4-argselect
.la source
say
), au prix de 2 caractères supplémentaires. Je ne pense pas que je puisse changer l'ordre de remplissage très facilement, cependant; ma mise en œuvre y est plutôt fondamentalement liée.HTML et JavaScript, 436 caractères
Ajoutez-le à l'entrée:
Voyez-le fonctionner pour chaque exemple: code golf , logo Stack Overflow , arbres de Noël . Les utilisateurs d'Internet Explorer doivent exécuter la version 9 et définir le "Mode Document" sur "Normes IE9" (à l'aide des outils de développement F12) pour que cette soumission fonctionne correctement.
la source
Python, 299 caractères
Cela doit être conforme aux règles, en supposant que la nouvelle ligne est incluse dans la limite de 80 caractères.
la source
a
et gâche ainsi l'indexation. Je viens de l'essayer et il semble que le remplacement%e
par la%e.rstrip()
ligne 6 corrige le problème. (Bien sûr, il pourrait bien y avoir une solution plus courte; je ne suis pas bon au golf Python.)Java, 625 caractères
Une solution simple en Java.
la source
"\033[H"
devrait le faire).