Code Golf: Connect Points

You can remember these drawings from the moment you were a child, but now it’s time to let the computer draw them (in full splendor ascii). Enjoy!

Description:

Input is a few lines (terminated by a new line) that describe the "field". There are “numbers” in this field (separated by spaces). All lines can be considered the same length (you can fill in the blanks to the end).

  • numbers always begin with 1
  • they follow the order of natural numbers: each "next number" is increased by 1
  • each number is surrounded by (at least) one space left and right

A task:

Draw the lines between these numbers in natural order (1 -> 2 -> 3 -> ...N) (suppose that N <= 99) with the following characteristics:

  • replace number with ' + '
  • for horizontal lines: use ' - '
  • for vertical lines: use ' | ''
  • move left and down or right and up: /
  • move left and up or right and down: \

Important notes:

  • When drawing lines of type 4 and 5, you can assume (given the points to connect with the coordinates x1, y1 and x2, y2) that distance(x1,x2) == distance(y1,y2) . Or, in other words (as the jball user comments): "consecutive elements that do not align horizontally or vertically always align with the slash or backslash."

  • It is important to follow the order in which the dots are connected (new lines can delete old lines).

- Input example 1 -

                                   8 

                                   7 6 
                       10 9       

                                         5            

                                      3 4        
                  eleven 

                    12 13    
           12                     

- Example output 1 -

                                  +                                
                                 / |                                
                                / + - +                             
                      + -------- + \                            
                     / \                           
                    / +                          
                   / |                          
                  / + - +                          
                 + |                             
                  \ | |                             
                   + ------------------------ +                      
          + -------------------------- +        

- Input example 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                       

- Sample output 2 - ( link for unicorn )

                        +        
                       / +      
                      //          
                     //        
                    //           
                   / + - +        
               + + \         
               |  + + - \ +          
               + \ + \ +         
              / + + \ + \    
             + \ \ |  +       
             |  + + + /           
             |  + - + + ------- + /               
             + + - + +              
            / \              
           +++               
           |  +                 
           + + /             
            \ + \ + --- + +           
             \ + - + + \ / +              
              + + - + / \ / + |             
             / |  | + + / + |                 
            / + ||  / // +            
           + + ||  / // /                
            \ + ||  / // /              
             \ | |  ||  / + / /                  
              \ + --- + + + \ +                  
               + |  |  |  + |                 
                + - + + --- + +               

Winner:

The shortest solution (by the number of code characters). The input can be read using standard input.

+49
language-agnostic code-golf rosetta-stone
Mar 26 '10 at 23:37
source share
16 answers

Perl, 222 char (211)

Perl, 384 365 276 273 253 225 222 218 211 characters (222 when the competition ended). Newlines are for readability only and are not included in the number of characters.

Last edit: $" no longer overwritten and @S is not printed

  $_=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 

