Еволюція "х"


15

Дана дошка змінного розміру з максимальним розміром у 5 разів 5 полів. Кожен польовий канн заповнюється символом "x". Якщо вона не заповнена символом "x", вона заповнюється символом "o".

Наводиться початковий стан кожної дошки (див. Нижче). З кожною дошкою потрібно провести 10 раундів (за максимумом, умови: див. Нижче), і слідкувати за еволюцією x.

Один раунд працює наступним чином:

  1. кожен x поширюється на ортогонально межуючі поля, але відпадає
  2. кожного разу, коли два «х» знаходяться на одному полі, вони нейтралізують один одного

Еволюція всіх "х" у кожному раунді повинна відбуватися одночасно. Приклад:

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

З кожним етапом еволюції ви повинні бачити, чи дошка не буде випорожнена "x". Якщо це не порожньо, може бути присутнім повторюваний шаблон. Якщо це теж не так, ми відмовляємось від аналізу еволюції. Крім того, ви повинні роздрукувати максимальний відсоток x полів для кожної стартової дошки (округлену до цілих чисел).

Вхід:

Вхідні дані можна знайти тут (Pastebin) Ці дані містять 100 стартових станів. Як вже було сказано, дошки відрізняються за розміром. Кількість рядків зазначається цифрою n від 1 до 5, а далі n рядків, що містять лише "x" і "o", являють собою початковий малюнок. Кожен ряд дошки має від 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

Після восьми днів я позначу робочу відповідь з найменшими персонажами як переможця. Додатково я опублікую правильний вихід для 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

Будь ласка, позначте як код-гольф або виклик коду, але не обидва. (У цьому випадку це повинен бути код-гольф).
user80551

1
Хтось повинен змінити це на чітко визначений стільниковий автомат. :-)
Джастін

Відповіді:


4

Перл, 308, 304, 305, 293, 264 , 262

Редагувати: помилка виникла після одного з останніх редагувань, що спричинило неправильний вихід порожніх дощок (вихід тестового набору був у порядку). Оскільки Round 0у заданому вихідному форматі може означати лише те, що на вході можуть бути порожні дошки (хоча жодна не є в тестовому наборі), помилку довелося виправити. Швидке виправлення означало збільшення кількості байтів (фактично на 1) - звичайно, не варіант. Тому мені довелося трохи більше пограти в гольф.

Запустити з -p(додано +1 для підрахунку), читає з STDIN. Потрібно 5.014 через rмодифікатор заміни.

(@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подається рядок за рядком для перевірки одного запису (завершити з ctrl-D( ctrl-Z)). Не забудьте перевірити, 5.014чи є ваш perl чи новіший.
користувач2846289

Спасибі ВадимР, зараз він працює. Але я маю різні результати в двох рядках щодо відсотка надрукованого заповнення. Але це можуть бути помилки округлення.
заговори

1
@DevanLoper, вибачте, це моя помилка, відсоток взято з попередньої ітерації. Я скоро це виправлю.
користувач2846289

1
Виправлено помилку, + кілька байтів викинуто. Результати тестів відповідають результатам із пов’язаного веб-сайту. Технічно проводиться 11 раундів, але стан останнього раунду не перевіряється і не використовується. Це все для стислості Я розмістив умови розбиття циклу на початку, щоб зафіксувати 1 \n oвхід.
користувач2846289

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

Тільки що директиви, що використовують, вже налічують 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 # термінах ...
Пол Факлам

2

J - 275 char

О, всі ці специфікації вводу / виводу! Такий ганебно великий результат для 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в гольфі), щоб з'ясувати, як закінчилося моделювання, який відсоток був найбільшим тощо, перш ніж форматувати все це у рядок.

Нарешті, }:доглядайте за сміттям, перш ніж ; joinlnз'єднати всі виходи окремих дощок в одну рядку, розділену новим рядком.


Вітаю, алгоритм, добре, будь ласка, надайте інструкції, як запустити свій скрипт із командного рядка з файлом .txt як вхідним параметром? Спасибі!
заговори

1
@DevanLoper Це мені нагадує, я забув зробити його виведенням на stdout; додав, що виправлення. Він повинен працювати стандартний спосіб в даний час: jconsole golf.ijs < input.txt.
алгоритм

Дякую за інформацію, але вона все ще не роздруковує жодного результату для мене, навіть якщо ваш код змінено.
заговори

@DevanLoper Проблема, як видається, полягає в моєму використанні vяк імені, яке з будь-якої причини заборонено в сценаріях. (Я працював у фрагменті у відповіді.) Зміна його, aсхоже, працює.
Алгоритм

@algoshark Це міг бути я, але я все ще не можу його отримати, щоб мені щось надрукувати.
заговори
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.