Код Гольфа: Песочные Часы
Вызов
Самый короткий код по количеству символов для вывода песочных часов в соответствии с вводом пользователя.
Входные данные состоят из двух чисел: первое число-это целое число больше 1, которое представляет высоту лампочек, второе число-это процент (0 - 100) от емкости песочных часов.Высота песочных часов создается путем добавления большего количества линий к лампочкам песочных часов, поэтому размер 2 (минимальный принятый размер) будет:
_____
/
/
/
/___
Размер 3 добавит больше строк чтобы луковицы могли поместиться больше "песка".
Песок будет нарисован с помощью символа x
. Верхняя колба будет содержать N процентов "песка", в то время как нижняя колба будет содержать (100 - N) процентов песка, где N-вторая переменная.
"вместимость" измеряется количеством пространств.() песочные часы содержат. Там, где процент не является точным, он должен быть округлен.
Песок вытягивается снаружи внутрь, давая приоритет правой стороне в случае, если процентный результат равен даже.
Тестовые случаи
Input:
3 71%
Output:
_______
x xx/
xxx/
x/
/
/
/__xx_
Input:
5 52%
Output:
___________
/
xx xx/
xxxxx/
xxx/
x/
/
/
/
/ xxx
/xxxxxxxxx
Input:
6 75%
Output:
_____________
x x/
xxxxxxxxx/
xxxxxxx/
xxxxx/
xxx/
x/
/
/
/
/
/
/_xxxxxxxxx_
Подсчет кода включает вход / выход (т. е. полную программу).
13 ответов:
Golfscript-136 символов (вписывается в твит)
Убедитесь, что после % на входе нет новой строки
например$ echo -n 3 71%|./golfscript.rb hourglass.gs
Вы можете оживить песочные часы следующим образом:
$ for((c=100;c>=0;c--));do echo -n "15 $c%"|./golfscript.rb hourglass.gs;echo;sleep 0.1;done;
Golfscript-136 Символов
Убедитесь, что вы не сохраняете его с дополнительной новой строкой в конце, или он напечатает дополнительное число);' ': /(~: ;0=~100.@- .**\/:t;'_':&& *.n ,{:y *.'\\'+{[&'x':x]0t(:t>=}:S~ (y-,{;S\+S+.}%;'/'++\+}%.{&/ *}%\-1%{-1%x/ *&/x*}%) /&[*]++n*
Golfscript-144 Символа
);' ':|/(~:^.*:X ;0=~100.@-X*\/ X'x':x*'_':& @*+:s;&&&+ ^*n^,{:y |*.[92 ]+{s [) \# :s;] }:S~^( y-,{;S\+ S+.}%;'/'+ +\+}%.{&/|*} %\-1%{-1%x/|*& /x*}%)|/&[*]++n*Как это работает
Сначала сделайте верхнюю строку подчеркивается, что2n+1
Создайте верхнюю половину песочных часов, но используйте символы '_' вместо пробелов, поэтому для 3 71% мы будем иметь.\x__xx/ \xxx/ \x/
Завершите верхнюю половину, заменив " _ " на "" , но сохраните копию, чтобы создать нижнюю половину
Нижняя половина создается путем обращения всей вещи вспять
/x\ /xxx\ /xx__x\
Заменив все 'x' на ' ', а затем ' _ ' на ' x '
/ \ / \ / xx \
Наконец, замените ''в нижней строке на' _ '
/ \ / \ /__xx_\
Круговая развязка но для меня код оказался короче, чем попытка сгенерировать обе половинки сразу
C/C++, мрачные 945 символов...
Принимает входные данные в качестве параметров: а. из 5 52%
#include<stdio.h> #include<memory.h> #include<stdlib.h> #define p printf int h,c,*l,i,w,j,*q,k;const char* z;int main(int argc,char**argv) {h=atoi(argv[1]);c=(h*h*atoi( argv[2])+99)/100;l=new int[ h*3];for(q=l,i=0,w=1;i<h; i++,c=(c-w)&~((c-w)>>31 ),w+=2)if(c>=w){*q++= 0;*q++ =0;* q++=w;} else {*q++=(c+1)/ 2;*q++=w-c;*q++ =c/2;}p("_"); for(i=0;i<h ;i ++)p ( "__");p ("\n" );q = l+h *3-1; for (i= --h;i>=0; i--){p("%*" "s\\",h-i,"") ; z= "x\0 \0x"; for(k=0;k<3;k++,q --,z+=2)for(j=0;j<* q;j++)p(z);q-=0;p("/" "\n");}q=l;for(i=0;i<=h ;i++){z =i==h? "_\0x\0_": " \0x\0 ";p("%*s/",h-i,""); for(k=0;k<3;k++,q++,z+=2)for( j=0;j<*q;j++)p(z);p("\\\n") ;}}
...и расшифрованная версия этого для нас, простых людей:
#include <stdio.h> #include <memory.h> #include <stdlib.h> #define p printf int h, c, *l, i, w, j, *q, k; const char *z; int main(int argc, char** argv) { h = atoi(argv [1]); c = (h*h*atoi(argv[2])+99)/100; l = new int[h*3]; for (q = l,i = 0,w = 1; i<h; i++,c = (c-w)&~((c-w)>>31),w += 2) { if (c>=w) { *q++ = 0; *q++ = 0; *q++ = w; } else { *q++ = (c+1)/2; *q++ = w-c; *q++ = c/2; } } p("_"); for (i = 0; i<h; i++) { p("__"); } p("\n"); q = l+h*3-1; for (i = --h; i>=0; i--) { p("%*s\\",h-i,""); z = "x\0 \0x"; for (k = 0; k<3; k++,q--,z += 2) { for (j = 0; j<*q; j++) { p(z); } } p("/\n"); } q = l; for (i = 0; i<=h; i++) { z = i==h ? "_\0x\0_" : " \0x\0 "; p("%*s/",h-i,""); for (k = 0; k<3; k++,q++,z += 2) { for (j = 0; j<*q; j++) { p(z); } } p("\\\n") ; } }
Perl, 191 char
205199191 чарс.$S=-int((1-.01*pop)*($N=pop)*$N)+$N*$N;$S-=$s=$S>++$r?$r:$S, $\=$/.$"x$N."\\".x x($v=$s/2).$"x($t=$r++-$s).x x($w=$v+.5)."/$\ ".$"x$N."/".($^=$N?$":_)x$w.x x$t.$^x$v."\\"while$N--;print$^x++$r
Требуется явная новая строка между 2-й и 3-й строками.
И с помощью нового модуляAcme::AsciiArtinator :
$S=-int((1-.01*pop)*($N=pop ) * $ N ) + $ N *$N;( ${B},$ F,${x})=qw(\\ / x );while($N){;/l ater/g;$S-=$s =$S>++$r?$r :$S;'than you';@o =(" " x-- $ N . $ B . x x ( $ v = $ s / 2 ) .$"x($t= $ r++-$s).x x($w=$v+.5) .$F,@o,$"x$N.$F.($^=$N? $":_)x$w.x x$t.$^x$v.$B); $,=$/}print$^x++$r,@o;think
Python, 213 char
N,p=map(int,raw_input()[:-1].split()) S=N*N-N*N*(100-p)/100 _,e,x,b,f,n=C='_ x\/\n' o="" r=1 while N:N-=1;z=C[N>0];s=min(S,r);S-=s;t=r-s;v=s/2;w=s-v;r+=2;o=n+e*N+b+x*v+e*t+x*w+f+o+n+e*N+f+z*w+x*t+z*v+b print _*r+o
Ребму : 188 символов
Он конкурирует с более короткими решениями здесь, хотя на самом деле решает проблему "наивным" способом. Более или менее он занимается "физикой песка" вместо того, чтобы использовать симметрии или вращающиеся матрицы или что-то еще.
rJ N 0% rN Wad1mpJ2 S{ \x/ }D0 Hc&[u[Z=~wA Qs^RTkW[isEL0c[skQdvK2][eEV?kQ[tlQ]]pcSeg--B0[eZ1 5]3]prRJ[si^DspSCsQfhS]eZ1[s+DcA+wMPc2no]]]Va|[mpAj**2]prSI^w{_}Ls+W2 h1tiVsb1n -1 chRVs{_}hLceVn1
H
определяет функцию для печати половины песочных часов, к которой вы передаете число, которое является количеством пробелов для печати, прежде чем начать печатать символы "x". Если вы находитесь на верхней половине, то песок струна строится путем чередования присоединений к голове и хвосту. Если вы находитесь внизу, он выбирает источник вставки, пропуская в середину строки. Прокомментированный источник доступен по адресу:Http://github.com/hostilefork/rebmu/blob/master/examples/hourglass.rebmu
Но настоящий трюк в рукаве Ребму - это тонкий диалект, который не нарушает ни одного из правил синтаксического анализа своего основного языка (Rebol). Вы можете превратить это в визуализацию конца света с помощью ввод обычного кода прямо в середину, пока вы кодируете в нижнем регистре:
>> rebmu [rJ birthday: to-date (ask "When were you born? ") n: (21-dec-2012 - now/date) / (21-dec-2012 - birthday) Wad1mpJ2 S{ \x/ }D0 Hc~[u[Ze?Wa Qs^RTkW[isEL0c[skQdvK2][eEV?kQ[tlQ]]pcSeg--B0[eZ1 5]3]prRJ[si^DspSCsQfhS]eZ1[s+DcA+wMPc2no]]]Va|[mpAj**2]prSI^w{_}Ls+W2h1tiVsb1n -1 chRVs{_}hLceVn1]
Input Integer: 10 When were you born? 23-May-1974 _____________________ \ / \ / \ / \ / \ / \ / \ / \x xx/ \xxx/ \x/ / \ / \ / xx \ /xxxxxxx\ /xxxxxxxxx\ /xxxxxxxxxxx\ /xxxxxxxxxxxxx\ /xxxxxxxxxxxxxxx\ /xxxxxxxxxxxxxxxxx\ /xxxxxxxxxxxxxxxxxxx\
О нет! :)
(Примечание: основная причина, по которой я могу писать и отлаживать программы Rebmu, заключается в том, что я могу в любой момент взломать обычное кодирование, чтобы использовать существующие средства отладки/etc.)
Хаскелл. 285 знаков. (Без побочных эффектов!)
x n c=h s++'\n':reverse(h(flip s)) where h s=r w '-'++s '+' b(w-2)0 p;w=(t n);p=d(n*n*c)100 s x n i o p|i>0='\n':l++s x n(i-2)(o+1)(max(p-i)0)|True=[] where l=r o b++'\\':f d++r(i#p)n++f m++'/':r o b;f g=r(g(i-(i#p))2)x b=' ' r=replicate t n=1+2*n d=div (#)=min m=(uncurry(+).).divMod
Запустить, например, с
x 5 50
Ответ на c++, это 592 символы до сих пор, все еще имеющие разумное форматирование.
#include<iostream> #include<string> #include<cstdlib> #include<cmath> using namespace std; typedef string S; typedef int I; typedef char C; I main(I,C**v){ I z=atoi(v[1]),c=z*z,f=ceil(c*atoi(v[2])/100.); cout<<S(z*2+1,'_')<<'\n'; for(I i=z,n=c;i;--i){ I y=i*2-1; S s(y,' '); C*l=&s[0]; C*r=&s[y]; for(I j=0;j<y;++j) if(n--<=f)*((j&1)?l++:--r)='x'; cout<<S(z-i,' ')<<'\\'<<s<<"/\n"; } for(I i=1,n=c-f;i<=z;++i){ I y=i*2-1; S s(y,'x'); C*l=&s[0]; C*r=&s[y]; for(I j=0;j<y;++j) if(n++<c)*(!(j&1)?l++:--r)=(i==z)?'_':' '; cout<<S(z-i,' ')<<'/'<<s<<"\\\n"; } }
Если я решу просто забыть форматировать его разумно, я могу получить его как можно ниже.531:
#include<iostream> #include<string> #include<cstdlib> #include<cmath> using namespace std;typedef string S;typedef int I;typedef char C;I main(I,C**v){I z=atoi(v[1]),c=z*z,f=ceil(c*atoi(v[2])/100.);cout<<S(z*2+1,'_')<<'\n';for(I i=z,n=c;i;--i){I y=i*2-1;S s(y,' ');C*l=&s[0];C*r=&s[y];for(I j=0;j<y;++j)if(n--<=f)*((j&1)?l++:--r)='x';cout<<S(z-i,' ')<<'\\'<<s<<"/\n";}for(I i=1,n=c-f;i<=z;++i){I y=i*2-1;S s(y,'x');C*l=&s[0];C*r=&s[y];for(I j=0;j<y;++j)if(n++<c)*(!(j&1)?l++:--r)=(i==z)?'_':' ';cout<<S(z-i,' ')<<'/'<<s<<"\\\n";}}
Баш:
639- 373 символыЯ думал, что дам Башу попробовать(не видел в нем много игры в гольф). (моя версия: GNU bash, версия 3.2.48 (1)-release (i486-pc-linux-gnu))
На основехорошего ответа Mobrule на python .
Оптимизация все еще должна быть доступна, поэтому все предложения приветствуются!
Начните с командной строки, например:
./hourglass.sh 7 34%
function f () { for i in `seq $1`;do printf "$2";done; } N=$1;S=$[$1*$1-$1*$1*$[100-${2/\%/}]/100] b='\';o=$b;n="\n";r=1;while [ $N -gt 0 ];do N=$[N-1];z=" ";s=$r;[ $N -eq 0 ]&& z=_;[ $S -lt $r ]&& s=$S S=$[S-s];t=$[r-s];v=$[s/2];w=$[s-v];r=$[r+2] o=$n`f $N " "`$b`f $v x;f $t " ";f $w x`/$o$b$n`f $N " "`/`f $w "$z";f $t x;f $v "$z"`$b done;f $r _;echo -e "${o/\/\\\\//}"
Java; 661 символ
Мне нужно найти лучший набор клюшек для гольфа.public class M{public static void main(String[] a){int h=Integer.parseInt(a[0]);int s=(int)Math.ceil(h*h*Integer.parseInt(a[1])/100.);r(h,h-1,s,true);r(h,h-1,s,false);}static void r(int h,int c,int r,boolean t){if(c<0)return;int u=2*(h-c)-1;if(t&&c==h-1)p(2*h+1,0,'_','_',true,0,false);int z=r>=u?u:r;r-=z;if(t)r(h,c-1,r,true);p(u,z,t?'x':((c==0)?'_':' '),t?' ':'x',t,c,true);if(!t)r(h,c-1,r,false);}static void p(int s,int n,char o,char i,boolean t,int p,boolean d){int f=(s-n);int q=n/2+(!t&&(f%2==0)?1:0);int e=q+f;String z = "";int j;for(j=0;j<p+4;j++)z+=" ";if(d)z+=t?'\\':'/';for(j=0;j<s;j++)z+=(j>=q&&j<e)?i:o;if(d)z+=t?'/':'\\';System.out.println(z);}}
PHP - 361
<?$s=$argv[1];$x='str_pad';$w=$s*2-1;$o[]=$x('',$w+2,'_'); $r=$s*ceil($w/2);$w=$r-($r*substr($argv[2],0,-1)/100);$p=0; $c=-1;while($s){$k=$s--*2-1;$f=$x($x('',min($k,$w),' '),$k,'x',2); $g=$x($x('',min($k,$w),'x'),$k,' ',2);$w-=$k;$o[]=$x('',$p)."\\$f/"; $b[]=$x('',$p++)."/$g\\";}$b[0]=str_replace(' ','_',$b[0]); krsort($b);echo implode("\n",array_merge($o,$b));?>
Python-272 символа
X,p=map(int,raw_input()[:-1].split()) k=X*X;j=k*(100-p)/100 n,u,x,f,b,s='\n_x/\ ' S=list(x*k+s*j).pop;T=list(s*k+u*(2*X-j-1)+x*j).pop A=B="" for y in range(X): r=S();q=T() for i in range(X-y-1):r=S()+r+S();q+=T();q=T()+q A+=n+s*y+b+r+f;B=n+s*y+f+q+b+B print u+u*2*X+A+B
Java Exabyte18, преобразованная в C#, 655 байт:
public class M {public static void Main(){int h = Convert.ToInt32(Console.ReadLine()); int s = Convert.ToInt32(h * h * Convert.ToInt32(Console.ReadLine()) / 100);r(h,h-1,s,true); r(h,h-1,s,false);Console.ReadLine();}static void r(int h, int c, int r, bool t){ if(c<0) return;int u=2*(h-c)-1;if (t&&c==h-1)p(2*h+1,0,'_','_',true,0,false); int z=r>=u?u:r; r-=z;if (t)M.r(h,c-1,r,true); p(u,z,t?'x':((c==0)?'_':' '), t?' ':'x',t,c,true); if(!t)M.r(h,c-1,r,false);}static void p(int s, int n, char o, char i, bool t, int p, bool d) {int f=(s-n);int q=n/2+(!t&&(f%2==0)?1:0);int e=q+f;string z="";int j;for(j=0;j<p+4;j++) z+=" ";if(d)z+=t?'\\':'/'; for (j=0;j<s;j++) z+=(j>=q&&j<e)?i:o; if(d)z+=t?'/':'\\';Console.WriteLine(z);}}
Руби,
297254 (после сжатия)Запустите оба с
ruby -a -p f.rb
n,p = $F.map{|i|i.to_i} r="\n" y='' g,s,u,f,b=%w{x \ _ / \\} $> << u*2*n+u+r # draw initial underbar line a=u c=100.0/n/n # amount of sand a single x represents e = 100.0 # percentage floor to indicate sand at this level n.times{ |i| d=2*n-1-2*i # number of spaces at this level e-= c*d # update percentage floor x = [((p - e)/c+0.5).to_i,d].min x = 0 if x<0 w = x/2 # small half count z = x-w # big half count d = d-x # total padding count $> << s*i+b+g*w+s*d+g*z+f+r y=s*i+f+a*z+g*d+a*w+b+r+y a=s } $_=y
Руби, 211
Это mobrule's tour de force, в Ruby. (И все еще нет финальной новой строки. :- )
m,p=$F.map{|i|i.to_i} q=m*m-m*m*(100-p)/100 _,e,x,b,f=%w{_ \ x \\ /} n="\n" o='' r=1 while m>0 m-=1 z=m>0?e:_ s=q<r ?q:r q-=s t=r-s v=s/2 w=s-v r=r+2 o=n+e*m+b+x*v+e*t+x*w+f+o+n+e*m+f+z*w+x*t+z*v+b end $_=_*r+o