Код гольфу: Гра життя Конвея


76

Завдання: Напишіть найкоротшу програму, яка реалізує клітинний автомат « Гра життя» Джона Х. Конвея . [ посилання ]

РЕДАГУВАТИ: Приблизно через тиждень змагань, я вибрав переможця: pdehaan , щоб мені вдалося перемогти рішення Matlab одним персонажем за допомогою perl.

Для тих, хто не чув про «Гра життя», ви берете сітку (в ідеалі нескінченну) квадратних клітинок. Клітини можуть бути живими (наповненими) або мертвими (порожніми). Ми визначаємо, які клітини живі на наступному кроці часу, застосовуючи такі правила:

  1. Будь-яка жива клітина, у якій менше двох живих сусідів, гине, ніби спричинена недостатньою чисельністю населення.
  2. Будь-яка жива клітина з більш ніж трьома живими сусідами гине, ніби через перенаселеність.
  3. Будь-яка жива клітина з двома-трьома живими сусідами живе до наступного покоління.
  4. Будь-яка мертва клітина з рівно трьома живими сусідами стає живою клітиною, ніби шляхом розмноження.

Ваша програма читатиме текстовий файл ASCII розміром 40x80 символів, вказаний як аргумент командного рядка, а також кількість ітерацій (N), які потрібно виконати. Нарешті, він виведе у файл ASCII out.txt стан системи після N ітерацій.

Ось приклад запуску з відповідними файлами:

in.txt:

................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.............................................
.......................................X........................................
................................XXXXXX.X........................................
................................X...............................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................

Повторіть 100 разів:

Q:\>life in.txt 100

Результат (out.txt)

................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
..................................XX............................................
..................................X.X...........................................
....................................X...........................................
................................XXXXX.XX........................................
................................X.....X.........................................
.................................XX.XX...XX.....................................
..................................X.X....X.X....................................
..................................X.X......X....................................
...................................X.......XX...................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................
................................................................................

Правила:

  • Вам потрібно використовувати файловий ввід / вивід для читання / запису файлів.
  • Вам потрібно прийняти в якості вхідного файлу та кількість ітерацій як аргументи
  • Вам потрібно створити out.txt (перезаписати, якщо він існує) у вказаному форматі
  • Вам не потрібно мати справу з краями дошки (обгортка, нескінченні сітки. Тощо)
  • EDIT: Ви дійсно повинні мати в своєму нового рядка вихідного файлу.

Переможець визначатиметься за підрахунком символів.

Удачі!


22
Це такий чудовий кодовий гольф! І я цілком вважаю, що це належить SO. Я знайшов чудову реалізацію в APL кілька днів тому: youtube.com/watch?v=a9xAKttWgP4
Віктор Хурдугаці

Прийнятна ідея, але вам потрібно її посилити. meta.stackexchange.com/questions/24242/…
zaf

4
відносна популярність - погана метрика для гольфу. perl завжди отримує багато голосів, навіть якщо він не найкоротший, і навіть якщо не відповідає специфікації. слід дотримуватися підрахунку символів. Люди з більш багатослівними мовами все ще змагаються між собою
Джон Ла Рой,

2
О, Боже мій, що страшно. Саме в цей момент я хотів опублікувати точно такий же конкурс. : O
Вінсент

2
Чи є у вхідному файлі нові рядки?
Гейб,

Відповіді:


24

perl, 127 129 135 символів

Вдалося позбавити ще пари символів ...

$/=pop;@b=split'',<>;map{$n=-1;@b=map{++$n;/
/?$_:($t=grep/X/,@b[map{$n+$_,$n-$_}1,80..82])==3|$t+/X/==3?X:'.'}@b}1..$/;print@b

2
Дуже мило! Вам вдалося перемогти пару спеціалізованих мов із більш загальною. :)
hb2pencil

4
це пише в 'out.txt'?
AShelly

2
@b=<>=~/./gзберігає більше 3 гольця
моб

40

