「x」の進化


15

最大サイズが5フィールドの5倍の可変サイズのボードがあります。すべてのフィールドは「x」で埋められます。「x」で埋められていない場合は、「o」で埋められます。

すべてのボードの開始状態が示されます(以下を参照)。各ボードでは、10ラウンドをプレイする必要があり(最大、条件:以下を参照)、xの進化を監視する必要があります。

1ラウンドは次のように機能します。

  1. すべての「x」は、直交するフィールドに広がりますが、消えます
  2. 2つの「x」が1つのフィールドにあるたびに、互いに中和します。

各ラウンドのすべての「x」の進化は同時に発生する必要があります。例:

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

進化の各ラウンドで、ボードに「x」が空になるかどうかを確認する必要があります。空ではない場合、繰り返しパターンが存在する可能性があります。これも当てはまらない場合は、進化の分析を放棄します。さらに、開始ボードごとにxフィールドの最大パーセンテージを印刷する必要があります(整数に切り捨てられます)。

入力:

入力データはここ(Pastebin)にあります。このデータには100の開始状態が含まれています。すでに述べたように、ボードのサイズはさまざまです。行の数は、1から5までの番号nで示され、その後に「x」と「o」のみを含むn行が続き、開始パターンを表します。ボードの各行には1〜5個のフィールドがあります。

出力:

完全な結果を印刷する必要があります。開始ボードごとに1行を次の形式で印刷します。

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

例:

例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

例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

8日後、私は最も少ないキャラクターで作業中の回答を勝者としてマークします。さらに、100個の開始ボード(入力)の正しい出力を投稿します。

好みの(プログラミング/スクリプト/何でも)言語を使用できます。

楽しんで!

PS:ご質問がありましたら、お気軽にお問い合わせください。

PPS:オリジナルクリエイターについて:ドイツ語を話すことができる人のために、ここでネタバレをしたくない場合はクリックしないで ください。チャレンジを完了するための公式時間が終了したので、私は誰かが短くてエレガントな解決策を思い付くことができるかどうかを見たかったです。

22.04.2014:

チャレンジ完了!受賞者は承認済みとしてマークされました。正しい出力:

    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

code-golfまたはcode-challengeとしてタグ付けしてください。両方ではありません。(この場合、コードゴルフである必要があります)。
user80551

1
誰かがこれを明確に定義されたセルオートマトンに変更する必要があります。:
ジャスティン14

回答:


4

Perlの、308、304、305、293、264、262

編集:最近の編集の後にバグが入り込み、空のボードに対して誤った出力を引き起こしました(テストスイートの出力は問題ありませんでした)。以来、Round 0所定の出力形式(いずれもテストスイートではありませんが)入力に空のボードが存在し得ることのみを意味することができ、バグを修正しなければなりませんでした。クイックフィックスとは、バイト数の増加(実際には1)を意味します-もちろんオプションではありません。したがって、もう少しゴルフをしなければなりませんでした。

-p(カウントに+1を追加)で実行し、STDINから読み取ります。r置換修飾子のために5.014が必要です。

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

すなわち

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

うわー、非常に高速なソリューション。びっくりしました。私はPERLに詳しくないので(インストールしています)、入力データを使用してスクリプトを開始するにはどうすればよいですか?
プロック

2
@DevanLoper。たとえばperl -p x.pl < input.txt、データがファイル内にある場合、またはperl -p x.pl単一のエントリをテストするために1行ずつフィードするctrl-D((ctrl-Z)で終了)。あなたのperlが5.014新しいかどうかを確認することを忘れないでください。
user2846289

VadimR、ありがとうございます。しかし、印刷された塗りつぶし率に関しては2行で異なる結果が得られます。しかし、それは丸め誤差である可能性があります。
プロック

1
@DevanLoper、申し訳ありませんが、それは私のエラーです。パーセンテージは前の反復から取得されます。すぐに修正します。
user2846289

1
修正されたバグ+いくつかのバイトが捨てられました。テスト結果は、リンク先サイトのものと一致します。技術的には、11ラウンドが実行されますが、最終ラウンドの状態はチェックも使用もされません。簡潔にするためです。1 \n o入力をキャッチするために、ループブレーク条件を最初に配置しました。
user2846289

3

C#-1164文字

これはコードゴルフへの私の最初の参加ですので、お楽しみください;-)

私は知っている、私は最高の結果からは程遠い-本当に素晴らしい!

しかし、とにかく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;}}}

usingディレクティブはすでに97文字を数えているだけです-したがって、200文字未満で残りを達成するのは非常に難しいと思います。

これはかなり反復的なアプローチであり、多くの場所でLINQを使用しています。また、入力ファイルのダウンロードとコードへの出力ファイルの書き込みも含めました。

ここにもう少し読みやすいバージョンがあります:

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
短く、短く、ベンのソリューション。あなたは... C#の用語で解決思考のようにマイクロを作成しました
ポールFacklam

2

J-275文字

ああ、これらすべてのI / O仕様!最終的には、Jにとってこのような恥ずかしいほど大きなスコアです。STDINの入力に末尾の改行を使用し、キャリッジリターン(\r)します。これを質問のサンプル入力ファイルに適用した結果です。

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:(後でJ-newbieフレンドリな、より徹底した説明を追加するかもしれません。)

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

$:部分は、入力に対して本体を再帰させ(Jが構文解析するのに非常に不便な形式です)、@各セクションにデイジーチェーンを適用します。nlines次のボードの行数を見つけます。

各ボード(evolvex)のアクションはきちんとしています:(ゴルフでiterate呼ばaれます)シミュレーションの各反復のリストを作成し、前に見たものに到達するか、ステップが多すぎます。それからpercent@,.、各結果の塗りつぶされた四角のパーセンテージを計算し、formatいくつかの統計(ゴルフstatで呼ばれるt)を実行して、シミュレーションの終了方法、最大のパーセンテージなどを把握してから、すべてを文字列にフォーマットします。

最後に、個々のボード出力のすべてを1つの改行で区切られた文字列}:; joinln結合する前に、いくつかのゴミを処理します。


こんにちはAlgorithmshark、入力パラメータとして.txtファイルを使用してコマンドラインからスクリプトを開始する方法についての指示を提供できますか?ありがとう!
14

1
@DevanLoperそれは私に思い出させる、私はそれを標準出力に出力することを忘れていました。その修正を追加しました。これで標準的な方法で動作するはずjconsole golf.ijs < input.txtです:。
algorithmshark 14

情報に感謝しますが、コードが変更されたとしても、まだ出力されません。
14

@DevanLoper問題はv、名前としての私の使用のように見えますが、それは何らかの理由でスクリプトで許可されていません。(REPLでスニペットを実行していました。)動作するように変更しaます。
algorithmshark 14

@algosharkそれは私かもしれませんが、私はまだ私に何かを印刷するためにそれを得ることができません。
14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.