Wyzwanie klepsydry

43

Klepsydra

Ta klepsydra ma 60 „piasków czasu” i całkowicie wypełnia każdą komorę. Zegar ma szerokość 19 znaków i wysokość 13 znaków. Każda komora ma 5 rzędów piasku, a na środku jest rząd, który może pomieścić 1 piasek. Górny rząd może pomieścić 17 piasków, następny 15 i tak dalej (patrz poniżej). Piaski wpadają do dolnej komory z prędkością jednego piasku na sekundę.

       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 
███████     ███████            ███████  .  ███████            ███████  .  ███████  
█████         █████            █████    .    █████            █████    .    █████   
███             ███            ███      .      ███            ███....         ███
██               ██            ██               ██            ██...............██  
█                 █            █                 █            █.................█  
███████████████████            ███████████████████            ███████████████████   

Wyzwanie

Wyświetl klepsydrę (nie są wymagane żadne cyfry ani nagłówki) po pewnym czasie (0 ≤ t ≤ 60).

Zasady kodowania

  1. Klepsydra powinna wyglądać dokładnie tak, jak pokazano tutaj. Możesz zamienić znak i / lub .znak na cokolwiek, co chcesz dopasować do swojego języka (Unicode, problemy ze zgodnością ASCII).
  2. Wejście powinno być liczbą taką jak 45 lub 7. Wyświetl zegar po tych wielu sekundach.
  3. Dane wyjściowe można wyświetlić lub zapisać w pliku. Nie jest wymagany żaden dodatkowy tekst ani etykiety, jak pokazano powyżej - wystarczy klepsydra.
  4. Jeśli użytkownik wpisze t> 60, nie musisz obsługiwać błędu.

Zwrotnica

  1. Najkrótszy kod wygrywa.
Renae Lider
źródło
Nie wiem, czy to tylko ja, ale klepsydry wyglądają zupełnie inaczej w edytorze niż w samym poście. Prawdopodobnie dlatego, że znak █ nie wyświetla się z odpowiednią szerokością.
Dennis
1
Czy ziarno piasku dotyka bieżącej warstwy, a następnie sekundę później wyrównuje do lewej?
xnor
2
Jaka powinna być wydajność dla t == 59?
edc65
3
Gratulujemy utworzenia listy gorących pytań o stos wymiany sieci!
Alex A.
1
To naprawdę nie jest odpowiedź, ponieważ nie pasuje do specyfikacji, ale spójrz tutaj, aby przesłać zgłoszenie w Desmos. (Naciśnij przycisk odtwarzania i ustaw prędkość na 0,15x na ~ 1 jednostkę / sekundę)
Conor O'Brien

Odpowiedzi:

27

JavaScript ( ES6 ), 203 208 233 270 256 znaków

Edytuj Zmieniono za pomocą pętli zamiast sekwencji wywołań.

Edytuj Dodane brakujące górne i dolne rzędy.

Funkcja zwracająca dane wyjściowe. Uruchom fragment w przeglądarce Firefox, aby go przetestować.

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>

edc65
źródło
5
Ku mojej ciekawości, dlaczego dwukrotnie to odrzucono? Nie mogę znaleźć z tym problemu.
manatwork
Ta odpowiedź jest niesamowita ! Otwórz to w Firefoksie, ludzie!
Cristian Lupascu,
1
Dobra odpowiedź, ale wydaje się, że brakuje górnej i dolnej części klepsydry.
Renae Lider,
@manatwork nie jestem pewien (oczywiście), ale rzeczywiście była wada
edc65
Zrób setInterval (), javascript byłby do tego świetny:setTimeout( tick, 1000);
Martijn
18

Python 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 stworzył 197 bajtową wersję na czacie .

Chciałbym opublikować wyjaśnienie, ale straciłem orientację, jak to naprawdę działa ...

Oto animowana wersja z przekleństwami:

klepsydra

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()
grc
źródło
1
kudos, Sprawiłeś, że odkryłem, że łańcuchy mają metodę center ()!
dieter
13

Python 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]

klepsydra

Wyjście po 38 sekundach:

###################
#                 #
##               ##
###.......      ###
#####.........#####
#######.....#######
#########.#########
#######  .  #######
#####    .    #####
###...   .      ###
##...............##
#.................#
###################
dieter
źródło
2
Co to za kod Python? Chciałbym nauczyć się kodować jak oni. Proszę kierować we właściwym kierunku.
Rajat Saxena
1
Nie jestem pewien, czy jest to prawidłowa odpowiedź. Jeśli spojrzysz na przykład, który stworzył przez 38 sekund, zobaczysz, że najniższa kropka, która wciąż spada, nie znajduje się w linii, w której kropki się wyrównują. (w 4 linii od dołu, w środku)
RononDex
3
@RononDex: Jak wyjaśniono w komentarzach do pytania, kolejność napełniania nie jest tak ścisła - moja implementacja przykleja ziarna piasku w lewo w sposób nieco inny od pytania, ale wciąż ważny
dieter
3

