Виклик пісочного годинника


43

Пісочний годинник

Цей пісочний годинник має 60 «пісків часу», і він повністю заповнює кожну камеру. Годинник - 19 символів завширшки і 13 символів у висоту. Кожна камера має 5 рядів піску, а в центрі є ряд, який може вмістити 1 пісок. У верхньому ряді вміщується 17 пісків, у наступному - 15 тощо (див. Нижче). Піски потрапляють до нижньої камери зі швидкістю одного піску в секунду.

       START                     3 SECONDS LATER               38 SECONDS LATER

███████████████████            ███████████████████            ███████████████████
█.................█   17       █..............   █   14       █                 █    0
██...............██   15       ██...............██   15       ██               ██    0
███.............███   13       ███.............███   13       ███.......      ███    7  
█████.........█████   09       █████.........█████   09       █████.........█████   09 
███████.....███████   05       ███████.....███████   05       ███████.....███████   05 
█████████.█████████   01       █████████.█████████   01       █████████.█████████   01 
███████     ███████            ███████  .  ███████            ███████  .  ███████  
█████         █████            █████    .    █████            █████    .    █████   
███             ███            ███      .      ███            ███....         ███
██               ██            ██               ██            ██...............██  
█                 █            █                 █            █.................█  
███████████████████            ███████████████████            ███████████████████   

Змагання

Показуйте пісочний годинник (ніякі цифри та заголовки не потрібно) через певний проміжок часу (0 ≤ t ≤ 60).

Правила кодування

  1. Пісочний годинник повинен виглядати точно так, як показано тут. Ви можете замінити символу та / або .символу тим, що вам подобається, щоб відповідати вашій мові (питання сумісності Unicode, ASCII).
  2. Вхід повинен бути таким, як 45 або 7. Показуйте годинник через ці багато секунд.
  3. Вихід може бути відображений або збережений у файл. Ніяких додаткових текстів або міток, як показано вище, не потрібно - лише пісочний годинник - це все, що нам потрібно.
  4. Якщо користувач вводить t> 60, вам не доведеться обробляти помилку.

Очки

  1. Найкоротший код виграє.

Я не знаю, чи це тільки я, але пісочний годинник виглядає в редакторі зовсім інакше, ніж у самому дописі. Можливо, тому, що символ █ не відображається з відповідною шириною.
Денніс

1
Чи торкається зерна піску поточний шар, а потім вирівняється ліворуч на секунду пізніше?
xnor

2
Яким повинен бути вихід для t == 59?
edc65

3
Вітаю вас із створенням списку питань гарячої мережі Stack Exchange!
Олексій А.

1
Це насправді не відповідь, оскільки вона не відповідає специфікаціям, але подивіться тут для подання у Десмосі. (Натисніть кнопку відтворення та встановіть швидкість 0,15x на ~ 1 одиницю / секунду)
Conor O'Brien

Відповіді:


27

JavaScript ( ES6 ), 203 208 233 270 256 символів

Редагувати Переглянуто, використовуючи цикл замість послідовності дзвінків.

Редагувати Додано верхній і нижній рядки, які відсутні.

Функція, що повертає вихід. Запустіть фрагмент у Firefox для тестування.

f=w=>[h='█'[R='repeat'](19),...[17,15,13,9,5,1,5,9,13,15,17].map((d,i)=>(t=i>5?-v:v,v-=i<5?d:1-d,e=' '[R](d/2),b='█'[R](10-d/2),b+('.'[R](t<d&&d-t)+e+' .'[i>4&w>i-6&t>=d|0]+e).slice(0,d)+b),v=w),h].join`
`

// Less golfed
F=
w=>[h='█'.repeat(19),
    ... [17, 15, 13, 9, 5, 1, 5, 9, 13, 15, 17].map(
     (d,i) => (
       t = i>5 ? -v : v,
       v -= i<5 ? d : 1-d, 
       e = ' '.repeat(d / 2),
       b = '█'.repeat(10 - d / 2),
       b + 
        ('.'.repeat(t < d && d - t) 
         + e + ' .'[i > 4 & w > i-6 & t >= d | 0]
         + e).slice(0,d)
       + b
     ), v = w
    ),
    h].join('\n')

