So spricht der Hirte

23

Ich bin müde, aber ich kann nicht einschlafen. Hilf mir, Schafe zu zählen.

Lassen Sie bei einer Eingabe von N (positive ganze Zahl) N Schafe über einen ASCII-Zaun springen, wie in der folgenden Abbildung dargestellt. Es sollte immer nur ein Frame angezeigt werden:

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

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

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

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

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

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

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

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

Die Zählung sollte auf der unteren rechten Seite des "Bodens" erfolgen. Nachgestellte und führende Leerzeichen und Zeilenumbrüche sind zulässig. Wenn Ihre Sprache Schwierigkeiten hat, den Bildschirm für jeden Frame zu löschen, können Sie ausreichend neue Zeilen hinzufügen, um den Bildschirm zu löschen. Bitte geben Sie in Ihrer Antwort an, wie viele Zeilen Sie dafür hinzufügen. Das Programm sollte enden, wenn sich das N-te Schaf im fünften Floortile befindet.

Ich muss morgen früh aufstehen, damit der kürzeste Code in Bytes gewinnt. Bitte reichen Sie eine Funktion oder ein vollständiges Programm ein. Es gelten Standardlücken.

steenbergh
quelle
6
1. Bitte, es schmerzt mich, wenn Leute Begründungen für den Kurzcode verwenden ("Ich muss morgen früh aufstehen"). 2. Wie viel Leerzeichen setzen wir zwischen Frames? Es sieht so aus, als wäre 1 Newline, aber Sie möchten das vielleicht klar ausdrücken.
1.
12
1) Nehmen Sie Aspirin. 2) Möglicherweise ist nur 1 Bild auf dem Bildschirm. Diese Rahmen sollen jeden Status einzeln veranschaulichen und NICHT gleichzeitig auf einem Bildschirm sichtbar sein.
Steenbergh
3
Viele Sprachen haben nicht die Möglichkeit, die Anzeige zu löschen. Welche Ausgabe sollten sie in solchen Fällen bereitstellen?
Jonathan Allan
6
msgstr "füge genügend Zeilenumbrüche hinzu, um den Bildschirm zu löschen". Ist das nicht abhängig von der Größe des Ausgabefensters und der Bildschirmauflösung?
Emigna
3
Nach Ihrem Beispiel wird für N=3den letzten Frame ein Schaf am rechten Ende enthalten und der Zähler wird immer noch sagen 2. Ist das korrekt?
Luis Mendo

Antworten:

15

MATL , 60 56 53 Bytes

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

Die Animation mit dem obigen Code läuft sehr schnell. Die folgende Version enthält eine Pause, um die Animation langsamer und damit übersichtlicher zu gestalten (für die Challenge nicht erforderlich). Dies kostet 4 weitere Bytes:

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

Probieren Sie es bei MATL Online! Der Dolmetscher ist eine Beta; Aktualisieren Sie die Seite, wenn es nicht funktioniert.

Oder sehen Sie sich eine Aufzeichnung vom Offline-Compiler an:

Bildbeschreibung hier eingeben

Erläuterung

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

JavaScript (ES6), 120 bis 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))):''

Der zuletzt berechnete Frame wird zuerst angezeigt. Dank dessen ist die Sprungzahl n-1
In alert, die Zeichen haben eine andere Breite, so dass es so aussieht, als ob sie kaputt sind.


Vorherige Antwort:

120 Bytes, die Sprungnummer ist falsch, da sie bei 1 statt bei 0 beginnt

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
quelle
@ LuisMendo Ich habe den Zähler so aktualisiert, dass er bei 0 beginnt. Für die Balken ist es der Schriftart zu verdanken, die von verwendet wird alert. Ich habe das gleiche Ergebnis wie Chrom mit Rand, und es ist schlimmer mit Firefox.
Hedi
6

JavaScript (ES6), 144 142 Bytes

Löscht die Ausgabe und wartet 300 ms zwischen den einzelnen Bildern:

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)

Sie können es hier testen (stellen Sie sicher, dass Sie die Konsole öffnen).

