Programación de Cebolla

22

Usando solo ASCII imprimible (códigos hexadecimales 20 a 7E), escriba un programa central cuadrado N × N sin comentarios que esté rodeado por 4 capas más , creando un programa cuadrado (N + 8) × (N + 8) cuadrado (N> 0) . Para N = 3, el diseño (para ser reemplazado por el código real) se ve así:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • Las C representan el núcleo del programa 3 × 3.
  • Los 1 representan la primera capa, los 2 representan la segunda capa, etc.

El programa siempre toma una cadena de enteros separados por espacios, como a 0 -1 31 -1 2 2 2través de stdin o similar (solo deben ser números simples, sin comillas ni corchetes ni nada). El resultado depende de qué partes del diseño se ejecutaron.

Hay cinco formas de ejecutar el programa (se incluyen nuevas líneas en la ejecución). Cada uno hace algo diferente a la lista:

  1. Ejecute solo el núcleo:

    CCC
    CCC
    CCC
    

    Esto calcula el máximo de los valores absolutos de los elementos de la lista de entrada e imprime COREen una nueva línea muchas veces. Si el máximo es 0, no se emite nada (una nueva línea está bien).

    • La salida para 0 -1 31 -1 2 2 2sería

      CORE
      CORE
      ...
      

      31 veces

  2. Ejecute el núcleo con la capa 1:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    Esto genera el promedio (media aritmética ) de los valores de la lista con precisión de coma flotante estándar.

    • La salida para 0 -1 31 -1 2 2 2sería 35/7 = 5( 5.0está bien).
  3. Ejecute el núcleo con las capas 1 y 2:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    Esto genera una lista separada por espacios de la lista de entrada invertida.

    • La salida para 0 -1 31 -1 2 2 2sería 2 2 2 -1 31 -1 0.
  4. Ejecute el núcleo con las capas 1, 2 y 3 (el patrón debería ser obvio).
    Esto genera una lista separada por espacios de la lista de entrada ordenada.

    • La salida para 0 -1 31 -1 2 2 2sería -1 -1 0 2 2 2 31.
  5. Ejecute el núcleo con las capas 1, 2, 3 y 4.
    Esto genera una lista separada por espacios de la lista de entrada con los duplicados eliminados, el orden no importa.

    • La salida para 0 -1 31 -1 2 2 2podría ser -1 0 2 31.

Todo el resultado es stdout o una alternativa similar.

Solo estas 5 combinaciones de diseño tienen un comportamiento específico.

Notas

  • No se permiten comentarios en el núcleo o capas o combinaciones de los mismos. El código que no funciona o que no hace nada constructivo no cuenta como un comentario.
  • Recuerde que el núcleo puede tener cualquier dimensión N × N (positiva), pero las capas tienen solo un carácter de grosor.
  • Puede suponer que la entrada no tiene espacios iniciales o finales y exactamente un espacio entre los números. Siempre contendrá al menos un número. (Las listas de salida también deberían estar formateadas de esta manera).
  • Puede suponer que la lista y los cálculos necesarios para la salida no tendrán valores que desborden (o desborden) sus enteros (siempre que su máximo sea algo razonable como 2 16 ).

Tanteo

Escribir este programa normalmente sería fácil. Escribirlo con un núcleo pequeño es difícil.

El programa con el tamaño de núcleo más pequeño (el N más pequeño) gana. En caso de empate, el ganador es el programa completo (el cuadrado (N + 8) × (N + 8)) con la menor cantidad de caracteres distintos (sin contar líneas nuevas).

Informe su valor de N en la parte superior de su respuesta.

Pasatiempos de Calvin
fuente
1
Pensé que este también sería otro de esos nuevos tipos
Optimizer,
¿Puedo usar un lenguaje que ignore todo después de una nueva línea?
isaacg
1
@isaacg Sí (siempre que la nueva línea no se considere el carácter de comentario, lo que sería extraño).
Aficiones de Calvin
3
@Optimizer No me tientes ... " Cada respuesta agrega una nueva capa a la cebolla de código para que haga algo nuevo con la lista ... "
Pasatiempos de Calvin
1
@Optimizer No. (Sé que estas reglas de E / S son un poco duras, pero eso es para mantener las cosas consistentes en todos los idiomas)
Calvin's Hobbies

Respuestas:

10

CJam, N = 5, 27 (26) caracteres únicos

Son 26 caracteres si no cuento los espacios. El programa podría convertirse en uno que no use espacios, simplemente llenando todos los espacios vacíos con no-ops (por ejemplo, _;que duplica el elemento superior de la pila y luego los descarta, o ordenando la matriz una y otra vez), pero solo distraería del código real.

l~]_|S*      
{l~]$S*      
 {l~]W%S*    
  {l~]_,\    
   {l~]{z    
    }%$W=    
    "CORE    
    "*       
         }   
   ;:+d\/ }  
  ;        } 
 ;          }
;            

Pruébalo aquí.

El núcleo es

l~]{z
}%$W=
"CORE
"*

(Más una línea vacía).

