Programação de Cebola


22

Usando apenas ASCII imprimível (códigos hexadecimais 20 a 7E), escreva um programa central N × N quadrado sem comentários, cercado por mais 4 camadas , criando um programa quadrado (N + 8) × (N + 8) (N> 0) . Para N = 3, o layout (a ser substituído pelo código real) fica assim:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • Os C representam o programa principal 3 × 3.
  • Os 1s representam a primeira camada, os 2 representam a segunda camada, etc.

O programa sempre usa uma sequência de números inteiros separados por espaço, como 0 -1 31 -1 2 2 2via stdin ou similar (devem ser apenas números simples, sem aspas ou colchetes ou algo assim). A saída depende de quais partes do layout foram executadas.

Existem cinco maneiras de executar o programa (novas linhas estão incluídas na execução). Cada um faz algo diferente da lista:

  1. Execute apenas o núcleo:

    CCC
    CCC
    CCC
    

    Isso calcula o máximo dos valores absolutos dos elementos da lista de entrada e imprime COREem uma nova linha várias vezes. Se o máximo for 0, nada será emitido (uma nova linha está correta).

    • A saída para 0 -1 31 -1 2 2 2seria

      CORE
      CORE
      ...
      

      31 vezes.

  2. Execute o núcleo com a camada 1:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    Isso gera a média (média aritmética ) dos valores da lista com precisão padrão de ponto flutuante.

    • A saída para 0 -1 31 -1 2 2 2seria 35/7 = 5( 5.0está correta).
  3. Execute o núcleo com as camadas 1 e 2:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    Isso gera uma lista separada por espaço da lista de entrada invertida.

    • A saída para 0 -1 31 -1 2 2 2seria 2 2 2 -1 31 -1 0.
  4. Execute o núcleo com as camadas 1, 2 e 3 (o padrão deve ser óbvio).
    Isso gera uma lista separada por espaços da lista de entradas classificadas.

    • A saída para 0 -1 31 -1 2 2 2seria -1 -1 0 2 2 2 31.
  5. Execute o núcleo com as camadas 1, 2, 3 e 4.
    Isso gera uma lista separada por espaço da lista de entradas com duplicatas removidas, a ordem não importa.

    • A saída para 0 -1 31 -1 2 2 2poderia ser -1 0 2 31.

Toda saída é para stdout ou uma alternativa semelhante.

Somente essas 5 combinações de layout especificaram o comportamento.

Notas

  • Comentários não são permitidos no núcleo ou nas camadas ou combinações dos mesmos. Código que não é operacional ou não faz nada construtivo não conta como comentário.
  • Lembre-se de que o núcleo pode ter qualquer dimensão N × N (positiva), mas as camadas têm apenas um caractere de espessura.
  • Você pode assumir que a entrada não possui espaços à esquerda ou à direita e exatamente um espaço entre os números. Sempre conterá pelo menos um número. (As listas de saída também devem ser formatadas dessa maneira.)
  • Você pode assumir que a lista e os cálculos necessários para a saída não terão valores que excedam (ou subcorrem) seus números inteiros (desde que o máximo seja algo razoável como 2 16 ).

Pontuação

Escrever este programa normalmente seria fácil. Escrever com um núcleo pequeno é difícil.

O programa com o menor tamanho de núcleo (o menor N) vence. Em caso de empate, o vencedor é o programa completo (o quadrado (N + 8) × (N + 8)) com o menor número de caracteres distintos (sem contar as novas linhas).

Por favor, reporte o seu valor N na parte superior da sua resposta.


1
Eu pensei que este também seria outro desses novos tipos
Optimizer

Posso usar um idioma que ignore tudo após uma nova linha?
Isaacg #

1
@isaacg Sim (desde que a nova linha não seja considerada o caractere de comentário, o que seria estranho).
Passatempos de Calvin

3
@Optimizer Não me tente ... " Cada resposta adiciona uma nova camada à cebola do código, para fazer algo novo com a lista ... "
Calvin's Hobbies

1
@Optimizer No. (Eu sei que estas i / o regras são meio duro, mas isso é para manter as coisas consistente em línguas.)
de Calvino Hobbies

Respostas:


10

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

São 26 caracteres se não contar os espaços. Na verdade, o programa pode ser convertido em um que não use espaços, preenchendo todos os espaços vazios com no-ops (por exemplo, _;que duplica o elemento da pilha superior e depois descarta ou classificando a matriz repetidamente), mas apenas distrairia o código real.

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

Teste aqui.

O núcleo é

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

(Mais uma linha vazia.)

Tenho certeza de que isso N = 4não pode ser feito no CJam (e tenho certeza de que Dennis me convencerá do contrário: D). O texto acima possui 17 caracteres e, embora seja possível reduzi-lo a 16 (por exemplo, se o CJam não tiver um bug para engasgar :z, o que exige {z}%ou usando o ARGV), acho que você não pode ajustá-lo. no layout sem introduzir uma quebra de linha CORE.

Todas as implementações são soluções muito diretas para as tarefas fornecidas. Todos eles começam com o l~]que lê STDIN, avalia e coloca em uma matriz.

A camada anterior é sempre cercada {...}, o que a torna um bloco que não é executado automaticamente. E, em vez de executá-lo, apenas o descarto da pilha com ;, portanto, nenhuma camada depende do código da camada anterior. Na Camada 1, o código não se encaixava na primeira linha, então continuei depois de descartar o bloco principal.

