Simulieren Sie das Drehen eines Boards


14

Einführung

Sie spielen ein Matching-Spiel, bei dem Münzen oben eingeworfen werden und aufgrund der Schwerkraft nach unten (auf die obere Münze) fallen.

Also das

O <- inserting this coin

OO O
OOOOO

wird dies werden

O
OO O
OOOOO

Stellen Sie sich vor, jemand dreht das Board im Uhrzeigersinn. Folgendes wird passieren:

1. Die Platine wird gedreht

OOO
OO
O
OO
O

2. Münzen fallen aufgrund der Schwerkraft herunter

O
O
OO
OO
OOO

Deine Aufgabe

Ihre Aufgabe ist es, die Drehung der Platine durch Schreiben eines Programms oder einer Funktion zu simulieren. Der Einfachheit halber haben wir es nur mit einer Art Münze zu tun (es ist kein allzu aufregendes Matching-Spiel, oder?). Sie können davon ausgehen, dass die Schwerkraft erst nach Abschluss der Drehung angewendet wird. Das Brett wird im Uhrzeigersinn gedreht.

Eingang

Die Eingabe wird eine Zeichenfolge sein, die drei Arten von Zeichen enthält:

  • O (Kapital o) ODER 0 (Null) - eine Münze (Sie entscheiden, welche Ihre Lösung unterstützt)
  • (Leerzeichen) - ein leeres Feld
  • \ n (neue Zeile) - Zeilenende

Der Eingang repräsentiert den Zustand der Karte. Sie können davon ausgehen, dass die Eingabe wohlgeformt ist und einen gültigen Status der Karte enthält (keine Münzen schweben). Die Eingabe kann ein Funktionsparameter sein oder von der Standardeingabe oder aus einer Datei gelesen werden.

Ausgabe

Der Ausgang ist der neue Zustand der Karte nach dem Drehen. Die Ausgabe enthält die gleichen 3 Arten von Zeichen wie die Eingabe. Die Ausgabe kann von Ihrer Funktion zurückgegeben oder in die Standardausgabe oder in eine Datei geschrieben werden.

Stichprobe

Input1:

O
OO O
OOOOO

Output1:

O
O
OO
OO
OOO

Input2:

O O
O O

Output2:

OO
OO

Sie können jede Sprache und die Standardbibliothek der gewählten Sprache verwenden. Das kürzeste Programm in Bytes gewinnt.


Sind die kürzeren Zeilen mit Leerzeichen aufgefüllt?
Ventero

Wenn du das brauchst, dann ja.
David Frank

Was sind die Anforderungen an die Boardgröße? Kann ich eine angemessene Maximalgröße wählen oder muss die Anwendung / Funktion für alle möglichen Größen funktionieren?
Fors

2
Wie wird Input2 zu Output2, wenn nach der Drehung die Schwerkraft angewendet wird? Ich hätte gedacht, es würde die obersten Münzen fallen lassen, aber nicht horizontal?
Matt

2
@Matt Beachten Sie, dass weder in Input2 noch in Output2 leere Zeilen vorhanden sind (SE zeigt den Abstand zwischen den Zeilen an).
David Frank

Antworten:


16

GolfScript, 14 12 Zeichen

' '-n%zip$n*

Die Eingabe muss auf STDIN erfolgen, das Zeichen für Münzen kann ein beliebiges Nicht-Leerzeichen sein. Versuchen Sie es hier . Vielen Dank an Peter für den Hinweis auf eine Reduzierung um zwei Zeichen.


Oh, was würde ich für einen transposein Ruby geben, der Arrays mit unterschiedlichen Längen verarbeiten kann ...
Ventero

@Ventero Die meisten der Zeit ich diese Hacky Version benutzen ([nil]*a.map(&:size).max).zip(*a). Nicht gut zum Golfen.
Howard

Sie können 2 Zeichen sparen: da die längste Zeile immer am unteren Ende, können Sie ersetzen -1%mit $.
Peter Taylor

@PeterTaylor Sie haben Recht - wir können Zeichen sparen. Vielen Dank.
Howard

1
@PeterTaylor Nun, ich habe einen Alias ​​mit einem Buchstaben für eingefügt " ".
Aditsu

6

Javascript (E6) 103

Versuchen Sie zuerst, nur Matrixoperationen. Jede Zeile in der Eingabezeichenfolge muss aufgefüllt werden.
Ganz schön wortreich.

R=t=>(x=t.split('\n').reverse().map(x=>[...x].sort()),x.map((c,i)=>x.map(r=>r[i]).join('')).join('\n'))

Pseudocode

  1. Zeichenfolge -> Array von Zeilen
  2. Up / Down-Reverse-Array
  3. jede Zeile -> char Array
  4. sortiere jede Reihe (Münzen fallen nach rechts)
  5. transponieren
  6. jedes Zeichen-Array in einer Reihe -> eine Zeichenfolge
  7. join array -> single string

Oh wow, das Sortieren ist klug (+1)! Darf ich es stehlen?
Siehe auch

Ich habe die Syntax noch nie gesehen [...x]. Wie heißt es?
ComFreek


2
@ edc65 Du hast deinen eigenen Link mit Klammern getrennt. Hier ist der richtige Link
Chris Cirefice

6

Ruby 2.0, 59 Zeichen

puts$<.map(&:chars).reverse.transpose.sort[1,50].map &:join

Bei der Eingabe über stdin wird davon ausgegangen, dass alle Zeilen die gleiche Länge haben. Dies ist wahrscheinlich viel länger als nötig. Aber zumindest ist es lesbar ...


Ich denke, Sie können $<.mapstattdessen verwenden.
Howard

