牧羊人这样说


23

我很累,但似乎无法入睡。帮我数羊。

给定输入N(正整数),使N只羊跳过ascii栅栏,如以下示例所示。一次只能显示一帧:

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

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

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

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

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

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

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

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

计数应保持在“地面”的右下角。允许尾随和前导空格以及换行符。如果您选择的语言难以清除每一帧的屏幕,则可以添加足够的换行符来清除屏幕-请在回答中说明为此添加的行数。该程序应在第N只羊位于第五层时终止。

我明天需要早起,所以以字节为单位的最短代码会获胜。请提交功能或完整程序。有标准漏洞。


6
1.拜托,当人们使用理由说明短代码时(“我明天必须早起”),这让我很痛苦。2.我们在帧之间放多少空格?它看起来像是1个换行符,但您可能需要清楚地说明这一点。
Rɪᴋᴇʀ

12
1)服用阿司匹林2)屏幕上可能只有一帧。这些框是为了分别说明每种状态,不应同时在一个屏幕上显示。
steenbergh '16

3
许多语言没有清除显示的选项,在这种情况下,它们应提供什么输出?
乔纳森·艾伦

6
“添加足够的换行符以清除屏幕”。这不取决于输出窗口的大小以及屏幕分辨率吗?
Emigna

3
根据您的示例,N=3最后一帧的右端将包含一只羊,而计数器仍会说2。那是对的吗?
路易斯·门多

Answers:


15

MATL60 56 53字节

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

上面代码的动画运行非常快。以下版本包含一个暂停,以使动画变慢并因此更易于观看(挑战不需要),但要多花4个字节:

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

MATL在线上尝试一下口译员是测试版;刷新页面(如果它不起作用)。

或查看脱机编译器的记录:

在此处输入图片说明

说明

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

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

计算的最后一帧首先显示。由于此跳转数字为n-1
In alert,字符的宽度不同,因此看起来好像坏了。


先前的答案:

120个字节,跳转号是错误的,因为它从1而不是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我将计数器更新为从0开始。对于条形图,这要归功于所使用的字体alert。我得到的结果与带有边的chrome的结果相同,而使用Firefox则更糟。
Hedi

6

的JavaScript(ES6),144个 142字节

清除输出并在每帧之间等待300ms:

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)

您可以在此处进行测试(确保打开控制台)。


这似乎并不增加计数器(从45)最后的羊已经跃过了栅栏...之后
ʰᵈˑ

@ʰᵈˑ-我认为这是预期的行为。(请参阅挑战说明中的路易斯·门多(Luis Mendo)的问题。)
Arnauld

嗯,是的,我没看过- 链接到其他人发表评论
ʰᵈˑ

4

Ruby,83个字节

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

打印到标准输出。输出以换行符分隔。将屏幕高度减小到3可使一次仅显示一幅图像。


4

C#,234个字节

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

乍一看,在string[] args和处有一些空白for (intInt32.Parse可能是int.Parse
Yytsi

1
您可以将班级的名称从更改Program为公正P或类似
Matias Cicero

1
string可能是var。for循环中的整数可以在解析args[0]为整数的同时初始化。
Yytsi

我看到您每次降低字节数时都对其进行编辑。但是,我建议保留旧字节数(与行交叉),以跟踪进度:)
Yytsi

您只需要具有一个编译为的函数Action<string[]>,就可以删除外部for循环周围的括号,因此我相信我可以得到200个字节: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字节

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

保存到文件s.php,然后使用调用浏览器s.php?n=<n>

每帧都使用新参数调用自身,没有延迟。


我可以再存5个index.php; 但我不想走那么远。


我曾尝试在PHP 5和7上运行此程序,但Chrome给我的只有C AB|─|DE ──|─|── $c",EABCD,$s),($c+=!$f)<$n?"
steenbergh '16

@steenbergh您已short_open_tag禁用。启用它(默认)或php在后面添加+空格<?
泰特斯

是的,就是这样。现在开始运行。
steenbergh

