Zwiebelprogrammierung

22

Mit nur druckbare ASCII (hex - Codes 20 bis 7e), schreibt , ein quadratisches NxN - Kernprogramm ohne Kommentare , die von 4 weiteren umgeben Schichten , die Schaffung eines (N + 8) × (N + 8) quadratisches Programm (n> 0) . Für N = 3 sieht das Layout (durch den tatsächlichen Code zu ersetzen) folgendermaßen aus:

44444444444
43333333334
43222222234
43211111234
4321CCC1234
4321CCC1234
4321CCC1234
43211111234
43222222234
43333333334
44444444444
  • Die Cs repräsentieren das 3 × 3-Kernprogramm.
  • Die 1en repräsentieren die erste Schicht, die 2en repräsentieren die zweite Schicht usw.

Das Programm verwendet immer eine Reihe von durch Leerzeichen getrennten Ganzzahlen, wie z. B. 0 -1 31 -1 2 2 2stdin oder ähnliches (es sollten nur die einfachen Zahlen, keine Anführungszeichen oder Klammern oder ähnliches sein). Die Ausgabe hängt davon ab, welche Teile des Layouts ausgeführt wurden.

Es gibt fünf Möglichkeiten, das Programm auszuführen (Zeilenumbrüche sind im Programm enthalten). Jeder macht etwas anderes mit der Liste:

  1. Führe nur den Kern aus:

    CCC
    CCC
    CCC
    

    Dadurch wird das Maximum der Absolutwerte der Eingabelistenelemente berechnet und so COREoft in eine neue Zeile gedruckt . Wenn das Maximum 0 ist, wird nichts ausgegeben (ein Zeilenumbruch ist in Ordnung).

    • Die Ausgabe für 0 -1 31 -1 2 2 2wäre

      CORE
      CORE
      ...
      

      31 mal.

  2. Führe den Core mit Layer 1 aus:

    11111
    1CCC1
    1CCC1
    1CCC1
    11111
    

    Dies gibt den Durchschnitt ( arithmetisches Mittel ) der Listenwerte mit Standard-Gleitkommagenauigkeit aus.

    • Die Ausgabe für 0 -1 31 -1 2 2 2wäre 35/7 = 5( 5.0ist in Ordnung).
  3. Führen Sie den Kern mit den Schichten 1 und 2 aus:

    2222222
    2111112
    21CCC12
    21CCC12
    21CCC12
    2111112
    2222222
    

    Dies gibt eine durch Leerzeichen getrennte Liste der Eingabeliste in umgekehrter Reihenfolge aus.

    • Die Ausgabe für 0 -1 31 -1 2 2 2wäre 2 2 2 -1 31 -1 0.
  4. Führen Sie den Kern mit den Schichten 1, 2 und 3 aus (das Muster sollte offensichtlich sein).
    Dies gibt eine durch Leerzeichen getrennte Liste der sortierten Eingabeliste aus.

    • Die Ausgabe für 0 -1 31 -1 2 2 2wäre -1 -1 0 2 2 2 31.
  5. Führen Sie den Core mit den Ebenen 1, 2, 3 und 4 aus.
    Dadurch wird eine durch Leerzeichen getrennte Liste der Eingabeliste mit entfernten Duplikaten ausgegeben, die Reihenfolge spielt keine Rolle.

    • Die Ausgabe für 0 -1 31 -1 2 2 2könnte sein -1 0 2 31.

Alle Ausgaben erfolgen auf Standardausgabe oder eine ähnliche Alternative.

Nur diese 5 Layoutkombinationen haben ein bestimmtes Verhalten.

Anmerkungen

  • Kommentare im Kern oder in Schichten oder Kombinationen davon sind nicht zulässig . Code, der ein No-Op ist oder nichts Konstruktives tut, zählt nicht als Kommentar.
  • Denken Sie daran, dass der Kern beliebige (positive) N × N-Dimensionen haben kann, die Schichten jedoch nur ein Zeichen dick sind.
  • Sie können davon ausgehen, dass die Eingabe keine führenden oder nachfolgenden Leerzeichen und genau ein Leerzeichen zwischen Zahlen enthält. Es wird immer mindestens eine Zahl enthalten. (Die Ausgabelisten sollten auch so formatiert sein.)
  • Sie können davon ausgehen, dass die Liste und die für die Ausgabe erforderlichen Berechnungen keine Werte enthalten, die Ihre ganzen Zahlen über- oder unterschreiten (sofern deren Maximalwert etwa 2 16 beträgt ).

Wertung

Normalerweise wäre es einfach, dieses Programm zu schreiben. Es ist schwer, es mit einem kleinen Kern zu schreiben.

Das Programm mit der kleinsten Kerngröße (das kleinste N) gewinnt. Bei Gleichstand gewinnt das vollständige Programm (das Quadrat (N + 8) × (N + 8)) mit den wenigsten unterschiedlichen Zeichen (ohne Zeilenvorschub).

Bitte geben Sie Ihren N-Wert oben in Ihrer Antwort an.

