Geordnete Folge aufsteigender Ganzzahlkombinationen

8

Schreiben Sie ein Programm oder eine Funktion, um die folgende Ausgabe in der richtigen Reihenfolge zu erzeugen.

EDIT: Die Symbole sind nicht mathematisch! Die Zahlen stellen nur eindeutige Daten dar und die +und -können zwei beliebige Symbole sein.

Nehmen Sie einen nicht negativen ganzzahligen Eingang n. Die erste Zeile ist immer -, auch für n = 0.

  • Wenn die aktuelle Zeile ist -, ist die nächste Zeile1+2+ ... (n-1)+n-
    • n = 4: -=>1+2+3+4-
  • Wenn die letzte Ganzzahl gleich n ist, entfernen Sie alle Ganzzahlen vom Ende, auf die unmittelbar a folgt -, und ändern Sie die letzte +in a-
    • n = 4: 1-2+3-4-=>1-2-
    • BEARBEITEN: Wenn die Zeichenfolge voll ist (alle Ganzzahlen von 1 bis n sind enthalten), entfernen Sie alle Ganzzahlen vom Ende, auf die a folgt -, bis Sie eine Ganzzahl gefolgt von a erreichen +. Lassen Sie diese Ganzzahl, aber ändern Sie die folgenden +in a-
    • Entfernen , entfernen , ändern Sie mit dem gleichen Beispiel wie unmittelbar oben (das nicht folgt -) . ändert sich nicht, seit wir bei aufhören . Ergebnis: 4-3-2+2-1-21-2-
  • Wenn die letzte Ganzzahl kleiner als n ist, hängen Sie die verbleibenden Ganzzahlen +nach jeder mit einem an, mit Ausnahme der letzten Ganzzahl, an die eine Ganzzahl -angehängt werden soll
    • n = 4: 1+2-=>1+2-3+4-
    • BEARBEITEN: Wenn die aktuelle Zeichenfolge nicht voll ist (nicht alle Ganzzahlen von 1 bis n enthält), addieren Sie jede Ganzzahl, die noch nicht in aufsteigender Reihenfolge enthalten ist, bis zu n-1 mit einem +nach jeder und fügen Sie dann die letzte Ganzzahl n hinzu, die folgt durch eine-
    • Wenn die aktuelle Zeile lautet 1-, hängen Sie an 2+, fügen Sie 3+n-1 hinzu, wenn n = 4 ist. Dann anhängen 4-. Ergebnis:1-2+3+4-
  • Wenn die aktuelle Zeile alle Ganzzahlen enthält und auf jede unmittelbar a folgt -, beenden Sie den Code
    • n = 4: 1-2-3-4-=> ENDE

In keiner Zeile dürfen führende oder nachfolgende Leerzeichen vorhanden sein. Zwischen jeder Zeile muss ein Zeilenumbruch liegen. In der letzten Zeile kann ein Zeilenumbruch auftreten oder nicht.

BEARBEITEN: Sie sollten Ihren Code bis zu mindestens n = 10 testen (über 1000 Ausgabezeilen, damit ich ihn hier nicht einfügen kann). Jede Zahl, die nicht dazu führt, dass Ihrem Code die Ressourcen ausgehen, sollte (irgendwann!) Die richtige Ausgabe liefern, aber Sie müssen nicht auf das Ende des Universums warten!

Dies ist , also gewinnt der kürzeste Code in Bytes!

Eingabe n = 0:

-

Eingabe n = 1:

-
1-

Eingabe n = 2:

-
1+2-
1-
1-2-

Eingabe n = 4:

-
1+2+3+4-
1+2+3-
1+2+3-4-
1+2-
1+2-3+4-
1+2-3-
1+2-3-4-
1-
1-2+3+4-
1-2+3-
1-2+3-4-
1-2-
1-2-3+4-
1-2-3-
1-2-3-4-
CJ Dennis
quelle

Antworten:

5

Haskell , 89 Bytes

g Nimmt eine Ganzzahl und gibt eine Zeichenfolge zurück.

g n=unlines$max"-".foldr(\(s,i)r->id=<<[show i++s:r|s:r>"+"])""<$>mapM(mapM(,)"+-")[1..n]

Probieren Sie es online aus!

Wie es funktioniert

  • Grob gesagt, konstruiert der Algorithmus eine Liste aller 2^nKombinationen 1+2+...n+, 1+2+...n-bis die 1-2-...n-Streifen die letzten weg +terminierte Zahlen, und wenn das Ergebnis leer ist, ersetzt sie durch -.

  • mapM(,)"+-"ist eine kürzere Art zu schreiben (mit der Funktion Monade) \i->[('+',i),('-',i)].

  • mapM(mapM(,)"+-")[1..n]erzeugt (unter Verwendung der Listenmonade für das Äußere mapM) eine Liste mit allen Kombinationen als Listen von Tupeln, z [(1,'+'),(2,'-'),...,(n,'+')].
  • foldr ... <$> ... kombiniert jede dieser Tupellisten zu einer Zeichenfolge und erstellt sie mit dem Lambda-Ausdruck von rechts.
    • (s,i)ist ein Tupel aus einem Zeichen und einer Zahl und rist die Zeichenfolge, die aus den Tupeln rechts davon aufgebaut ist.
    • id=<<[show i++s:r|s:r>"+"]vorangestellt iund san die bisher rkonstruierte Zeichenfolge , aber nicht, wenn das Vorzeichen spositiv und rleer ist.
      • Dies wird durch Vergleich s:rmit getestet "+". Glücklicherweise ist dies die lexikographisch kleinste Zeichenfolge, die sich aus der Verkettung ergeben kann, sodass der Vergleich >eher als verwenden kann /=.
  • Glücklicherweise "-"ist es auch kleiner als jede nicht leere Zeichenfolge, die durch die Falte erstellt werden kann, sodass die leere Zeichenfolge durch Verwendung durch diese ersetzt werden kann max.
  • Schließlich werden unlinesdie Zeichenfolgen in eine einzelne Zeichenfolge umgewandelt.
Ørjan Johansen
quelle
5

Python 2 , 101 Bytes

n=input()
for i in range(2**n):s='';m=n;exec"s=`m`+'+-'[i%2]+s;s*='-'in s;i/=2;m-=1;"*m;print s or'-'

Probieren Sie es online aus!

xnor
quelle
Gute Verwendung vons*=<condition>
Chas Brown
3

Python 2 , 136 141 133 Bytes

def f(n,s="+"):
 while"+"in s:s=s[:s.rfind("+")]+"-";print s[s>"-":];s+="+".join(map(str,range(len(s)/2+1,n+1)))+"-";print(n>0)*s[1:]

Probieren Sie es online aus!

Das erste -(un) überraschenderweise fügte dem Code ein paar Bytes hinzu.

notjagan
quelle
Die String-Manipulationslösung war also doch kürzer?
HyperNeutrino
Oder ich bin nur schlecht: P
HyperNeutrino
Der Ansatz scheint kürzer zu sein, aber es gibt einige Dinge, die bei Ihnen verbessert werden könnten. Ich werde in Kürze einen Kommentar mit einigen Tipps veröffentlichen.
Notjagan
n = 0 erzeugt fälschlicherweise zwei -Zeilen.
CJ Dennis
@ CJDennis behoben.
Notjagan
3

Python 2 , 150 164 159 154 146 118 Bytes 115 112 Bytes

def f(n,i=0):
 while i<2**n:t=''.join(`j+1`+'+-'[i>>n+~j&1]for j in range(n));print t[:t.rfind('-')+1]or'-';i+=1

Probieren Sie es online aus!