Agora, para os programas atuais:

  • Testemunho:

    {z}%$W="CORE
    "*
    

    Mapeie abspara a lista, classifique-a, pegue o último elemento, repita CORE(e uma quebra de linha) várias vezes.

  • Camada 1:

    _,\:+d\/
    

    Duplique a lista, calcule o comprimento, troque os elementos da pilha, obtenha a soma, faça a doubleconversão para , troque os elementos da pilha, divida. Eu acho que isso pode ser mais curto, mas não há incentivo para isso.

  • Camada 2:

    W%S*
    

    Inverta a matriz, corrija com espaços.

  • Camada 3:

    $S*
    

    Classifique a matriz, corrija com espaços.

  • Camada 4:

    Duplicar, tomar conjunto união, riffle com espaços.

Algumas outras otimizações também são possíveis, como a reutilização da ;e *Sda Camada 2, mas novamente, mas isso não afeta a pontuação.


17

Python 2 - N = 17, 53 caracteres

Ah, eu adoro desafios de layout de código-fonte com 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;"   (_)   :|   (_)   ";

Ainda há algum espaço em branco não utilizado.

Eu ainda poderia melhorar a contagem de caracteres únicos, mas continuarei com uma melhor legibilidade - se houver alguma.

Edit: Oh, é Stan novamente !


Você provavelmente pode salvar algumas linhas por aliasing de impressão em vez do i=*truque
M.Herzkamp

@ M.Herzkamp: Aliasing printnão é possível com Python 2. Mas com certeza, provavelmente há espaço para melhorias - talvez usando Python 3.
Falko

Eu não sei Python, mas não é esse valor em falta absoluta na saída código do núcleo -c*max(n)
nutki

@nutki: Você está certo! Eu não li com atenção. Mas eu consegui consertar isso.
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))         

Obrigado a @Falko por ser minha musa. Isso funciona, porque o Python não cria um novo escopo para cada instrução if, portanto, as variáveis ​​persistem nas printinstruções externas . Uma coisa irritante é que um mapobjeto (no nosso caso n) pode ser usado apenas uma vez. Portanto, foi necessário definir a R=E(...)linha, mas Rnão foi definido. Por isso, tive sorte de restar quatro espaços na primeira linha!

A saída pode ser resolvida fornecendo vários elementos em *b[::-1]vez da lista. A alternativa ' '.join(...)teria sido muito longa.


Lindo! É bom ver uma abordagem alternativa para lidar com o início de linhas variáveis ​​em python. Apenas algumas declarações if curtas e todos esses espaços estão bem. :)
Falko

@Falko: A desvantagem é: não há espaço para Stan :(
M.Herzkamp

2

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

Assume sizeof(int) == 4e 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 Camadas

3 camadas

2 camadas

1 camada

Testemunho


0

Encantos 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:{=?\~

Experimente online!

Acontece que eu estava errado , esqueci que já tinha um ocomando s rt explícito , por ter encontrado o problema "classificar uma lista" antes. No entanto, isso limita o tamanho das entradas que o programa final pode receber (8 valores) devido aos custos internos do comando de classificação. Um pequeno ajuste pode aumentar o tamanho da entrada para 13 ao custo de 1 caractere único ou para 19 para dois caracteres únicos (todos os caracteres adicionais estão na Camada 1 e são adicionados ao mesmo tempo, mas a capacidade aumentada da pilha do IP não é necessário até a camada 3, pois C, L1 e L2 podem executar seus cálculos sem reter toda a entrada na memória).

Núcleo: Experimente online!

Camada 1: Experimente online!

Camada 2: Experimente online!

Camada 3: Experimente online!

Camada 4: Experimente online!

Uma compactação adicional é altamente improvável, devido ao menor espaço que requer um aumento no número de caracteres de controle de fluxo. Encontrei um arranjo que dava 9 espaços vazios no programa principal, mas isso não é suficiente, pois precisamos (um arranjo correto) 15.

Explicar como qualquer um desses programas funciona é difícil sem um mapa visual do caminho que o IP adota, o que é complicado e demorado de construir. O ponto de entrada inicial é o canto superior esquerdo do programa Core ( ^), que permite um controle de fluxo consistente à medida que novas camadas são adicionadas, pois cada camada tem a oportunidade de interceptar a linha recém-adicionada na parte superior ou inferior.

As camadas 1 e 2 interceptam na parte inferior (para que a linha superior permaneça vazia para futuras camadas) e, em seguida, executam suas operações ao longo da borda direita (um loop organizado verticalmente). A camada 1 é um pouco longa demais e leva 3 caracteres ao longo da borda superior, mas o refletor diagonal ( \) no canto superior direito realinha o IP com a próxima iteração de loop.

A camada 3 intercepta ao longo da borda superior para capturar o primeiro valor de entrada antes de redirecionar para a borda inferior (a Camada 4 deixa um NOP nesta coluna em sua linha inferior) e lê a entrada completa usando o loop da borda inferior, redirecionando para baixo command ( D) no canto inferior esquerdo. A partir daí, o IP salta algumas vezes antes de terminar em um $loop de saída ( ) no canto inferior esquerdo para separar os valores em espaço.

A camada 4 utiliza toda a funcionalidade da camada 3 (daí o espaço em branco), mas intercepta em sua própria nova borda superior (canto superior esquerdo) para executar sua própria funcionalidade no final do processamento da camada 3. O canto superior esquerdo insere uma string "@"que é usada para indicar o final da matriz antes de inserir o loop de processamento na parte inferior. Se um valor duplicado for encontrado, ele será exibido ( ~canto inferior direito), caso contrário, será feita a ramificação que consome a nova borda direita. Essa ramificação lateral verifica se o final da matriz foi atingido e, se for o caso, interrompa e siga para o mesmo loop de saída separado por espaço da Camada 3. Caso contrário, use o espaço em branco na Camada 3 para retornar à página principal. loop.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.