Explanation:

 $_=join'',@S=map{$n=s/$/$"x97/e;(/./g)[0..95],$/}<>; 

This task will be easier if all lines are the same length (say, 97 characters). This operator takes each line of input, replaces the end of line character with 96 spaces, then pushes the first 96 characters plus a new line into the @S array. Note that we also set $n=1 , as 1 is the first number we will look for in the input. The join statement creates one row from the @S array. It is more convenient to use the scalar variable $_ for pattern matching, and it is more convenient to use the @S array to create updates for the image.

 while(/\b$n /){ 

Find the number $n in the variable $_ . Perl regex evaluation has several side effects. One of them is to set a special variable $-[0] with the position of the beginning of the matched template in the agreed line. This gives us the position of the number $n in the string $_ , as well as the @S array.

Of course, the loop will end when $n is high enough so that we cannot find it at the input.

  $S[$q=$-[0]]='+'; 

Let $q be the position of the number $n in the string $_ and the array @S , and assign the character "+" at this position.

  $ P = ($ p || = $ q) + $ q - ($ Q = $ q> $ p? $ Q: $ p)
         ($ P, $ Q) = sort {$ a- $ b} $ p || $ q, $ q; 

For the first time through a loop, set $p to $q . After the first time $p will hold the previous value of $q (which will refer to the position at the input of the previous number). Assign $p and $q such that $p = min ( $p , $q ), $q = max ( $p , $q )

  for(qw'\98 |97 /96 -1'){ 

By construction, consecutive numbers are either

  • connected by a vertical line. Since the input is built to have 97 characters in each line, this case means that $p-$q is divisible by 97.

  • "that matches the backslash slope" that $p-$q is divisible by 98

  • "matching slash" that $p-$q is divisible by 96

  • on the same horizontal line

Elements of this list encode the possible number of positions between line segments and a character to encode this segment.

  /\D/; 

Another trivial assessment of regular expressions. As a side effect, it sets the special variable $& ( MATCH variable) to the line segment ( \ | / or - ) and $' ( POSTMATCH variable) to the number (98 97 96 or 1) encoded in the list item.

  $S[$P]=$&until($Q-$P)%$'||$Q<=($P+=$') 

This operator draws a line segment between two numbers. If $Q-$P is divisible by $' , then continue to increment $p by $' and assign the character $& to $S[$P] until $p reaches $q . More specifically, for example, if $Q-$P is divisible by 97, then increment $p by 97 and set $S[$P]='|' . Repeat until $P>=$Q

  $n++;$p=$q 

Get ready for the next iteration of the loop. Increment $n to the next number to search for input, and let $p hold the position of the previous number.

 s/\d/ /,print for@S 

Output the array, converting any remaining digits (from double bit identifiers at the input, where we only rewrite the first with a space "+") to spaces.

+36
Mar 27 '10 at 5:55
source share

Commodore 64 BASIC - 313 characters

EDIT: see below for golf

A short drive through the memory strip with PET graphics, POKE s and PEEK s and that’s all :)

It fits in a single screen :)

The program works directly in the screen memory, so you just continue, clear the screen, place points and type RUN :

Input

You need to wait a minute or so until he finds the points, and then begins to draw. This is not fast - you can see the lines that are drawn, but the coolest part :)

Output

Golf Version:

Commodore BASIC seems like a great golf language because it doesn't require spaces :). You can also shorten most commands by entering an unbiased first letter followed by a shifted second letter. For example, POKE can be entered as P [SHIFT + O], which is displayed as P┌ on the screen:

Golfed version

+58
Mar 29 '10 at 22:25
source share

MS-DOS package (yes, you read it right!)

I often hear (or read) that people say that the party is not very strong, and you can’t do much with them, I tell them well, here, the power of BATCH!

