'x'의 진화


15

최대 크기가 5 x 5 필드 인 가변 크기 보드가 제공됩니다. 모든 필드는 'x'로 채워져 있습니다. 'x'로 채워지지 않으면 'o'로 채워집니다.

모든 보드의 시작 상태가 제공됩니다 (아래 참조). 각 보드마다 10 라운드를 플레이해야하며 (최대, 조건 : 아래 참조) x의 진화를 관찰해야합니다.

한 라운드는 다음과 같은 방식으로 작동합니다.

  1. 모든 'x'는 직교 경계 필드로 확산되지만 자체적으로 사라집니다.
  2. 두 개의 'x'가 한 필드에있을 때마다 서로 중화됩니다.

각 라운드에서 모든 '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 개의 필드가 있습니다.

산출:

전체 결과는 다음과 같은 형식으로 각 시작 보드마다 한 줄씩 인쇄해야합니다.

    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 개의 시작 보드 (입력)에 대한 올바른 출력을 게시합니다.

선호하는 (프로그래밍 / 스크립팅 / 어쨌든) 언어를 사용할 수 있습니다.

즐기세요!

추신 : 질문이 있으시면 언제든지 문의하십시오.

PPS : 독창적 인 제작자 : 독일어를 할 줄 아는 사람들의 경우, 여기에 스포일러를 원하지 않으면 클릭 하지 마십시오 . 도전을 완료하기위한 공식 시간이 끝났으므로, 누군가가 짧고 우아한 해결책을 제시 할 수 있는지 알고 싶었습니다.

2014 년 4 월 22 일 :

도전하세요! 수상자가 수락 된 것으로 표시되었습니다. 올바른 출력 :

    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
누군가 이것을 이것을 잘 정의 된 셀룰러 오토 마톤으로 바꿔야합니다. :-)
저스틴

답변:


4

펄, 308, 304, 305, 293, 264 , 262

편집 : 최근 편집 중 하나에서 버그가 발생하여 빈 보드에 대해 잘못된 출력이 발생합니다 (테스트 스위트 출력은 정상이었습니다). Round 0주어진 출력 형식에서는 입력에 빈 보드가있을 수 있음을 의미 할 수 있기 때문에 (테스트 스위트에는 없음) 버그를 수정해야했습니다. 빠른 수정은 물론 옵션이 아닌 바이트 수 증가 (실제로는 1 씩 증가)를 의미했습니다. 따라서 골프를 조금 더해야했습니다.

-pSTDIN에서 읽은 (+1을 카운트로 추가)로 실행 합니다. 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에 익숙하지 않기 때문에 (설치되어 있지만) 입력 데이터로 스크립트를 어떻게 시작합니까?
plocks

2
@DevanLoper, 예를 들어 perl -p x.pl < input.txt데이터가 파일에 있거나 perl -p x.pl단일 항목을 테스트하기 위해 한 줄씩 피드 ctrl-D(( ctrl-Z)로 종료 ). 펄이 5.014최신인지 확인하십시오 .
user2846289

감사합니다 VadimR, 이제 실행됩니다. 그러나 인쇄 된 채우기 비율과 관련하여 두 줄로 다른 결과가 있습니다. 그러나 반올림 오류 일 수 있습니다.
plocks

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
짧고 짧으며 Ben의 솔루션. 당신은 C # 용어로 생각하는 솔루션의 마이크로를 만들었습니다.
Paul 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- 초보자 친화적 인 설명을 추가 할 수 있습니다.)

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골프에서 호출 )를 실행하여 시뮬레이션이 어떻게 종료되었는지, 백분율이 가장 큰 등을 문자열로 형식화하기 전에 계산합니다.

마지막으로 모든 개별 보드 출력을 하나의 줄 바꿈 문자열로 결합 }:하기 전에 약간의 가비지를 처리 ; joinln합니다.


안녕하세요 algorithmshark, 입력 매개 변수로 .txt 파일을 사용하여 명령 줄에서 스크립트를 시작하는 방법에 대한 지침을 제공해 주시겠습니까? 감사!
plocks

1
@DevanLoper 저에게 상기시켜주는 것은 stdout으로 출력하는 것을 잊었습니다; 그 수정을 추가했습니다. 이제 표준 방식으로 작동해야합니다 jconsole golf.ijs < input.txt.
algorithmshark

정보에 감사하지만 코드가 변경 되어도 여전히 출력을 인쇄하지 않습니다.
plocks

@DevanLoper 문제 v는 어떤 이유로 든 스크립트에서 허용되지 않는 이름으로 사용하는 것 같습니다. (REPL에서 스 니펫을 실행했습니다.) a작동 하도록 변경했습니다 .
algorithmshark

@algoshark 그것은 나일 수 있지만 여전히 나에게 아무것도 인쇄 할 수는 없습니다.
plocks
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.