Così dice il pastore


23

Sono stanco, ma non riesco ad addormentarmi. Aiutami a contare le pecore.

Dato un input N (numero intero positivo), fai saltare N pecore su una recinzione ASCII, come nell'esempio seguente. Dovrebbe essere visualizzato solo un fotogramma alla volta:

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

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

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

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

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

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

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

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

Il conteggio dovrebbe essere tenuto nella parte in basso a destra del "terreno". Sono ammessi trailing e leader spazi bianchi e newline. Se la tua lingua preferita ha difficoltà a svuotare lo schermo per ogni fotogramma, puoi aggiungere nuove righe sufficienti per svuotare lo schermo. Indica quante righe aggiungi per questo nella tua risposta. Il programma dovrebbe terminare quando l'ennesima pecora si trova sul quinto floortile.

Ho bisogno di alzarmi presto domani, quindi vince il codice più corto in byte. Si prega di inviare una funzione o completare il programma. Si applicano scappatoie standard.


6
1. Per favore, mi dispiace quando le persone usano giustificazioni per i codici brevi ("Devo alzarmi presto domani") 2. Quanto spazio bianco mettiamo tra i frame? Sembra 1 newline, ma potresti volerlo dichiarare chiaramente.
Rɪᴋᴇʀ

12
1) prendere l'aspirina 2) Potrebbe esserci solo 1 fotogramma sullo schermo. Questi frame qui sono per dimostrare ogni stato individualmente e NON dovrebbero essere visibili su 1 schermo contemporaneamente.
Steenbergh,

3
Molte lingue non hanno l'opzione per cancellare la visualizzazione, in questi casi quale output dovrebbero fornire?
Jonathan Allan,

6
msgstr "aggiungi sufficienti newline per cancellare lo schermo". Ciò non dipende dalle dimensioni della finestra di output e dalla risoluzione dello schermo?
Emigna,

3
Secondo il tuo esempio, per N=3l'ultimo fotogramma conterrà una pecora all'estremità destra e il contatore continuerà a dire 2. È corretto?
Luis Mendo,

Risposte:


15

MATL , 60 56 53 byte

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

L'animazione con il codice sopra funziona molto velocemente. La seguente versione include una pausa per rendere l'animazione più lenta e quindi più facile da vedere (non richiesta dalla sfida), al costo di altri 4 byte:

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

Provalo a MATL Online! L'interprete è una beta; aggiorna la pagina se non funziona.

Oppure guarda una registrazione dal compilatore offline:

enter image description here

Spiegazione

:"              % 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

6

JavaScript (ES6), 120 124 byte

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))):''

Viene visualizzato per primo l'ultimo frame calcolato. Grazie a questo il numero di salto è n-1
In alert, i caratteri hanno una larghezza diversa, quindi sembra che sia rotto.


Risposta precedente:

120 byte, il numero di salto è errato perché inizia da 1 anziché 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))):''

@LuisMendo Ho aggiornato il contatore per iniziare da 0. Per le barre è grazie al carattere utilizzato da alert. Ho lo stesso risultato di Chrome con Edge ed è peggio con Firefox.
Hedi,

6

JavaScript (ES6), 144 142 byte

Cancella l'output e attende 300 ms tra ciascun frame:

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)

Puoi provarlo qui (assicurati di aprire la console).


Questo non sembra aumentare il contatore (da 4a 5) dopo che l'ultima pecora ha saltato la recinzione ...
ʰᵈˑ

@ ʰᵈˑ - Penso che questo sia il comportamento previsto. (Vedi la domanda di Luis Mendo nei commenti sulla sfida.)
Arnauld,


4

Rubino, 83 byte

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

Stampa su stdout. Uscita separata da newline. Ridurre l'altezza dello schermo a 3 rende visibile solo un'immagine alla volta.


4

C #, 234 byte

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);}}}}

A prima vista, ci sono alcuni spazi bianchi in giro a string[] argse a for (int. Int32.Parsepotrebbe essere int.Parse.
Yytsi,

1
Puoi cambiare il nome della classe da Programsolo Po qualcosa del genere
Matias Cicero,

1
stringpotrebbe essere var. Il numero intero nel ciclo for potrebbe essere inizializzato nello stesso momento in cui si analizza args[0]un numero intero.
Yytsi,

Vedo che modifichi il conteggio dei byte ogni volta che viene abbassato. Tuttavia, raccomando di tenere traccia dei vecchi conteggi di byte (incrociati con una linea), per tenere traccia dell'avanzamento :)
Yytsi

Hai solo bisogno di avere una funzione così compilata in an Action<string[]>e puoi rimuovere le parentesi attorno al ciclo esterno per così credo di ottenere 200 byte: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 byte

<?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>":"";

Salva su file s.php, chiama nel browser cons.php?n=<n> .

Si chiama con nuovi parametri per ogni frame, senza ritardi.


Potrei risparmiare altri 5 con index.php; ma non voglio andare così lontano.


Ho provato a eseguirlo su PHP 5 e 7, ma tutto ciò che Chrome mi dà è C AB|─|DE ──|─|── $c",EABCD,$s),($c+=!$f)<$n?".
Steenbergh,

@steenbergh Hai short_open_tagdisabilitato. Abilitalo (impostazione predefinita) o aggiungi php+ spazio dopo <?.
Tito

Sì, tutto qui. Ora funziona.
steenbergh,

3

Tcl, 168 byte

Versione che utilizza uno schermo di 10 righe. (Sostituisci quanto 7segue con l'altezza dello schermo in colonne meno quattro.)

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}}

