Evolusi 'x'

15

Diberikan adalah papan ukuran variabel dengan ukuran maksimum 5 kali 5 bidang. Setiap bidang dapat diisi dengan 'x'. Jika tidak diisi dengan 'x', itu diisi dengan 'o'.

Status awal setiap papan diberikan (lihat di bawah). Dengan setiap papan, 10 putaran harus dimainkan (maksimal, syarat: lihat di bawah) dan evolusi x harus diawasi.

Satu putaran bekerja dengan cara berikut:

  1. setiap 'x' menyebar ke bidang yang berbatasan secara orthogonal, tetapi menghilang dengan sendirinya
  2. setiap kali dua 'x' berada di satu bidang, mereka menetralkan satu sama lain

Evolusi semua 'x' di setiap putaran harus terjadi secara bersamaan. Contoh:

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

Dengan setiap putaran evolusi, Anda harus melihat apakah papan dikosongkan dari 'x'. Kalau tidak kosong, pola berulang bisa hadir. Jika tidak demikian halnya, kami menyerah pada analisis evolusi. Selain itu Anda harus mencetak persentase maksimum bidang x untuk setiap papan awal (dibulatkan ke seluruh angka).

Memasukkan:

Data input dapat ditemukan di sini (Pastebin) Data ini berisi 100 status awal. Seperti yang telah disebutkan, ukuran papan bervariasi. Jumlah baris dinyatakan dengan angka n dari 1 hingga 5, diikuti oleh n baris yang hanya berisi 'x' dan 'o', mewakili pola awal. Setiap baris papan memiliki 1 hingga 5 bidang.

Keluaran:

Hasil lengkap harus dicetak, satu baris tercetak untuk setiap papan awal dalam bentuk berikut:

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

Contoh:

Contoh 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

Contoh 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

Setelah delapan hari saya akan menandai jawaban yang berfungsi dengan karakter paling sedikit sebagai pemenang. Selain itu saya akan memposting output yang benar untuk 100 papan awal (input).

Anda dapat menggunakan bahasa pilihan Anda (pemrograman / skrip / apa pun).

Selamat bersenang-senang!

PS: Jika ada pertanyaan, jangan ragu bertanya.

PPS: Sehubungan dengan pembuat asli: Untuk orang yang mampu berbahasa Jerman, pertanyaan diambil dari JANGAN KLIK JIKA ANDA TIDAK INGIN SPOILER di sini . Karena waktu resmi untuk menyelesaikan tantangan telah berakhir, saya ingin melihat apakah seseorang dapat memberikan solusi yang singkat dan elegan.

22.04.2014:

Tantang Selesai! Pemenang ditandai sebagai diterima. Output yang benar:

    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
sumber
Harap beri tanda sebagai kode-golf atau kode-tantangan tetapi tidak keduanya. (Seharusnya kode-golf dalam hal ini).
user80551
1
Seseorang harus mengubahnya menjadi otomat seluler yang terdefinisi dengan baik. :-)
Justin

Jawaban:

4

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

Sunting: Bug merayap masuk setelah salah satu pengeditan baru-baru ini, menyebabkan output yang salah untuk papan kosong (output test suite OK). Karena Round 0dalam format output yang diberikan hanya dapat berarti bahwa ada papan kosong di input (meskipun tidak ada dalam test suite), bug harus diperbaiki. Perbaikan cepat berarti peningkatan jumlah byte (sebenarnya 1) - bukan pilihan, tentu saja. Karena itu, saya harus bermain golf sedikit lagi.

Jalankan dengan -p(+1 ditambahkan ke hitungan), dibaca dari STDIN. Membutuhkan 5.014 karena rpengubah substitusi.

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

yaitu

