Entwicklung des 'x'

15

Gegeben ist eine Tafel variabler Größe mit einer maximalen Größe von 5 mal 5 Feldern. Jedes Feld kann mit einem 'x' gefüllt werden. Wenn es nicht mit einem 'x' gefüllt ist, wird es mit einem 'o' gefüllt.

Der Ausgangszustand jeder Karte ist angegeben (siehe unten). Mit jedem Brett müssen 10 Runden gespielt werden (max. Bedingungen: siehe unten) und die Entwicklung des x muss beobachtet werden.

Eine Runde funktioniert folgendermaßen:

  1. Jedes 'x' breitet sich auf orthogonal angrenzende Felder aus, verschwindet jedoch von selbst
  2. Jedes Mal, wenn sich zwei 'x' auf einem Feld befinden, neutralisieren sie sich gegenseitig

Die Entwicklung aller 'x' in jeder Runde muss gleichzeitig erfolgen. Beispiel:

    o o o            o x o
    o x o     ->     x o x
    o o o            o x o

Bei jeder Evolutionsrunde muss man sehen, ob das Brett von "x" geleert wird. Ist es nicht leer, könnte ein sich wiederholendes Muster vorliegen. Ist dies auch nicht der Fall, geben wir die Analyse der Evolution auf. Zusätzlich müssen Sie für jedes Startbrett den maximalen Prozentsatz an x ​​Feldern ausdrucken (auf ganze Zahlen abgerundet).

Eingang:

Die Eingabedaten finden Sie hier (Pastebin) Diese Daten enthalten 100 Startzustände. Wie bereits erwähnt, variieren die Platten in der Größe. Die Anzahl der Zeilen wird mit der Nummer n von 1 bis 5 angegeben, gefolgt von n Zeilen, die nur 'x' und 'o' enthalten und das Startmuster darstellen. Jede Reihe einer Tafel hat 1 bis 5 Felder.

Ausgabe:

Das komplette Ergebnis muss ausgedruckt werden, eine gedruckte Reihe für jede Starttafel in der folgenden Form:

    Round {0-10}: {repetition/empty/giveup}, {0-100} percent maximum-fill

Beispiele:

Beispiel 1:

    Input: 2       Starting state: x o x
           xox                     x x
           xx

                          Round 1: x x o
                                   o x

                          Round 2: x o x
                                   o x

                          Round 3: o x o
                                   o o

                          Round 4: x o x   -> The pattern repeats:
                                   o x        It is the same as in round 2,
                                              therefore we stop. Maximum fill was
                                              in the starting state with four times 'x'
                                              of 5 fields altogether,
                                              so we have 4/5 = 80 %.

    Output: Round 4: repetition, 80 percent maximum-fill

Beispiel 2:

    Input: 1       Starting state: x x
           xx                      

                          Round 1: x x    ->  We already have a repetition, because
                                              the pattern is the same as in the starting
                                              state. The board is always filled 100 %.

    Output: Round 1: repetition, 100 percent maximum-fill

Nach acht Tagen werde ich die funktionierende Antwort mit den wenigsten Zeichen als Gewinner markieren. Zusätzlich werde ich den korrekten Output für die 100 Startboards (Input) posten.

Sie können Ihre bevorzugte Sprache (Programmierung / Scripting / was auch immer) verwenden.

Habe Spaß!

PS: Wenn Sie Fragen haben, können Sie diese gerne stellen.

PPS: In Bezug auf die ursprünglichen Schöpfer: Für Menschen, die in der Lage sind, Deutsch zu sprechen, wurde die Frage von NICHT KLICKEN, WENN SIE KEINE SPOILER WOLLEN, hier genommen . Da die offizielle Zeit für das Abschließen der Herausforderung abgelaufen ist, wollte ich sehen, ob jemand eine kurze und elegante Lösung finden kann.

22.04.2014:

Herausforderung erledigt! Gewinner als akzeptiert markiert. Richtige Ausgabe:

    Round 10: giveup, 50 percent maximum-fill
    Round 5: empty, 66 percent maximum-fill
    Round 1: repetition, 100 percent maximum-fill
    Round 1: empty, 100 percent maximum-fill
    Round 4: repetition, 100 percent maximum-fill
    Round 4: repetition, 70 percent maximum-fill
    Round 2: repetition, 60 percent maximum-fill
    Round 4: empty, 88 percent maximum-fill
    Round 10: giveup, 50 percent maximum-fill
    Round 5: repetition, 80 percent maximum-fill
    Round 10: repetition, 80 percent maximum-fill
    Round 1: empty, 80 percent maximum-fill
    Round 3: repetition, 60 percent maximum-fill
    Round 4: repetition, 48 percent maximum-fill
    Round 9: empty, 41 percent maximum-fill
    Round 10: giveup, 92 percent maximum-fill
    Round 10: giveup, 53 percent maximum-fill
    Round 10: giveup, 66 percent maximum-fill
    Round 6: repetition, 50 percent maximum-fill
    Round 10: giveup, 88 percent maximum-fill
    Round 10: giveup, 76 percent maximum-fill
    Round 10: giveup, 68 percent maximum-fill
    Round 10: giveup, 40 percent maximum-fill
    Round 10: giveup, 100 percent maximum-fill
    Round 10: giveup, 71 percent maximum-fill
    Round 2: empty, 81 percent maximum-fill
    Round 6: repetition, 36 percent maximum-fill
    Round 10: giveup, 61 percent maximum-fill
    Round 10: giveup, 60 percent maximum-fill
    Round 4: repetition, 66 percent maximum-fill
    Round 10: giveup, 72 percent maximum-fill
    Round 3: empty, 80 percent maximum-fill
    Round 10: giveup, 50 percent maximum-fill
    Round 10: giveup, 83 percent maximum-fill
    Round 7: repetition, 37 percent maximum-fill
    Round 9: repetition, 85 percent maximum-fill
    Round 5: repetition, 40 percent maximum-fill
    Round 5: repetition, 60 percent maximum-fill
    Round 4: empty, 80 percent maximum-fill
    Round 10: giveup, 60 percent maximum-fill
    Round 4: repetition, 46 percent maximum-fill
    Round 6: repetition, 42 percent maximum-fill
    Round 10: giveup, 72 percent maximum-fill
    Round 4: repetition, 70 percent maximum-fill
    Round 4: repetition, 80 percent maximum-fill
    Round 6: repetition, 50 percent maximum-fill
    Round 4: repetition, 56 percent maximum-fill
    Round 10: giveup, 60 percent maximum-fill
    Round 10: giveup, 54 percent maximum-fill
    Round 10: giveup, 66 percent maximum-fill
    Round 2: repetition, 40 percent maximum-fill
    Round 2: repetition, 40 percent maximum-fill
    Round 6: repetition, 75 percent maximum-fill
    Round 7: empty, 85 percent maximum-fill
    Round 10: giveup, 50 percent maximum-fill
    Round 6: repetition, 70 percent maximum-fill
    Round 2: empty, 66 percent maximum-fill
    Round 1: empty, 66 percent maximum-fill
    Round 3: empty, 100 percent maximum-fill
    Round 3: empty, 66 percent maximum-fill
    Round 8: repetition, 42 percent maximum-fill
    Round 1: empty, 60 percent maximum-fill
    Round 2: repetition, 100 percent maximum-fill
    Round 2: repetition, 83 percent maximum-fill
    Round 4: repetition, 66 percent maximum-fill
    Round 6: repetition, 75 percent maximum-fill
    Round 4: empty, 66 percent maximum-fill
    Round 10: giveup, 61 percent maximum-fill
    Round 10: giveup, 56 percent maximum-fill
    Round 4: empty, 66 percent maximum-fill
    Round 6: repetition, 33 percent maximum-fill
    Round 3: empty, 57 percent maximum-fill
    Round 3: repetition, 100 percent maximum-fill
    Round 6: repetition, 73 percent maximum-fill
    Round 10: giveup, 50 percent maximum-fill
    Round 6: repetition, 50 percent maximum-fill
    Round 10: giveup, 73 percent maximum-fill
    Round 5: empty, 80 percent maximum-fill
    Round 10: giveup, 61 percent maximum-fill
    Round 3: repetition, 53 percent maximum-fill
    Round 10: giveup, 33 percent maximum-fill
    Round 10: giveup, 80 percent maximum-fill
    Round 10: giveup, 63 percent maximum-fill
    Round 10: giveup, 70 percent maximum-fill
    Round 10: giveup, 84 percent maximum-fill
    Round 7: repetition, 70 percent maximum-fill
    Round 10: repetition, 57 percent maximum-fill
    Round 10: giveup, 55 percent maximum-fill
    Round 6: repetition, 36 percent maximum-fill
    Round 4: repetition, 75 percent maximum-fill
    Round 10: giveup, 72 percent maximum-fill
    Round 10: giveup, 64 percent maximum-fill
    Round 10: giveup, 84 percent maximum-fill
    Round 10: giveup, 58 percent maximum-fill
    Round 10: giveup, 60 percent maximum-fill
    Round 10: giveup, 53 percent maximum-fill
    Round 4: repetition, 40 percent maximum-fill
    Round 4: empty, 40 percent maximum-fill
    Round 10: giveup, 50 percent maximum-fill
    Round 10: giveup, 68 percent maximum-fill
