Programmation de l'oignon

22

En utilisant uniquement ASCII imprimable (codes hexadécimaux 20 à 7E), écrivez un programme de base carré N × N sans commentaires qui est entouré de 4 couches supplémentaires , créant un programme carré (N + 8) × (N + 8) (N> 0) . Pour N = 3, la présentation (à remplacer par le code réel) ressemble à ceci:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • Les C représentent le programme de base 3 × 3.
  • Les 1 représentent la première couche, les 2 représentent la deuxième couche, etc.

Le programme prend toujours une chaîne d'entiers séparés par des espaces tels que 0 -1 31 -1 2 2 2via stdin ou similaire (il ne doit s'agir que de chiffres simples, sans guillemets ou crochets ou quoi que ce soit). La sortie dépend des parties de la mise en page qui ont été exécutées.

Il existe cinq façons d'exécuter le programme (les sauts de ligne sont inclus dans l'analyse). Chacun fait quelque chose de différent de la liste:

  1. Exécutez juste le noyau:

    CCC
    CCC
    CCC
    

    Cela calcule le maximum des valeurs absolues des éléments de la liste d'entrée et imprime COREsur une nouvelle ligne autant de fois. Si le max est 0, rien n'est sorti (une nouvelle ligne est très bien).

    • La sortie pour 0 -1 31 -1 2 2 2serait

      CORE
      CORE
      ...
      

      31 fois.

  2. Exécutez le noyau avec la couche 1:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    Cela génère la moyenne (moyenne arithmétique ) des valeurs de liste avec une précision standard en virgule flottante.

    • La sortie pour 0 -1 31 -1 2 2 2serait 35/7 = 5( 5.0c'est bien).
  3. Exécutez le noyau avec les couches 1 et 2:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    Cela génère une liste séparée par des espaces de la liste d'entrée inversée.

    • La sortie pour 0 -1 31 -1 2 2 2serait 2 2 2 -1 31 -1 0.
  4. Exécutez le noyau avec les couches 1, 2 et 3 (le motif doit être évident).
    Cela génère une liste séparée par des espaces de la liste d'entrée triée.

    • La sortie pour 0 -1 31 -1 2 2 2serait -1 -1 0 2 2 2 31.
  5. Exécutez le noyau avec les couches 1, 2, 3 et 4.
    Cela génère une liste séparée par des espaces de la liste d'entrée avec les doublons supprimés, l'ordre n'a pas d'importance.

    • La sortie pour 0 -1 31 -1 2 2 2pourrait être -1 0 2 31.

Toutes les sorties sont vers stdout ou une alternative similaire.

Seules ces 5 combinaisons de disposition ont un comportement spécifié.

Remarques

  • Les commentaires ne sont pas autorisés dans le noyau ou les couches ou leurs combinaisons. Un code qui est un no-op ou qui ne fait rien de constructif ne compte pas comme un commentaire.
  • N'oubliez pas que le noyau peut avoir n'importe quelle dimension (positive) N × N, mais les couches n'ont qu'un caractère.
  • Vous pouvez supposer que l'entrée n'a pas d'espaces de début ou de fin et exactement un espace entre les nombres. Il contiendra toujours au moins un chiffre. (Les listes de sortie doivent également être formatées comme ceci.)
  • Vous pouvez supposer que la liste et les calculs nécessaires pour la sortie n'auront pas de valeurs qui débordent (ou dépassent) vos entiers (tant que leur max est quelque chose de raisonnable comme 2 16 ).

Notation

Écrire ce programme serait normalement facile. L'écrire avec un petit noyau est difficile.

Le programme avec la plus petite taille de noyau (le plus petit N) gagne. En cas d'égalité, le gagnant est le programme complet (le carré (N + 8) × (N + 8)) avec le moins de caractères distincts (sans compter les nouvelles lignes).

Veuillez indiquer votre valeur N en haut de votre réponse.

Loisirs de Calvin
la source
1
Je pensais que ce serait aussi un autre de ces nouveaux types
Optimizer
Puis-je utiliser une langue qui ignore tout après une nouvelle ligne?
isaacg
1
@isaacg Oui (tant que la nouvelle ligne n'est pas considérée comme le caractère de commentaire, ce qui serait bizarre).
Calvin's Hobbies
3
@Optimizer Ne me tentez pas ... " Chaque réponse ajoute une nouvelle couche à l'oignon de code pour qu'elle fasse quelque chose de nouveau avec la liste ... "
Calvin's Hobbies
1
@Optimizer No. (Je sais que ces règles d'E / S sont un peu dures mais c'est pour garder les choses cohérentes dans toutes les langues.)
Calvin's Hobbies

Réponses:

10

CJam, N = 5, 27 (26) caractères uniques

C'est 26 caractères si je ne compte pas les espaces. Le programme pourrait en fait être converti en un programme qui n'utilise pas d'espaces, en remplissant simplement tous les espaces vides sans opération (par exemple, _;qui duplique l'élément de pile supérieur puis les supprime, ou en triant le tableau encore et encore), mais il ne ferait que distraire du code réel.

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

Testez-le ici.

Le noyau est

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

(Plus une ligne vide.)

Je suis assez sûr que N = 4cela ne peut pas être fait dans CJam (et je suis sûr que Dennis me convaincra du contraire: D). Ce qui précède a 17 caractères, et bien qu'il soit possible de le ramener à 16 (par exemple, si CJam n'a pas eu de bug à étouffer :z, ce qui nécessite {z}%, ou en utilisant ARGV), je ne pense pas que vous puissiez l'adapter dans la mise en page sans introduire de saut de ligne CORE.