// TEST            

O.innerHTML=f(+I.value)

function tick(d) {
  var i=+I.value+d
  I.value=i
  O.innerHTML=f(i)
}

var int=0;

function auto()
{
  function go()
  {
    var t = I.value;
    O.innerHTML=f(++t)
    if (t>70)t=0;
    I.value = t;
  }
  if (A.checked && !int)
  { 
    int = setInterval(go, 200);
  }
  else if (!A.checked && int)
  {
    clearInterval(int);
    int = 0;
  }
}
input[type=text] { width: 3em }
<button onclick='tick(-1)'>-</button>
<input type=text id=I value=0 onchange='tick(0)' >
<button onclick='tick(1)'>+</button>
<input type=checkbox id=A onclick='auto()'>Fly time
<pre id=O><pre>


5
З моєї цікавості, чому це було знято двічі? Я не можу знайти з цим проблеми.
манатура

Ця відповідь приголомшлива ! Відкрийте його у Firefox, люди!
Крістіан Лупаску

1
Хороша відповідь, але, здається, верх і основа пісочного годинника відсутні.
Рена Лідер

@manatwork не впевнений (звичайно), але в цьому був недолік
edc65

Будь ласка, зробіть набірInterval (), javascript для цього буде чудовим:setTimeout( tick, 1000);
Martijn

18

Пітон 2, 200

t=input()+1
s=' '*t+'.'*60+' '*70
n=0
d=sum((1<t<56,2<t<48,3<t<36,4<t<22))
for c in'ctrplhdhlprtc':i=ord(c)-99;print[s[n+i:n:-1],[s[180-n-i+d:][:i],'.'][5+d*3>i>0]][n>59].center(i).center(19,'#');n+=i

xnor зробив 197- байтну версію в чаті .

Я б опублікував пояснення, але я втратив слідку, як це насправді працює ...

Також ось анімаційна версія з прокльонами:

пісочний годинник

from curses import*
w=initscr()

for t in range(1,61):
    s=' '*t+'.'*60+' '*70
    n=0
    d=sum((1<t<56,2<t<48,3<t<36,4<t<22))
    for i in 0,17,15,13,9,5,1,5,9,13,15,17,0:w.addstr([s[n+i:n:-1],[s[180-n-i+d:][:i],'.'][5+d*3>i>0]][n>59].center(i).center(19,'#')+"\n");n+=i
    w.refresh()
    w.clear()
    napms(999)

endwin()

1
kudos, Ти змусив мене виявити, що у струнах є метод center ()!
дітер

13

Пітон 2.7, 362 356 347

e,c,x,a,b,n=' .#ab\n';R,r,s,l,T,m=range,str.replace,'',19,[1,2,3,5,7,9],-1
for t in[T,T[:m][::m]]:s+=''.join([n+x*y+c*(l-y*2)+x*y for y in t]);c=b
s=list(s)
for i in R(130,220,20):s[i]=a
for _ in R(input()):s[s.index('.')]=e;i=s.index(a)if a in s else 219-s[::m].index(b);s[i]='.'
for l in(x*l+r(r(''.join(s),a,e),b,e)+n+x*l).split(n):print l[::m]

пісочний годинник

Вихід за 38 секунд:

###################
#                 #
##               ##
###.......      ###
#####.........#####
#######.....#######
#########.#########
#######  .  #######
#####    .    #####
###...   .      ###
##...............##
#.................#
###################

2
Що це за Python код? Я хотів би навчитися кодувати, як вони. Підкажіть, будь ласка, у правильному напрямку.
Rajat Saxena

1
Я не впевнений, чи справжня це відповідь. Якщо ви подивитесь на приклад, який він зробив протягом 38 секунд, ви можете побачити, що найнижча точка, яка все ще падає, знаходиться не в лінії, де точки вирівнюються. (у 4-му рядку знизу, в центрі)
RononDex