plocks
quelle
Bitte taggen Sie entweder als Code-Golf oder Code-Challenge, aber nicht als beides. (Es sollte in diesem Fall Code-Golf sein).
user80551
1
Jemand sollte dies in einen gut definierten Zellularautomaten verwandeln. :-)
Justin

Antworten:

4

Perl, 308, 304, 305, 293, 264 , 262

Bearbeiten: Nach einer der letzten Änderungen ist ein Fehler aufgetreten, der zu einer falschen Ausgabe für leere Boards geführt hat (die Ausgabe der Testsuite war in Ordnung). Schon seitRound 0 in einem bestimmten Ausgabeformat nur leere Karten in der Eingabe vorhanden sein können (obwohl sich keine in der Testsuite befindet), musste der Fehler behoben werden. Schnelle Fehlerbehebung bedeutete eine Erhöhung der Bytezahl (tatsächlich um 1) - natürlich keine Option. Deshalb musste ich ein bisschen mehr Golf spielen.

Run with -p(+1 zur Zählung addiert), liest aus STDIN. Benötigt 5.014 wegen rSubstitutionsmodifikator.

(@a,%h,$m)=('',map<>=~y/ox\n/\0!/rd,1..$_);for$n(0..10){$_="Round $n: ".($h{$_="@a"}++?repetition:(($.=100*y/!///y/ //c)<$m?$.:$m=$.)?giveup:empty).", $m percent maximum-fill\n";@a=/g/?map{$_=$a[$i=$_];y//!/cr&(s/.//r.P^P.s/.$//r^$a[$i+1]^$a[$i-1])}0..$#a:last}

dh

# '-p' switch wraps code into the 'while(<>){....}continue{print}' loop, 
# which reads a line from STDIN into $_, executes '....' and prints contents 
# of $_. We use it to read board height and print current board's result.

# First line reads board's state into @a array, a line per element, at the same 
# time replacing 'o' with 'x00', 'x' with '!' and chomping trailing newlines. 
# '!' was chosen because it's just like 'x01' except 5th bit (which is not important)
# but saves several characters in source code.

# Note: array is prepended with an empty line, which automatically remains in this 
# state during evolution, but saves us trouble of checking if actual (any non-empty)
# line has neighboring line below.

# %h hash and $m hold seen states and maximum fill percentage for current board,
# they are initialized to undef i.e empty and 0.

(@a,%h,$m)=('',map<>=~y/ox\n/\0!/rd,1..$_);

# /
# Then do required number of evolutions:

for$n(0..10){

# Stringify board state, i.e. concatenate lines with spaces ($") as separators.
# Calculate fill percentage - divide number of '!' by number of non-spaces. 
# Note: using $. magick variable automatically takes care of rounding.
# Construct output string. It's not used if loop gets to next iteration. 
# Check if current state was already seen (at the same time add it to %h) 
# and if fill percentage is 0.

$_="Round $n: "
    .($h{$_="@a"}++?repetition:(($.=100*y/!///y/ //c)<$m?$.:$m=$.)?giveup:empty)
    .", $m percent maximum-fill\n";

# /
# Next is funny: if output string contains 'g' (of 'giveup' word), then evolve 
# further, otherwise break-out of the loop.

    @a=/g/
        ?map{

# Do evolution round. Act of evolution for a given line is none other than 
# XOR-ing 4 strings: itself shifted right, itself shifted left, line above, line 
# below. Result of this operation is truncated to original length using bitwise '&'. 
# Note, when shifting string right or left we prepend (append) not an ascii-0, 
# but 'P' character. It's shorter, and 4th and 6th bits will be annihilated anyway.

            $_=$a[$i=$_];
            y//!/cr
            &(s/.//r.P
            ^P.s/.$//r
            ^$a[$i+1]
            ^$a[$i-1])
        }0..$#a
        :last
}
user2846289
quelle
Wow, eine Lösung so schnell. Ich bin erstaunt. Wie starte ich Ihr Skript mit meinen Eingabedaten, da ich mit PERL nicht vertraut bin (obwohl ich es installiert habe)?
Plocks
2
@DevanLoper, z. B. perl -p x.pl < input.txtwenn sich Daten in einer Datei befinden, oder perl -p x.plund Zeile für Zeile, um eine einzelne Eingabe zu testen (mit ctrl-D( ctrl-Z) beenden ). Denken Sie daran, Ihre Perl-Version 5.014oder eine neuere Version zu überprüfen .
user2846289
Danke VadimR, jetzt läuft es. Aber ich habe unterschiedliche Ergebnisse in zwei Zeilen in Bezug auf den Prozentsatz der gedruckten Füllung. Aber das könnte Rundungsfehler sein.
Plocks
1
@ DevanLoper, sorry, es ist mein Fehler, der Prozentsatz stammt aus der vorherigen Iteration. Ich werde es bald beheben.
user2846289
1
Bug behoben, + einige Bytes weggeworfen. Die Testergebnisse stimmen mit denen der verlinkten Site überein. Technisch gesehen werden 11 Runden gefahren, aber der Status der letzten Runde wird weder überprüft noch verwendet. Es ist alles der Kürze halber. Am Anfang habe ich die Bedingungen für die Unterbrechung der Schleife gesetzt, um die 1 \n oEingabe abzufangen.
user2846289
3

C # - 1164 Zeichen

Dies ist meine erste Teilnahme am Code-Golf.

Ich weiß, ich bin weit entfernt von den besten Ergebnissen - übrigens wirklich erstaunlich!

Aber ich dachte, ich würde meine Lösung trotzdem in C # teilen.

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;class Program{static void Main(string[] args){new WebClient().DownloadFile("http://mc.capgemini.de/challenge/in.txt",@"D:\in.txt");var a=File.ReadAllLines(@"D:\in.txt");int l=0;while(l<a.Length){int n=Int32.Parse(a[l]);var b=a.Skip(l+1).Take(n).ToArray();var f=new List<string[]>{b};var d=0;string g=null;while(d<10){var s=f.Last();if(s.All(e=>e.All(c=>c=='o'))){g="empty";break;}var h=new string[n];for(int r=0;r<n;r++){var k="";for(int c=0;c<b[r].Length;c++){int x=0;try{if(s[r][c-1]=='x')x++;}catch{}try{if(s[r][c+1]=='x')x++;}catch{}try{if(s[r-1][c]=='x')x++;}catch{}try{if(s[r+1][c]=='x')x++;}catch{}k+=((x%2)==1)?'x':'o';}h[r]=k;}d++;f.Add(h);var w=false;for(int i=0;i<f.Count-1;i++){var m=f[i];if (!h.Where((t,y)=>t!=m[y]).Any())w=true;}if(w){g="repetition";break;}}if(d==10&&g==null)g="giveup";File.AppendAllLines(@"D:\out.txt",new[]{string.Format("Round {0}: {1}, {2} percent maximum-fill",d,g,f.Select(z=>{int t=0;int x=0;foreach(var c in z.SelectMany(s=>s)){t++;if(c=='x')x++;}return(int)Math.Floor((double)x/t*100);}).Concat(new[]{0}).Max())});l=l+n+1;}}}

Lediglich die using-Direktiven zählen bereits 97 Zeichen - daher denke ich, dass es ziemlich schwierig sein wird, den Rest innerhalb von weniger als 200 Zeichen zu erreichen.

Es ist ein ziemlich iterativer Ansatz, bei dem LINQ an vielen Stellen verwendet wird. Ich habe auch das Herunterladen der Eingabedatei und das Schreiben der Ausgabedatei in den Code aufgenommen.

Hier ist eine etwas besser lesbare Version:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;

class Program
{
    static void Main(string[] args)
    {
        // Download the file
        new WebClient().DownloadFile("http://mc.capgemini.de/challenge/in.txt", @"D:\in.txt");
        // Read of lines of downloaded file
        var a = File.ReadAllLines(@"D:\in.txt");
        // Line index in input file
        int l = 0;
        while (l < a.Length)
        {
            // Parse number of rows to take
            int n = Int32.Parse(a[l]);

            // Take the n rows
            var b = a.Skip(l + 1).Take(n).ToArray();
            var f = new List<string[]> { b };
            var d = 0;
            string g = null;
            while (d < 10)
            {
                // Last state consists only of o's? -> 
                var s = f.Last();
                if (s.All(e => e.All(c => c == 'o')))
                {
                    g = "empty";
                    break;
                }
                // In h we will build up the new state
                var h = new string[n];
                // Loop through all rows of initial state
                for (int r = 0; r < n; r++)
                {
                    // This is our new row we will build up for the current state
                    var k = "";
                    // Count number of orthogonal adjacent x's
                    // And catch potential OutOfRangeExceptions
                    for (int c = 0; c < b[r].Length; c++)
                    {
                        int x = 0;
                        try { if (s[r][c - 1] == 'x') x++; }
                        catch { }
                        try { if (s[r][c + 1] == 'x') x++; }
                        catch { }
                        try { if (s[r - 1][c] == 'x') x++; }
                        catch { }
                        try { if (s[r + 1][c] == 'x') x++; }
                        catch { }
                        // Is number of adjacent x's odd? -> character will be 'x'
                        // otherwise -> 'o'
                        k += ((x % 2) == 1) ? 'x' : 'o';
                    }
                    // Add the new row to the current state
                    h[r] = k;
                }
                // Increase round count
                d++;
                // Add the new state to our state collection
                f.Add(h);
                // Now check, whether it is a repetition by comparing the last state (h) with all other states
                bool w = false;
                for (int i = 0; i < f.Count - 1; i++)
                {
                    var m = f[i];
                    if (!h.Where((t, y) => t != m[y]).Any())
                        w = true;
                }
                if (w)
                {
                    g = "repetition";
                    break;
                }
            }
            // Check whether we reached maximum AND the last round wasn't a repetition
            if (d == 10 && g == null)
                g = "giveup";
            // Now we append the final output row to our text file
            File.AppendAllLines(@"D:\out.txt",
                new[]
                    {
                        string.Format("Round {0}: {1}, {2} percent maximum-fill",
                        d,
                        g,
                        // Here we select all rates of x's per state
                        // and then grab the maximum of those rates
                        f.Select(z =>
                            {
                                int t=0;
                                int x=0;
                                foreach (char c in z.SelectMany(s => s))
                                {
                                    t++;
                                    if(c=='x')
                                        x++;
                                }
                                return (int) Math.Floor((double) x / t *100);
                            }).Concat(new[] {0}).Max())
                    });
            // finally we shift our index to the next (expected) number n in the input file
            l = l + n + 1;
        }
    }
}
Ben Sch
quelle
1
Kurz, kürzer, Bens Lösung. Sie haben ein solches Mikro einer Lösung geschaffen, die in C #
-Begriffen
2

J - 275 char

Oh, all diese I / O-Spezifikationen! So eine beschämend hohe Punktzahl für J am Ende. Übernimmt die Eingabe in STDIN mit einer nachgestellten Zeile und geht davon aus, dass \rdie Eingabe keine Zeilenumbrüche ( ) enthält. Hier ist das Ergebnis der Anwendung auf die Beispieleingabedatei in der Frage.

stdout;,&LF&.>}:(".@{~&0(('Round ',":@(#->/@t),': ',(empty`repetition`giveup{::~2<.#.@t=.11&=@#,0={:),', ',' percent maximum-fill',~0":>./)@(100*1&=%&(+/"1)_&~:)@,.@(a=:(a@,`[@.(e.~+.10<#@[)(_*_&=)+[:~:/((,-)(,:|.)0 1)|.!.0=&1){:)@,:@('ox'&i.^_:)@{.;$: ::]@}.)}.)];._2[1!:1]3

Ungolfed: (Ich kann später eine gründlichere und J-Neuling-freundlichere Erklärung hinzufügen.)

input   =: ];._2 [ 1!:1]3
convert =: 'ox'&i. ^ _:               NB. 'x'=>1  'o'=>0  else=>infinity
spread  =: ((,-)(,:|.)0 1) |.!.0 =&1  NB. x spreading outwards
cover   =: (_*_&=) + [: ~:/ spread    NB. collecting x`s and removing tiles not on board
iterate =: (iterate@, ` [ @. (e.~ +. 10<#@[) cover) {:
percent =: 100 * 1&= %&(+/"1) _&~:    NB. percentage of x at each step
max     =: 0 ": >./
stat    =: 11&=@# , 0={:              NB. information about the simulation
ending  =: empty`repetition`giveup {::~ 2 <. #.@stat   NB. how simulation ended
round   =: ": @ (# - >/@stat)         NB. round number
format  =: 'Round ', round, ': ', ending, ', ', ' percent maximum-fill',~ max
evolvex =: format @ percent@,. @ iterate@,: @ convert
joinln  =: ,&LF &.>
nlines  =: ". @ {~&0
remain  =: }.
stdout ; joinln }: (nlines (evolvex@{. ; $: ::]@}.) remain) input

Der $:Teil bewirkt, dass der Hauptteil über die Eingabe rekursiv wird (eine schrecklich unbequeme Form für das Parsen von J), wobei die @Verkettung über jeden Abschnitt angewendet wird . nlinesfindet die Anzahl der Zeilen für die nächste Tafel.

Die Aktion auf jedem Brett ( evolvex) ist ordentlich: iterate( aim Golf aufgerufen ) erstellt eine Liste jeder Iteration der Simulation, bis wir entweder etwas vorher gesehenes oder zu viele Schritte treffen. Dann percent@,.berechnet den Prozentsatz des gefüllten Quadrats in jedem Ergebnis, und formatläuft einige Statistiken ( stat, genanntt in dem Golf) , um herauszufinden , wie die Simulation beendet, welcher Prozentsatz war die größt, und so weiter, bevor all das in einen String formatiert wird .

Kümmert sich schließlich }:um etwas Müll, bevor ; joinlnalle einzelnen Board-Ausgaben in einer durch Zeilenumbrüche getrennten Zeichenfolge zusammengefasst werden.

algorithmshark
quelle
Hallo algorithmshark, könnten Sie bitte Anweisungen geben, wie Sie Ihr Skript über die Befehlszeile mit einer TXT-Datei als Eingabeparameter starten können? Vielen Dank!
Plocks
1
@ DevanLoper Das erinnert mich, ich habe vergessen, es auf stdout auszugeben; fügte diese Korrektur hinzu. Es sollte die Standardmethode arbeitet jetzt: jconsole golf.ijs < input.txt.
Algorithmushai
Danke für die Info, aber es wird trotzdem keine Ausgabe für mich gedruckt, auch wenn sich dein Code geändert hat.
Plocks
@ DevanLoper Das Problem scheint meine Verwendung vals Name zu sein, was aus irgendeinem Grund in Skripten nicht erlaubt ist. (Ich hatte das Snippet in der REPL ausgeführt.) Das Ändern in ascheint zu funktionieren.
Algorithmushai
@algoshark Es könnte ich sein, aber ich kann es immer noch nicht bekommen, mir irgendetwas auszudrucken.
Plocks