Mathematica - 179 163 154 151 151 знак

    a = {2, 2, 2};
    s = Export["out.txt", 
       CellularAutomaton[{224, {2, {a, {2, 1, 2}, a}}, {1,1}}, 
                (ReadList[#1, Byte, RecordLists → 2>1] - 46)/ 42, #2]〚#2〛
       /. {0 → ".", 1 → "X"}, "Table"] &
Додано місця для читабельності

Закликати с

    s["c:\life.txt", 100]

Анімація:

текст заміщення

Ви також можете отримати графік середнього населення за певний час:

текст заміщення

Гарний зразок для створення планерів з Вікіпедії

аа

AFAIK Mathematica використовує стільниковий автомат для генерації випадкових чисел за допомогою правила 30.


1
На основі анімації, здається, вона не розвивається правильно.
gnovice

62
наявність вбудованої CellularAutomatonфункції, здається, вирішує деякі проблеми.
Ешлі

@gnovice так. сталася помилка ... tnx!
Доктор Белісарій,

17
@AShelly Я гадаю, що виклики кодового гольфу можна виконувати в обидві сторони>
Підправити неналежний

2
@Adrian Різні виклики різними мовами. У Mathematica форматування ASCII є головним болем ...
Доктор Белісаріус,

33

MATLAB 7.8.0 (R2009a) - 174 171 161 150 138 131 128 124 символів

Синтаксис функції: (124 символи)

Ось легша для читання версія (з додаванням зайвих рядків та пробілів для кращого форматування):

function l(f,N),
  b=char(importdata(f))>46;
  for c=1:N,
    b=~fix(filter2(ones(3),b)-b/2-3);
  end;
  dlmwrite('out.txt',char(b*42+46),'')

Ось як програма запускається з командного вікна MATLAB:

l('in.txt',100)

Синтаксис команди: (130 символів)

Після коментаря щодо виклику функцій із синтаксисом команди, я поглибився трохи глибше і з’ясував, що фактично функції MATLAB можна викликати у форматі командного рядка (з деякими обмеженнями). Ви щодня дізнаєтесь щось нове!

function l(f,N),
  b=char(importdata(f))>46;
  for c=1:eval(N),
    b=~fix(filter2(ones(3),b)-b/2-3);
  end;
  dlmwrite('out.txt',char(b*42+46),'')

Ось як програма запускається з командного вікна MATLAB:

l in.txt 100


Додатковий виклик: Tweetable GIF maker - 136 символів

Для розваги я подумав, чи не зможу я вивести вихідні дані у файл GIF замість текстового файлу, зберігаючи при цьому кількість символів нижче 140 (тобто "tweetable"). Ось приємно відформатований код:

function l(f,N),
  b=char(importdata(f))>46;
  k=ones(3);
  for c=1:N+1,
    a(:,:,:,c)=kron(b,k);
    b=~fix(filter2(k,b)-b/2-3);
  end;
  imwrite(~a,'out.gif')

Незважаючи на те, що IMWRITE повинен створити GIF, який за замовчуванням нескінченно циклічно повторюється , мій GIF повторюється лише один раз. Можливо, це помилка, яку було виправлено в нових версіях MATLAB. Отже, щоб анімація тривала довше та полегшила перегляд кроків еволюції, я залишив затримку кадру за значенням за замовчуванням (яке, здається, становить приблизно півсекунди). Ось вихід GIF із використанням шаблону пістолета Gosper Glider :

текст заміщення


Покращення

  • Оновлення 1: Змінено матрицю bз логічного (тобто "булевого") типу на числовий, щоб позбутися кількох перетворень.
  • Оновлення 2: Скоротив код для завантаження файлу та використав функцію MAGIC як трюк для створення ядра згортки із меншою кількістю символів.
  • Оновлення 3: спрощено логіку індексації, замінено ~~b+0на b/42та замінено 'same'на 's'як аргумент для CONV2 (і це, на диво, все-таки спрацювало!).
  • Оновлення 4: Думаю, я мав би спершу шукати в Інтернеті, оскільки Лорен з The MathWorks вела блоги про гольф та «Гра життя» на початку цього року. Я включив деякі з обговорених там технік, які вимагали від мене bповернення до логічної матриці.
  • Оновлення 5: коментар від Aslak Grinsted на вищевказаному блозі передбачає більш короткий алгоритм як логіки і виконання згортки ( з допомогою функції Filter2 ), так що я «включено» (читай «скопійовані») свої пропозиції. ;)
  • Оновлення 6: обрізано два символи з ініціалізації bта перероблено логіку в циклі, щоб зберегти 1 додатковий символ.
  • Оновлення 7: Ерік Самсон зазначив в електронній пошті , що я міг би замінити cell2matз char, зберігаючи 4 -х символів. Дякую Еріку!

@AShelly: Покопавши ще трохи, я виявив, що можна викликати функції MATLAB із синтаксисом команди (що я раніше не думав, що це можливо). Я додав це інше рішення до своєї відповіді. Він додає лише 6 символів.
gnovice

30

Рубінові 1,9 - 189 178 159 155 153 символів

f,n=$*
c=IO.read f
n.to_i.times{i=0;c=c.chars.map{|v|i+=1
v<?.?v:('...X'+v)[[83,2,-79].map{|j|c[i-j,3]}.to_s.count ?X]||?.}*''}
File.new('out.txt',?w)<<c

Редагувати: обробляє нові рядки з 4 символами менше.
Можна видалити ще 7 ( v<?.?v:), якщо ви дозволите йому затухати нові рядки, коли живі клітини досягнуть країв.


19
Просто почекайте, поки прийдуть хлопці з Perl ...;)
Младен Ябланович

1
@ hb2pencil, Младене, я не думаю, що відповідь на кодовий гольф ніколи не була прийнята до того, як було подано хоча б один запис на perl :)
Джон Ла Рой,

Я бачу, що конкуренція нагрівається, тож я зачекаю. Дякую!
hb2pencil

Я думаю, ви можете відняти 12 символів, замінивши 3-й рядок на v<13?v:l==3||v-l==?T?X:?.}}. Але у мене не встановлено 1.9 для тестування.
AShelly

Я не думаю, що ви можете порівняти v(рядок) із цілим числом.
Младен Ябланович,

20

Пітон - 282 символи

цілком можливо, щоб м'яч котився ...

import sys
_,I,N=sys.argv;R=range(3e3);B=open(I).read();B=set(k for k in R if'A'<B[k])
for k in R*int(N):
 if k<1:b,B=B,set()
 c=sum(len(set((k+o,k-o))&b)for o in(1,80,81,82))
 if(c==3)+(c==2)*(k in b):B.add(k)
open('out.txt','w').write(''.join('.X\n'[(k in B)-(k%81<1)]for k in R))

