Helado ASCII

15

Escriba un programa o función que tome un entero positivo N e imprima o devuelva una cadena de arte ASCII N × N cuya mitad superior es un semicírculo hecho de ('sy cuya mitad inferior es un triángulo apuntando hacia abajo hecho de V' s, con espacios utilizados como relleno.

En otras palabras, haga un cono de helado ASCII: (salida para N = 17)

      (((((      
    (((((((((    
  (((((((((((((  
  (((((((((((((  
 ((((((((((((((( 
 ((((((((((((((( 
(((((((((((((((((
(((((((((((((((((
VVVVVVVVVVVVVVVVV
 VVVVVVVVVVVVVVV 
  VVVVVVVVVVVVV  
   VVVVVVVVVVV   
    VVVVVVVVV    
     VVVVVVV     
      VVVVV      
       VVV       
        V        

Ejemplos

Aquí están las salidas para N = 1 a 5. Tenga en cuenta que para N impar, el triángulo siempre debe ser la mitad más grande.

V

((
VV

(((
VVV
 V 

 (( 
((((
VVVV
 VV 

 ((( 
(((((
VVVVV
 VVV 
  V  

Aquí hay una N = 101 pastebin.

Y aquí hay una implementación de referencia de Python 3 sin golf:

N = int(input())
ic = [[' '] * N for _ in range(N)]
for y in range(N//2):
    for x in range(N):
        if (x - (N - 1) / 2)**2 + (y - (N - 1) / 2)**2 < (N / 2)**2:
            ic[y][x] = '('
for y in range(N//2, N):
    for x in range(y - N//2, N - (y - N//2)):
        ic[y][x] = 'V'
for line in ic:
    print(''.join(line))

Detalles

  • Tome la entrada de stdin, línea de comando o como argumento de función. Salida a stdout o similar, o puede devolver la cadena si escribe una función.
  • La porción del cono debe coincidir exactamente con la implementación de referencia para todos los N.
  • La porción de helado no necesita coincidir exactamente con la implementación de referencia, siempre y cuando tenga claramente la forma de un semicírculo para todo N. (Esto es para que no tenga que preocuparse por pequeñas diferencias en el semicírculo debido a errores de redondeo .)
  • No debe haber espacios iniciales innecesarios, pero puede haber espacios finales superfluos.
  • La salida puede contener opcionalmente una nueva línea final.
  • Opcionalmente, puedes usar cualquier otro 3 distintas ASCII imprimibles caracteres en lugar de (, Vy espacio.

Puntuación

La presentación más corta en bytes gana. Tiebreaker va a la presentación más antigua.

Pasatiempos de Calvin
fuente
66
¿Soy el único que pensó "IceCII ASCream" cuando leí el título?
Sp3000
15
@ Sp3000 Jeez, eso espero ...
Calvin's Hobbies

Respuestas:

7

CJam, 46 bytes

Pruébalo en línea.

{:Z{Z{Z(2./:R-zYR<):P#YR-zP#+Z2./P#>SP?}/N}fY}

Creo que actualmente imita exactamente la especificación original, que era necesaria cuando comencé a producir esta respuesta. Puede existir la posibilidad de ahorrar algunos bytes haciendo que las matemáticas sean menos precisas para la especificación original, pero hasta que vea una manera de guardar más de uno o dos bytes, lo dejaré tal cual.

Explicación

{               "Begin block";
  :Z{             "For each y from 0 to input-1";
    Z{              "For each x from 0 to input-1";
      Z(2./:R         "Calculate the radius as (input-1)/2.0";
      -z              "Calculate the horizontal distance from the center";
      YR<):P          "Calculate the power to raise distances to: (y<radius)+1
                       (This results in Euclidean distance being calculated for
                        the ice cream and Manhattan distance being calculated
                        for the cone)";
      #               "Raise the horizontal distance to the determined power";
      YR-zP#          "Calculate the vertical distance from the center and
                       raise it to the determined power";
      +               "Add the horizontal and vertical distances";
      Z2./P#          "Calculate the solid distance threshold and raise it to
                       the determined power";
      >SP?            "If the solid threshold is exceeded, produce a space;
                       otherwise, produce the determined power digit
                       (This results in ice cream being represented by the
                        digit '2' and the cone by the digit '1')";
    }/              "End x loop";
    N               "Produce a new line";
  }fY             "End y loop";
}               "End block";
Runer112
fuente
Esto parece usar 2'sy 1' en lugar de( 'sy V' s?
Mark Reed
@ MarkReed Esto está permitido. Última línea en la sección de detalles.
Jakube
3

inca2 129 129 123 121 111 107

Esto usa principalmente las fórmulas del ejemplo de Python, pero usa jot-dots e iotas en lugar de doble bucle. La ifunción realiza la prueba circular para la jfunción que invoca jot-dot sobre ella. Y la kfunción realiza la prueba de triángulo para la lfunción. La cfunción clasifica los resultados de jy ly los rediseña a N × N.

editar: -6 combinar 2 mapas en 1.
editar: -2 eliminar enredos inútiles.
editar: mejor mecanografiado.
editar: -10 aplica expresiones repetidas en forma de matriz.
editar: -4 factorizar la expresión repetida como una función.
editar: comentario línea por línea.

q:y-(n-1)%2
i:[((n%2)^2)>+/(qx y)^2
j:(~[y%2)i.(~y)
k:2*[x>[|qy
l:(@1+~]y%2)k.(~y)
c:y y#((jn<y),ly){' (V' 

Más detalladamente, el punto de entrada es la cfunción que toma un argumento implícitamente nombrado y.

c:y y#((jn<y),ly){' (V' 
         n<y            } assign y to 'n'
        jn<y            } call j(y)
              ly        } call l(y)
      ((    ),  )       } catenate the results
      (         ){' (V' } map 0 1 2 to ' ' '(' 'V'
  y y#                  } reshape to NxN

La jfunción recibe el mismo valor de entrada que su yparámetro.

j:(~[y%2)i.(~y)
     y%2         } y divided by 2
    [            } floor
   ~             } iota. this generates the row indices 0..y/2
            ~y   } iota y. this generates the column indices 0..y
  (     )i.(  )  } jot-dot with the function i

El punto jot aquí hace el doble bucle. Llama a la ifunción con cada combinación de elementos de las matrices izquierda y derecha (0..n / 2 y 0..n). Entonces eli función recibe como xel índice y de la tabla, y recibe como yel índice x . Los nombres se pusieron un poco al revés aquí :).

i:[((n%2)^2)>+/(qx y)^2
     n%2                 } n divided by 2
    (n%2)^2              } squared
                 x y     } make a 2-element array (x,y)
                qx y     } call q on this array

donde qhace

q:y-(n-1)%2
     n-1    } n minus 1
         %2 } divided by 2
  y-        } y minus that

de regreso i

i:[((n%2)^2)>+/(qx y)^2
               (    )^2  } square the result from q(x,y)
             +/          } sum the two numbers
            >            } compare the left side (above) with the right (=> 0/1)
  [                      } floor

El piso no debería ser necesario. Pero aparentemente hay un error en el intérprete.

La lfunción funciona de manera similar a la jfunción, utilizando un punto de jot.

l:(@1+~]y%2)k.(~y)
        y%2         } y divided by 2
       ]            } ceiling
      ~             } iota 0..ceil(y/2)-1
    1+              } add 1 => 1..ceil(y/2)
   @                } reverse => ceil(y/2)..1
               ~y   } iota y  0..y-1
  (        )k.(  )  } jot-dot using k

La kfunción produce un valor booleano escalado en 2 para que los valores se puedan distinguir de los valores de helado más adelante, en el mapeo.

k:2*[x>[|qy
     x       } k's left arg
         qy  } y-(n-1)%2
        |    } abs
       [     } floor
     x       } left-hand-side again
      >      } compare 
    [        } floor (should be unnecessary)
  2*         } scale by 2

En acción (canalizando trpara eliminar los caracteres de tabulación que son la solicitud de REPL):

josh@Z1 ~/inca
$ ./inca2 <icecream | tr -d '\t'

c1
V

c2
((
VV

c3
(((
VVV
 V 

c4
 (( 
((((
VVVV
 VV 

c5
 ((( 
(((((
VVVVV
 VVV 
  V  

josh@Z1 ~/inca
$ 
luser droog
fuente
2

Pitón 2, 193 192

No usa cadenas, solo matemáticas

N=input()
R=(N+1)/2;r=range(R)
s=lambda L,U:(10**U-10**L)/9
f=lambda N,m:s(0,N)+s(m,N-m)
g=lambda N,m:s(0,N)+s(m,N-m)*6
for i in r[1:]:print f(N,int(R-(2*R*i-i*i)**.5))
for i in r:print g(N,i)

s(L,U)devuelve un número de la forma " U-dígitos con los Lceros más a la derecha y los restantes"
f(N,m)devuelve un número de N dígitos con la sección interna de 2y un borde de ancho m de 1cada lado
g(N,m)hace lo mismo, pero usando7 para el 'color' de la sección interior, ya que coincide más con la textura del cono

Salida

N=8         N=9
11122111    112222211
12222221    122222221
22222222    222222222
22222222    222222222
77777777    777777777
17777771    177777771
11777711    117777711
11177111    111777111
            111171111
DenDenDo
fuente
Una forma muy única de hacerlo :)
Calvin's Hobbies
Si solo pudiéramos ver el helado también: P
Optimizer
2

Perl 6, 175

Implementación bastante sencilla sin mucho golf, solo espacios en blanco extraños / eliminación de puntuación:

sub MAIN($d){my$r=($d/2).Int;for 1..$r ->$n
{my$y=$n-$r;my$h=sqrt($r*$r-$y*$y).Int;my$w=2*$h+$d%2;say
' 'x($r-$h)~'('x$w};for 1..($d-$r) ->$y {say ' 'x($y-1)~'V'x($d-2*$y+2)}}
Mark Reed
fuente