Actual script (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 

And so you call it

 echo off setlocal ENABLEDELAYEDEXPANSION call script.bat input.txt 

where "input.txt" is the file containing the input for the "program".

PS At the moment it is not yet optimized for the line length. I already spent a couple of hours to get to this point, and now I need to sleep ... I will see if I can improve it tomorrow (currently a “script.. Bat 'sits at 2755 bytes)

+14
Mar 31 '10 at 14:21
source share

Rebmu : 218 characters

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

I read and edit it very well in my lead-Latin form. (Although I use line breaks !!) :)

But here is how the dialect is transformed by the translator, when the case-insensitive "shaking" trick is brewed, and they get used to it. I will add some comments. (Tips: fi is, fe is foreach, sp is the space character, i? Is the index, hd is the voice, ch is the change, sk is the skip, pc is the choice, bk is the gap, i is if, e is either ee equal to or 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 ab] ; d finds you the iterator position of the first digit of a two digit ; number in the matrix d: a| [fe sm [t: fi s rj [sp a sp] it [++ 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 [xjyj]] ; b is the (b)eginning coordinate pair for our stroke. f+ returns the ; element at G current position and advances G (f+ = "first+") ; advance g iteration position b: f+ g wh b [ ; j is the iterator position of the beginning stroke j: cb ; 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 if [ ; k is the iterator position of the end of the stroke k: cf ; the (h)orizontal and (v)ertical offsets we'll step by (-1,0,1) h: qxkxjv: qykyju [ ; 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 cb pc l ez v 1 [ez h 2 [ee hv 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 [hv] 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 je fi l sc j {+} {+ } ; update from finish pair to be new begin pair for next loop iteration j: k b: f ] ; write out m wm 

Both language and pattern are new in the experimental stage. For example, ad cannot be used to add vectors and matrices before I modified it to help with this pattern. But I think that in any case, a language designed specifically for code golf should be like that. This is a fine line between “language” and “library”.

The latest commentary source is available on GitHub.

+12
Jun 18 '10 at 2:28
source share

Haskell, 424 characters

Current char count: 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] lkpq|p>q=lkqp|True=head[[p,p+j..q]%c|m<-zip[k-1,k,k+1,1]"/|\\-",let (j,c)=m,mod(qp)j==0] w=map snd q(k,m,x)z=w$sort$nubBy((==)&fst)$x%'+'++(concat$zipWith(lk)x$tail x)++z%'\n'++[1..m]%' ' r(z,m,x)=q(last z,m-1,w$sort x)z u[(m,_)]nx=(-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)nx) y&x=(.x).yx main=interact$r.foldl t([],1,[]).groupBy((&&)&(>' ')) 

This version greatly inspires the original Haskell entry below, but makes significant changes. Most importantly, it represents the location of the image with one index, and not with two coordinates.

There are some changes:

  • Now the input should contain all lines with the same length (allowed by the rules.)
  • No language extension required



Original version:

(Requires -XTupleSections and possibly -XNoMonomorphismRestriction )

 import List b=length f=map g=reverse a(x,y)" "=(x,y+1) a(x,y)z=([y,read z]:x,y+bz) 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).yx y?x=f y.sort.x.concat rz=snd?(nubBy((==)&fst).g)$[((y,x),kx)|x<-[0..maximum$fbd],y<-[1..bd]]:[((y,x),'+')|[x,y]<-e]:(fj$zip e$tail e)where d=f(groupBy$(&&)&(>' '))$lines z;e=tail?fg$zipWith(f.(:))[1..]$f(fst.foldl a([],1))d main=interact r 



Explanation:

(1) d=... : splits the input into spaces and numbers, e.g.

  z = " 6 5\n\n1 2\n\n 4 3\n\n 7" => d = [[" ","6"," "," ","5"],[],["1"," "," "," "," "," "," "," ","2"],[],[" "," "," "," ","4"," "," "," ","3"],[],[" ","7"]] 

(2) e=... : converts d to a list of coordinates (y, x) for each number.

  e = [[1,3],[9,3],[9,5],[5,5],[5,1],[2,1],[2,7]] --- // 1 2 3 4 5 6 7 

(3)

  • [((y,x),kx)|...] is an empty board. ( k returns a space or \n depending on the x-coordinate.)
  • [((y,x),'+'))|...] - plus signs in numbers.
  • (fj$zip e$tail e) are lines connecting numbers. ( j maps a pair of coordinates to a list (coordinate, character) that represents a string.)

These 3 components are combined and filtered to form the actual output. Note that order is important, so nubBy(...).g can only contain the last character in the same place.

+11
Mar 27 '10 at 9:05
source share

AWK - 296 317 321 324 334 340

Not a winner of the prize (yet), but I am pleased with the effort (line breaks to display). This new version uses VT-100 escape sequences. "^ [" is just one character, Escape !!! Cut and paste will not work with this version, since the sequence "^ [" must be replaced with a real ESC character. To make it forum friendly, ESC can be specified as "\ 0x1b", but it takes up too much space ...

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

Older Standard Version

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

Now a little explanation

 # This will break the input in fields separated by exactly 1 space, # ie 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 } } 
+10
Mar 29 '10 at 0:19
source share

C, 386

402,386 characters in C. Newlines after the first are read-only.

 #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?(jk|mn?j+k|m+n?j|m?b:'|':'/':'\\'):b:'-':'+'; putchar(b); } } 
+9
Mar 27 '10 at 9:12
source share

Intel assembler

Collected size: 506 bytes

Source: 2252 bytes (hey, this is not a trivial problem)

Build: use A86 Run: Tested using the WinXP DOS window. Call 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: 

Fun features: self-modifying code, animated output (the second example works, but too large to display), the abuse of "ret" to create a loop counter, an interesting way to determine the direction of the line / movement.

+7
Mar 31 '10 at 22:55
source share

F #, 725 characters

 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 ax)+1..(max ax)-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..yb-1 do o.[b+i,a+i]<-'\\' else for i in 1..yb-1 do o.[b+i,ai]<-'/') for h in 0..h-1 do for x in 0..w do printf"%c"o.[h,x] printfn"" 