3
@RononDex: Як пояснено в коментарях до запитання, порядок заповнення не настільки суворий - моя реалізація приклеює зерна піску зліва таким чином, що дещо відрізняється від питання, але все-таки діє
dieter

3

C 544

Ось що я поки що мав для рішення C.

#include <stdio.h>
int main(int z,char **a){int r,i,y=i=0,v,d,t,m,s=atoi(a[1]),n[13]={0,43,28,15,6,1,0,1,5,13,25,39,0};char H[13][20];while(y<13){int x,b=x=i=0;v=y-6;t=3+abs(v);m=2*abs(v);d=t<m?t:m;d=9-d;if(d==0)d=10;while (b<d){H[y][b]='#';H[y][18-b]='#';b++;}while(x<19-2*b){if(x<=s-n[y])H[y][x+b]=v>0?' ':'.';else H[y][x+b]=v>0?'.':' ';x++;}if(s>58)r=0;else if(s==58)r=1;else if(s==57)r=2;else if(s==56)r=3;else if(s>38)r=4;else if(s>24)r=3;else if(s>12)r=2;else if(s>4)r=1;while(i<r){H[7+i][9]='.';i++;}H[y][19]='\n';y++;}fputs(H,stdout);}

Складено за допомогою наступної команди:

gcc -w -o hourglass hourglass.c  // I realize I should have cast H as a char *, but since it works this way, I just decided to suppress the error from the compiler instead to save space.

Справді, ця мова має велику кількість - серед них висловлювання було чимось гандикапом, що виходив прямо з блоків, але я справді просто шукав привід, щоб практикувати використання C.

Я сподіваюся, що вам подобається моє рішення, і повідомте мене, якщо ви бачите способи вдосконалення.


2
Є багато способів поліпшити, зробивши його гіршим, але набагато коротшим.
edc65

1
Підказки: forзамість того , щоб where, ?:замість того if else, глобальний змінний ІНТ не потрібно int, includeне потрібно. (Мені подобається ваша математика)
edc65

