Evoluzione della "x"


15

Dato è una scheda di dimensioni variabili con una dimensione massima di 5 volte 5 campi. Ogni campo può essere riempito con una 'x'. Se non è riempito con una 'x', è riempito con una 'o'.

Viene indicato lo stato iniziale di ogni scheda (vedere di seguito). Con ogni tavola, devono essere giocati 10 round (al massimo, condizioni: vedi sotto) e l'evoluzione della x deve essere osservata.

Un round funziona nel modo seguente:

  1. ogni "x" si diffonde in campi confinanti ortogonalmente, ma scompare da sola
  2. ogni volta che due "x" sono su un campo, si neutralizzano a vicenda

L'evoluzione di tutte le 'x' in ogni round deve avvenire contemporaneamente. Esempio:

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

Ad ogni round di evoluzione, devi vedere se il tabellone si svuota di 'x'. Se non è vuoto, potrebbe essere presente uno schema ripetuto. In caso contrario, rinunciamo all'analisi dell'evoluzione. Inoltre, devi stampare la percentuale massima di campi x per ogni tavola di partenza (arrotondata per difetto a numeri interi).

Ingresso:

I dati di input sono disponibili qui (Pastebin) Questi dati contengono 100 stati iniziali. Come già accennato, le schede hanno dimensioni variabili. Il numero di righe è indicato con il numero n da 1 a 5, seguito da n righe che contengono solo 'x' e 'o', rappresentano il modello iniziale. Ogni riga di una tavola ha da 1 a 5 campi.

Produzione:

Il risultato completo deve essere stampato, una riga stampata per ogni tavola di partenza nel seguente formato:

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

Esempi:

Esempio 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

Esempio 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

Dopo otto giorni segnerò la risposta operativa con il minor numero di personaggi come vincitore. Inoltre pubblicherò l'output corretto per le 100 schede di partenza (input).

Puoi usare la tua lingua preferita (programmazione / scripting o altro).

Divertiti!

PS: se hai domande, sentiti libero di chiedere.

PPS: Rispetto ai creatori originali: per le persone in grado di parlare tedesco, la domanda è stata presa da NON FARE CLIC SE NON VUOI SPOILER qui . Dal momento che il tempo ufficiale per completare la sfida è finito, volevo vedere se qualcuno potesse trovare una soluzione breve ed elegante.

2014/04/22:

Sfida completata! Vincitore contrassegnato come accettato. Uscita corretta:

    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

Si prega di taggare come code-golf o code-challenge ma non entrambi. (Dovrebbe essere code-golf in questo caso).
user80551

1
Qualcuno dovrebbe cambiarlo in un automa cellulare ben definito. :-)
Justin

Risposte:


4

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

Modifica: si è verificato un errore dopo una delle recenti modifiche, causando un output errato per le schede vuote (l'output della suite di test era OK). Poiché Round 0in un determinato formato di output può significare solo che possono esserci schede vuote nell'input (sebbene nessuna sia nella suite di test), il bug ha dovuto essere corretto. La correzione rapida significava un aumento del conteggio dei byte (di 1, in realtà) - ovviamente non un'opzione. Pertanto, ho dovuto giocare a golf un po 'di più.

Esegui con -p(+1 aggiunto al conteggio), legge da STDIN. Richiede 5.014 a causa del rmodificatore di sostituzione.

(@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}

vale a dire

# '-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
}

Caspita, una soluzione così veloce. Sono stupito. Dal momento che non ho familiarità con PERL (ce l'ho installato), come posso iniziare il tuo script con i miei dati di input?
apre il

2
@DevanLoper, ad es. perl -p x.pl < input.txtSe i dati sono in un file o perl -p x.ple avanzano riga per riga per testare una singola voce (terminare con ctrl-D( ctrl-Z)). Ricorda di controllare il tuo perl è 5.014o più recente.
user2846289

Grazie VadimR, ora funziona. Ma ho due risultati diversi in due righe riguardanti la percentuale di riempimento stampata. Ma potrebbero essere errori di arrotondamento.
apre il

1
@DevanLoper, scusa, è un mio errore, la percentuale è presa dall'iterazione precedente. Lo riparerò presto.
user2846289

1
Bug risolto, + alcuni byte eliminati. I risultati dei test corrispondono a quelli del sito collegato. Tecnicamente, vengono eseguiti 11 round, ma lo stato dell'ultimo round non viene verificato né utilizzato. È tutto per brevità. Ho inserito le condizioni di interruzione del loop all'inizio per catturare l' 1 \n oinput.
user2846289

3

C # - 1164 caratteri

Questa è la mia prima partecipazione al code-golf, quindi per favore sii indulgente ;-)

Lo so, sono molto lontana dai migliori risultati - tra l'altro davvero incredibile!

Ma ho pensato di condividere la mia soluzione in C # comunque.

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;}}}

Solo le direttive sull'utilizzo contano già 97 caratteri, quindi penso che sarà abbastanza difficile ottenere il resto in meno di 200 caratteri.

È un approccio piuttosto iterativo, che utilizza LINQ in molti luoghi. Ho anche incluso il download del file di input e la scrittura del file di output nel codice.

Ecco una versione un po 'più leggibile:

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;
        }
    }
}

1
Breve, più breve, la soluzione di Ben. Hai creato una tale micro di soluzione pensando in termini di C # ...
Paul Facklam,

2

J - 275 caratteri

Oh, tutte queste specifiche I / O! Un punteggio così vergognoso per J, alla fine. Prende input su STDIN con una nuova riga finale e presume che non ci siano ritorni a capo ( \r) nell'input. Ecco il risultato dell'applicazione al file di input di esempio nella domanda.

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: (Potrei aggiungere una spiegazione più approfondita e amichevole per i neofiti in seguito.)

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

La $:parte fa ricorrere al corpo principale sull'input (un modulo terribilmente scomodo da analizzare per J), applicando il @collegamento a margherita su ciascuna sezione. nlinestrova il numero di righe per la scheda successiva.

L'azione su ogni board ( evolvex) è ordinata: iterate(chiamato anel golf) costruisce un elenco di ogni iterazione della simulazione fino a quando non colpiamo qualcosa visto prima o troppi passaggi. Quindi percent@,.calcola la percentuale di quadrato pieno in ciascun risultato ed formatesegue alcune statistiche ( stat, chiamate tnel campo da golf) per capire come è terminata la simulazione, quale percentuale è stata la più grande e così via, prima di formattare tutto ciò in una stringa.

Infine, }:si occupa di un po 'di immondizia prima di ; joinlnunire tutti gli output delle singole schede in una stringa separata da una nuova riga.


Ciao algoritmo, potresti fornire istruzioni su come avviare lo script dalla riga di comando con un file .txt come parametro di input? Grazie!
apre il

1
@DevanLoper Questo mi ricorda, ho dimenticato di renderlo output su stdout; aggiunta quella correzione. Dovrebbe funzionare il modo standard ora: jconsole golf.ijs < input.txt.
algoritmo

Grazie per le informazioni, ma non stampa ancora alcun output per me, anche con il codice modificato.
apre il

@DevanLoper Il problema sembra essere il mio uso di vcome nome, che per qualsiasi motivo non è consentito negli script. (Avevo eseguito lo snippet in REPL.) La modifica in asembra funzionare.
algoritmo

@algoshark Potrei essere io, ma non riesco ancora a farmi stampare qualcosa.
apre il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.