Chr*_*heD 49 language-agnostic code-golf rosetta-stone
你可能还记得你小时候的这些图画,但现在是时候让电脑画出来了(完整的ascii辉煌).玩得开心!
描述:
输入是多行(由换行符终止),描述"字段".这个领域散布着"数字"(由空格分隔).所有行都可以被认为是相同的长度(您可以将空格填充到末尾).
任务:
以这些数字的自然顺序
绘制线条(1 -> 2 -> 3 -> ...N)
(假设N <= 99),具有以下特征:
+
'字符替换数字-
'|
'/
\
重要笔记:
当绘制类型为4和5的线时,您可以假设(给定点与坐标x1,y1和x2,y2连接)distance(x1,x2) == distance(y1,y2)
.或换句话说(如用户jball评论):"非水平或垂直对齐的连续元素始终与斜杠或反斜杠的斜率对齐".
重要的是遵循点连接的顺序(较新的线可以击出较旧的线).
- 样本输入1 -
8 7 6 10 9 5 3 4 11 12 13 1 2
- 样本输出1 -
+ /| / +--+ +--------+ \ / \ / + / | / +--+ + | \ | +------------------------+ +--------------------------+
- 样本输入2 -
64 63 62 61 1 65 66 57 58 2 56 59 45 67 55 46 3 44 54 60 47 53 52 49 48 4 51 50 43 5 42 41 6 23 22 25 26 40 20 21 24 34 7 13 12 33 19 27 32 14 35 8 15 16 39 17 18 28 31 36 9 38 10 11 29 30 37
- 样本输出2 -(独角兽参考)
+ /+ // // // /+--+ + + \ | + +-\+ + \ + \ + / + + \ +\ + \ \ | + | + + +/ | +--+ +-------+/ + +--+ + / \ + + | + + + / \ +\ +---+ + \ +--+ + \ /+ + +--+ / \ /+| / | |+ + /+ | / + || / // + + + || / // / \ + || / // / \ | || / +/ / \ +---+ + +\ + + | | | +| +--+ +---+ +
优胜者:
最短的解决方案(按代码字符计数).输入可通过标准输入读取.
Dan*_*bić 58
编辑:见下面的高尔夫版本
使用PET图形,POKE和PEEK以及所有内容在记忆道上进行一次小旅行:)
程序直接在屏幕内存中运行,因此您可以继续操作,清除屏幕,放置点,然后键入RUN:
你必须等待一分钟左右找到点然后它开始绘制.它并不快 - 你实际上可以看到正在绘制的线条,但这是最酷的部分:)
Commodore BASIC似乎是一种很棒的高尔夫语言,因为它不需要空格:)你也可以通过输入一个未移位的第一个字母,然后输入第二个字母来缩短大部分命令.例如,POKE
可以键入P [SHIFT + O],它显示P?
在屏幕上:
mob*_*mob 36
Perl,384 365 276 273 253 225 222 218 211 chars(比赛结束后222).换行仅用于"可读性",不包括在字符数中.
上次编辑:不再覆盖$"
,@S
直接打印
$_=join'',@S=map{$n=s/$/$"x97/e;(/./g)[0..95],$/}<>;
while(/\b$n /){$S[$q=$-[0]]='+';($P,$Q)=sort{$a-$b}$q,$p||$q;
for(qw'\98 |97 /96 -1'){/\D/;$S[$P]=$&until($Q-$P)%$'||$Q<=($P+=$')}
$n++;$p=$q}s/\d/ /,print for@S
Run Code Online (Sandbox Code Playgroud)
说明:
$_=join'',@S=map{$n=s/$/$"x97/e;(/./g)[0..95],$/}<>;
Run Code Online (Sandbox Code Playgroud)
如果所有行的长度相同(例如,97个字符),则此任务将更容易.此语句接受每行输入,用96个空格替换行尾字符,然后将前96个字符加上换行符推入数组@S
.注意我们也在设置$n=1
,因为1是我们在输入中寻找的第一个数字.该join
语句从数组中创建一个字符串@S
.使用标量变量$_
进行模式匹配更方便,使用数组更方便@S
地对图片进行更新.
while(/\b$n /){
Run Code Online (Sandbox Code Playgroud)
搜索$n
变量中的数字$_
.在Perl中评估正则表达式有几个副作用.一种是$-[0]
在匹配的字符串中设置匹配模式的起始位置的特殊变量.这为我们提供$n
了字符串中数字的位置$_
以及数组@S
.
当然,循环将在$n
足够高时结束,以至于我们无法在输入中找到它.
$S[$q=$-[0]]='+';
Run Code Online (Sandbox Code Playgroud)
让$q
是数的位置$n
在字符串中$_
和阵列@S
,以及分配在该位置的字符"+".
$P=($p||=$q)+$q-($Q=$q>$p?$q:$p)($P,$Q)=sort{$a-$b}$p||$q,$q;
第一次通过循环,设置$p
为$q
.在第一次之后,$p
将保持之前的值$q
(这将指代前一个数字的输入中的位置).分配$P
和$Q
使得$P
=分钟($p
,$q
),
$Q
= MAX( ,)$p
$q
for(qw'\98 |97 /96 -1'){
Run Code Online (Sandbox Code Playgroud)
通过建设,连续数字也是
通过垂直线连接.由于输入构造为每行有97个字符,这种情况意味着
$p-$q
可以被97整除.
"与反斜杠的斜率对齐",这
$p-$q
可以被98整除
"与正斜线斜坡对齐",
$p-$q
可以被96整除
在同一水平线上
此列表的元素编码线段之间可能的位置数,以及编码该段的字符.
/\D/;
Run Code Online (Sandbox Code Playgroud)
另一个琐碎的正则表达式评估.作为副作用,它将特殊变量$&
(MATCH变量)设置为线段字符(\ | /
或-
)和$'
(POSTMATCH变量)为list元素中编码的数字(98 97 96或1).
$S[$P]=$&until($Q-$P)%$'||$Q<=($P+=$')
Run Code Online (Sandbox Code Playgroud)
此语句绘制两个数字之间的线段.如果$Q-$P
是可分的$'
,然后不断递增$P
通过$'
和分配角色$&
来$S[$P]
,直到$P
到达$Q
.更具体地说,例如,如果$Q-$P
可被97整除,则增加$P
97并设置$S[$P]='|'
.重复直到$P>=$Q
.
$n++;$p=$q
Run Code Online (Sandbox Code Playgroud)
准备循环的下一次迭代.递增$n
到要在输入中搜索的下一个数字,并$p
保持前一个数字的位置.
s/\d/ /,print for@S
Run Code Online (Sandbox Code Playgroud)
输出数组,转换任何剩余的数字(从输入中的双位数字标识符,我们只用'+'覆盖第一个数字)到我们去的空格.
Gra*_*ers 14
MS-DOS Batch(是的,你看对了!)
我经常听到(或读过)人们说批次不是很强大,你不能对它们做太多的事情,对我们说得好,我说,看,BATCH的力量!
实际的脚本(script.bat):
set file=%~1
call :FindNextNum 1
for /F "tokens=2 delims=:" %%i IN ('find /c /V "" "%file%"') DO set /a totalLines=%%i
set maxLen=0
for /F "delims=" %%i IN (%file%) DO (
call :CountChars "%%i"
if /i !charCount! gtr !maxLen! set maxLen=!charCount!
)
for /L %%i IN (0,1,%totalLines%) DO set "final_%%i=" & for /L %%j IN (0,1,%maxLen%) DO set "final_%%i=!final_%%i! "
:MainLoop
set currLineNum=%lineNum%
set currCol=%linePos%
set currNum=%nextNum%
set /a targetNum=%currNum%+1
call :FindNextNum %targetNum%
if "%nextNum%"=="" goto MainEnd
REM echo %currNum% -^> %nextNum%
if /I %currLineNum% lss %lineNum% (
call :DrawLine %currCol% %currLineNum% %linePos% %lineNum%
) else (
call :DrawLine %linePos% %lineNum% %currCol% %currLineNum%
)
goto MainLoop
:MainEnd
for /L %%i IN (0,1,%totalLines%) DO echo.!final_%%i!
goto:eof
:DrawLine
if /I %2 equ %4 goto:DrawHoriz
set "char=" & set "pos=%1" & set "inc=0"
if /I %1 LSS %3 set "char=\" & set "pos=%1" & set "inc=1"
if /I %1 GTR %3 set "char=/" & set "pos=%1" & set "inc=-1"
for /L %%i IN (%2,1,%4) DO call :DrawChar %%i !pos! %char% & set /a "pos+=%inc%"
goto:DrawEnds
:DrawHoriz
set "start=%1+1" & set "end=%3"
if /I %start% gtr %end% set "start=%3+1" & set "end=%1"
set /a lineEnd=%end%+1
set lineEnd=!final_%2:~%lineEnd%!
for /L %%i IN (%start%,1,%end%) DO set final_%2=!final_%2:~0,%%i!-
set final_%2=!final_%2!!lineEnd!
:DrawEnds
call :DrawChar %2 %1 +
call :DrawChar %4 %3 +
goto:eof
:DrawChar
set /a skip2=%2+1
if "%3"=="" (
set final_%1=!final_%1:~0,%2!^|!final_%1:~%skip2%!
) else (
set final_%1=!final_%1:~0,%2!%3!final_%1:~%skip2%!
)
goto:eof
:CountChars
set charCount=0
set val=%~1
:CountChars_loop
if not "%val:~1%"=="" (
set /a charCount+=1
set val=!val:~1!
goto CountChars_loop
)
goto:eof
:FindNextNum
for /F "delims=" %%i IN ('type "%file%" ^| find /V /N ""') DO (
for /F "tokens=1,2 delims=[]" %%j IN ("%%i") DO (
set /a lineNum=%%j-1
call :FindNext_internal "%%k" %1
if /I !nextNum! equ %1 goto :eof
)
)
goto:eof
:FindNext_internal
set currLine=%~1
set linePos=0
:FindNext_internal_loop
call :NextNumInLine "%currLine%"
set /a linePos+=%spaceInterval%
if "%nextNum%"=="" goto :EOF
if /I %nextNum% equ %2 goto :EOF
set /a spaceInterval+=1
set /a linePos+=1
if /I %nextNum% GTR 9 set /a "spaceInterval+=1" & set /a linePos+=1
set currLine=!currLine:~%spaceInterval%!
goto FindNext_internal_loop
:NextNumInLine
set nextNum=
for /F %%i IN (%1) DO set /a nextNum=%%i
if "%nextNum%"=="" goto :eof
set /a spaceInterval=0
set val=%~1
:NextNumInLine_loop
if "%val:~0,1%"==" " (
set /a spaceInterval+=1
set val=!val:~1!
goto NextNumInLine_loop
)
goto :eof
Run Code Online (Sandbox Code Playgroud)
这就是你如何称呼它
echo off
setlocal ENABLEDELAYEDEXPANSION
call script.bat input.txt
Run Code Online (Sandbox Code Playgroud)
其中"input.txt"是包含"程序"输入的文件.
PS这实际上并没有针对线路长度进行优化,我已经花了几个小时才达到这一点,现在我需要睡觉......我明天是否可以改进它(目前是'script.bat '坐在2755字节)
Hos*_*ork 12
Ma L{-|\/}Qb|[sg?SBaB]Da|[feSm[TfiSrj[spAsp]iT[++Tbr]]t]Xa|[i?A]Ya|[i?FImHDa]Ca|[skPCmSCaBKfsA]wh[Jd++N][roG[xJyJ]]Bf+GwhB[JcB Ff+GiF[KcF HqXkXj VqYkYju[chCbPClEZv1[ezH2[eeHv3 4]]e?A+bRE[hV]f]]chJeFIlSCj{+}{+ }Jk Bf]wM
我很擅长以猪拉丁形式阅读和编辑它.(虽然我确实使用换行!!):)
But here's how the dialect is transformed by the interpreter when the case-insensitive "mushing" trick is boiled away, and one gets accustomed to it. I'll add some comments. (Tips: fi
is find, fe
is foreach, sp
is a space character, i?
is index, hd
is head, ch
is change, sk
is skip, pc
is pick, bk
is break, i
is if, e
is either, ee
is either equal, ad nauseum)
; copy program argument into variable (m)atrix
m: a
; string containing the (l)etters used for walls
l: {-|\/}
; q is a "b|function" (function that takes two parameters, a and b)
; it gives you the sign of subtracting b from a (+1, -1, or 0)
q: b| [sg? sb a b]
; d finds you the iterator position of the first digit of a two digit
; number in the matrix
d: a| [fe s m [t: fi s rj [sp a sp] i t [++ t br]] t]
; given an iterator position, this tells you the x coordinate of the cell
x: a| [i? a]
; given an iterator position, this tells you the y coordinate of the cell
y: a| [i? fi m hd a]
; pass in a coordinate pair to c and it will give you the iterator position
; of that cell
c: a| [sk pc m sc a bk fr a]
; n defaults to 1 in Rebmu. we loop through all the numbers up front and
; gather their coordinate pairs into a list called g
wh [j: d ++ n] [ro g [x j y j]]
; b is the (b)eginning coordinate pair for our stroke. f+ returns the
; element at G's current position and advances G (f+ = "first+")
; advance g's iteration position
b: f+ g
wh b [
; j is the iterator position of the beginning stroke
j: c b
; f is the (f)inishing coordinate pair for our stroke
f: f+ g
; if there is a finishing pair, we need to draw a line
i f [
; k is the iterator position of the end of the stroke
k: c f
; the (h)orizontal and (v)ertical offsets we'll step by (-1,0,1)
h: q x k x j
v: q y k y j
u [
; change the character at iterator location for b (now our
; current location) based on an index into the letters list
; that we figure out based on whether v is zero, h is zero,
; v equals h, or v doesn't equal h.
ch c b pc l ez v 1 [ez h 2 [ee h v 3 4]]
; if we update the coordinate pair by the offset and it
; equals finish, then we're done with the stroke
e? a+ b re [h v] f
]
]
; whether we overwrite the number with a + or a plus and space
; depends on whether we detect one of our wall "letters" already
; one step to the right of the iterator position
ch j e fi l sc j {+} {+ }
; update from finish pair to be new begin pair for next loop iteration
j: k
b: f
]
; write out m
w m
Run Code Online (Sandbox Code Playgroud)
语言和样本都是新的,处于试验阶段.例如,ad
在我更改它以帮助这个样本之前,不能用于将向量和矩阵相加.但我认为这就是专门为代码高尔夫设计的语言无论如何都必须具备的东西.这是"语言"和"图书馆"之间的微妙界限.
最新消息来源,GitHub上有评论
ken*_*ytm 11
目前的字数:424 430 451 466 511 515 516 518 525 532 541 545 550 556 569 571 577 582 586 592.
import List
x%c=[(i,c)|i<-x]
l k p q|p>q=l k q p|True=head[[p,p+j..q]%c|m<-zip[k-1,k,k+1,1]"/|\\-",let (j,c)=m,mod(q-p)j==0]
w=map snd
q(k,m,x)z=w$sort$nubBy((==)&fst)$x%'+'++(concat$zipWith(l k)x$tail x)++z%'\n'++[1..m]%' '
r(z,m,x)=q(last z,m-1,w$sort x)z
u[(m,_)]n x=(-m::Int,n):x;u _ _ x=x
t(z,n,x)s|s=="\n"=(n:z,n+1,x)|True=(z,n+length s,u(reads s)n x)
y&x=(.x).y.x
main=interact$r.foldl t([],1,[]).groupBy((&&)&(>' '))
Run Code Online (Sandbox Code Playgroud)
这个版本从下面的原始Haskell条目中获得了很多灵感,但是做了一些重大改变.最重要的是,它表示具有单个索引的图像位置,而不是一对坐标.
有一些变化:
原始版本:
(需要-XTupleSections
,也许-XNoMonomorphismRestriction
)
import List
b=length
f=map
g=reverse
a(x,y)" "=(x,y+1)
a(x,y)z=([y,read z]:x,y+b z)
x%y=[min x y+1..max x y-1]
j([x,y],[w,z])|y==z=f(,'-')$f(y,)$x%w|x==w=f(,'|')$f(,x)$y%z|(y<z)==(x<w)=f(,'\\')$zip(y%z)$x%w|True=f(,'/')$zip(y%z)$g$x%w
k 0='\n'
k _=' '
y&x=(.x).y.x
y?x=f y.sort.x.concat
r z=snd?(nubBy((==)&fst).g)$[((y,x),k x)|x<-[0..maximum$f b d],y<-[1..b d]]:[((y,x),'+')|[x,y]<-e]:(f j$zip e$tail e)where d=f(groupBy$(&&)&(>' '))$lines z;e=tail?f g$zipWith(f.(:))[1..]$f(fst.foldl a([],1))d
main=interact r
Run Code Online (Sandbox Code Playgroud)
说明:
(1) d=...
:将输入拆分为空格和数字,例如
z = " 6 5\n\n1 2\n\n 4 3\n\n 7"
=> d = [[" ","6"," "," ","5"],[],["1"," "," "," "," "," "," "," ","2"],[],[" "," "," "," ","4"," "," "," ","3"],[],[" ","7"]]
Run Code Online (Sandbox Code Playgroud)
(2) e=...
:转换d
为每个数字的(y,x)坐标列表.
e = [[1,3],[9,3],[9,5],[5,5],[5,1],[2,1],[2,7]]
--- // 1 2 3 4 5 6 7
Run Code Online (Sandbox Code Playgroud)
(3)
[((y,x),k x)|...]
是一块空板.(k
返回空格或\n
取决于x坐标.)[((y,x),'+'))|...]
是数字的加号.(f j$zip e$tail e)
是连接数字的线.(j
将一对坐标映射到表示一条线的(坐标,字符)列表中.)将这3个组件连接并过滤以形成实际输出.请注意,顺序很重要,因此nubBy(...).g
只能将最后一个字符保留在同一位置.
Dan*_*tta 10
不是奖品获得者(但是),但我很满意这些努力(显示的换行符).这个新版本使用VT-100转义序列.'^ ['只是一个字符,Escape !!! 剪切和粘贴不适用于此版本,因为序列"^ ["必须替换为真正的ESC字符.为了使论坛友好,可以将ESC指定为"\ 0x1b",但它需要太多空间......
BEGIN{FS="[ ]"}{for(j=i=0;i<NF;j+=length(g)){if(g=$++i){x[g]=k=i+j;y[g]=NR;
m=m>k?m:k}}}END{printf"^[[2J[%d;%dH+",Y=y[i=1],X=x[1];while(a=x[++i])
{a-=X;b=y[i]-Y;t=a?b?a*b>0?92:47:45:124;A=a?a>0?1:-1:0;B=b?b>0?1:-1:0;
for(r=a?a*A:b*B;--r;){printf"^[[%d;%dH%c",Y+=B,X+=A,t}
printf"^[[%d;%dH+",Y+=B,X+=A}}
Run Code Online (Sandbox Code Playgroud)
较旧的标准版本
BEGIN{FS="[ ]"}{for(j=i=0;i<NF;j+=length(g)){if(g=$++i){x[g]=k=i+j;y[g]=NR;
m=m>k?m:k}}}END{q[X=x[1],Y=y[i=1]]=43;while(a=x[++i]){a-=X;b=y[i]-Y;
t=a?b?a*b>0?92:47:45:124;A=a?a>0?1:-1:0;B=b?b>0?1:-1:0;for(r=a?a*A:b*B;--r;
q[X+=A,Y+=B]=t);q[X+=A,Y+=B]=43}for(j=0;++j<NR;){for(i=0;i<m;){t=q[i++,j];
printf"%c",t?t:32}print}}
Run Code Online (Sandbox Code Playgroud)
现在有点解释
# This will break the input in fields separated by exactly 1 space,
# i.e. the fields will be null or a number.
BEGIN{FS="[ ]"}
# For each line we loop over all fields, if the field is not null
# it is a number, hence store it.
# Also account for the fact the numbers use space.
# Also, find the maximum width of the line.
{
for(j=i=0;i<NF;j+=length(g)){
if(g=$++i){
k=j+i;x[g]=k;y[g]=NR;m=m>k?m:k
}
}
}
# Once we have all the data, let start cooking.
END{
# First, create a matrix with the drawing.
# first point is a +
q[X=x[1],Y=y[i=1]]=43;
# loop over all points
while(a=x[++i]){
# Check next point and select character
# If a == 0 -> -
# If b == 0 -> |
# If a and b have same sign -> \ else /
a-=X;b=y[i]-Y;t=a?b?a*b>0?92:47:45:124;
# there is no sgn() function
A=a?a>0?1:-1:0;B=b?b>0?1:-1:0;
# Draw the line between the points
for(k=0;++k<(a?a*A:b*B);){
q[X+=A,Y+=B]=t
}
# store + and move to next point
q[X+=A,Y+=B]=43
}
# Now output all lines. If value in point x,y is 0, emit space
for(j=0;++j<NR;){
for(i=0;i<m;){
t=q[i++,j];printf("%c",t?t:32)
}
print
}
}
Run Code Online (Sandbox Code Playgroud)
C,386
C中的402 386字符.第一个后面的Newlines仅用于可读性.
#include <stdio.h>
int x[101],y[101],c=1,r,w,h,b,i,j,k,m,n;
int main(){
while((b=getchar())-EOF)
b-' '?b-'\n'?ungetc(b,stdin),scanf("%d",&b),x[b]=c++,y[b]=h,c+=b>9:(w=c>w?c:w,++h,c=1):++c;
for(r=0;r<h&&putchar('\n');++r)
for(c=0;c<w;++c){
for(b=' ',i=2,m=x[1]-c,n=y[1]-r;j=m,k=n,m=x[i]-c,n=y[i]-r,x[i++];)
b=j|k&&m|n?j*m>0|k|n?k*n<0?(j-k|m-n?j+k|m+n?j|m?b:'|':'/':'\\'):b:'-':'+';
putchar(b);
}
}
Run Code Online (Sandbox Code Playgroud)
英特尔汇编程序
汇编大小:506字节
来源:2252字节(嘿,这不是一个小问题)
要组装:使用A86运行:使用WinXP DOS框测试.调用jtd.com < input > output
mov ax,3
int 10h
mov ax,0b800h
mov es,ax
mov ah,0bh
int 21h
mov bx,255
cmp al,bl
mov dh,bh
mov si,offset a12
push offset a24
je a1
mov si,offset a14
a1: inc bl
a2: mov dl,255
call si
cmp al,10
jb a4
a3: cmp al,10-48
jne a1
inc bh
mov bl,dh
jmp a2
a4: mov dl,al
call si
cmp al,10
jae a5
mov ah,dl
aad
mov dl,al
a5: mov di,dx
mov ch,al
shl di,2
mov [di+a32],bx
cmp bl,[offset a30]
jb a6
mov [offset a30],bl
a6: cmp bh,[offset a31]
jb a7
mov [offset a31],bh
a7: push offset a19
mov al,80
mul bh
add al,bl
adc ah,0
add ax,ax
lea di,[di+2+a32]
mov [di],ax
add di,2
cmp di,[a22-3]
jbe a8
mov [a22-3],di
mov [a25-3],di
a8: mov di,ax
mov al,dl
aam
cmp ah,0
je a10
a9: add ah,48
mov es:[di],ah
add di,2
a10:add al,48
mov es:[di],al
mov al,ch
inc bl
jmp a3
a11:jmp si
a12:mov ah,0bh
int 21h
cmp al,255
jne a15
mov ah,8
int 21h
a13:cmp al,13
je a11
sub al,48
ret
a14:mov ah,1
int 21h
cmp al,26
jne a13
mov si,offset a15
ret
a15:cmp dl,255
je a16
mov al,32
ret
a16:mov si,offset a32 + 4
lodsw
mov cx,ax
mov dx,ax
lodsw
mov di,ax
mov b es:[di],1
mov bp,0f000h
call a26
add sp,6
mov bx,[a22-3]
mov ax,[offset a31]
inc ax
a17:mov bp,[offset a30]
a18:mov b[bx],32
inc bx
dec bp
jnz a18
mov w[bx],0a0dh
add bx,2
dec ax
jnz a17
mov b[bx],'$'
add w[a30],2
a19:lodsw
xchg ax,dx
cmp ah,dh
lahf
mov bl,ah
cmp al,dl
lahf
shr bl,6
shr ah,4
and ah,12
or bl,ah
mov bh,0
shl bx,3
a20:mov b es:[di],43
a21:mov al,b[a30]
mul ch
add al,cl
adc ah,0
mov bp,ax
mov b[bp+100h],43
a22:add di,[bx + a29]
add cl,[bx + a29 + 4]
add ch,[bx + a29 + 6]
mov b es:[di],1
mov al,[bx + a29 + 2]
mov [a21-1],al
mov [a22-1],al
mov bp,01000h
call a26
cmp di,[si]
jne a20
mov al,es:[di+2]
sub al,48
cmp al,10
jae a23
mov b es:[di+2],0
a23:mov b[a21-1],43
mov b[a22-1],43
mov b es:[di],43
lodsw
ret
a24:mov al,b[a30]
mul ch
add al,cl
adc ah,0
mov bp,ax
mov b[bp+100h],43
a25:mov dx,[a22-3]
mov ah,9
int 21h
ret
a26:pusha
a27:mov cx,0ffffh
a28:loop a28
dec bp
jnz a27
popa
ret
a29:dw -162,92,-1,-1,-2,45,-1,0,158,47,-1,1,0,0,0,0,-160,124,0,-1
a30:dw 0
a31:dw 0,0,0,160,124,0,1,0,0,0,0,-158,47,1,-1,2,45,1,0,162,92,1,1
a32:
Run Code Online (Sandbox Code Playgroud)
有趣的功能:自修改代码,动画输出(第二个示例有效,但是太大而无法显示),滥用'ret'来实现循环计数器,确定线/运动方向的有趣方式.
open System
let mutable h,s,l=0,Set.empty,Console.ReadLine()
while l<>null do
l.Split([|' '|],StringSplitOptions.RemoveEmptyEntries)
|>Seq.iter(fun t->s<-s.Add(int t,h,(" "+l+" ").IndexOf(" "+t+" ")))
h<-h+1;l<-Console.ReadLine()
let w=Seq.map(fun(k,h,x)->x)s|>Seq.max
let o=Array2D.create h (w+1)' '
Seq.sort s|>Seq.pairwise|>Seq.iter(fun((_,b,a),(_,y,x))->
let a,b,x,y=if b>y then x,y,a,b else a,b,x,y
o.[b,a]<-'+'
o.[y,x]<-'+'
if b=y then for x in(min a x)+1..(max a x)-1 do o.[y,x]<-'-'
elif a=x then for h in b+1..y-1 do o.[h,x]<-'|'
elif a<x then for i in 1..y-b-1 do o.[b+i,a+i]<-'\\'
else for i in 1..y-b-1 do o.[b+i,a-i]<-'/')
for h in 0..h-1 do
for x in 0..w do printf"%c"o.[h,x]
printfn""
Run Code Online (Sandbox Code Playgroud)
传说:
h = height
s = set
l = curLine
w = (one less than) width
o = output array of chars
Run Code Online (Sandbox Code Playgroud)
第1-6行:我保留一组(number,lineNum,xCoord)元组; 当我在每行输入中读到时,我找到所有数字并将它们添加到集合中.
第7-8行:然后我创建一个输出字符数组,初始化为所有空格.
第9行:对集合进行排序(按'数字'),然后取每个相邻的对...
第10-16行:...排序所以(a,b)是两个点中的"最高",而(x,y)是另一个.放置'+'符号,然后如果是水平的,则绘制它,否则如果是垂直的,则绘制它,否则绘制正确的对角线.如果输入不是"有效",那么谁知道发生了什么(在我高尔夫球化之前,这段代码充斥着'断言').
第17-19行:打印结果
$i=$l=0;$k=@{}
$s=@($input|%{[regex]::matches($_,"\d+")|%{$k[1*$_.Value]=@{y=$l
x=$_.Index}};$l++;""})
while($a=$k[++$i]){
if($i-eq1){$x=$a.x;$y=$a.y}
do{$d=$a.x.CompareTo($x);$e=$a.y.CompareTo($y)
$s[$y]=$s[($y+=$e)].PadRight($x+1).Remove($x,1).Insert(($x+=$d),
"\-/|+|/-\"[4+$d*3+$e])}while($d-or$e)}$s
Run Code Online (Sandbox Code Playgroud)
这是一个带有评论的漂亮版本:
# Usage: gc testfile.txt | dots.ps1
$l=$i=0 # line, dot index (used below)
$k=@{} # hashtable that maps dot index to coordinates
# Apply regular expression to each line of the input
$s=@( $input | foreach{
[regex]::matches($_,"\d+") | foreach{
# Store each match in the hashtable
$k[ 1*$_.Value ] = @{ y = $l; x = $_.Index }
}
$l++; # Next line
"" # For each line return an empty string.
# The strings are added to the array $s which
# is used to produce the final output
}
)
# Connect the dots!
while( $a = $k[ ++$i ] )
{
if( $i -eq 1 ) # First dot?
{
# Current position is ($x, $y)
$x = $a.x;
$y = $a.y
}
do
{
$d = $a.x.CompareTo( $x ) # sign( $a.x - $x )
$e = $a.y.CompareTo( $y ) # sign( $a.y - $y )
$c = '\-/|+|/-\'[ 4 + $d * 3 + $e ] # character '
# Move
$x += $d
$y += $e
# "Replace" the charcter at the current position
# PadRight() ensures the string is long enough
$s[ $y ]=$s[ $y ].PadRight( $x+1 ).Remove( $x, 1 ).Insert( $x, $c )
} while( $d -or $e ) # Until the next dot is reached
}
# Print the resulting string array
$s
Run Code Online (Sandbox Code Playgroud)