Estoy bastante seguro de que N = 4no se puede hacer en CJam (y estoy seguro de que Dennis me convencerá de lo contrario: D). Lo anterior tiene 17 caracteres, y si bien es posible reducirlo a 16 (por ejemplo, si CJam no tuvo un error para atragantarse :z, lo que requiere {z}%, o usando ARGV), no creo que pueda encajarlo en el diseño sin introducir un salto de línea dentro CORE.

Todas las implementaciones son soluciones muy sencillas para las tareas dadas. Todos comienzan con lo l~]que lee STDIN, lo evalúa y lo coloca en una matriz.

La capa anterior siempre está rodeada {...}, lo que la convierte en un bloque que no se ejecuta automáticamente. Y en lugar de ejecutarlo, simplemente lo descarto de la pila ;, por lo que ninguna capa depende del código de la capa anterior. En la Capa 1, el código no encajaba en la primera línea, así que lo continué después de descartar el bloque central.

Ahora para los programas actuales:

  • Núcleo:

    {z}%$W="CORE
    "*
    

    Asigne absen la lista, ordénelo, tome el último elemento, repita CORE(y un salto de línea) muchas veces.

  • Capa 1:

    _,\:+d\/
    

    Duplique la lista, tome la longitud, intercambie los elementos de la pila, obtenga la suma, eche a double la pila, divida. Creo que esto puede ser más corto, pero no hay incentivo para hacerlo.

  • Capa 2:

    W%S*
    

    Invierta la matriz, riffle con espacios.

  • Capa 3:

    $S*
    

    Ordenar la matriz, revolver con espacios.

  • Capa 4:

    Duplicar, tomar set union, revolver con espacios.

Algunas otras optimizaciones también son posibles, como reutilizar el ;y *Sde la capa 2, pero nuevamente, pero no afecta la puntuación.

Martin Ender
fuente
17

Python 2 - N = 17, 53 caracteres

Oh, me encantan los desafíos de diseño de fuente con Python ...

i=4                     ;
ii=3                    ;
iii=2                   ;
iiii=1                  ;
iiiii=0;R=raw_input     ;
iiiii;w=R().split()     ;
iiiii;n=map(int,w)      ;
iiiii;S=set(n);M=max    ;
iiiii;s=sorted(n)       ;
iiiii;J="\n".join       ;
iiiii;j=" ".join        ;
iiiii;k=M(map(abs,n))   ;
iiiii;A=J(["CORE"]*k)   ;
iiiii;B=sum(n)/len(n)   ;
iiiii;C=j(w[::-1])      ;
iiiii;D=j(map(str,s))   ;
iiiii;E=j(map(str,S))   ;
iiiii;P=A,B,C,D,E       ;
iiiii;print P[i]        ;
iiiii;" /__----__\  "   ;
iiiii;"|/ (')(') \| "   ;
iiii;"  \   __   /  "   ;
iii;"   ,'--__--'.   "  ;
ii;"   /    :|    \   " ;
i;"   (_)   :|   (_)   ";

Sin embargo, todavía hay algunos espacios en blanco no utilizados.

Todavía podría mejorar el recuento de caracteres únicos, pero me quedaré con una mejor legibilidad, si es que hay alguna.

Editar: ¡Oh, es Stan otra vez !

Falko
fuente
Probablemente pueda guardar algunas líneas aliasing print en lugar del i=*truco
M.Herzkamp
@ M.Herzkamp: Aliasing printno es posible con Python 2. Pero claro, probablemente hay margen de mejora, tal vez usando Python 3.
Falko
No sé Python, pero no es este valor falta absoluta en la salida del código del núcleo -c*max(n)
nutki
@nutki: ¡Tienes razón! No leí con cuidado. Pero pude arreglarlo.
Falko
6

Python 3: N = 11, 40 caracteres distintos

if 1:              
 if 1:             
  if 1:            
   if 1:           
    p=print;R=0    
    a=input()      
    b=a.split()    
    m=map;a=abs    
    E=max;l=len    
    n=m(int,b);    
    C=['CORE']     
   "R=E(m(a,n))"   
   OO=C*R;s=sum    
   "x='\n'.join"   
   "p(x(O))    "   
  "p(s(n)/l(b)) "  
 "p(*b[::-1])    " 
"p(*sorted(n))    "
p(*set(n))         

Gracias a @Falko por ser mi musa. Esto funciona, porque Python no crea un nuevo alcance para cada instrucción if, por lo que las variables persisten en las printdeclaraciones externas . Una cosa molesta es que un mapobjeto (en nuestro caso n) solo se puede usar una vez. Por lo tanto, era necesario tender la R=E(...)línea, pero luego Rno se definió. ¡Por lo tanto, tuve la suerte de que quedaran cuatro espacios en la primera línea!

La salida se puede resolver proporcionando múltiples elementos en *b[::-1]lugar de la lista. La alternativa ' '.join(...)habría sido demasiado larga.