Arnauld
quelle
Dies scheint den Zähler (von 4bis 5) nicht zu
erhöhen,
@ ʰᵈˑ - Ich denke das ist das erwartete Verhalten. (Siehe Luis Mendos Frage in den Kommentaren zur Herausforderung.)
Arnauld
Ah ja, das habe ich nicht gelesen - Link zum Kommentieren für andere
anyone
4

Ruby, 83 Bytes

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

Druckt nach Standard. Ausgabe durch Zeilenumbrüche getrennt. Wenn Sie die Bildschirmhöhe auf 3 reduzieren, wird immer nur ein Bild angezeigt.

Level River St
quelle
4

C #, 234 Bytes

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
quelle
Auf den ersten Blick liegen bei string[] argsund um einige Leerzeichen herum for (int. Int32.Parsekönnte sein int.Parse.
Yytsi
1
Sie können den Namen der Klasse von Programauf einfach Poder so ändern
Matias Cicero
1
stringkönnte sein var. Die Ganzzahl in der for-Schleife kann gleichzeitig mit dem Parsen args[0]einer Ganzzahl initialisiert werden .
Yytsi
Ich sehe, dass Sie die Byteanzahl jedes Mal ändern, wenn sie verringert wird. Ich empfehle jedoch, die alte
Anzahl von
Sie müssen nur eine Funktion haben, um eine zu kompilieren, Action<string[]>und Sie können die Klammern um die äußere for-Schleife entfernen, damit ich glaube, ich bekomme 200 Bytes: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 Bytes

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

In Datei speichern s.php, Browser mit aufrufen s.php?n=<n>.

Ruft sich mit neuen Parametern für jeden Frame ohne Verzögerung auf.


Ich könnte noch 5 sparen mit index.php; aber so weit will ich nicht gehen.

Titus
quelle
Ich habe versucht, dies auf PHP 5 und 7 auszuführen, aber alles, was Chrome mir bietet, ist C AB|─|DE ──|─|── $c",EABCD,$s),($c+=!$f)<$n?".
Steenbergh
@steenbergh Sie haben short_open_tagdeaktiviert. Aktiviere es (Standard) oder füge php+ Leerzeichen danach hinzu <?.
Titus
Ja, das ist es. Habe es jetzt laufen.
Steenbergh
3

Tcl, 168 Bytes

Version mit 10 Zeilen hohem Bildschirm. (Ersetzen Sie das 7Folgende durch Ihre Bildschirmhöhe in Spalten minus vier.)

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

Das geht sehr schnell, also können Sie in Zeile zwei eine Pause einfügen:

Tcl, 177 Bytes

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

Es funktioniert, indem der String oben für zwei verschiedene Dinge wiederverwendet wird:

  • als Liste für die innere Schleife (um jede Version des Schafs + Zauns anzuzeigen)
  • als Zuordnung von Ziffer → Leerzeichen zum Entfernen von Ziffern aus der Schaf + Zaun-Bildvorlage

Die Vorlage selbst ist das anzuzeigende Zeichenfolgenbild. Zuerst ordnen wir die aktuelle Positionsziffer des Schafes (innere Schleife) einem 'o' zu (Zeichenfolge ersetzen). Dann ordnen wir die verbleibenden Ziffern Leerzeichen zu. Dann drucken wir die resultierende Zeichenfolge.

(Die Zeichenfolge selbst beginnt nach dem letzten {in der dritten Zeile und endet mit dem am weitesten links stehenden} in der letzten Zeile.)

Dúthomhas
quelle
3

QBasic, 110 Bytes

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

Schleifen über 5*nTicks. Löscht bei jedem Häkchen den Bildschirm, druckt den Zauntritt und die Anzahl der Schafe und LOCATEdruckt dann die oan der entsprechenden Stelle. Mit xdem Positionscode zwischen 0 und 4:

  • Reihe: (x=2)+2
    • Wenn x=2ja, -1+2=1
    • Wenn x=2ist falsch, 0+2=2
  • Säule: 1+x-(x>1)+x\3
    • Wenn xist 0oder 1, x>1ist falsch und x\3ist 0: 1+x-0+0= 1oder2
    • Wenn xist 2, x>1ist wahr und x\3ist 0: 1+x-(-1)+0=4
    • Wenn xist 3oder 4, x>1ist wahr und x\3ist 1: 1+x-(-1)+1= 6oder7

Schließlich SLEEPfür 1 Sekunde und Schleife. Wenn es Ihnen nichts ausmacht, bei jedem Frame die Eingabetaste zu drücken, kann ich zwei Bytes durch Entfernen des Arguments auf rasieren SLEEP.

DLosc
quelle
3

PHP, 132 131 Bytes

Änderungen nach Kommentaren (danke!):

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

Welches ist 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

Ursprünglicher Beitrag

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

Getestet auf Ubuntu (weiß nicht, ob es system("clear")unter Windows funktioniert)

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);
}
user470370
quelle
1
Idk entweder über Windows, aber ich bin sicher, das clearbraucht keine Anführungszeichen.
Titus
1
Denken Sie an Windows ... es war clsin DOS.
Titus
1
Entfernen Sie die $i=0;, Warnungen werden in der Regel nicht in Code Golf (-5 Bytes) angezeigt. Aus dem gleichen Grund brauchen Sie keine Anführungszeichen um clearund o(-4 Bytes). Ersetzen Sie das \ns durch echte Zeilenumbrüche (-2 Bytes). Da Sie nur Ausdrücke und keine Anweisungen haben, können Sie alles außer dem letzten in Ihre forSchleife einfügen und so die Klammern ( for(;;system(clear),$c=…)sleep(1);) (-2 Byte) entfernen . Und schließlich vergessen Sie, die Bedingung $i<$argv[0](+ 11 Bytes) hinzuzufügen .
Blackhole
Vielen Dank! Ich habe kein Echo in die Schleife bekommen. Aber die neu gepostete Lösung macht es.
user470370
3