3

Tcl,168个字节

使用10行高屏幕的版本。(将7下面的屏幕高度替换为下面的四列。)

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

这运行得非常快,因此您可以在第二行添加一个暂停:

Tcl,177字节

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

它通过将顶部的字符串重用于两种不同的方式来工作:

  • 作为内循环的列表(以显示绵羊和围栏的每个版本)
  • 作为数字→空间的映射,以从羊+栅栏图像模板中删除数字

模板本身就是要显示的字符串图像。首先,我们将绵羊的当前位置数字(内循环)映射(替换为字符串)为“ o”。然后我们将剩余的数字映射到空格。然后我们打印结果字符串。

(字符串本身从第三行的最后一个{开始,到最后一行的最左端}结束。)


3

QBasic,110个字节

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

遍历5*n刻度线。在每个刻度上,清除屏幕,打印阶梯和绵羊数,然后用于在适当的位置LOCATE打印o。与x为0和4之间的位置的代码:

  • 行: (x=2)+2
    • 如果x=2为真,则-1+2=1
    • 如果x=2为假,则0+2=2
  • 柱: 1+x-(x>1)+x\3
    • 如果x01x>1则为false,并且x\301+x-0+0= 12
    • 如果x2x>1则为true,x\301+x-(-1)+0=4
    • 如果x34x>1则为true且x\311+x-(-1)+1= 67

最后,SLEEP持续1秒钟并循环。如果您不介意在每一帧按回车键,则可以通过删除参数来剃除两个字节SLEEP


3

PHP,132个 131字节

在评论后进行编辑(谢谢!):

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

这是不符合要求的:

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

原始帖子

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

在ubuntu上测试(不知道,是否system("clear")可以在Windows上运行)

取消高尔夫:

<?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
对Windows都不太了解,但是我敢肯定clear不需要引号。
泰特斯(Titus)

1
考虑Windows ...这是cls在DOS中。
泰特斯(Titus)

1
删除$i=0;,通常不会在代码高尔夫中显示警告(-5字节)。出于相同的原因,您不需要在clear和之间加上引号o(-4个字节)。将\ns 替换为实际的换行符(-2个字节)。由于只有表达式而不是任何语句,因此可以将除最后一个语句之外的所有内容放入for循环中,从而可以删除方括号(for(;;system(clear),$c=…)sleep(1);)(-2个字节)。最后,您忘记添加条件$i<$argv[0](+ 11个字节)。
黑洞

谢谢!我没有收到回声进入循环。但是重新发布的解决方案正在这样做。
user470370 '16

3

node.js + sleep,169字节

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

原始解决方案

的node.js,146个 142 185字节

仅使用ubuntu终端进行了测试(现在使用n个羊):

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)

好吧,这是每9毫秒发送一帧。更加舒缓睡眠的版本(每1秒帧一次):

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

和无高尔夫球场:

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)

在我的第一个解决方案中,我忘记了N个羊的参数
user470370 '16

2

05AB1E66 60 59字节

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

使用CP-1252编码。

说明

迭代是指绵羊旅程的内部迭代(0-> 4)。

主循环

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

产生顶行

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

产生中间行

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

产生底行

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

果冻55 54 53 字节

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

在线试用

打印由换行分隔的帧。

怎么样?

ị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字节,163个 151 136字符

使用递归函数的解决方案。呼叫为f(int)

编辑

重读注释并看到绵羊到达字段末尾时计数不必增加,因此返回-12

-15通过直接遍历索引列表并丢失变量

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)

笔记

假设采用UTF-8编码

使用-而不是─(如@Luis MATL回答)将使字节数减少8以匹配字符数,并且将失去UTF-8依赖性

添加了50条换行符-输出位于控制台的底部(比导入和使用os.system(“ clear”)更便宜,并且在Windows和Linux上都可以使用)

版本之间的输出之间有1秒的时间延迟(170字节,162个字符)

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

Bash +标准Linux实用程序(339字节)

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.