Funziona molto velocemente, quindi puoi aggiungere una pausa sulla seconda riga:

Tcl, 177 byte

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}}

Funziona riutilizzando la stringa in alto per due cose diverse:

  • come un elenco per il ciclo interno (per visualizzare ogni versione della pecora + recinzione)
  • come mappatura di cifra → spazio per rimuovere le cifre dal modello di immagine pecora + recinzione

Il modello stesso è l'immagine della stringa da visualizzare. Per prima cosa mappiamo (sostituzione stringa) la cifra della posizione corrente della pecora (anello interno) su una 'o'. Quindi mappiamo le cifre rimanenti agli spazi. Quindi stampiamo la stringa risultante.

(La stringa stessa inizia dopo l'ultimo {sulla terza riga e termina con l'ultimo a sinistra} sull'ultima riga.)


3

QBasic, 110 byte

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

Passa sopra le 5*nzecche. Ad ogni segno di spunta, cancella lo schermo, stampa lo stile e il conteggio delle pecore, quindi utilizza LOCATEper stampare onel punto appropriato. Con xil codice di posizione compreso tra 0 e 4:

  • Riga: (x=2)+2
    • Se x=2è vero, -1+2=1
    • Se x=2è falso, 0+2=2
  • Colonna: 1+x-(x>1)+x\3
    • Se xè 0o 1, x>1è falso ed x\3è 0: 1+x-0+0= 1o2
    • Se xè 2, x>1è vero ed x\3è 0: 1+x-(-1)+0=4
    • Se xè 3o 4, x>1è vero ed x\3è 1: 1+x-(-1)+1= 6o7

Infine, SLEEPper 1 secondo e loop. Se non ti dispiace premere Invio in ogni frame, posso radere due byte rimuovendo l'argomento SLEEP.


3

PHP, 132 131 byte

Modifiche dopo i commenti (grazie!):

<?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;

Che è ungolfed:

<?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

Posta originale

<?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);}

Testato su Ubuntu (non so se system("clear") funziona su Windows)

Ungolfed:

<?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);
}

1
Idk su Windows, ma sono sicuro che clearnon ha bisogno di virgolette.
Tito

1
Pensando a Windows ... era clsin DOS.
Tito

1
Rimuovere gli $i=0;avvisi, in genere non vengono visualizzati nel codice golf (-5 byte). Per lo stesso motivo, non hai bisogno di virgolette intorno cleare o(-4 byte). Sostituisci la \ns con newline reali (-2 byte). Dato che hai solo espressioni, non dichiarazioni, puoi mettere tutto tranne l'ultimo nel tuo forciclo, permettendoti di rimuovere le parentesi ( for(;;system(clear),$c=…)sleep(1);) (-2 byte). E infine, si dimentica di aggiungere la condizione $i<$argv[0](+ 11 byte).
Blackhole,

Grazie! Non ho avuto l'eco nel loop. Ma la soluzione ripubblicata lo sta facendo.
user470370,

3

node.js + sleep , 169 byte

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))

Soluzione originale

node.js, 146 142 185 byte

Testato solo con il terminale Ubuntu (e ora con n pecore):

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)

Bene, questo è un frame ogni 9 ms. Una versione più rilassante per il sonno (frame ogni 1s):

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

E non golfato:

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)

Nella mia prima soluzione, ho dimenticato il parametro per N ovini
user470370,

2

05AB1E , 66 60 59 byte

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

Utilizza la codifica CP-1252 .

explanantion

L'iterazione si riferisce all'iterazione interna (0 -> 4) del viaggio delle pecore.

Anelli principali

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

Genera riga superiore

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

Genera riga centrale

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

Genera riga inferiore

…──|  # 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

1

Gelatina , 55 54 53 byte

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

TryItOnline

Stampa cornici separate da avanzamenti di riga.

Come?

ị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)

1

Python 2, 171 159 144 byte, 163 151 136 caratteri

Soluzione che utilizza una funzione ricorsiva. Chiama come f (int)

MODIFICARE

-12 dopo aver riletto i commenti e visto che il conteggio non deve aumentare quando le pecore raggiungono la fine del campo

-15 scorrendo direttamente l'elenco degli indici e perdendo una variabile

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)

Gli appunti

Presuppone la codifica UTF-8

L'uso di - anziché ─ (come nella risposta @Luis MATL) ridurrebbe il conteggio dei byte di 8 per abbinare il conteggio dei caratteri e perderebbe la dipendenza UTF-8

50 nuove righe aggiunte: l'output è in fondo alla console (più economico dell'importazione e dell'utilizzo di os.system ("clear") e funziona su Windows e Linux)

Versione con 1 secondo di ritardo tra le uscite (170 byte, 162 caratteri)

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)

1

Utilità Linux standard Bash + (339 byte)

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.