6
мені розбиває серце бачити, як пітон заплутаний - це такий спосіб; P гарна робота :)
Ешлі Гренон

1
Затуманений? Я думав, що це було досить чисто? ;)
Kyle Rosendo

1
Але 2.7 (і 3.x) приймає фігурні дужки для розуміння набору, тому set(...)їх можна замінити на {...}, а заміна range(3e3)на range(3000)дає чисте поліпшення на 2 символи.
Дон О'Доннелл

20

Python 2.x - 210/234 символів

Гаразд, код із 210 символів - це свого роду обман.

#coding:l1
exec'xÚ=ŽA\nÂ@E÷sŠº1­ƒÆscS‰ØL™Æª··­âî¿GÈÿÜ´1iÖ½;Sçu.~H®J×Þ-‰­Ñ%ª.wê,šÖ§J®d꘲>cÉZË¢V䀻Eîa¿,vKAËÀå̃<»Gce‚ÿ‡ábUt¹)G%£êŠ…óbÒüíÚ¯GÔ/n×Xši&ć:})äðtÏÄJÎòDˆÐÿG¶'.decode('zip')

Можливо, ви не зможете скопіювати та вставити цей код і змусити його працювати. Це має бути Latin-1 (ISO-8859-1), але я думаю, що це десь по шляху перекрутилося у Windows-1252. Крім того, ваш браузер може проковтнути деякі символи, що не належать до ASCII.

Отже, якщо це не працює, ви можете створити файл із простих старих 7-бітових символів:

s = """
23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 3D 8E 41 5C 6E C2
40 0C 45 F7 73 8A BA 31 13 AD 83 15 11 11 C6 73 08 63 17 05 53 89 D8 4C
99 C6 AA B7 B7 AD E2 EE BF 47 C8 FF DC B4 31 69 D6 BD 3B 53 E7 75 2E 7E
48 AE 4A D7 DE 90 8F 2D 89 AD D1 25 AA 2E 77 16 EA 2C 9A D6 A7 4A AE 64
EA 98 B2 3E 63 C9 5A CB A2 56 10 0F E4 03 80 BB 45 16 0B EE 04 61 BF 2C
76 0B 4B 41 CB C0 E5 CC 83 03 3C 1E BB 47 63 65 82 FF 87 E1 62 55 1C 74
B9 29 47 25 A3 EA 03 0F 8A 07 85 F3 62 D2 FC ED DA AF 11 47 D4 2F 6E D7
58 9A 69 26 C4 87 3A 7D 29 E4 F0 04 74 CF C4 4A 16 CE F2 1B 44 88 1F D0
FF 47 B6 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29
"""

with open('life.py', 'wb') as f:
    f.write(''.join(chr(int(i, 16)) for i in s.split()))

Результатом цього є дійсний вихідний файл із Python із 210 символів. Все, що я тут зробив, - це стиснення zip у вихідному вихідному коді Python. Справжній обман полягає в тому, що я використовую символи, що не є ASCII, у результуючому рядку. Це все ще дійсний код, він просто громіздкий.

Нестиснута версія важить 234 символи, що, як мені здається, все ще поважно.

import sys
f,f,n=sys.argv
e=open(f).readlines()
p=range
for v in p(int(n)):e=[''.join('.X'[8+16*(e[t][i]!='.')>>sum(n!='.'for v in e[t-1:t+2]for n in v[i-1:i+2])&1]for i in p(80))for t in p(40)]
open('out.txt','w').write('\n'.join(e))

Вибачте за горизонтальну прокрутку, але всі перелічені вище рядки обов’язкові, і я зарахував їх як по одному символу.

Я б не намагався читати гольф-код. Імена змінних вибираються випадковим чином для досягнення найкращого стиснення. Так, я серйозно. Нижче наведено краще відформатований і коментований варіант

# get command-line arguments: infile and count
import sys
ignored, infile, count = sys.argv

# read the input into a list (each input line is a string in the list)
data = open(infile).readlines()

# loop the number of times requested on the command line
for loop in range(int(count)):
    # this monstrosity applies the rules for each iteration, replacing
    # the cell data with the next generation
    data = [''.join(

                # choose the next generation's cell from '.' for
                # dead, or 'X' for alive
                '.X'[

                    # here, we build a simple bitmask that implements
                    # the generational rules.  A bit from this integer
                    # will be chosen by the count of live cells in
                    # the 3x3 grid surrounding the current cell.
                    #
                    # if the current cell is dead, this bitmask will
                    # be 8 (0b0000001000).  Since only bit 3 is set,
                    # the next-generation cell will only be alive if
                    # there are exactly 3 living neighbors in this
                    # generation.
                    #
                    # if the current cell is alive, the bitmask will
                    # be 24 (8 + 16, 0b0000011000).  Since both bits
                    # 3 and 4 are set, this cell will survive if there
                    # are either 3 or 4 living cells in its neighborhood,
                    # including itself
                    8 + 16 * (data[y][x] != '.')

                    # shift the relevant bit into position
                    >>

                    # by the count of living cells in the 3x3 grid
                    sum(character != '.' # booleans will convert to 0 or 1
                        for row in data[y - 1 : y + 2]
                        for character in row[x - 1 : x + 2]
                    )

                    # select the relevant bit
                    & 1
                ]

               # for each column and row
                for x in range(80)
            )
            for y in range(40)
    ]