Calvins Hobbys
quelle
1
Ich dachte, dass dies auch einer dieser neuen Typen sein würde
Optimizer
Kann ich eine Sprache verwenden, die nach einem Zeilenumbruch alles ignoriert?
isaacg
1
@isaacg Ja (solange Newline nicht als Kommentarzeichen betrachtet wird, was seltsam wäre).
Calvins Hobbys
3
@Optimizer Versuch mich nicht ... " Jede Antwort fügt der Code-Zwiebel eine neue Ebene hinzu, damit sie etwas Neues mit der Liste anfängt ... "
Calvins Hobbys
1
@Optimizer Nein. (Ich weiß, dass diese I / O-Regeln ein bisschen streng sind, aber damit die Dinge in allen Sprachen konsistent bleiben.)
Calvins Hobbys

Antworten:

10

CJam, N = 5, 27 (26) eindeutige Zeichen

Es sind 26 Zeichen, wenn ich die Leerzeichen nicht zähle. Das Programm könnte tatsächlich in ein Programm konvertiert werden, das keine Leerzeichen verwendet, indem einfach alle leeren Leerzeichen mit No-Ops aufgefüllt werden (z. B. _;indem das oberste Stapelelement dupliziert und dann verworfen wird oder indem das Array immer wieder sortiert wird) würde nur vom eigentlichen Code ablenken.

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

Teste es hier.

Der Kern ist

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

(Plus eine leere Zeile.)

Ich bin mir ziemlich sicher, dass N = 4das in CJam nicht geht (und ich bin mir sicher, dass Dennis mich sonst überzeugen wird: D). Das hat über 17 Zeichen, und während es möglich sein könnte , es auf 16 runter (zB wenn CJam nicht um einen Fehler zu ersticken hat :z, die erfordert {z}%, oder durch ARGV verwenden), ich glaube nicht , dass Sie es passen im Layout ohne Zeilenumbruch CORE.

Alle Implementierungen sind sehr einfache Lösungen für die gegebenen Aufgaben. Alle von ihnen beginnen mit l~]dem Lesen von STDIN, werten es aus und ordnen es einem Array zu.

Die vorherige Ebene ist immer umgeben {...}, wodurch es sich um einen Block handelt, der nicht automatisch ausgeführt wird. Und anstatt es auszuführen, verwerfe ich es einfach vom Stapel mit ;, sodass keine Ebene vom Code in der vorherigen Ebene abhängt. In der Ebene 1 passte der Code nicht in die erste Zeile, also setzte ich ihn fort, nachdem ich den Kernblock verworfen hatte.

Nun zu den eigentlichen Programmen:

  • Ader:

    {z}%$W="CORE
    "*
    

    Ordne es absder Liste zu, sortiere es, nimm das letzte Element, wiederhole CORE(und einen Zeilenumbruch) so oft.

  • Schicht 1:

    _,\:+d\/
    

    Duplizieren Sie die Liste, nehmen Sie die Länge, tauschen Sie die Stapelelemente aus, erhalten Sie die Summe, werfen Sie sie auf double, tauschen Sie die Stapelelemente aus, teilen Sie sie. Ich denke, das kann kürzer sein, aber es gibt keinen Anreiz dazu.

  • Schicht 2:

    W%S*
    

    Kehre das Array um und riffle mit Leerzeichen.

  • Schicht 3:

    $S*
    

    Sortieren Sie das Array, riffeln Sie mit Leerzeichen.

  • Schicht 4:

    Duplizieren, Union setzen, mit Leerzeichen wühlen.

Einige andere Optimierungen sind möglich, wie die Wiederverwendung ;und *Svon Layer 2, aber wieder, es gibt aber keine Partitur beeinflussen.

Martin Ender
quelle
17

Python 2 - N = 17, 53 Zeichen

Oh, ich liebe Source-Layout-Herausforderungen mit 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;"   (_)   :|   (_)   ";

Es gibt jedoch noch einige nicht verwendete Leerzeichen.

Ich könnte die Anzahl der eindeutigen Zeichen noch verbessern, aber ich bleibe bei der besseren Lesbarkeit - sofern überhaupt welche vorhanden sind.

Edit: Oh, es ist wieder Stan !

Falko
quelle
Sie können wahrscheinlich einige Zeilen durch Aliasing von print anstelle des i=*Tricks
speichern
@ M.Herzkamp: Aliasing printist mit Python 2 nicht möglich. Aber sicher gibt es Verbesserungspotential - vielleicht mit Python 3.
Falko
Ich kenne Python nicht, aber fehlt dieser absolute Wert nicht in der c*max(n)
Kerncode-
@nutki: Du hast recht! Ich habe nicht sorgfältig gelesen. Aber ich konnte es reparieren.
Falko
6

Python 3: N = 11, 40 verschiedene Zeichen

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

Vielen Dank an @Falko, dass er meine Muse ist. Dies funktioniert, da Python nicht für jede if-Anweisung einen neuen Gültigkeitsbereich erstellt, sodass die Variablen in den äußeren printAnweisungen bestehen bleiben . Eine ärgerliche Sache war, dass ein mapObjekt (in unserem Fall n) nur einmal verwendet werden kann. Es war also notwendig, die R=E(...)Zeile auszufädeln, wurde dann Raber nicht definiert. Daher hatte ich das Glück, dass in der ersten Zeile noch vier Plätze frei waren!