Toutes les implémentations sont des solutions très simples aux tâches données. Tous commencent par celui l~]qui lit STDIN, l'évalue et le place dans un tableau.

La couche précédente est toujours entourée {...}, ce qui en fait un bloc qui n'est pas exécuté automatiquement. Et au lieu de l'exécuter, je le jette simplement de la pile avec ;, donc aucune couche ne dépend du code de la couche précédente. Dans la couche 1, le code ne correspondait pas à la première ligne, donc je l'ai continué après avoir supprimé le bloc de base.

Maintenant pour les programmes réels:

  • Coeur:

    {z}%$W="CORE
    "*
    

    Mappez abssur la liste, triez-la, prenez le dernier élément, répétez CORE(et un saut de ligne) autant de fois.

  • Couche 1:

    _,\:+d\/
    

    Dupliquez la liste, prenez la longueur, permutez les éléments de la pile, obtenez la somme, transtypez double, permutez les éléments de la pile, divisez. Je pense que cela peut être plus court, mais il n'y a aucune incitation à le faire.

  • Couche 2:

    W%S*
    

    Inversez le tableau, riffle avec des espaces.

  • Couche 3:

    $S*
    

    Triez le tableau, riffle avec des espaces.

  • Couche 4:

    Dupliquer, prendre ensemble union, riffle avec des espaces.

D'autres optimisations sont également possibles, comme la réutilisation de ;et *Sde la couche 2, mais encore une fois, mais cela n'affecte pas le score.

Martin Ender
la source
17

Python 2 - N = 17, 53 caractères

Oh, j'adore les défis de mise en page avec 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;"   (_)   :|   (_)   ";

Il reste cependant des espaces inutilisés.

Je pourrais encore améliorer le nombre de caractères uniques, mais je resterai avec une meilleure lisibilité - s'il y en a du tout.

Edit: Oh, c'est encore Stan !

Falko
la source
Vous pouvez probablement enregistrer certaines lignes en aliasant print au lieu de l' i=*astuce
M.Herzkamp
@ M.Herzkamp: L'aliasing printn'est pas possible avec Python 2. Mais bien sûr, il y a probablement place à amélioration - peut-être en utilisant Python 3.
Falko
Je ne connais pas Python, mais cette valeur absolue n'est-elle pas manquante dans la sortie du code principal -c*max(n)
nutki
@nutki: Tu as raison! Je n'ai pas lu attentivement. Mais j'ai pu le réparer.
Falko
6

Python 3: N = 11, 40 caractères distincts

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

Merci à @Falko d'être ma muse. Cela fonctionne, car Python ne crée pas de nouvelle portée pour chaque instruction if, donc les variables persistent dans les printinstructions externes . Une chose ennuyeuse était qu'un mapobjet (dans notre cas n) ne peut être utilisé qu'une seule fois. Il était donc nécessaire de ficeler la R=E(...)ligne, mais cela Rn'a pas été défini. J'ai donc eu de la chance qu'il restait quatre espaces dans la première ligne!