# write the results out
open('out.txt','w').write('\n'.join(data))

Вибачте, Pythonistas, щодо форматування дужки C-ish, але я намагався пояснити, що закриває кожна дужка.


1
+1 Молодці, unicode - це чесна гра для codegolf на SO - зовсім не "вид обману"
Джон Ла Рой

open(f).readlines()слід поставити як list(open(f)). Еквівалент і шість символів коротше зменшене і на 3 байти коротше застібку-блискавку і, що цікаво, 4 символи коротше застібається за допомогою EOL на EOF, що робить його 206 (застібається за допомогою EOL) і 228 (зменшується без EOL).
Chris Morgan

14

Хаскелл - 284 272 232 символи

import System
main=do f:n:_<-getArgs;s<-readFile f;writeFile"out.txt"$t s$read n
p '\n'_='\n'
p 'X'2='X'
p _ 3='X'
p _ _='.'
t r 0=r
t r n=t[p(r!!m)$sum[1|d<-1:[80..82],s<-[1,-1],-m<=d*s,m+d*s<3240,'X'==r!!(m+d*s)]|m<-[0..3239]]$n-1

10

F #, 496

Я міг би це значно зменшити, але мені це подобається, оскільки він все ще перебуває у стадіоні і досить читабельний.

open System.IO
let mutable a:_[,]=null
let N y x=
 [-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]
 |>Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X' then 1 else 0 with _->0)
[<EntryPoint>]
let M(r)=
 let b=File.ReadAllLines(r.[0])
 a<-Array2D.init 40 80(fun y x->b.[y].[x])
 for i=1 to int r.[1] do 
  a<-Array2D.init 40 80(fun y x->
   match N y x with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
 File.WriteAllLines("out.txt",Array.init 40(fun y->
  System.String(Array.init 80(fun x->a.[y,x]))))
 0

РЕДАГУВАТИ

428

За запитом, ось мій наступний удар:

open System
let mutable a,k=null,Array2D.init 40 80
[<EntryPoint>]
let M r=
 a<-k(fun y x->IO.File.ReadAllLines(r.[0]).[y].[x])
 for i=1 to int r.[1] do a<-k(fun y x->match Seq.sumBy(fun(i,j)->try if a.[y+i,x+j]='X'then 1 else 0 with _->0)[-1,-1;-1,0;-1,1;0,-1;0,1;1,-1;1,0;1,1]with|3->'X'|2 when a.[y,x]='X'->'X'|_->'.')
 IO.File.WriteAllLines("out.txt",Array.init 40(fun y->String(Array.init 80(fun x->a.[y,x]))))
 0

Це зниження на 14% за допомогою деяких основних видів гри в гольф. Я не можу не відчувати, що програю, використовуючи 2D-масив / масив-рядків, а не 1D-масив, але не хочу робити це перетворення зараз. Зверніть увагу, як я елегантно читав файл 3200 разів, щоб ініціалізувати свій масив :)


Будь ласка, сильно зменшіть, мені цікаво!
Landei

10

Рубін 1,8: 178 175 символів

f,n=$*;b=IO.read f
n.to_i.times{s=b.dup
s.size.times{|i|t=([82,1,-80].map{|o|b[i-o,3]||''}*'').count 'X'
s[i]=t==3||b[i]-t==?T??X:?.if s[i]>13};b=s}
File.new('out.txt','w')<<b

Нові рядки є значними (хоча всі їх можна замінити з крапкою з комою.)

Редагувати: виправлено проблему з новим рядком та обрізано 3 символи.


Рядки у вихідному файлі не здаються розділеними.
Младен Ябланович

вони не є, але вони чудово відображаються на моїй консолі 80 char.
Ешлі

Вам потрібно мати нові рядки; вибачте, що я не вказав на це явно.
hb2pencil

10

Java, 441 ... 346


  • Оновлення 1 Видалено внутрішнє, якщо і більше потворність
  • Оновлення 2 Виправлено помилку та отримано характер
  • Оновлення 3 Використання набагато більше пам’яті та масивів, ігноруючи деякі проблеми з межами. Можливо, можна було врятувати кілька символів.
  • Оновлення 4 Збережено кілька символів. Завдяки BalusC.
  • Оновлення 5 Кілька незначних змін, щоб опуститися нижче 400, і зробити це ще трохи трохи потворнішим.
  • Оновлення 6 Тепер речі настільки чітко закодовані, що їх можна прочитати точно в один прийом. Плюс ще кілька заощаджень.
  • Оновлення 7 Прив’яжіть запис до файлу, щоб зберегти символ. Плюс кілька непарних бітів.

Просто граючись із рішенням BalusC. Обмежена репутація означає, що я не міг нічого додати як коментар до його.

class M{public static void main(String[]a)throws Exception{int t=3240,j=t,i=new Integer(a[1])*t+t;char[]b=new char[i+t],p={1,80,81,82};for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){char c=b[j],l=0;for(int n:p)l+=b[j+n]/88+b[j-n]/88;b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;}new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();}}

Більш читабельна (?) Версія:

class M{
 public static void main(String[]a)throws Exception{
  int t=3240,j=t,i=new Integer(a[1])*t+t;
  char[]b=new char[i+t],p={1,80,81,82};
  for(new java.io.FileReader(a[0]).read(b,t,t);j<i;){
    char c=b[j],l=0;
    for(int n:p)l+=b[j+n]/88+b[j-n]/88;
    b[j+++t]=c>10?(l==3|l+c==90?88:'.'):c;
  }
  new java.io.FileWriter("out.txt").append(new String(b,j,t)).close();
 }
}

Рядок замість char [] дорожчий, але це справді не має значення в коді-гольфі! Хороший :)
BalusC

Зверніть увагу, що загальна довжина файлу / символу не становить 2754 символів.
BalusC

@BallusC Дякую, мені вдалося скопіювати лише 34 рядки, а не всі 40!
Molehill

Це справді справжня свиня пам'яті! Btw --iможе увійти, new char[i--*t]а b[l++]+=(char)jможе просто бути b[l++]=(char)j. Це економить ще 3 символи.
BalusC

До речі: чому ви видалили &n+j<s? Це призведе до AIOBE, коли вхідний файл справді має 3240 символів. Більше оптимізації: подивіться, як я читаю файл char[], ваш може бути замінений на while(l<t)b[l++]=(char)r.read();, економить 4 символи.
BalusC

9

Scala - 467 364 339 символів

object G{def main(a:Array[String]){val l=io.Source.fromFile(new java.io.File(a(0)))getLines("\n")map(_.toSeq)toSeq
val f=new java.io.FileWriter("out.txt")
f.write((1 to a(1).toInt).foldLeft(l){(t,_)=>(for(y<-0 to 39)yield(for(x<-0 to 79)yield{if(x%79==0|y%39==0)'.'else{val m=t(y-1)
val p=t(y+1);val s=Seq(m(x-1),m(x),m(x+1),t(y)(x-1),t(y)(x+1),p(x-1),p(x),p(x+1)).count('X'==_)
if(s==3|(s==2&t(y)(x)=='X'))'X'else'.'}})toSeq)toSeq}map(_.mkString)mkString("\n"))
f.close}}

Я думаю, що є багато можливостей для вдосконалення ...

[Редагувати] Так, це:

object G{def main(a:Array[String]){var l=io.Source.fromFile(new java.io.File(a(0))).mkString
val f=new java.io.FileWriter("out.txt")
var i=a(1).toInt
while(i>0){l=l.zipWithIndex.map{case(c,n)=>if(c=='\n')'\n'else{val s=Seq(-83,-82,-81,-1,1,81,82,83).map(_+n).filter(k=>k>=0&k<l.size).count(l(_)=='X')
if(s==3|(s==2&c=='X'))'X'else'.'}}.mkString
i-=1}
f.write(l)
f.close}}

[Редагувати] І у мене відчуття, що ще потрібно вичавити ще ...

object G{def main(a:Array[String]){val f=new java.io.FileWriter("out.txt")
f.write(((1 to a(1).toInt):\(io.Source.fromFile(new java.io.File(a(0))).mkString)){(_,m)=>m.zipWithIndex.map{case(c,n)=>
val s=Seq(-83,-82,-81,-1,1,81,82,83)count(k=>k+n>=0&k+n<m.size&&m(k+n)=='X')
if(c=='\n')c else if(s==3|s==2&c=='X')'X'else'.'}.mkString})
f.close}}

2
Ви змусили мене прочитати статтю Вікіпедії Scala. Яка гарна мова! :)
Вінсент,

2
Так. Це змінило моє життя.
Landei

7

Наступне рішення використовує мою власну спеціальну мову програмування, яку я назвав NULL:

3499538

Якщо вам цікаво, як це працює: Моя мова складається лише з одного твердження на програму. Оператор представляє ідентифікатор потоку StackOverflow, що належить коду нитки гольфу. Мій компілятор компілює це у програму, яка шукає найкраще рішення javascript (із SO API), завантажує та запускає у веб-браузері.

Час роботи може бути кращим для нових потоків (це може зайняти деякий час, поки не з’явиться перша відповідь на підтримку Javascript), але для підвищення потрібно лише дуже мало навичок кодування.


4
@Platinum Azure: Ви маєте на увазі, що хтось ще мав таку ідею раніше? Чесно кажучи, я не бачив цього в іншій темі.
Адріан Григоре,

3
Ну, мабуть, великі уми думають однаково ;-). Але на відміну від наведеного вище рішення, моє рішення насправді може вирішити практично всі проблеми з гольфом коду, тоді як наведене вище може друкувати лише "Hello World".
Адріан Григоре,

2
Це не повний Тьюрінг, він не може інтерпретувати абстрактний код. Це не обов’язково працює щоразу, оскільки можливо ніколи не буде дійсного рішення (javascript). Це не повинно бути на Code Golf.
Каллум Роджерс

2
Гей, це лише мій перекладач. Чи включали рішення Javascript кількість символів для механізму javascript? ;-)
Адріан Григоре

4
Я думав, що це жарт, поки не прочитав усіх серйозних коментарів.
kirk.burleson

5

Javascript / Node.js - 233 236 символів

a=process.argv
f=require('fs')
m=46
t=f.readFileSync(a[2])
while(a[3]--)t=[].map.call(t,function(c,i){for(n=g=0;e=[-82,-81,-80,-1,1,80,81,82][g++];)t[i+e]>m&&n++
return c<m?c:c==m&&n==3||c>m&&n>1&&n<4?88:m})
f.writeFile('out.txt',t)

