language-agnostic code-golf rosetta-stone

language agnostic - Código de golf: reloj de arena



language-agnostic code-golf (13)

C / C ++, un sombrío 945 caracteres ...

Toma la entrada como parámetros: a.out 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") ;}}

... y la versión desencriptada de esto para nosotros simples humanos:

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

El reto

El código más corto por número de caracteres para generar un reloj de arena según la entrada del usuario.

La entrada está compuesta por dos números: el primer número es mayor que 1 entero que representa la altura de las bombillas, el segundo número es un porcentaje (0 - 100) de la capacidad del reloj de arena.

La altura del reloj de arena se hace agregando más líneas a las bombillas del reloj de arena, por lo que el tamaño 2 (el tamaño mínimo aceptado) sería:

_____ / / / / / / /___/

El tamaño 3 agregará más líneas para que las bombillas puedan caber más "arena".

La arena se dibujará utilizando el carácter x . La bombilla superior contendrá N por ciento de ''arena'' mientras que la bombilla inferior contendrá (100 - N) por ciento de arena, donde N es la segunda variable.

La ''capacidad'' se mide por la cantidad de espacios ( ) el reloj de arena contiene. Donde el porcentaje no es exacto, se debe redondear hacia arriba.

La arena se extrae de afuera hacia adentro, dando prioridad al lado derecho en caso de que el porcentaje de resultado sea uniforme.

Casos de prueba

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_/

El conteo de códigos incluye entrada / salida (es decir, programa completo).


Golfscript - 136 caracteres (cabe en un tweet)

Asegúrese de no tener una nueva línea después del% para la entrada
p.ej
$ echo -n 3 71%|./golfscript.rb hourglass.gs

Puedes animar el reloj de arena así:

$ for((c=100;c>=0;c--));do echo -n "15 $c%"|./golfscript.rb hourglass.gs;echo;sleep 0.1;done;

Golfscript - 136 caracteres
Asegúrese de no guardarlo con una nueva línea adicional al final o se imprimirá un número adicional

);'' '': /(~: ;0=~100.@- .**//:t;''_'':&& *.n ,{:y *.''//'+{[&''x'':x]0t(:t>=}:S~ (y-,{;S/+S+.}%;''/''++/+}%.{&/ *}%/-1%{-1%x/ *&/x*}%) /&[*]++n*

Golfscript - 144 caracteres

);'' '':|/(~:^.*:X ;0=~100.@-X*// X''x'':x*''_'':& @*+:s;&&&+ ^*n^,{:y |*.[92 ]+{s [) /# :s;] }:S~^( y-,{;S/+ S+.}%;''/''+ +/+}%.{&/|*} %/-1%{-1%x/|*& /x*}%)|/&[*]++n*

Cómo funciona
Primero haga la línea superior de guiones bajos que es 2n+1 Cree la mitad superior del reloj de arena, pero use los caracteres ''_'' en lugar de espacios, así que para el 3 71% tendríamos.

/x__xx/ /xxx/ /x/

Complete la mitad superior reemplazando la "_" con "" pero guarde una copia para generar la mitad inferior

La mitad inferior se crea invirtiendo todo.

/x/ /xxx/ /xx__x/

Reemplazando todas las ''x'' con '''' y luego ''_'' con ''x''

/ / / / / xx /

Finalmente reemplace el '''' en la fila inferior con ''_''

/ / / / /__xx_/

Rotonda, pero para mí, el código resultó más corto que intentar generar ambas mitades a la vez


Python - 272 caracteres

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


Bash: 639 - 373 caracteres

Pensé que le daría una oportunidad a bash (no he visto mucho código de golf en él). (Mi versión: GNU bash, versión 3.2.48 (1) -release (i486-pc-linux-gnu) )

Basado en la agradable respuesta de Python de Mobrule .

Las optimizaciones aún deben estar disponibles, por lo que todas las sugerencias son bienvenidas.

Comience desde la línea de comando, por ejemplo: ./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/////////}"


Haskell. 285 caracteres. (¡Sin efectos secundarios!)

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

Ejecutar con, por ejemplo, x 5 50


Java; 661 caracteres

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

Necesito encontrar un mejor conjunto de palos de golf.


Perl, 191 char

205 199 191 caracteres.

$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

Se requiere una nueva línea explícita entre las líneas 2 y 3.

Y con la ayuda del nuevo módulo 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 caracteres

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


Rebmu : 188 caracteres

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

Es competitivo con las soluciones más cortas aquí, aunque en realidad está resolviendo el problema de una manera "ingenua". Más o menos es hacer la "física de la arena" en lugar de explotar simetrías o matrices rotativas o cualquier otra cosa.

H define una función para imprimir la mitad de un reloj de arena, a la que se le pasa un número que indica cuántos espacios se deben imprimir antes de comenzar a imprimir los caracteres "x". Si está en la mitad superior, la cadena de arena se construye alternando apéndices a la cabeza y la cola. Si está en la parte inferior, elige la fuente de inserción saltando en el medio de la cadena. Fuente comentada disponible en:

http://github.com/hostilefork/rebmu/blob/master/examples/hourglass.rebmu

Pero el verdadero truco bajo la manga de Rebmu es que es un dialecto delgado que no rompe ninguna de las reglas de análisis de su lenguaje principal (Rebol). Puedes convertir esto en una visualización de Doomsday inyectando código ordinario justo en el medio, siempre que codifiques en minúsculas:

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

¡Oh no! :)

(Nota: una de las principales razones por las que puedo escribir y depurar programas Rebmu es que puedo ingresar a la codificación normal en cualquier momento para usar las herramientas de depuración existentes, etc.)


El java de Exabyte18 se convirtió a C #, 655 bytes:

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


Una respuesta de c ++ es 592 caracteres hasta ahora, aún teniendo un formato razonable.

#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"; } }

Si decido olvidarme de formatearlo razonablemente, puedo obtenerlo tan bajo como 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";}}


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


Ruby, 297 254 (después de la compresión)

Corre ambos con 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

Ruby, 211

Este es el tour de force de mobrule , en Ruby. (Y aún no hay nueva línea final. :-)

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