M.Herzkamp
fuente
¡Hermosa! Es bueno ver un enfoque alternativo para tratar con inicios de línea variables en python. Solo algunas declaraciones if cortas y todos esos espacios están bien. :)
Falko
@Falko: La desventaja es que no hay espacio para Stan :(
M.Herzkamp
2

C (gcc) , N = 15, 47 caracteres únicos

Asume sizeof(int) == 4y sizeof(int*) >= sizeof(int).

;                     ;
 ;                   ; 
  ;                 ;  
   ;           float   
    s;c(a,b)int*a,*    
    b;{b=*b-*a;}i,n    
    ,*f;*q,*R,C,E ;    
    main(a){for(;0<    
    scanf("%i",&a);    
    i=i<abs(a)?a:i,    
    s+=f[n-!0]=a)f=    
    realloc(f,++n*4    
    );qsort(f,n*C,4    
    ,c);for(i=q?R?n    
    :!0:i;i--;a=f[i    
    ])!E|n-i<2|a!=f    
    [i]&&printf(q?R    
    ?R:q:"CORE\n",!    
    q+R?f[i]:s/n);}    
   ;*q="%f";       ;   
  ;*R="%.0f ";      ;  
 ;C=!0;              ; 
;E=!0;                ;

4 capas

3 capas

2 capas

1 capa

Núcleo

gastropner
fuente
0

Encantamientos rúnicos , N = 9 N = 8, 38 caracteres

/ o/\  \     \S\
" //RiU\      \}
@            q "
"        }+1\r @
}   ^U \    {q "
     \{\?)}\+  }
  o\/'|A:{:/R' S
 //r/Ril2=?\?R :
   ,A~/"OC"/=? {
   @| \"RE"\3= =
 D$\' /rqka/l2S?
    i \*@   il\/
   'R1i     Ui ~
 R$/Rak      U \
 ?!D  Rlril1-{=
R   R: }S:{=?\~

Pruébalo en línea!

Resulta que estaba equivocado , olvidé que ya tenía un ocomando s rt explícito , debido a que había encontrado antes el problema de "ordenar una lista". Sin embargo, esto limita el tamaño de las entradas que el programa final puede tomar (8 valores) debido a los costos internos del comando de clasificación. Un ligero ajuste puede aumentar el tamaño de entrada a 13 a costa de 1 carácter único o a 19 para dos caracteres únicos (todos los caracteres adicionales están en la Capa 1 y se agregan al mismo tiempo, pero la mayor capacidad de la pila de IP no es necesario hasta la capa 3, ya que C, L1 y L2 pueden realizar sus cálculos sin mantener toda la entrada en la memoria).

Core: ¡ Pruébelo en línea!

Capa 1: ¡ Pruébelo en línea!

Capa 2: ¡ Pruébelo en línea!

Capa 3: Pruébelo en línea!

Capa 4: ¡ Pruébelo en línea!

La compresión adicional es altamente improbable, debido al espacio más pequeño que requiere un aumento en el número de caracteres de control de flujo. Encontré una disposición que daba 9 espacios vacíos en el programa principal, pero eso no es suficiente, ya que necesitamos (una disposición correcta) 15.

Explicar cómo funciona cualquiera de estos programas es difícil sin un mapa visual del camino que toma la IP, que es engorroso y requiere mucho tiempo de construcción. El punto de entrada inicial es la esquina superior izquierda del programa Core ( ^) que permite un control de flujo constante a medida que se agregan nuevas capas, ya que cada capa tiene la oportunidad de interceptar en la línea recién agregada en la parte superior o inferior.

Las capas 1 y 2 interceptan en la parte inferior (para que la línea superior permanezca vacía para futuras capas) y luego realizan sus operaciones a lo largo del borde derecho (un bucle dispuesto verticalmente). La capa 1 es un poco demasiado larga y también tiene 3 caracteres a lo largo del borde superior, pero el reflector diagonal (\ ) en la esquina superior derecha vuelve a alinear la IP con la siguiente iteración del bucle.

La capa 3 intercepta a lo largo del borde superior para tomar el primer valor de entrada antes de redirigir al borde inferior (la capa 4 deja un NOP en esta columna en su línea inferior) y lee la entrada completa usando el bucle del borde inferior, redirigiendo hacia abajo comando ( D) en la esquina inferior izquierda. A partir de ahí, la IP rebota varias veces antes de terminar en un $bucle de salida ( ) en la esquina inferior izquierda para separar los valores.

La capa 4 utiliza toda la funcionalidad de la capa 3 (de ahí el espacio en blanco), pero intercepta en su nuevo borde superior (superior izquierdo) para realizar su propia funcionalidad al final del procesamiento de la capa 3. La esquina superior izquierda inserta una cadena"@" que se utiliza para denotar el final de la matriz antes de ingresar al ciclo de procesamiento en la parte inferior. Si se encuentra un valor duplicado, aparece ( ~esquina inferior derecha); de lo contrario, se toma la rama que consume el nuevo borde derecho. Esta rama lateral verifica si se ha alcanzado el final de la matriz y, en caso afirmativo, salga y diríjase al mismo bucle de salida separado por espacios de la Capa 3. De lo contrario, use el espacio en blanco en la Capa 3 para volver a la página principal. lazo.

Draco18s
fuente