# '-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
}
pengguna2846289
sumber
Wow, solusinya sangat cepat. Saya heran. Karena saya tidak terbiasa dengan PERL (saya sudah menginstalnya), bagaimana saya memulai skrip Anda dengan data input saya?
pasang
2
@DevanLoper, mis. perl -p x.pl < input.txtJika data ada dalam file, atau perl -p x.pldan masukkan baris demi baris untuk menguji entri tunggal (diakhiri dengan ctrl-D( ctrl-Z)). Ingatlah untuk memeriksa perl Anda 5.014atau lebih baru.
user2846289
Terima kasih VadimR, sekarang ini berjalan. Tetapi saya memiliki hasil yang berbeda dalam dua baris mengenai persentase pengisian yang tercetak. Tapi itu bisa jadi kesalahan pembulatan.
colok
1
@DevanLoper, maaf, ini kesalahan saya, persentase diambil dari iterasi sebelumnya. Saya akan segera memperbaikinya.
user2846289
1
Bug diperbaiki, + beberapa byte dibuang. Hasil pengujian cocok dengan yang dari situs tertaut. Secara teknis, 11 putaran dijalankan, tetapi keadaan putaran terakhir tidak dicentang atau digunakan. Ini semua untuk singkatnya. Saya menempatkan kondisi melanggar lingkaran di awal untuk menangkap 1 \n oinput.
user2846289
3

C # - 1164 karakter

Ini adalah partisipasi pertama saya dalam kode-golf jadi harap memanjakan ;-)

Saya tahu, saya jauh dari hasil terbaik - sungguh menakjubkan!

Tapi saya pikir saya akan membagikan solusi saya dalam C #.

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

Semata-mata arahan menggunakan sudah menghitung 97 karakter - jadi saya pikir itu akan sangat sulit untuk mencapai sisanya dalam waktu kurang dari 200 karakter.

Ini adalah pendekatan yang cukup iteratif, memanfaatkan LINQ di banyak tempat. Saya juga memasukkan pengunduhan file input dan penulisan file output ke dalam kode.

Berikut ini satu versi yang lebih mudah dibaca:

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
sumber
1
Singkat, lebih pendek, Solusi Ben. Anda telah membuat mikro solusi yang berpikir dalam istilah C # ...
Paul Facklam
2

J - 275 char

Oh, semua spesifikasi I / O ini! Skor yang sangat memalukan bagi J, pada akhirnya. Mengambil input pada STDIN dengan trailing newline, dan mengasumsikan tidak ada carriage return ( \r) pada input. Inilah hasil penerapannya pada file input sampel dalam pertanyaan.

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

Tidak dikelompokkan: (Saya dapat menambahkan penjelasan yang lebih menyeluruh dan ramah bagi pemula).)

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

Bagian tersebut $:membuat badan utama berulang atas input (bentuk yang sangat tidak nyaman untuk mengurai J), menerapkan @rantai daisy pada setiap bagian. nlinesmenemukan jumlah garis untuk papan berikutnya.

Tindakan pada setiap papan ( evolvex) rapi: iterate(dipanggil adalam golf) menyusun daftar setiap iterasi simulasi sampai kami mencapai sesuatu yang terlihat sebelumnya atau terlalu banyak langkah. Kemudian percent@,.hitung persentase kuadrat terisi pada setiap hasil, danformat jalankan beberapa statistik ( stat, dipanggil tdalam golf) untuk mengetahui bagaimana simulasi berakhir, persentase mana yang terbesar, dan seterusnya, sebelum memformat semua itu menjadi string.

Akhirnya, }:urus beberapa sampah sebelum ; joinlnbergabung dengan semua output papan individu menjadi satu string yang dipisahkan baris baru.

algoritme hiu
sumber
Hai algoritme hiark, bisakah Anda memberikan petunjuk tentang cara memulai skrip dari baris perintah dengan file .txt sebagai parameter input? Terima kasih!
colok
1
@DevanLoper Itu mengingatkan saya, saya lupa membuatnya menjadi stdout; menambahkan koreksi itu. Ini harus bekerja dengan cara standar sekarang: jconsole golf.ijs < input.txt.
algorithmshark
Terima kasih atas informasinya, tetapi masih tidak mencetak output untuk saya, bahkan dengan kode Anda berubah.
pasang
@DevanLoper Masalahnya tampaknya saya gunakan vsebagai nama, yang karena alasan apa pun tidak diizinkan dalam skrip. (Saya telah menjalankan cuplikan di REPL.) Mengubahnya atampaknya berfungsi.
algorithmshark
@algoshark Bisa jadi saya, tapi saya masih belum bisa mencetaknya.
pasang