node.js + sleep , 169 Bytes

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

Originelle Lösung

node.js, 146 142 185 Bytes

Getestet nur mit Ubuntu Terminal (und jetzt mit n Schafen):

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)

Nun, das ist ein Frame alle 9 ms. Eine ruhigere Version (Rahmen alle 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)

Und ungolfed:

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
quelle
In meiner ersten Lösung habe ich den Parameter für N
Schafe
2

05AB1E , 66 60 59 Bytes

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

Verwendet CP-1252- Codierung.

Erklärung

Iteration bezieht sich auf die innere Iteration (0 -> 4) der Schafreise.

Hauptschleifen

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

Oberste Zeile generieren

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

Mittlere Reihe generieren

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

Untere Reihe generieren

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

Jelly , 55 54 53 Bytes

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

TryItOnline

Druckt durch Zeilenvorschübe getrennte Bilder.

Wie?

ị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
quelle
1

Python 2, 171 159 144 Bytes, 163 151 136 Zeichen

Lösung mit einer rekursiven Funktion. Aufruf als f (int)

BEARBEITEN

-12 nach dem erneuten Lesen der Kommentare und dem Erkennen, dass die Zählung nicht erhöht werden muss, wenn das Schaf das Ende des Feldes erreicht

-15 durch direktes Durchlaufen der Indexliste und Verlust einer Variablen

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)

Anmerkungen

Übernimmt die UTF-8-Codierung

Die Verwendung von - anstelle von ─ (wie in der @ Luis MATL-Antwort) würde den Byte-Countdown um 8 verringern, um mit der Zeichenanzahl übereinzustimmen, und die UTF-8-Abhängigkeit verlieren

50 neue Zeilen hinzugefügt - die Ausgabe befindet sich am unteren Rand der Konsole (billiger als das Importieren und Verwenden von os.system ("clear") und funktioniert unter Windows und Linux)

Version mit 1 Sekunde Verzögerung zwischen den Ausgaben (170 Bytes, 162 Zeichen)

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
quelle
1

Bash + Standard-Linux-Dienstprogramme (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
user2064000
quelle