5

С - 300


Просто дивувався, наскільки меншим і потворнішим моє рішення Java може бути в C. Зменшується до 300, включаючи нові рядки для бітів препроцесора. Залишає звільнення пам’яті ОС! Можна зберегти ~ 20, припускаючи, що ОС також закриє та очистить файл.

#include<stdio.h>
#include<stdlib.h>
#define A(N)j[-N]/88+j[N]/88

int main(int l,char**a){
  int t=3240,i=atoi(a[2])*t+t;
  char*b=malloc(i+t),*j;
  FILE*f;
  fread(j=b+t,1,t,fopen(a[1],"r"));
  for(;j-b-i;j++[t]=*j>10?l==3|l+*j==90?88:46:10)
      l=A(1)+A(80)+A(81)+A(82);
  fwrite(j,1,t,f=fopen("out.txt","w"));
  fclose(f);
}

5

СВІНОК: 314 символів

L(F,N,R=40,C=80)
    N (F,N,R,C)
    O F:"RS" U F D  C F
    .F I=1:1:R R L F J=1:1:C S G(0,I,J)=($E(L,J)="X")
    F A=0:1:N-1 F I=1:1:R F J=1:1:C D  S G(A+1,I,J)=$S(X=2:G(A,I,J),X=3:1,1:0)
    .S X=0 F i=-1:1:1 F j=-1:1:1 I i!j S X=X+$G(G(A,I+i,J+j))
    S F="OUT.TXT" O F:"WNS" U F D  C F
    .F I=1:1:R F J=1:1:C W $S(G(N,I,J):"X",1:".") W:J=C !
    Q

2
Це жахлива мова. Приємна кількість персонажів.
hb2pencil

4

Java, 556 532 517 496 472 433 428 420 418 381 символів


  • Оновлення 1 : замінити 1 - й StringBufferпо Appendableі другий по char[]. Збережено 24 символи.

  • Оновлення 2: знайдено коротший спосіб читання файлу char[]. Збережено 15 символів.

  • Оновлення 3: замінено if/elseна ?:та об’єднано char[]та intоголошено. Збережено 21 символ.

  • Update 4: замінити (int)f.length()і c.lengthна s. Збережено 24 символи.

  • Оновлення 5: внесено вдосконалення згідно з підказками Molehill. Основний з них жорстко кодував довжину символу, щоб я міг позбутися File. Збережено 39 символів.

  • Оновлення 6: незначна рефакторинг. Збережено 6 символів.

  • Оновлення 7: замінено Integer#valueOf()на new Integer()та оновлено для циклу. Збережено 8 символів.

  • Оновлення 8: Покращений розрахунок сусідів. Збережено 2 символи.

  • Оновлення 9: Оптимізоване читання файлів, оскільки довжина файлу вже жорстко закодована. Збережено 37 символів.


 import java.io.*;class L{public static void main(String[]a)throws Exception{int i=new Integer(a[1]),j,l,s=3240;int[]p={-82,-81,-80,-1,1,80,81,82};char[]o,c=new char[s];for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;o[j]=c[j]>13?l==3|l+c[j]==90?88:'.':10;}Writer w=new FileWriter("out.txt");w.write(c);w.close();}}

Більш читабельна версія:

import java.io.*;
class L{
 public static void main(String[]a)throws Exception{
  int i=new Integer(a[1]),j,l,s=3240;
  int[]p={-82,-81,-80,-1,1,80,81,82};
  char[]o,c=new char[s];
  for(new FileReader(a[0]).read(c);i-->0;c=o)for(o=new char[j=s];j-->0;){
   l=0;for(int n:p)l+=n+j>-1&n+j<s?c[n+j]/88:0;
   o[j]=c[j]>10?l==3|l+c[j]==90?88:'.':10;
  }
  Writer w=new FileWriter("out.txt");w.write(c);w.close();
 }
}

Закриття після запису абсолютно обов'язково, інакше файл залишається порожнім. Інакше це врятувало б ще 21 символ.

Далі я міг би також зберегти ще один символ, коли використовую 46замість '.', але як javac, так і Eclipse смикається з помилкою компіляції Можлива втрата точності . Дивні речі.


Примітка: тут очікується вхідний файл із \nновими рядками, а не \r\nяк Windows використовує за замовчуванням!


Ви можете просто використовувати новий FileWriter (out.txt) .write (c), щоб вимовити кілька символів. На жаль, ви не можете зафіксувати всю змінну, оскільки write () цього не повертає. Якби ви могли знайти клас написання файлів, який це робить, можна було б істотно заощадити. Крім того, мені подобається ваше використання кидків - всього, щоб уникнути цих жахливих примусових уловів.
Щеня,

3

PHP - 365 328 322 символів.


list(,$n,$l) = $_SERVER["argv"];
$f = file( $n );
for($j=0;$j<$l;$j++){   
    foreach($f as $k=>$v){  
        $a[$k]="";      
        for($i=0;$i < strlen( $v );$i++ ){
            $t = 0;
            for($m=-1;$m<2;$m++){
                for($h=-1;$h<2;$h++){
                    $t+=ord($f[$k + $m][$i + $h]);
                }
            }
            $t-=ord($v[$i]);          
            $a[$k] .= ( $t == 494 || ($t == 452 && ord($v[$i])==88)) ?  "X" : "." ;
        }
    }
    $f = $a;
}       
file_put_contents("out.txt", implode("\n", $a )); 