1
317: r,i,y,x,b,d,n[]={0,43,28,15,6,1,0,1,5,13,25,39,0};char H[14][20];main(s,a)char**a;{for(s=atoi(a[1]);y<13;){b=x=i=0;d=abs(y-6);d+=3<d?3:d;d=9-d?9-d:10;r=s>55?59-s:s>38?4:s>24?3:s>12?2:s>4?1:r;for(;b<19;)H[y][b++]=35;for(;x<19-2*d;x++)H[y][x+d]=(x>s-n[y]?" .":". ")[y>6];for(;i<r;)H[7+i++][9]=46;H[y++][b]=10;}puts(H);}(будьте
уважні

3

Матлаб, 252 байти

Ідея побудови матриці виглядає приблизно так:

0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
0  17  16  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
0   0  32  31  30  29  28  27  26  25  24  23  22  21  20  19  18   0   0
0   0   0  45  44  43  42  41  40  39  38  37  36  35  34  33   0   0   0
0   0   0   0   0  54  53  52  51  50  49  48  47  46   0   0   0   0   0
0   0   0   0   0   0   0  59  58  57  56  55   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0  60   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0 116 117  61 118 119   0   0   0   0   0   0   0
0   0   0   0   0 108 109 110 111  62 112 113 114 115   0   0   0   0   0
0   0   0  96  97  98  99 100 101  63 102 103 104 105 106 107   0   0   0
0   0  82  83  84  85  86  87  88  64  89  90  91  92  93  94  95   0   0
0  66  67  68  69  70  71  72  73  65  74  75  76  77  78  79  80  81   0
0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

Звідси легко заповнити записи залежними від рядків n(заповнення всіх записів, більших nта менших, ніж n+60точок)

function c=f(n);
b=zeros(13,19);
z=[0,17,32,45,54,59];
y=-2:3;
for k=2:6;
    d=k+sum(k>4:5);
    b(k,d:20-d)=z(k):-1:z(k-1)+1;
    b(14-k,d:19-d)=68+(z(k-1):z(k)-2)-k;
end;
b(8:12,11:19)=b(8:12,10:18);
b(7:12,10)=60:65;c=[ones(13,19)*32,''];
c(~b)='¶';c(n<b)=46;c(b>n+60)=32

Бо n=38ми отримуємо цей вихід:

¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶
¶                 ¶
¶¶               ¶¶
¶¶¶.......      ¶¶¶
¶¶¶¶¶.........¶¶¶¶¶
¶¶¶¶¶¶¶.....¶¶¶¶¶¶¶
¶¶¶¶¶¶¶¶¶.¶¶¶¶¶¶¶¶¶
¶¶¶¶¶¶¶  .  ¶¶¶¶¶¶¶
¶¶¶¶¶    .    ¶¶¶¶¶
¶¶¶...   .      ¶¶¶
¶¶...............¶¶
¶.................¶
¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶

2

Ява, 712

Введення береться з командного рядка. Обробляє як негативні значення за час, так і більше, ніж потрібно.

enum H{;public static void main(String[]r){int x=0,y=0,z=0,l,t=Integer.parseInt(r[0]);String b="",d="█",e=" ",f=".",n="\n",j,k,a="███████████████████"+n;int[]w={17,15,13,9,5},v;int[][]h=new int[10][];for(;x<5;){l=w[x];v=(h[x++]=new int[l--]);l/=2;v[l]=++z;for(y=0;y++<l;){v[l-y]=++z;v[l+y]=++z;}}for(z=0;x>0;){l=w[--x];v=(h[9-x]=new int[l--]);v[l/2]=++z;}for(;x<5;){l=(w[x]-1)/2;v=h[9-x++];for(y=0;y++<l;){v[l-y]=++z;v[l+y]=++z;}}p(a);for(x=0;x<5;x++){l=w[x];j=b;for(y=0;y++*2<19-l;)j+=d;k=b;for(y=0;y<l;)k+=t<h[x][y++]?f:e;p(j+k+j+n);}j="█████████";p(j+f+j+n);for(;x>0;){l=w[--x];j=b;for(y=0;y++*2<19-l;)j+=d;k=b;for(y=0;y<l;)k+=t<h[9-x][y++]?e:f;p(j+k+j+n);}p(a);}static void p(String s){System.out.print(s);}}

вихід:

time: 0
███████████████████
█.................█
██...............██
███.............███
█████.........█████
███████.....███████
█████████.█████████
███████     ███████
█████         █████
███             ███
██               ██
█                 █
███████████████████

time: 1
███████████████████
█........ ........█
██...............██
███.............███
█████.........█████
███████.....███████
█████████.█████████
███████  .  ███████
█████         █████
███             ███
██               ██
█                 █
███████████████████

time: 9
███████████████████
█....         ....█
██...............██
███.............███
█████.........█████
███████.....███████
█████████.█████████
███████  .  ███████
█████    .    █████
███      .      ███
██       .       ██
█      .....      █
███████████████████

time: 41
███████████████████
█                 █
██               ██
███..         ..███
█████.........█████
███████.....███████
█████████.█████████
███████  .  ███████
█████    .    █████
███   .......   ███
██...............██
█.................█
███████████████████

Він заповнює пісок від центру, розширюючись назовні. Я, напевно, можу більше гольфу, якщо я лінуюся, як вона заповнює нижню половину та спорожнює верхню половину. Але зараз мені це дуже подобається.


2

Haskell 512 байт

h=[17,15,13,9,5,1];b=drop 1$reverse h;n#s=[1..n]>>[s];s='.';n =' ';c q=(q#n)++(60-q)#s;f q|q<=5=q#s|3>2=g#s where{g=foldl i 5 (scanl (+) 0 h);i x y=if q>x+y then x-1 else x};e q=j#s++(59-length(k q)-(j))#n where{j=q-length(f q)};l q=c q++k q++(reverse$e q);p _ []=[];p x y=reverse(z++take q x++z):p (drop (head y) x) (tail y)where{q=head y;z=replicate(div (19-q) 2) '|'};k q= (concat.map(\x -> z x ++ "." ++ z x).take (length.f$q)$b)where{z x=(div x 2)#n};m n=mapM_ putStrLn $ t ++ p (l n) (h++b) ++ t;t=[19#'|'] 

Вхідні дані m 55

Вихідні дані

|||||||||||||||||||
|                 |
||               ||
|||             |||
|||||         |||||
|||||||.... |||||||
|||||||||.|||||||||
|||||||  .  |||||||
|||||.........|||||
|||.............|||
||...............||
|.................|
|||||||||||||||||||

Вхідний m 48 вихід

    |||||||||||||||||||
    |                 |
    ||               ||
    |||             |||
    |||||......   |||||
    |||||||.....|||||||
    |||||||||.|||||||||
    |||||||  .  |||||||
    |||||..       |||||
    |||.............|||
    ||...............||
    |.................|
    |||||||||||||||||||

1
Ласкаво просимо до PPCG! Я бачу, що ви вже це вже багато гольфували, але все ще залишається багато зайвого простору, наприклад. оточуючих ++. Також ви можете зберегти деякі байти, попередньо визначивши lengthі reverse.
Лайконі

1

C #, 382 410

все-таки можливо зменшити його на кілька байт ...

class Program{static void Main(){int u=60-22,d=u,i,j,k,l,m;var c=new char[260];var r=new int[]{0,17,15,13,9,5,1,5,9,13,15,17,0,54,45,32,17,0};for(i=0;i<13;){m=0;l=(19-r[i])/2-1;for(j=19;j>=0;){k=i*20+j--;var b=j>=l&&j<r[i]+l;if(i>6&b)c[k-r[i]+m++ +m]=r[i+6]<d&&d-->0||j==8&r[i+6]>d&&d-->0?'.':' ';else c[k]=i<7&b?u-->1?' ':'.':'█';}c[++i*20-1]='\n';}System.Console.WriteLine(c);}}

Fiddler - 38 сек


Класно! Як воно приймає вклад?
isaacg

@isaacg, ой, я виправлю це пізніше сьогодні, я знав, що це занадто коротко для рішення AC # :-) поки змінити u = 60-22 на щось інше
Fredou

Чому ви використовуєте, int u=60-22а не просто int u=38??
dev-masih

1

Рубі: 196 190 186 185 184 символів

u=[0,17,15,13,9,5].map{|i|(?.*i).center 19,?#}*$/
(?1..$*[0]).map{u[?.]=' '}
l=u.reverse
5.times{|i|l[p=i*20+9]==?.&&l[' ']&&(l[p]=?|)&&l[' ']=?.}
puts u,?#*9+?.+?#*9,l.tr('. | ',' .')

CW не відповідає точно розміщеним зразкам, оскільки він споживає пісок, починаючи зліва. Переважно лише демонстрація String.[]=методу.

Проба зразка:

bash-4.3$ ruby hg.rb 38
###################
#                 #
##               ##
###      .......###
#####.........#####
#######.....#######
#########.#########
#######  .  #######
#####    .    #####
###      .   ...###
##...............##
#.................#
###################

Ruby: 215 символів

Це генерує точний необхідний вихід:

u=[0,17,15,13,9,5].map{|i|(?.*i).center 19,?#}*$/
(?1..$*[0]).map{u[?.]=' '}
l=u.reverse
5.times{|i|l[p=i*20+9]==?.&&l[' ']&&(l[p]=?|)&&l[' ']=?.}
puts ([u,?#*9+?.+?#*9,l.tr('. | ',' .')]*$/).split($/).map &:reverse

Проба зразка:

bash-4.3$ ruby hg.rb 38
###################
#                 #
##               ##
###.......      ###
#####.........#####
#######.....#######
#########.#########
#######  .  #######
#####    .    #####
###...   .      ###
##...............##
#.................#
###################
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.