Die Ausgabe kann durch Bereitstellen mehrerer Elemente *b[::-1]anstelle der Liste gelöst werden . Die Alternative ' '.join(...)wäre zu lang gewesen.

M.Herzkamp
quelle
Schön! Es ist schön, einen alternativen Ansatz für den Umgang mit variablen Zeilenanfängen in Python zu sehen. Nur ein paar kurze if-Anweisungen und all diese Leerzeichen sind in Ordnung. :)
Falko
@ Falko: Der Nachteil ist: Es gibt keinen Platz für Stan :(
M.Herzkamp
2

C (gcc) , N = 15, 47 eindeutige Zeichen

Angenommen, sizeof(int) == 4und 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 Schichten

3 Schichten

2 Schichten

1 Schicht

Ader

Gastropner
quelle
0

Runenverzauberungen , N = 9 N = 8, 38 Zeichen

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

Probieren Sie es online!

Es stellte sich heraus, dass ich falsch lag. Ich habe vergessen, dass ich bereits einen expliziten oBefehl s rt hatte, da ich zuvor auf das Problem "Liste sortieren" gestoßen war. Dies begrenzt jedoch die Größe der Eingaben, die das endgültige Programm aufgrund der internen Kosten des Sortierbefehls annehmen kann (8 Werte). Durch eine geringfügige Änderung kann die Eingabegröße auf 13 zum Preis von 1 eindeutigen Zeichen oder auf 19 für zwei eindeutige Zeichen erhöht werden (alle zusätzlichen Zeichen befinden sich auf Ebene 1 und werden gleichzeitig hinzugefügt, die erhöhte Kapazität des IP-Stacks jedoch nicht benötigt, bis Schicht 3 als C, L1 und L2 ihre Berechnungen durchführen kann, ohne die gesamte Eingabe im Speicher zu halten).

Core: Online ausprobieren!

Schicht 1: Probieren Sie es online!

Schicht 2: Online ausprobieren!

Schicht 3: Probieren Sie es online!

Schicht 4: Probieren Sie es online!

Eine weitere Komprimierung ist höchst unwahrscheinlich, da aufgrund des geringeren Platzbedarfs die Anzahl der Flusssteuerzeichen erhöht werden muss. Ich habe ein Arrangement gefunden, das 9 Leerstellen im Kernprogramm enthielt, aber das ist nicht genug, da wir (ein korrekt arrangiertes) 15 brauchen.

Es ist schwierig zu erklären, wie eines dieser Programme funktioniert, ohne eine visuelle Karte des IP-Pfads zu haben, was mühsam und zeitaufwendig ist. Der anfängliche Einstiegspunkt ist die obere linke Ecke des Core-Programms ( ^), die eine konsistente Ablaufsteuerung ermöglicht, wenn neue Ebenen hinzugefügt werden, da jede Ebene die Möglichkeit hat, die neu hinzugefügte Linie oben oder unten abzufangen.

Die Ebenen 1 und 2 schneiden sich unten ab (sodass die obere Zeile für zukünftige Ebenen leer bleibt) und führen ihre Operationen dann entlang der rechten Kante aus (eine vertikal angeordnete Schleife). Die Ebene 1 ist etwas zu lang und benötigt am oberen Rand ebenfalls 3 Zeichen, aber der diagonale Reflektor ( \) oben rechts richtet die IP bei der nächsten Schleifeniteration neu aus.

Layer 3 fängt entlang der oberen Kante ab, um den ersten Eingabewert zu erfassen, bevor er zur unteren Kante umgeleitet wird (Layer 4 belässt eine NOP in dieser Spalte in der unteren Zeile), und liest die vollständige Eingabe mithilfe der unteren Kantenschleife und leitet sie nach unten um Befehl ( D) unten links. Von dort springt die IP einige Male auf und landet dann in einer output ( $) - Schleife unten links, um die Werte durch Leerzeichen voneinander zu trennen.

Layer 4 nutzt die gesamte Funktionalität von Layer 3 (daher der Leerraum), fängt jedoch an seiner eigenen neuen Oberkante (oben links) ab, um am Ende der Verarbeitung von Layer 3 seine eigene Funktionalität auszuführen. In der oberen linken Ecke wird eine Zeichenfolge "@"eingefügt, mit der das Ende des Arrays angegeben wird, bevor die Verarbeitungsschleife unten eingegeben wird. Wenn ein doppelter Wert gefunden wird, erscheint dieser ( ~untere rechte Ecke), andernfalls wird der Zweig genommen, der den neuen rechten Rand belegt. Dieser Nebenzweig prüft, ob das Ende des Arrays erreicht wurde. Wenn dies der Fall ist, brechen Sie in die gleiche durch Leerzeichen getrennte Ausgabeschleife aus Schicht 3 aus und steuern Sie sie an. Verwenden Sie andernfalls das Leerzeichen in Schicht 3, um zum Hauptbereich zurückzukehren Schleife.

Draco18s
quelle