Я впевнений, що це можна покращити, але мені було цікаво, як це буде виглядати в PHP. Можливо, це надихне когось, хто має трохи більше досвіду кодового гольфу.

  • Оновлений список використання () замість $ var = $ _SERVER ["argv"] для обох аргументів. Приємний Дон
  • Оновлено + = та - = це змусило мене / facepalm гех не можу повірити, що я це пропустив
  • Оновлений вихідний файл для використання file_put_contents () ще одного хорошого улову Дона
  • Оновлена видалена ініціалізація змінних $ q і $ w, які вони не використовували

список ($ n, $ l) = $ _SERVER ['argv'];
Дон Вільсон

ЗМІНА: $ o = fopen ("out.txt", "w"); fwrite ($ o, імплодувати ("\ n", $ a)); fclose ($ o); ДО: file_put_contents ("out.txt", імплодувати ("\ n", $ a));
Дон Вілсон,

ЗМІНА: $ t = $ t-ord ($ v [$ i]); ДО: $ t- = ord ($ v [$ i]);
Дон Вілсон,

ЗМІНА: $ t = $ t + ord ($ f [$ k + $ m] [$ i + $ h]); ДО $ t + = ord ($ f [$ k + $ m] [$ i + $ h]);
Дон Вілсон,

2

R 340 символів

cgc<-function(i="in.txt",x=100){
    require(simecol)
    z<-file("in.txt", "rb")
    y<-matrix(data=NA,nrow=40,ncol=80)
    for(i in seq(40)){
        for(j in seq(80)){
            y[i,j]<-ifelse(readChar(z,1) == "X",1,0)
        }
        readChar(z,3)
    }
    close(z)
    init(conway) <- y
    times(conway)<-1:x
    o<-as.data.frame(out(sim(conway))[[100]])
    write.table(o, "out.txt", sep="", row.names=FALSE, col.names=FALSE)
}
cgc()

Я відчуваю, що це трохи обман, якщо додати пакет в пакеті, який робить для вас фактичні автомати, але я йду з ним, тому що мені все одно довелося оббивати матриці та інше для читання у файлі з "X" замість 1.

Це мій перший "кодовий гольф", цікаво ....


2

c ++ - 492 454 386


мій перший код гольфу;)

#include<fstream>
#define B(i,j)(b[i][j]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);v[1]="out.txt";char b[40][83];for(i=0;i<40;++i)f.getline(b[i],83);std::ofstream g("out.txt");g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){int k=B(i-1,j)+B(i+1,j)+B(i,j-1)+B(i,j+1)+B(i-1,j-1)+B(i+1,j+1)+B(i+1,j-1)+B(i-1,j+1);(B(i,j)&&(k<2||k>3))?g<<'.':(!B(i,j)&&k==3)?g<<'X':g<<b[i][j];}g<<".\n";}g<<b[0]<<'\n';}}

Дещо переглянута версія, яка замінює частину логіки пошуком таблиці + кілька інших незначних хитрощів:

#include<fstream>
#define B(x,y)(b[i+x][j+y]=='X')
int main(int i,char**v){for(int n=0;n<atoi(v[2]);++n){std::ifstream f(v[1]);*v="out.txt";char b[40][83], O[]="...X.....";for(i=0;i<40;++i)f>>b[i];std::ofstream g(*v);g<<b[0]<<'\n';for(i=1;i<39;++i){g<<'.';for(int j=1;j<79;++j){O[2]=b[i][j];g<<O[B(-1,0)+B(1,0)+B(0,-1)+B(0,1)+B(-1,-1)+B(1,1)+B(1,-1)+B(-1,1)];}g<<".\n";}g<<b[0]<<'\n';}}

1
Кілька порад: не потрібно викликати аргументи до основних argc та argv. Натомість спробуйте c та v. Також спробуйте використовувати тернарний оператор замість if / else. Приємно бачити представлений С ++. :)
hb2pencil

1

Perl - 214 символів

Що, ще немає записів perl?

$i=pop;@c=<>;@c=map{$r=$_;$u='';for(0..79)
{$K=$_-1;$R=$r-1;$u.=((&N.(&N^"\0\W\0").&N)=~y/X//
|(substr$c[$r],$_,1)eq'X')==3?'X':'.';}$u}keys@c for(1..$i);
sub N{substr$c[$R++],$K,3}open P,'>','out.txt';$,=$/;print P@c

Запустити з:

conway.pl в файлі #times


1

Ще одна спроба Java, 361 символ

class L{public static void main(final String[]a)throws Exception{new java.io.RandomAccessFile("out.txt","rw"){{int e=88,p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;char[]b=new char[s];for(new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--){c=b[l];for(int n:p)c+=l+n>=0&l+n<s?b[l+n]/e:0;write(c>13?(c==49|(c|1)==91?e:46):10);}}};}}

І трохи читабельніше

class L {
    public static void main(final String[]a) throws Exception {
        new java.io.RandomAccessFile("out.txt","rw"){{
            int e=88, p[]={-1,1,-80,80,-81,81,-82,82},s=3240,l=0,i=new Byte(a[1])*s+s,c;
            char[] b = new char[s];
            for (new java.io.FileReader(a[0]).read(b);i>0;seek(l=++l%s),i--) {
                c=b[l];
                for (int n:p)
                    c+=l+n>=0&l+n<s?b[l+n]/e:0;
                write(c>13?(c==49|(c|1)==91?e:46):10);
            }
        }};
    }
}