Edit: Ups! Es muss auch für Zahlen größer als 4 funktionieren ... dann abplatzen ... bis mir klar wurde, dass ich es überlegt und 28 Bytes gespart habe ... und dann 6 weitere über kleine Golfplätze.

Chas Brown
quelle
Ausgabe ist falsch für Eingabe über n = 4.
CJ Dennis
@ CJ Dennis Ich denke, es funktioniert jetzt; Ausgabe ist die gleiche wie notjagan für zB n = 5
Chas Brown
Die Ausgabe scheint jetzt korrekt zu sein! Ich werde hinzufügen, dass Sie mindestens 10 testen sollten ...
CJ Dennis
Ich habe gerade bemerkt, dass Sie i = 0 in der Eingabe setzen! Das heißt, ich kann nur Zeilen ab i generieren, wie z. B. f (24,16777200)! :-)
CJ Dennis
3

Pyth, 23 Bytes

j+\-mssVSQd<Lx_d\-t^"+-

Demonstration

Die Basis dieses Programms ist die Feststellung, dass -die Plus- und Minus-Sequenz außer der Anfangssequenz der Standardsequenz von Kombinationen von +und -mit Ersetzung entspricht, wobei alle nachgestellten Zeichen +entfernt werden.

Erläuterung:

j+\-mssVSQd<Lx_d\-t^"+-
j+\-mssVSQd<Lx_d\-t^"+-"Q    Implicit string completion and variable introduction
                   ^"+-"Q    Form all sequences of + and - of length equal to
                             the input, ordered lexicographically.
                  t          Remove the first one, which we don't use.
           <L                Take the prefix of each one of length
             x               index in
              _d             the reversed string
                \-           of '-'.
    m                        Map the results to
      sV                     Apply the sum function to pairs of
        SQ                   [1, 2, 3 ... input]
          d                  and the previous string
     s                       Sum the pairs.
 +\-                         Add a '-' on to the front of the list
j                            Join on newlines.
isaacg
quelle
0

Python 3 , 305 Bytes

x=int(input())
o=lambda:list(range(1,x+1))or[0]
q=o()
q[-1]*=-1
print('-')
def f(a):print(''.join(str(abs(x))+'-+'[x>0]for x in a))
while any([k>0 for k in q])or[-k for k in q]!=o():
	f(q)
	if-q[-1]==x:
		while q[-1]<0:q=q[:-1]
		q[-1]*=-1
	elif-q[-1]<x:
		while q[-1]<x:q+=[abs(q[-1])+1]
		q[-1]*=-1
f(q)

Probieren Sie es online aus!

HyperNeutrino
quelle
Ich bin ein bisschen verwirrt von Ihrer Tab / Space-Mischung. Erstens habe ich nicht einmal gedacht, dass Sie in Python 3 KÖNNTEN, und zweitens scheint es wenig Sinn zu haben? Warum sich die Mühe machen, <tab><space>wenn <space><space>die gleiche Anzahl von Bytes wäre? Ich denke, wenn Sie die kleinen Einrückungen mit <space>und die größeren <tab>damit machen würden, würden Sie vielleicht ein Byte sparen ...
nmjcman101
@ nmjcman101 erm. Ich muss wirklich müde oder dumm sein oder beides. Ich habe versucht, Bytes zu speichern, indem ich diesen Leerzeichen / Tabulator-Einzug und nicht Tab / Tabulator> <danke gemacht habe!
HyperNeutrino
Dies ist 17 Byte kürzer, wird jedoch bei einem Fehler beendet. Ich versuche immer noch, das lästige q[-1]zu verkürzen q[0]. Übrigens: Das Mischen von Tabulatoren und Leerzeichen funktioniert in Python 3 nicht, daher gibt der aktuelle Code einen Fehler aus.
Notjagan
@notjagan oh hm. egal dann, es muss gewesen sein, weil ich früher dumm war: P aber okay, danke für den Vorschlag; Ich werde versuchen, von dort aus zu arbeiten
HyperNeutrino