Ainsi dit le berger

23

Je suis fatigué, mais je n'arrive pas à m'endormir. Aidez-moi à compter les moutons.

Étant donné une entrée N (entier positif), faites sauter N moutons par-dessus une clôture ascii, comme l'exemple ci-dessous. Un seul cadre doit être affiché à la fois:

o |-|
──|-|──  0

 o|-|
──|-|──  0

   o
  |-|
──|-|──  0

  |-|o
──|-|──  0

  |-| o
──|-|──  0

o |-|
──|-|──  1

 o|-|
──|-|──  1

   o
  |-|
──|-|──  1

Le dénombrement doit être conservé en bas à droite du «sol». Les espaces et les retours à la ligne de fin et de début sont autorisés. Si la langue de votre choix a du mal à vider l'écran pour chaque trame, vous pouvez ajouter suffisamment de nouvelles lignes pour effacer l'écran - veuillez indiquer le nombre de lignes que vous ajoutez pour cela dans votre réponse. Le programme devrait se terminer lorsque le mouton N'th est sur le cinquième floortile.

Je dois me lever tôt demain, donc le code le plus court en octets l'emporte. Veuillez soumettre une fonction ou un programme complet. Des échappatoires standard s'appliquent.

steenbergh
la source
6
1. S'il vous plaît, cela me fait mal quand les gens utilisent des justifications pour le code court ("Je dois me lever tôt demain") 2. Combien d'espace blanc mettons-nous entre les images? Cela ressemble à une nouvelle ligne, mais vous voudrez peut-être le dire clairement.
Rɪᴋᴇʀ
12
1) prenez de l'aspirine 2) Il ne peut y avoir qu'une seule image à l'écran. Ces cadres doivent illustrer chaque état individuellement et ne doivent PAS être visibles simultanément sur 1 écran.
steenbergh
3
De nombreuses langues n'ont pas la possibilité d'effacer l'affichage, dans quels cas quelle sortie devraient-elles fournir?
Jonathan Allan
6
msgstr "ajouter suffisamment de nouvelles lignes pour effacer l 'écran". Cela ne dépend-il pas de la taille de la fenêtre de sortie ainsi que de la résolution d'écran?
Emigna
3
Selon votre exemple, N=3la dernière image contiendra un mouton à l'extrémité droite et le compteur dira toujours 2. Est-ce exact?
Luis Mendo

Réponses:

15

MATL , 60 56 53 octets

:"@qXJx[HKCbO]"7Z"'  |-|  'v'o'@('--|-|--  '  JVhXxXD

L'animation avec le code ci-dessus s'exécute très rapidement. La version suivante comprend une pause pour rendre l'animation plus lente et donc plus facile à voir (non requise par le défi), au prix de 4 octets supplémentaires:

:"@qXJx[HKCbO]"7Z"'  |-|  'v'o'@('--|-|--  '  JVhXxXD.2Y.

Essayez-le sur MATL Online! L'interprète est une version bêta; actualisez la page si cela ne fonctionne pas.

Ou consultez un enregistrement du compilateur hors ligne:

entrez la description de l'image ici

Explication