Дуже схожий на версію Molehill. Я намагався використовувати інший FileWriter і підрахувати сусідів по клітці без додаткової змінної. На жаль, RandomAccessFileце досить довге ім’я, і вам потрібно пройти режим доступу до файлу.


1

ІРЖА - 469 символів Не знаю, чи слід мені розміщувати це тут, (цій публікації 3 роки), але в будь-якому випадку, мій приклад на русті (0.9)

use std::io::fs::File;fn main(){
let mut c=File::open(&Path::new(std::os::args()[1])).read_to_end();
for _ in range(0,from_str::<int>(std::os::args()[2]).unwrap()){
let mut b=c.clone();for y in range(0,40){for x in range(0,80){let mut s=0;
for z in range(x-1,x+2){for t in range(y-1,y+2){
if z>=0&&t>=0&&z<80&&t<40&&(x !=z||y !=t)&&c[t*81+z]==88u8{s +=1;}}}
b[y*81+x]=if s==3||(s==2&&c[y*81+x]==88u8){88u8} else {46u8};}}c = b;}
File::create(&Path::new("out.txt")).write(c);}

Для тих, хто цікавиться, ось код перед агресивним гольфом:

use std::io::fs::File;
fn main() {
    let f = std::os::args()[1];
    let mut c = File::open(&Path::new(f)).read_to_end();    
    let n = from_str::<int>(std::os::args()[2]).unwrap();   
    for _ in range(0,n)
    {
        let mut new = c.clone();
        for y in range(0,40) {
            for x in range(0,80) {
                let mut sum = 0;
                for xx in range(x-1,x+2){
                    for yy in range(y-1,y+2) {
                        if xx >= 0 && yy >= 0 && xx <80 && yy <40 && (x != xx || y != yy) && c[yy*81+xx] == 88u8
                        { sum = sum + 1; }
                    }
                }
                new[y*81+x] = if sum == 3 || (sum == 2 && c[y*81+x] == 88u8) {88u8} else {46u8};                    
            }
        }
        c = new;
    }
    File::create(&Path::new("out.txt")).write(c);
}

1

ét voilà, можливо, ви захочете використовувати цей файл html. не введення файлу, а текстове поле, яке робить цю роботу! є також деякі html та ініціація та vars. основна процедура має лише 235 символів. Це мінімізований JS.

<!DOCTYPE html>
<html><body><textarea id="t" style="width:600px;height:600px;font-family:Courier">
</textarea></body><script type="text/javascript">var o,c,m=new Array(3200),
k=new Array(3200),y,v,l,p;o=document.getElementById("t");for(y=0;y<3200;y++)
{m[y]=Math.random()<0.5;}setInterval(function(){p="";for(y=0;y<3200;y++){c=0;
for(v=-1;v<2;v+=2){c+=m[y-1*v]?1:0;for(l=79;l<82;l++)c+=m[y-l*v]?1:0;}
k[y]=c==3||m[y]&&c==2;}p="";for(y=0;y<3200;y++){p+=(y>0&&y%80==0)?"\n":"";
m[y]=k[y];p+=(m[y]?"O":"-");}o.innerHTML=p;},100);</script></html>

0

Один з класичних візерунків

***
..*
.*

Мій аватар був створений за допомогою моєї версії Game of Life, використовуючи цей шаблон та правило (зверніть увагу, що це не 23/3):

#D Thanks to my daughter Natalie
#D Try at cell size of 1
#R 8/1
#P -29 -29
.*********************************************************
*.*******************************************************.*
**.*****************************************************.**
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
****************************.*.****************************
***********************************************************
****************************.*.****************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
***********************************************************
**.*****************************************************.**
*.*******************************************************.*
.*********************************************************

IMHO - коли я дізнався про "Гра життя" Конвея, фокус полягав не в написанні короткого коду, а в коді, який міг швидко робити складні форми життя. Використовуючи класичний зразок вище та огорнутий світ з 594 441 клітин, найкраще, що я міг коли-небудь зробити, було близько 1000 поколінь / сек.

Ще один простий шаблон

**********
.
................*
.................**
................**.......**********

І планери

........................*...........
......................*.*...........
............**......**............**
...........*...*....**............**
**........*.....*...**..............
**........*...*.**....*.*...........
..........*.....*.......*...........
...........*...*....................
............**......................

10
Я думаю, можливо, ви неправильно зрозуміли суть питань коду гольфу.
gnovice

Ось колекція шаблонів на випадок, якщо вас
зачепить,

@gnovice - ні, але це була тема, з якою я дуже веселився. Стільникові автомати можуть бути цікавим найкоротшим кодовим питанням, але це також цікава тема сама по собі. Я зараз виб'юся.
dbasnett

1
Якщо у вас досвід роботи з мовою, яка тут не представлена, я рекомендую вам подати запис про кодовий гольф - всі вдячні, навіть якщо це трохи відстає від інших за тривалістю. :)
hb2pencil

Просто код Automaton складає майже 2000 рядків. Обробка файлів креслення / редагування (графічно) / шаблону, можливо, ще 2000. Тож, мабуть, я б перевищив рівень свого раунду;)
dbasnett
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.