Legend:

 h = height s = set l = curLine w = (one less than) width o = output array of chars 

Lines 1-6: I save a set of (number, lineNum, xCoord) tuples; as I read in each line of input, I find all the numbers and add them to the set.

Line 7-8: Then I create an array of output characters initialized for all spaces.

Line 9: Sort the set (by "number"), then take each adjacent pair and ...

Lines 10-16: ... sort so (a, b) is the "highest" of the two points, and (x, y) is the other. Place the “+” signs, and then, if horizontally, draw it, otherwise, if vertically, draw it, otherwise draw the correct diagonal. If the entry is not "valid", then who knows what is happening (this code was littered with "statements" before I included it in golf).

Lines 17-19: printing the result

+5
Mar 27 '10 at 2:31
source share

Powershell 328 304 characters

 $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=$ax;$y=$ay} do{$d=$axCompareTo($x);$e=$ayCompareTo($y) $s[$y]=$s[($y+=$e)].PadRight($x+1).Remove($x,1).Insert(($x+=$d), "\-/|+|/-\"[4+$d*3+$e])}while($d-or$e)}$s 

and here is a pretty printed version with comments:

 # 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 = $ax; $y = $ay } do { $d = $axCompareTo( $x ) # sign( $ax - $x ) $e = $ayCompareTo( $y ) # sign( $ay - $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 
+5
Mar 28 '10 at 19:57
source share

Python - 381

 import re b=list(iter(raw_input,'')) c=sum((zip([i]*999,re.finditer('\\d+',x))for i,x in enumerate(b)),[]) d=sorted((int(m.group()),i,m.start())for i,m in c) e=[[' ']*max(map(len,b))for x in b] for(t,u,v),(x,y,z)in zip(d,d[1:]+d[-1:]): e[u][v]='+' while u!=y or v!=z:i,j=(u<y)-(u>y),(v<z)-(v>z);u+=i;v+=j;e[u][v]=['|','/\\-'[(i==j)+2*(i==0)]][j!=0] print'\n'.join(map(''.join,e)) 
+4
Mar 27 '10 at 1:48
source share

C #, 422 characters

758 754 641 627 584 546 532 486 457 454 443 440 422 characters (next time, maybe I won’t send it so soon.)

 using A=System.Console;class B{static int C,o,d,e,G,O=1,f,F,u,n;static void Main(){var s=A.In.ReadToEnd();A.Clear();while(++u<s.Length){f++;if (s[u]<32){u++;F++;f= 0;}if(s[u]>32){if(int.Parse(s[u]+""+s[++u])==O){o= e>f?1:f>e?-1:0;C=d>F?1:F>d?-1:0 ;G=e+o;n=d+C;if(O++>1)while(n!=F||G!=f) {A.SetCursorPosition(G-=o,n-=C);A.Write( "+/-|\\"[n==d&&G==e?0:n==F&&G ==f?0:C+o==0?1:C==0?2:o==0?3:4]);}e=f;d=F;F=0;f=u=-1 ;}f++;}}A.Read();}} 

Usage: run, paste (or type) the input, make sure the last line is completed, press CTRL-Z or F6, press Enter.

A formatted, but still fundamentally incomprehensible version:

 using A = System.Console; class B { // code golf fun! static int C, o, d, e, G, O = 1, f, F, u, n; static void Main() { // read the input into a string char by char until EOF var s = A.In.ReadToEnd(); A.Clear(); // clear console, ready to draw picture // O is the "dot" number we're looking for // f is current column // F is current row // loop over the field looking for numbers sequentially // until no more are found while (++u < s.Length) { f++; // any char <32 is expected to be a CR/LF // increment the current row and reset the current column if (s[u] < 32) { u++; // skip the other half of the CR/LF pair F++; // next row f = 0; // column reset } // any char >32 is expected to be a number if (s[u] > 32) { // parse the current + next char and see if it // the number we want if (int.Parse(s[u] + "" + s[++u]) == O) { // set up coordinates, compare X1 with X2 // and Y1 with Y2 to figure out line direction // horizontal direction (same as o=e.CompareTo(f)) o = e > f ? 1 : f > e ? - 1 : 0; // vertical direction (same as C=d.CompareTo(F)) C = d > F ? 1 : F > d ? - 1 : 0; // initial offsets compensate for off-by-one G = e + o; n = d + C; // draw the line (except for the very first dot) if (O++ > 1) while (n != F || G != f) { // update coords and write desired char A.SetCursorPosition(G -= o, n -= C); // this lovely line decides which char to // print, and prints it A.Write( "+/-|\\"[n == d && G == e ? 0 : n == F && G == f ? 0 : C + o == 0 ? 1 : C == 0 ? 2 : o == 0 ? 3 : 4]); } // remember end point of this line, to use as start point // of next line e = f; d = F; // reset current row (F), column (f), field position (u) F = 0; f = u = -1; } // bump current column because we parse 2 chars when we // find a dot f++; } } A.Read(); // prevent command prompt from overwriting picture } } 
+3
28 . '10 20:34
source share

Like this!

 #include <stdio.h> #include <stdlib.h> #include <string.h> int sign(int x) { if (x < 0) return -1; if (x > 0) return +1; return 0; } #define MAX_ROWS 100 #define MAX_COLS 100 #define MAX_DIGITS 100 int main(void) { // Read in the digits int number[MAX_DIGITS][2]; int rows = 0; int cols = 0; char row[MAX_COLS]; int maxvalue = 0; int i, j, value, x; for (i = 0; i < MAX_ROWS; i++) { if (row != fgets(row, MAX_COLS, stdin)) break; value = 0; for (j=0; row[j] != 0; j++) { if (row[j] >= '0' && row[j] <= '9') { x = j; value = 0; do { value = 10*value + (row[j]-'0'); j++; } while (row[j] >= '0' && row[j] <= '9'); number[value][0] = i; number[value][1] = x; if (maxvalue < value) maxvalue = value; if (rows < i+1) rows = i+1; if (cols < x+1) cols = x+1; } } } // Create an empty field char field[rows][cols]; memset(field, ' ', rows*cols); char lines[] = "\\|/-+-/|\\"; int dr,dc; // Draw the numbers and lines field[number[1][0]][number[1][1]] = '+'; for (i = 2; i <= maxvalue; ++i) { int r = number[i-1][0]; int c = number[i-1][1]; int rt = number[i][0]; int ct = number[i][1]; dr = sign(rt-r); dc = sign(ct-c); char line = lines[(dr+1)*3+dc+1]; while (r != rt || c != ct) { r += dr; c += dc; field[r][c] = line; } field[r][c] = '+'; } for (i = 0; i < rows; ++i) { for (j = 0; j < cols; ++j) putchar(field[i][j]); putchar('\n'); } return 0; } 
+2
27 . '10 1:18
source share

#, 638

 using System; using System.Linq; using System.Text.RegularExpressions; class C { static void Main() { int i=0,j; var p = Console.In.ReadToEnd() .Split('\n') .SelectMany( r => { i++; j =0; return Regex.Matches(r, "\\s+(\\d+)").Cast<Match>() .Select(m => { j += m.Length; return new { X = j, Y = i-1, N = int.Parse(m.Groups[1].Value) }; }); } ).OrderBy(a=>aN).ToList(); var W = p.Max(a => aX)+1; var k = new char[W*i+W]; i = 0; while (i < p.Count) { var b = p[i > 0 ? i - 1 : 0]; var a = p[i]; int h = aY - bY, w = aX - bX; var s = "|-/\\"[h == 0 ? 1 : w == 0 ? 0 : h / w > 0 ? 3 : 2]; while ((h | w) != 0) { k[bX + w + W * (bY + h)] = s; h -= h.CompareTo(0); w -= w.CompareTo(0); } k[aX + aY * W] = '+'; k[W * ++i] = '\n'; } Console.Write(k); } } 
+2
27 . '10 7:21
source share

, . (x1, x2) == distance (y1, y2):

 + |\ +-+ + |\ | \ +--+ + |\ | \ | \ +---+ 

, , (x1, x2) == (y1, y2) +2:

 +\ | \ +--\+ +\ | \ | \ +---\+ +\ | \ | \ | \ +----\+ 
+1
27 . '10 0:03
source share

++ 637

 #include <iostream> #include <string> #include <vector> #define S(x)((x)<0?-1:x>0?1:0) using namespace std;enum{R=100,C=100,D=100};int main(){string s; int N[D][2],M=0,q=0,p=0,i,j,V,L,a,b;for(i=0;j=0,(i<R)&&getline(cin,s);i++) while((j=s.find_first_not_of(" ",j))<=s.size()){L=sscanf(&s[j],"%d",&V); N[V][0]=i;N[V][1]=j;if(M<V)M=V;if(q<=i)q=i+1;if(p<=j)p=j+1;j+=L+1;} string F(q*p,' '),l="\\|/-+-/|\\";F[p*N[1][0]+N[1][1]]='+';for(i=2;i<=M;++i){ int r=N[i-1][0],c=N[i-1][1],d=N[i][0],e=N[i][1];for(a=S(dr),b=S(ec);r!=d||c!=e;) r+=a,c+=b,F[p*r+c]=l[(a+1)*3+b+1];F[p*r+c]='+';}for(i=0;i<q;i++) cout<<string(&F[i*p],p)+"\n";} 

:

 #include <iostream> #include <string> #include <vector> #define S(x)((x)<0?-1:x>0?1:0) using namespace std; enum{R=100,C=100,D=100}; int main(){ string s; int N[D][2],M=0,rs=0,cs=0,i,j,V,L,dr,dc; for(i=0;j=0,(i<R)&&getline(cin,s);i++) while((j=s.find_first_not_of(" ",j))<=s.size()){ L=sscanf(&s[j],"%d",&V); N[V][0]=i; N[V][1]=j; if(M<V)M=V; if(rs<=i)rs=i+1; if(cs<=j)cs=j+1; j+=L+1; } string F(rs*cs,' '),lines="\\|/-+-/|\\"; F[cs*N[1][0]+N[1][1]]='+'; for(i=2;i<=M;++i){ int r=N[i-1][0],c=N[i-1][1],rt=N[i][0],ct=N[i][1]; for(dr=S(rt-r),dc=S(ct-c);r!=rt||c!=ct;) r+=dr,c+=dc,F[cs*r+c]=lines[(dr+1)*3+dc+1]; F[cs*r+c]='+'; } for(i=0;i<rs;i++) cout<<string(&F[i*cs],cs)+"\n"; } 

, morotspaj.

+1
27 . '10 5:55
source share



All Articles