C 544

Oto, co mam do tej pory dla rozwiązania 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);}

Skompilowano za pomocą następującego polecenia:

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.

Trzeba przyznać, że ten język jest bardzo obszerny - takie stwierdzenie stanowiło pewną przeszkodę przy wychodzeniu z bloków, ale tak naprawdę szukałem pretekstu do ćwiczenia posługiwania się C.

Mam nadzieję, że podoba Ci się moje rozwiązanie i daj mi znać, jeśli widzisz sposoby poprawy.

jaskółka oknówka
źródło
2
Jest wiele sposobów na poprawę, co czyni go gorszym C, ale o wiele krótszym.
edc65
1
Wskazówki: forzamiast where, ?:zamiast if elseglobalne zmienne int nie potrzeba int, includenie są potrzebne. (Lubię twoją matematykę)
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);}(uwaga, do długich komentarzy takich jak ten dodawane są dziwne niewidzialne znaki)
edc65
3

Matlab, 252 bajty

Pomysł polega na zbudowaniu macierzy, która wygląda następująco:

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

Stamtąd łatwo jest wypełnić wpisy ciągami zależnymi od n(wypełnienie wszystkich wpisów, które są większe ni mniejsze niż n+60kropkami)

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

Ponieważ n=38otrzymujemy ten wynik:

¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶
¶                 ¶
¶¶               ¶¶
¶¶¶.......      ¶¶¶
¶¶¶¶¶.........¶¶¶¶¶
¶¶¶¶¶¶¶.....¶¶¶¶¶¶¶
¶¶¶¶¶¶¶¶¶.¶¶¶¶¶¶¶¶¶
¶¶¶¶¶¶¶  .  ¶¶¶¶¶¶¶
¶¶¶¶¶    .    ¶¶¶¶¶
¶¶¶...   .      ¶¶¶
¶¶...............¶¶
¶.................¶
¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶¶
wada
źródło
2

Java, 712

Dane wejściowe są pobierane z wiersza poleceń. Obsługuje zarówno wartości ujemne dla czasu, jak i większe niż wymagane.

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

wynik:

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

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

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

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

Wypełnia piasek od środka, rozszerzając się na zewnątrz. Prawdopodobnie mogę grać w golfa bardziej, jeśli się lenię, jak wypełnia dolną połowę i opróżnia górną połowę. Ale na razie mi się podoba.

Jack Ammo
źródło
2

Haskell 512 bajtów

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#'|'] 

Wejście m 55

Wynik

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

Dane m 48 wyjściowe

    |||||||||||||||||||
    |                 |
    ||               ||
    |||             |||
    |||||......   |||||
    |||||||.....|||||||
    |||||||||.|||||||||
    |||||||  .  |||||||
    |||||..       |||||
    |||.............|||
    ||...............||
    |.................|
    |||||||||||||||||||
brander
źródło
1
Witamy w PPCG! Widzę, że już trochę grałeś w golfa, ale wciąż jest wiele niepotrzebnej białej przestrzeni, np. otaczające ++. Możesz także zaoszczędzić niektóre bajty, wstępnie definiując lengthi reverse.
Laikoni
1

C #, 382 410

nadal może być możliwe zmniejszenie go o kilka bajtów ...

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

Skrzypek - 38 sek

Fredou
źródło
Chłodny! Jak to wymaga wkładu?
isaacg
@isaacg, oops, naprawię to później dzisiaj, wiedziałem, że jest za krótki na ac # rozwiązanie :-) na razie zmień u = 60-22 na coś innego
Fredou
Dlaczego używasz, int u=60-22a nie tylko int u=38?
dev-masih
1

Rubinowy: 196 190 186 185 184 znaków

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, ponieważ nie jest dokładnie zgodny z wysłanymi próbkami, ponieważ pochłania piasek, zaczynając od lewej. Głównie tylko demonstracja String.[]=metody.

Przykładowy przebieg:

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

Ruby: 215 znaków

To generuje dokładnie wymaganą wydajność:

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

Przykładowy przebieg:

bash-4.3$ ruby hg.rb 38
###################
#                 #
##               ##
###.......      ###
#####.........#####
#######.....#######
#########.#########
#######  .  #######
#####    .    #####
###...   .      ###
##...............##
#.................#
###################
obrotowych
źródło