Код Гольф: Бег воды
Задача
Самый короткий код по количеству символов, чтобы идентифицировать и отмечать понижения воды в представлении ASCII земли с входа.
Ввод будет ASCII-представлением ландшафта, имеющего холмы, долины и плоские земли. Программа должна имитировать то, как выглядел бы пейзаж, если бы был затоплен - заполнение всех долин водой (символ x
).
Пейзаж всегда будет начинаться и останавливаться с символом _
и будет содержать не менее 2 символов, делая самый короткий вход __
.
Холм определяется как повышение и не должен быть заполнен водой:
__
_/ \_
Долина определяется как депрессия и заполняется водой до тех пор, пока не встретится плоская поверхность:
_ _
\__/
Ввод можно считать чистым и будет состоять только из пространства символов (
), новой строки (\n
), подчеркивания (_
) и косой черты вперед и назад (/
и \
). Ввод можно рассматривать как непрерывную линию, и любой вход, содержащий двусмысленные линейные входы, такие как _/_
или
_ _
\_/
/ \
Считается недействительным.
Что касается подводных пещер, уровень воды должен поддерживаться, если уровень пещеры превышает уровень воды.
Тестовые примеры
Input:
__/\__
\__
\ ___ ___________
/ / \_ \_
\_____/ \__ _/
\/
Output:
__/\__
\__
\ ___ ___________
/xxxxxx/ \xxxxxx\_
\xxxxx/ \xxxxx/
\/
Input:
__ ___
/ \_____/
/ _______
________ / \ /
_____/ \ /__ \ \_
____ / \ /__/ __/
\_ / \ ____/
\______\ /____/
Output:
__ ___
/ \xxxxx/
/ _______
________ / \ /
_____/ \xxx/__ \xxxx\_
____ / \xxxx/__/xxxxx/
\xxxxxxxx/ \xxxxxxxxx/
\xxxxxx\ /xxxx/
Input:
__ _
_ ____ ____ _____/ \ /
\ / \ __________/ \ __/ ___ /___\
\___/ \ \ \ \___/ /_
/________\ \___________\
Output:
__ _
_ ____ ____ _____/ \xxx/
\xxxxx/ \xxxxxxxxxxxxxxxxxx/ \xxxxxx/ ___ /xxx\
\xxx/ \xxxxxxx\ \xxx\___/xx/_
/xxxxxxxx\ \xxxxxxxxxxx\
Количество кодов включает ввод/вывод (т.е. полную программу).
Ответы
Ответ 1
C - 741 621 600 символов (но правильно обрабатывает новые случаи)
$ gcc water.c && ./a.out < test6.txt
__ ___
/ \xxxxx/
/ _______
________ / \ /
_____/ \xxx/__ \xxxx\_
____ / \xxxx/__/xxxxx/
\xxxxxxxx/ \xxxxxxxxx/
\xxxxxx\ /xxxx/
#include<stdio.h>
char d[99][99],*p,*e,*z,*s=d,c,S=' ',D='-',O='.',U='_';n,w,x,N=99,i;
g(y){for(i=0;!i;p+=N,e+=N){i=*p==D;for(z=p;z!=e;z+=y){if(*z!=O&&*z!=
D)break;*z=*z==O?S:U;}}}f(char*n,int r){if(*n==O||*n==D){*n=r>0?'x':
S;int k;for(k=0;k<9;k++)f(n+k/3*N-N+k%3-1,r+k/3-1);}}main(){for(p=s;
gets(p);p+=N,n++){x=strlen(p)-1;w=x>w?x:w;}for(p=s,e=d[N];p<s+N;p++)
{for(i=1,z=p;z<e;z+=N)c=*z,c==0?*z=c=S:0,i?c==S?*z=O:c==U?*z=D:0:0,(
c=='/'&&z[1]!=U)||(c=='\\'&&z[-1]!=D)||c==U?i=1-i:0;}p=s;e=s+w;g(1);
p=s+w;e=s;g(-1);for(p=s;p<s+w;p++){for(z=p;*z==S;z+=N);f(z,1);}for(i
=0;i<n;i++)printf("%.*s\n",w+1,d[i]);}
Ответ 2
Ruby, 794 759 769 752 715 692 663 655 626 616
Дополнительные тестовые примеры:
http://pastie.org/708281 и
http://pastie.org/708288 и
http://pastie.org/708310
Сжатый, кроме отступа:
def g i,j,&f
t=[-1,0,1]
t.each{|r|next [email protected][i][j,1]=='_'&&r>0
t.each{|c|a=i+r
b=j+c
if a>=0&&b>=0&&a<@r&&b<@c
@t[a]||=[]
if r!=0&&c!=0
[email protected][a][j,1]
[email protected][i][b,1]
next if/[\/\\]/=~k+l&&((k!=l)||((r<=>0)==(c<=>0)?k!='\\': k!='/'))
end
[email protected][a][b,1]
z,@t[a][b][email protected][a][b],1
return 1if !z&&(e==' '||r>=0&&e=='_')&&yield(a,b,f)
end}}
nil
end
w=$stdin.readlines
@c=w.map{|e|e.size}.max-1
@w=w=w.map{|e|[email protected]}
z=w.map{|e|e.dup}
@r=w.size
@r.times{|r|@m=r
@c.times{|c|e=w[r][c,1]
z[r][c]='x'if(e==' '||e=='_')&&(@t=[]
!g(r,c){|u,v,f|u>[email protected] and v==0||[email protected]||g(u,v,&f)})&&(@t=[]
g(r,c){|u,v,f|u==0||g(u,v,&f)})}}
puts z
Ответ 3
Python, 702 805 794 778 758 754 710 651
Обрабатывает тестовые примеры DigitalRoss, а также большие тестовые примеры, такие как http://pastie.org/708764.
Пример выполнения
$ python runningwater.py < test4.txt
____________________________
/
_ \ __
/ \xxxxx/ / \
___ _____/ /xxx/ / \
____________ / \xxxxx/ ____/xxx/ __ /xxxxxx\
\xxx/ /xxxxx\__ \xxxxxx/ /xx\___/xxxxxxx/
___/xxxxxxxxx\____ /xxxxxxxxxxxxxx/
/xxxxx/ \xxxxx\__/x/ \xxxxxxx/
/xxxxx/ \xxxxxxxx/ \xxxxx/
\xxxxx\ _________ \xxx/
\xxx\ /xxxxxxxxx\ /xx/
\x\ \x\ /\ \x\ /xx/
__________ \x\ \x\_/x/ /x/ /xx/
/xxxxxxxxxx\ \x\ \xxx/ /x/ /xx/
/xxxxxxxxxxxx\ \x\ \x/ /x/ /xx/
\xxxxxxxxxxxxx\ \x\ /x/ /xx/
\xxxxxxx\ \x\_/x/ /xx/
____/xxx/ \xx\ \xxx/ /xx/
\xxxxxx/ \xx\___________________/xx/
\xx/ \xxxxxxxxxxxxxxxxxxxxxxx/
Код
import sys
q=sys.stdin.readlines()
e=enumerate
s=type
k=int
o=[]
t=[0]*max(map(len,q))
n=1
L=[]
l={}
for p,d in e(q):
w=a=0;o+=[[]]
for i,c in e(d):
T=t[i];C=[[c,T]];D=d[i+1:];b=0;o[-1]+=C;L+=C
if c in'_ ':
if('/'in D or '\\'in D)*(T%2-1)*w*p:
for j in range(max(i-1,0),min(i+2,len(o[p-1]))):R=o[p-1][j][0];b=R*(k==s(R))or b
for x in L:x[0]=b*(x[0]==a)or x[0]
a=C[0][0]=b or a or n
elif c in'\\/':w=1;a=0;n+=1
D=d[i-1]+c;t[i-1]+=(D=='/_');t[i]+=(c in'_/\\')+(D=='_\\')
for i,a in e(o):
for c,r in a:
if(r==0)*(s(c)==k):l[c]=1
for j,(c,r)in e(a):
if(c in l)-1:a[j]=q[i][j],0
print''.join((k==s(x))*'x'or x for x,r in a),
Ответ 4
Perl, 534 545 550 566 569 567 578 594 596
sub i{$a=1;$a^=substr(x.$l[$_],$_[0],3)=~/^(.[_y]|.\/[^_]|[^_]\\)/for 0..$r-1;
$a}sub f{$c=$e-$s;$_=$l[$r];$f=s/(.{$s})(.{0,$c})/$1<$2>/;(/[ _x]>/&i$e-1and$f=
/>[ _xy]*[\\\/]/,$e=$+[0]-2)or/[ _]*>/,$e=$-[0]-1;(/<[ _x]/&i$s and$f&=
/[\\\/][ _xy]*</,$s=$-[0])or/<[ _]*/,$s=$+[0]-1;$f&$s<$e&&substr($l[$r],$s,$e-$s
)=~s!([\\/][ _xy]*)([\\/][ _]*)!($t=$1)=~y/ _/xy/,$t.$2!eg,$r--&&&f}[email protected]=<>;
while($q--){i$-[0]+1and substr($l[$r--],$-[1],length$1)=~y/_y/x/,$s=$-[0],$e=
$+[0],$q&&f while$l[$r=$q]=~m~\\/|[\\/]([_y]+)[\\/]~g}y/y/x/,print [email protected]
Это обрабатывает все тестовые примеры, которые я видел. Новые строки являются необязательными и предназначены только для форматирования.
Назовите его, например. perl water.pl test.txt
.
Вот еще один случай смешного края (для моего алгоритма в любом случае) не в любом из предыдущих примеров:
__ _
\__ /
/_/
расширенная версия, которую я поставил ранее, все еще не работает.