:"              % Input N implicitly. Repeat N times
  @q            %   Push iteration index minus 1, that is, from 0 to N-1. This
                %   are the numbers of sheep
  XJx           %   Copy into clipboard J and delete
  [HKCbO]       %   Push array [2 4 7 -2 0]
  "             %   For each value in that array. This loops generates the 5
                %   frames for each number of sheep
    7Z"         %     Push string of 7 spaces
    '  |-|  '   %     Push this string
    v           %     Concatenate vertically. This gives a 2x7 char array
                %     with the upper part of the frame, except the 'o',
                %     which will be now placed in a varying position 
    'o'         %     Push string 'o'
    @           %     Push loop variable, that is, 2, 4, 7, -2 or 0
    (           %     Write 'o' into that position of the 2x7 char array.
                %     The position is interpreated linearly, that is, a single
                %     number is used as index into the 2D array in column-major
                %     order (down, then across). So index 2 is lower-left corner,
                %     index 4 is to the right of that etc. Indexing is
                %     semi-modular (modular for non-positive values). So 0 is
                %     the lower-right corner, and -2 is to the left of that
    '--|-|--  ' %     Push this string
    JV          %     Push current number of sheep converted to string
    h           %     Concatenate horizontally
    Xx          %     Clear screen
    XD          %     Display all stack contents
    .2Y.        %     Pause for 0.2 seconds (optional)
                %   End implicitly
                % End implicitly
Luis Mendo
la source
6

JavaScript (ES6), 120 124 bytes

f=(n,m=`   2
43|-|10
──|-|── `,s=0)=>n?alert(m.replace(s%5,'o').replace(/\d/g,' ')+' '+(n-1),(++s%5?f(n,m,s):f(n-1,m,0))):''

La dernière image calculée s'affiche en premier. Grâce à cela, le numéro de saut est n-1
In alert, les caractères ont une largeur différente, il semble donc qu'il soit cassé.


Réponse précédente:

120 octets, le numéro de saut est incorrect car il commence à 1 au lieu de 0

f=(n,m=`   2
43|-|10
──|-|── `,s=0)=>n?alert(m.replace(s%5,'o').replace(/\d/g,' ')+' '+n,(++s%5?f(n,m,s):f(n-1,m,0))):''
Hedi
la source
@LuisMendo J'ai mis à jour le compteur pour commencer à 0. Pour les barres c'est grâce à la police utilisée par alert. J'ai le même résultat que Chrome avec Edge, et c'est pire avec Firefox.
Hedi
6

JavaScript (ES6), 144 142 octets

Efface la sortie et attend 300 ms entre chaque trame:

n=>(F=j=>((c=console).clear(),c.log(`   2
01|-|34
──|-|── `.replace(/\d/g,i=>(j-i)%5?' ':'o')+(j/5|0)),++j<n*5&&setTimeout(`F(${j})`,300)))(0)

Vous pouvez le tester ici (assurez-vous d'ouvrir la console).

Arnauld
la source
Cela ne semble pas augmenter le compteur (de 4à 5) après que le dernier mouton ait sauté la clôture ...
ʰᵈˑ
@ ʰᵈˑ - Je pense que c'est le comportement attendu. (Voir la question de Luis Mendo dans les commentaires du défi.)
Arnauld
Ah oui, je ne l' ai pas lu que - lien vers commentaire pour quelqu'un d' autre
ʰᵈˑ
4

Rubis, 83 octets

->n{(n*5).times{|i|$><<"   c
  |-|  
ab|-|de  #{i/5}
".tr('abcde',' '*(i%5)+'o ')}}

Imprime à la sortie standard. Sortie séparée par des retours à la ligne. Réduire la hauteur de l'écran à 3 rend une seule image visible à la fois.

Level River St
la source
4

C #, 234 octets

using C=System.Console;class P{static void Main(string[]a){for(int n=0;n-1+""!=a[0];++n){foreach(int p in new[]{5,6,3,10,11}){C.Clear();C.Write("    \n  |-|  \n──|-|── ".Remove(p,1).Insert(p,"o")+n);for(var w=3e7;w>0;--w);}}}}
Jörg Hülsermann
la source
À première vue, il y a des espaces blancs autour string[] argset à for (int. Int32.Parsepourrait être int.Parse.
Yytsi
1
Vous pouvez changer le nom de la classe de Programjuste Pou quelque chose
Matias Cicero
1
stringpourrait être var. L'entier dans la boucle for peut être initialisé en même temps que vous analysez args[0]un entier.
Yytsi
Je vois que vous modifiez le nombre d'octets à chaque fois qu'il est abaissé. Cependant, je recommande de garder les anciens comptages d'octets (croisés avec une ligne), pour garder une trace de la progression :)
Yytsi
Vous n'avez besoin que d'une fonction pour compiler en un Action<string[]>et vous pouvez supprimer les crochets autour de la boucle for externe, donc je pense que j'obtiens 200 octets:using C=System.Console;a=>{for(int n=0;n-1+""!=a[0];++n)foreach(int p in new[]{5,6,3,10,11}){C.Clear();C.Write(" \n |-| \n──|-|── ".Remove(p,1).Insert(p,"o")+n);for(var w=3e7;w>0;--w);}};
TheLethalCoder
3

PHP + JavaScript, 168 octets

<?extract($_GET);$s="     ";$s[$f=++$f%5]=o;echo strtr("<pre>   C
AB|─|DE
──|─|── $c",EABCD,$s),($c+=!$f)<$n?"<script>location.href='s.php?n=$n&c=$c&f=$f'</script>":"";

Enregistrer dans un fichier s.php, appeler dans le navigateur avec s.php?n=<n>.

S'appelle avec de nouveaux paramètres pour chaque trame, sans délai.


Je pourrais économiser 5 de plus avec index.php; mais je ne veux pas aller aussi loin.

Titus
la source
J'ai essayé de l'exécuter sur PHP 5 et 7, mais tout ce que Chrome me donne est C AB|─|DE ──|─|── $c",EABCD,$s),($c+=!$f)<$n?".
steenbergh
@steenbergh Vous avez short_open_tagdésactivé. Activez-le (par défaut) ou ajoutez php+ espace après <?.
Titus
Ouais, c'est tout. Je l'ai fait fonctionner maintenant.
steenbergh
3

Tcl, 168 octets

Version utilisant un écran de 10 rangées de haut. (Remplacez ce qui 7suit par la hauteur de votre écran dans les colonnes moins quatre.)

set s {0 1 2 3 4 }
for {set n 0} {$n<$argv} {incr n} {foreach x $s {
puts [string repe \n 6][string map [split $s {}] [string map "$x o" {   2
01|-|34
--|-|--  }]]$n}}

Cela fonctionne très rapidement, vous pouvez donc ajouter une pause sur la ligne deux:

Tcl, 177 octets

set s {0 1 2 3 4 }
for {set n 0} {$n<$argv} {incr n} {foreach x $s {after 250
puts [string repe \n 6][string map [split $s {}] [string map "$x o" {   2
01|-|34
--|-|--  }]]$n}}

Cela fonctionne en réutilisant la chaîne en haut pour deux choses différentes:

  • comme liste pour la boucle intérieure (pour afficher chaque version du mouton + clôture)
  • comme une cartographie de digit → espace pour supprimer les chiffres du modèle d'image mouton + clôture

Le modèle lui-même est l'image de chaîne à afficher. Tout d'abord, nous mappons (remplacement de chaîne) le chiffre de position actuelle du mouton (boucle intérieure) sur un «o». Ensuite, nous mappons les chiffres restants aux espaces. Ensuite, nous imprimons la chaîne résultante.

(La chaîne elle-même commence après la dernière {sur la troisième ligne et se termine par l'extrême gauche} sur la dernière ligne.)

Dúthomhas
la source
3

QBasic, 110 octets

INPUT n
FOR i=0TO 5*n-1
CLS
?
?"  |-|"
?"--|-|-- ";i\5
x=i MOD 5
LOCATE(x=2)+2,1+x-(x>1)+x\3
?"o"
SLEEP 1
NEXT

Boucles sur les 5*ntiques. À chaque tick, efface l'écran, imprime le nombre de stiles et de moutons, puis utilise LOCATEpour imprimer le oà l'endroit approprié. Avec xétant le code de position entre 0 et 4:

  • Rangée: (x=2)+2
    • Si x=2est vrai, -1+2=1
    • Si x=2est faux, 0+2=2
  • Colonne: 1+x-(x>1)+x\3
    • Si xest 0ou 1, x>1est faux et x\3est 0: 1+x-0+0= 1ou2
    • Si xest 2, x>1est vrai et x\3est 0: 1+x-(-1)+0=4
    • Si xest 3ou 4, x>1est vrai et x\3est 1: 1+x-(-1)+1= 6ou7

Enfin, SLEEPpendant 1 seconde et boucle. Si cela ne vous dérange pas d'appuyer sur Entrée à chaque trame, je peux raser deux octets en supprimant l'argument de SLEEP.

DLosc
la source
3

PHP, 132 131 octets

Modifications après commentaires (merci!):

<?php for(;$i<$argv[1]*5;sleep(1),system(clear),$c="    
  |-|  
──|-|──  ".floor($i/5),$c[[5,6,3,10,11][$i++%5]]=o)echo$c;

Ce qui n'est pas golfé:

<?php

ini_set('error_reporting', '0');        # golfing precondition

for(; $i<$argv[1]*5;                    # repeat N times
  sleep(1),                             # sleep after iteration
  system(clear),                        # clear screen (linux only)
  $c = "    
  |-|  
──|-|──  " . floor($i / 5),             # define template
  $c[[5, 6, 3, 10, 11][$i++ % 5]] = o)  # replace with sheep (and finish "for" statement)
  echo $c;                              # output result

Message d'origine

<?php $i=0;for(;;){system("clear");$c="  \n  |-|  \n──|-|──  ";$c[[3,4,1,8,9][$i%5]]='o';echo"  $c".floor($i++/5);sleep(1);}

Testé sur Ubuntu (ne sais pas, si system("clear")fonctionne sur Windows)

Non golfé:

<?php
$i = 0;
for(;;) {
  system("clear");
  $content = "  \n  |-|  \n──|-|──  ";
  $content[[3,4,1,8,9][$i%5]] = 'o';
  echo "  $content " . floor($i++/5);
  sleep(1);
}
user470370
la source
1
Idk soit sur Windows, mais je suis sûr que cela clearn'a pas besoin de devis.
Titus
1
En pensant à Windows ... c'était clssous DOS.
Titus
1
Supprimez le $i=0;, les avertissements ne sont généralement pas affichés dans le code golf (-5 octets). Pour la même raison, vous n'avez pas besoin de guillemets autour clearet o(-4 octets). Remplacez le \ns par de vrais retours à la ligne (-2 octets). Puisque vous n'avez que des expressions, pas des instructions, vous pouvez tout mettre sauf la dernière dans votre forboucle, vous permettant de supprimer les crochets ( for(;;system(clear),$c=…)sleep(1);) (-2 octets). Et enfin, vous oubliez d'ajouter la condition $i<$argv[0](+ 11 octets).
Blackhole
Merci! Je n'ai pas eu d'écho dans la boucle. Mais la solution repostée le fait.
user470370
3

node.js + sleep , 169 octets

c='   2\n01|-|34\n──|-|──  '
for(i=0;i<process.argv[2]*5;require('sleep').sleep(1))console.log('\033[2J'+c.replace(i%5,'o').replace(/\d/g,' ')+Math.floor(i++/5))

Solution originale

node.js, 146 142 185 octets

Testé avec le terminal ubuntu uniquement (et maintenant avec n moutons):

i=0
c='   2\n01|-|34\n──|-|──  '
setInterval(function(){console.log('\033[2J'+c.replace(i%5,'o').replace(/\d/g,' ')+Math.floor(i++/5))
if(process.argv[2]*5==i)process.exit()},9)

Eh bien, c'est une trame toutes les 9 ms. Une version plus apaisante pour le sommeil (cadre toutes les 1 s):

i=0;setInterval(function(){console.log('\033[2J'+'   2\n01|-|34\n──|-|──  '.replace(i%5,'o').replace(/\d/g,' ')+Math.floor(i++/5))},1000)

Et non golfé:

var i = 0;
setInterval(function(){
  console.log('\033[2J' + '   2\n01|-|34\n──|-|──  '.replace(i%5, 'o').replace(/\d/g, ' ') + Math.floor(i++/5));
}, 1000)
user470370
la source
Dans ma première solution, j'ai oublié le paramètre pour N moutons
user470370
2

05AB1E , 66 60 59 octets

FNU5Fð4×N<i¨'oJ},N<iðë'o}ðNÉis}"|-|  "JN1›iR},…──|Â'-sððXJ,

Utilise l' encodage CP-1252 .

Explication

L'itération se réfère à l'itération intérieure (0 -> 4) du voyage des moutons.

Boucles principales

F      # For N in range [0 .. input)
 NU    # Save N in variable X
 5F    # For N in range [0 .. 5)

Générer la ligne supérieure

ð4×         # push 4 spaces
N<i    }    # if we're on the 2nd iteration
   ¨'oJ     # replace the last space with an "o"
,           # print row

Générer la ligne du milieu

N<iðë'o}     # push a space if we're on the 2nd iteration, else push "o"
ð            # push a space
NÉis}        # if we're on an odd numbered iteration, swap the stacks top 2 chars
"|-|  "      # push this string
J            # join the stack to one string
N1›iR}       # if we're on the any of the last 3 iterations, reverse the string
,            # print row

Générer la ligne du bas

…──|  # push the string "──|"
     # push a reversed copy
'-s   # push "-" between the 2 strings on the stack
ðð    # push 2 spaces
X     # push the N we saved in the main loop (current sheep number)
J,    # join and print row
Emigna
la source
1

Gelée , 55 54 53 octets

ị30214D¤“o    ”ṙ“   “
““|-|““
__|-|__  ”ż
×5Ḷµ:5ż@Ç€Y

TryItOnline

Imprime les cadres séparés par des sauts de ligne.

Comment?

ị30214D¤“o    ”ṙ“   “
““|-|““
__|-|__  ”ż           - Link 1, build a frame without counts: frameNumber
       ¤              - nilad and link(s) as a nilad:
 30214                -     literal 30214 (a nilad)
      D               -     to decimal: [3,0,2,1,4]
ị                     - index into (1-based and modular, so frames go 4,3,0,2,1,4,...)
        “o    ”       - string "o    "
               ṙ      - rotated to the left by that number
                “   “ - the rest, except the last character, is:
““|-|““               -     an array of strings ["   ","\n","","|-|","","\n__|-|__  "]
__|-|__  ”            -     i.e. split where a sheep might go

          ż           - zip the sheep (the rotated "o    ") into that

×5Ḷµ:5ż@Ç€Y - Main link: nSheep
×5          - multiply by 5 -> nFrames
  Ḷ         - lowered range: [0,1,2,...nFrames-1]
   µ        - monadic chain separation
    :5      - integer division by 5 (vectorises): [5 zeros, 5 ones, ..., 5 (nSheep-1)s]
      ż@    - zip with reversed arguments
        ǀ  - call last link (1) as a monad for each (zip sheep numbers with frames)
          Y - join with line feeds (TODO: replace with future animate frames atom :p)
Jonathan Allan
la source
1

Python 2, 171 159 159 144 octets, 163 151 136 caractères

Solution utilisant une fonction récursive. Appeler comme f (int)

MODIFIER

-12 après avoir relu les commentaires et vu que le décompte n'a pas à augmenter lorsque le mouton atteint la fin du champ

-15 en itérant directement dans la liste d'index et en perdant une variable

def f(a,x=0):
 if a>0:
  for c in 5,6,3,10,11:
   b=list('    \n  |-|  \n──|-|──  ');b[c]='o';print"\n"*50+"".join(b)+(`x`)
  f(a-1,x+1)

Remarques

Suppose un codage UTF-8

L'utilisation de - au lieu de ─ (comme dans la réponse @Luis MATL) réduirait le nombre d'octets de 8 pour correspondre au nombre de caractères et perdrait la dépendance UTF-8

50 nouvelles lignes ajoutées - la sortie est en bas sur la console (moins cher que l'importation et l'utilisation d'os.system ("clear") et fonctionne sous Windows et Linux)

Version avec 1 seconde de retard entre les sorties (170 octets, 162 caractères)

import time
def f(a,x=0):
 if a>0:
  for c in 5,6,3,10,11:
   b=list('    \n  |-|  \n──|-|──  ');b[c]='o';print"\n"*50+"".join(b)+(`x`);time.sleep(1)
  f(a-1,x+1)
ElPedro
la source
1

Utilitaires Linux Bash + standard (339 octets)

e(){ echo "$@";}
n(){ e -n "$@";}
r(){ [ $? -eq 0 ]&&s=o||s=" ";[ $1 ]&&n " $s "||n "$s";}
f(){ k=$(($1%5));n "  ";[ $k -eq 2 ];r .;e "  ";for i in 0 1;do [ $k -eq $i ];r;done;n "|-|";for i in 3 4;do [ $k -eq $i ];r;done;e;n "──|-|──";}
for l in `seq 1 $1`;do for z in `seq 0 4`;do clear;f $z;e "  $((l-1))";sleep 1;done;done
user2064000
la source