@Howard Das ist eine Sache, die ich immer vergesse. Vielen Dank!
Ventero

1
was macht [1,50] dort?
Nicht dass Charles

1
@Charles Überspringt die erste Zeile, die alle Zeilenumbrüche aus der Eingabe enthält. David erwähnte in einem Kommentar, dass 50x50 die maximal mögliche Größe ist. Anstatt also alle bis auf die erste Zeile ( 1..-1) auszuwählen, wähle ich einfach 50 Zeilen aus, beginnend mit der zweiten Zeile ( 1,50).
Ventero

@Ventero hat es verstanden. cool. Vielen Dank!
Nicht dass Charles

3

J - 49 31 24 Bytes

Ich denke, es könnte unnötige Rotationen geben, aber sonst funktioniert es gut. Es ist eine Funktion, die die Eingabe wie angegeben übernimmt, Münzen werden O. In der Eingabe ist kein nachgestelltes Leerzeichen erforderlich.

Neue Version, inspiriert von der Javascript-Antwort von edc65 :

f=:[:|."1@|:[:/:~"1,;._2

Erläuterung:

f=:[:|."1@|:[:/:~"1,;._2
                   ,;._2 Split the string at every fret, which is the last character in the string (newline).
              /:~"1      Sort every row separately.
     |."1@|:             Rotate the array clockwise.

Alte Version:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)

Erläuterung:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)
                                          (,;._2) Split the string at every fret, which is the last character in the string (newline).
                                (|."1@|:)@        Rotate the array clockwise.
                             |:@                  Reverse the axes (columns become rows and vice-versa).
       ((#~=&' '),=&'O'#])"1                      Function that applies the "gravity"
                          "1                       Apply to every row separately:
                  =&'O'#]                           Get the O's in the row.
       (#~=&' ')                                    Get the spaces in the row.
                ,                                   Join them, spaces come first.
  [:|:                                            Reverse axes again.

Beispiele (beachten Sie, dass mehrzeilige Zeichenfolgen mit 0 : 0einer Klammer beginnen und enden):

   f 0 : 0
O
OO O
OOOOO
) NB. output starts now
O  
O  
OO 
OO 
OOO
   f 0 : 0
O O
O O
) NB. Output starts now.

OO
OO

Wenn du kannst, sortiere vor dem Drehen
edc65

@ edc65 Du bist ein kluger Mann.
Siehe auch

2

Haskell - 86

Ich lerne nur, also bin ich sicher, dass dies verbessert werden kann.

import Data.List
c=putStr.unlines.filter(/="").sort.map(filter(/=' ')).transpose.lines

Beispiel Input:

let a = "O    \nOO O \nOOOOO"
let b = " O O \n O O "
c a
c b

Beispielausgabe:

O
O
OO
OO
OOO

OO
OO

2

Python 2 (69) (79)

for c in sorted(zip(*raw_input().split("\\n"))):print''.join(c[::-1])

Nimmt mit Leerzeichen aufgefüllte Eingaben auf, damit alle Zeilen gleich lang sind. Das spliterzeugt ein Arrat jeder Zeile. Die ziptransponiert effektiv Array. Anschließend werden die sortedTupel in lexikografischer Reihenfolge sortiert, sodass alle Münzen auf den Boden fallen. Schließlich drucken wir jede Zeile aus und wandeln sie wieder in eine Zeichenfolge um, obwohl wir sie zuerst umkehren müssen. Dies print'O'*c.count('O')ist äquivalent und verwendet die gleiche Anzahl von Zeichen.

Beispiellauf:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO

1

C, 167 119 Bytes

Diese kürzere Version ist (leider?) Auch viel deutlicher als das Original.

m;j;b[99];r;main(){while(j=getchar()+1)j-11?m+=j-33&&++b[r]>m:++r;for(j=r;m+1;putchar(j--?m<b[j]?79:32:(j=r,m--,10)));}

0

Schläger: 130

(let l((a'()))(let((b(sort(string->list(read-line))char<?)))(if
(null? b)(apply map(λ x(map display x)(newline))a)(l(cons b a)))))

Sie müssen mit Leerzeichen auffüllen, damit die Linien gleich lang sind.


0

C # - 209 174 Bytes

Richtig, ich muss diesen Code Golf irgendwann ausprobieren, wie ich finde. Erstellt eine Funktion (r), die das Board dreht und druckt. Ich schätze, ich betrüge ein bisschen, wenn ich mein Char-Array drucke, aber wenn Sie nicht herausfinden können, warum Sie nicht sauer sein sollten :)

Danke an ProgramFOX für die Tipps :)

void r(string s){int x=s.IndexOf('\n'),j,i=-1,k,z=x+1;var y=new char[x*x+x];for(;++i<x;y[z*(i+1)-1]='\n')for(k=j=x;j>0;)if(s[i*z+--j]=='0')y[k--*z-i-2]='0';Console.Write(y);}

Betrügen

new char[x*x+x]füllt das Array mit '\0'und nicht' '


1
Entfernen Sie die Zeilenumbrüche und das Leerzeichen zwischen char[]und y, um die Anzahl Ihrer Zeichen auf 192 Zeichen zu reduzieren. Außerdem ist es nicht unbedingt erforderlich, das Schlüsselwort anzugeben, staticwenn Sie hier eine Antwort veröffentlichen. Wenn Sie es entfernen, wird Ihre Zeichenanzahl auf 185 Zeichen reduziert.
ProgramFOX

Ich konnte auch "ref" entfernen, das dort seit einem früheren Versuch vergessen wurde.
WozzeC
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.