La sortie peut être résolue en fournissant plusieurs éléments *b[::-1]au lieu de la liste. L'alternative ' '.join(...)aurait été trop longue.

M.Herzkamp
la source
Beau! C'est agréable de voir une approche alternative pour gérer les débuts de lignes variables en python. Juste quelques courtes instructions if et tous ces espaces sont très bien. :)
Falko
@Falko: L'inconvénient est: il n'y a pas de place pour Stan :(
M.Herzkamp
2

C (gcc) , N = 15, 47 caractères uniques

Suppose sizeof(int) == 4et 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 couches

3 couches

2 couches

1 couche

Coeur

gastropner
la source
0

Enchantements runiques , N = 9 N = 8, 38 caractères

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

Essayez-le en ligne!

Il s'est avéré que j'avais tort , j'ai oublié que j'avais déjà une ocommande s rt explicite , car j'avais déjà rencontré le problème "trier une liste". Cela limite cependant la taille des entrées que le programme final peut prendre (8 valeurs) en raison des coûts internes de la commande de tri. Un léger ajustement peut augmenter la taille d'entrée à 13 au prix d'un caractère unique ou à 19 pour deux caractères uniques (tous les caractères supplémentaires sont sur la couche 1 et ajoutés en même temps, mais la capacité accrue de la pile IP n'est pas nécessaire jusqu'à la couche 3, car C, L1 et L2 peuvent effectuer leurs calculs sans conserver la totalité de l'entrée en mémoire).

Core: Essayez-le en ligne!

Couche 1: Essayez-le en ligne!

Couche 2: Essayez-le en ligne!

Couche 3: Essayez-le en ligne!

Couche 4: Essayez-le en ligne!

Une compression supplémentaire est hautement improbable, en raison de l'espace plus petit nécessitant une augmentation du nombre de caractères de contrôle de flux. J'ai trouvé un arrangement qui a donné 9 espaces vides dans le programme de base, mais ce n'est pas suffisant, car nous en avons besoin (un correctement arrangé) 15.

Il est difficile d'expliquer comment l'un de ces programmes fonctionne sans une carte visuelle du chemin emprunté par l'IP, ce qui est fastidieux et long à construire. Le point d'entrée initial est le coin supérieur gauche du programme Core ( ^) qui permet un contrôle de flux cohérent à mesure que de nouvelles couches sont ajoutées, car chaque couche a la possibilité d'intercepter sur la ligne nouvellement ajoutée en haut ou en bas.

Les couches 1 et 2 interceptent en bas (de sorte que la ligne supérieure reste vide pour les couches futures), puis effectuent leurs opérations le long du bord droit (une boucle disposée verticalement). La couche 1 est légèrement trop longue et prend également 3 caractères le long du bord supérieur, mais le réflecteur diagonal ( \) en haut à droite réaligne l'IP avec l'itération de boucle suivante.

La couche 3 intercepte le long du bord supérieur afin de saisir la première valeur d'entrée avant de rediriger vers le bord inférieur (la couche 4 laisse un NOP dans cette colonne sur sa ligne inférieure) et lit l'entrée complète en utilisant la boucle du bord inférieur, en redirigeant vers le bas commande ( D) en bas à gauche. De là, l'IP rebondit plusieurs fois avant de se retrouver dans une $boucle de sortie ( ) en bas à gauche afin de séparer les valeurs.

La couche 4 utilise toutes les fonctionnalités de la couche 3 (d'où l'espace vide), mais intercepte sur son propre nouveau bord supérieur (en haut à gauche) afin d'exécuter sa propre fonctionnalité à la fin du traitement de la couche 3. Le coin supérieur gauche insère une chaîne "@"qui est utilisée pour indiquer la fin du tableau avant d'entrer dans la boucle de traitement en bas. Si une valeur en double est trouvée, elle est sautée ( ~, coin inférieur droit) sinon la branche est prise qui consomme le nouveau bord droit. Cette branche latérale vérifie si la fin du tableau a été atteinte, et si c'est le cas, éclatez et dirigez-vous vers la même boucle de sortie séparée par des espaces de la couche 3. Sinon, utilisez l'espace vide sur la couche 3 pour revenir à la principale boucle.

Draco18s
la source