Tự nhiên số 2 - Sông


12

Mục tiêu

Đưa ra một chuỗi với một chuỗi các giá trị băm, tính tổng chiều dài của nó và chia cho khoảng cách từ đầu đến cuối.

Mô phỏng

Chúng ta đang mô phỏng cái gì? Theo bài báo này , tỷ lệ chiều dài của một con sông với khoảng cách giữa điểm bắt đầu và điểm kết thúc là xấp xỉ Pi! (Điều này có thể đã bị từ chối theo kinh nghiệm, nhưng tôi có thể tìm thấy dữ liệu và đối với thử thách này, chúng tôi sẽ cho rằng đó là sự thật).

Làm thế nào chúng ta mô phỏng điều này?

  • Lấy một chuỗi đầu vào của khoảng trắng và giá trị băm
  • Mỗi hàm băm sẽ có hai cái khác liền kề với nó
    • Ngoại trừ hàm băm đầu tiên và cuối cùng sẽ chỉ có 1
  • Mỗi nhân vật nằm trên một điểm lưới (x, y)
  • x là chỉ số của nhân vật trong dòng của nó
    • ví dụ clà nhân vật thứ 4 trong0123c567
  • y là số dòng của nhân vật
    • ví dụ như ctrên dòng thứ 3:
      0line
      1line
      2line
      3c...
  • Tính tổng khoảng cách giữa các giá trị băm liền kề, gọi nó S
  • Lấy khoảng cách giữa các giá trị băm đầu tiên và cuối cùng, gọi nó D
  • Trở về S/D

nhập mô tả hình ảnh ở đây

Sự chỉ rõ

  • Đầu vào
    • Linh hoạt, nhận đầu vào theo bất kỳ cách tiêu chuẩn nào (ví dụ: tham số hàm, STDIN) và ở bất kỳ định dạng chuẩn nào (ví dụ: Chuỗi, Nhị phân)
  • Đầu ra
    • Linh hoạt, cung cấp đầu ra theo bất kỳ cách tiêu chuẩn nào (ví dụ: trả lại, in)
    • Không gian trắng, dấu vết và khoảng trắng hàng đầu được chấp nhận
    • Độ chính xác, vui lòng cung cấp ít nhất 4 chữ số thập phân chính xác (nghĩa là 3.1416)
  • Chấm điểm
    • Mã ngắn nhất sẽ thắng!

Các trường hợp thử nghiệm

Đây là những xấp xỉ của tôi về các dòng sông. Các xấp xỉ của tôi có thể kém hoặc đây là mẫu nghèo của dân số sông. Ngoài ra, tôi đã làm tính toán này bằng tay; Tôi có thể đã bỏ lỡ tính toán.

Dòng sông màu vàng

        ### ####           
       #   #    #          
       #       #          #
       #       #         # 
       #       #        #  
      #         #      #   
##   #          # #####    
  ##  #          #         
    ##                     
1.6519

Sông Nile

         #     
         #     
          #    
           #   
           #   
          #    
         #     
        #      
        #  #   
        # # #  
         #  #  
            #  
          ##   
         #     
         #     
        #      
        #      
       #       
       #       
       #       
       #       
   #  #        
  # ##         
  #            
  #            
   #           
    #          
     #         
     #         
      #        
     #         
    #          
     #         
      #        
1.5498

sông Mississippi

 ###            
#   #           
     #          
     #          
    #           
   #            
  #             
  #             
  #             
   #            
    #           
     #          
      #         
       #        
        #       
        #       
        #       
         #      
          #     
           #    
          #     
       ###      
      #         
       #        
      #         
     #          
    #           
    #           
    #           
    #           
     #          
      ##        
        #       
        #       
         ##     
           ##   
             ## 
               #
              # 
             #  
            #   
           #    
          #     
         #      
        #       
        #       
        #       
        #       
        #       
       #        
      #         
     #          
      #         
       #        
        ####    
            #   
             #  
1.5257

TL; DR

Những thách thức này là mô phỏng các thuật toán chỉ yêu cầu tự nhiên và bộ não của bạn (và có thể một số tài nguyên có thể sử dụng lại) để ước tính Pi. Nếu bạn thực sự cần Pi trong ngày tận thế zombie, những phương pháp này không lãng phí đạn ! Có chín thử thách tổng cộng.


3
Họ được gọi là băm một mình. "Hashtag" chỉ là thuật ngữ cho một thẻ nội tuyến được biểu thị bằng#<tag>
FlipTack

1
Tôi giả định rằng khoảng cách nên được tính bằng định lý Pythagore. Điều này có đúng không?
Loovjo

Ngoài ra, chúng ta có thể lấy đầu vào làm danh sách các dòng không?
Loovjo

@Loovjo ^^ Có thể, đó là hình học Euclide nên tuy nhiên bạn muốn tính toán nó là ổn. ^ Có, đầu vào là linh hoạt.
Phi tuyến

1
@Nonlinear Quả cảm ơn. Vậy thì có lẽ các phiên bản ASCII không đủ tội lỗi :)
Luis Mendo

Câu trả lời:


6

MATL , 48 44 42 37 33 byte

Khá nhiều byte được lưu nhờ vào ý tưởng của rahnema1 (câu trả lời Octave) về việc thu gọn hai kết quả thành một

t5BQ4B&vX^Z+*ssGt3Y6Z+1=*&fdwdYy/

Cái này lấy đầu vào là một ma trận nhị phân, với ;dấu phân cách hàng. 1tương ứng với hàm băm và 0không gian.

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Đây là một trình chuyển đổi định dạng lấy đầu vào là mảng char 2D (một lần nữa, với; dấu phân cách) và tạo ra các biểu diễn chuỗi của ma trận nhị phân tương ứng.

Giải trình

Điều này thật thú vị! Mã này sử dụng ba cấu trúc 2D, mỗi cấu hình cho một mục đích khác nhau:

  1. Để phát hiện hàng xóm dọc và ngang, đóng góp khoảng cách 1, mặt nạ cần thiết sẽ là

    0 1 0
    1 0 1
    0 1 0
    

    Nhưng chúng tôi chỉ muốn mỗi cặp hàng xóm được phát hiện một lần. Vì vậy, chúng tôi lấy một nửa mặt nạ (và hàng số không cuối cùng có thể được gỡ bỏ):

    0 1 0
    1 0 0
    

    Tương tự, để phát hiện hàng xóm chéo, đóng góp khoảng cách sqrt(2), mặt nạ sẽ là

    1 0 1
    0 0 0
    1 0 1
    

    nhưng với lý do tương tự như trên, nó trở thành

    1 0 1
    0 0 0
    

    Nếu mặt nạ này được nhân lên sqrt(2)và thêm vào mặt nạ đầu tiên, hai cấu trúc có thể được thay thế bằng một phép chập với mặt nạ kết hợp

    sqrt(2) 1  sqrt(2)
    1       0        0
    
  2. Theo định nghĩa, điểm bắt đầu và điểm kết thúc chỉ là một điểm lân cận. Để phát hiện ra chúng, chúng tôi kết hợp với

    1 1 1
    1 0 1
    1 1 1
    

    và xem điểm nào cho 1kết quả.

Để tạo mặt nạ kết hợp của mục 1, nó ngắn hơn để tạo hình vuông của nó và sau đó lấy căn bậc hai. Mặt nạ trong mục 2 là một nghĩa đen được xác định trước.

t     % Take input matrix implicitly. Duplicate
5B    % 5 in binary: [1 0 1]
Q     % Add 1; [2 1 2]
4B    % 4 in binary: [1 0 0]
&v    % Concatenate vertically
X^    % Square root of each entry
Z+    % 2D convolution, maintaining size
*     % Multiply, to only keep results corresponding to 1 in the input
ss    % Sum of all matrix entries. This gives total distance
Gt    % Push input again. Duplicate
3Y6   % Predefined literal. This gives third mask
Z+    % 2D convolution, maintaining size
1=    % Values different than 1 are set to 0
*     % Multiply, to only keep results corresponding to 1 in the input
&f    % Push array of row indices and array of column indices of nonzeros
d     % Difference. This is the horizontal difference between start and end
wd    % Swap, difference. This is the vertical difference between start and end 
Yy    % Hypothenuse. This gives total distance in straight line
/     % Divide. Display implicitly

2
Một số người thường nói, sự kết hợp đó là chìa khóa thành công !
flawr

4

Octave, 99 byte

@(a)sum((c=conv2(a,[s=[q=2^.5 1 q];1 0 1;s],'same').*a)(:))/2/{[x y]=find(c<2&c>0),pdist([x y])}{2}

Phương pháp gần giống như câu trả lời MATL nhưng ở đây, hạt nhân của kết quả là

1.41 ,  1  , 1.41
1    ,  0  , 1 
1.41 ,  1  , 1.41

đó sqrt(2) =1.41là cho hàng xóm chéo và 1 dành cho hàng xóm trực tiếp vì vậy khi chúng ta tính tổng các giá trị của kết quả qua sông, chúng ta sẽ nhận được gấp đôi khoảng cách thực.
phiên bản không có bản quyền :

a=logical([...
0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 
1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 0 0 0 0 
0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ]);
sq = sqrt(2);
kernel = [...
    sq ,  1  , sq
    1  ,  0  , 1 
    sq ,  1  , sq];
%2D convolution
c=conv2(a,kernel,'same').*a;
#river length
river_length = sum(c (:))/2;
#find start and end points
[x y]=find(c<2&c>0);
# distance between start and end points
dis = pdist([x y]);
result = river_length/ dis 

Hãy thử (dán) nó trên Octave Online


Ý tưởng của bạn để gộp hai kết quả đầu tiên thành một tiết kiệm cho tôi một vài byte :)
Luis Mendo

{[x y]=find(c<2&c>0),pdist([x y])}{2}thật là thông minh chết tiệt !!!
flawr

một tin tốt là chúng tôi không có hạn chế về MATLAB!
rahnema1

2
@flawr Đồng ý. Điều đó nên đi đến các mẹo chơi golf Octave !
Luis Mendo

@LuisMendo một số mục được bao gồm trong các mẹo
rahnema1

2

JavaScript (ES6), 178

Nhập dưới dạng một chuỗi với các dòng mới ở dạng hình chữ nhật : mỗi dòng được đệm với các khoảng trắng có cùng độ dài (như trong ví dụ)

r=>r.replace(/#/g,(c,i)=>([d=r.search`
`,-d,++d,-d,++d,-d,1,-1].map((d,j)=>r[i+d]==c&&(--n,s+=j&2?1:Math.SQRT2),n=1),n||(v=w,w=i)),w=s=0)&&s/2/Math.hypot(v%--d-w%d,~(v/d)-~(w/d))

Ít chơi gôn

r=>(
  r.replace(/#/g, // exec the following for each '#' in the string
    (c,i) => // c: current char (=#), i: current position
    ( // check in 8 directions
      // note: d starts as the offset to next row, prev x position
      // and is incremented up to offset to next row, succ x position
      // note 2: there are 2 diagonal offsets, then 2 orthogonal offsets
      //         then other 2 diagonal, then 2 more orthogonal
      [d=r.search`\n`,-d, ++d,-d, ++d,-d, 1,-1].map( // for each offset
        (d,j) => // d: current offset, j: array position (0 to 7)
        r[i+d] == c && // if find a '#' at current offset ...
          ( 
            --n, // decrement n to check for 2 neighbors or just 1
            s += j & 2 ? 1 : Math.SQRT2 // add the right distance to s
          ),
      n = 1), // n starts at 1, will be -1 if 2 neighbors found, else 0
      // if n==0 we have found a start or end position, record it in v and w
      n || (v=w, w=i)
   ),
  w=s=0), // init s and w, no need to init v
  // at the end 
  // d is the length of a line + 1
  // s is twice the total length of the river
  // v and w can be used to find the x,y position of start and end
  s/2/Math.hypot(v%--d-w%d,~(v/d)-~(w/d))
)

Kiểm tra

F=
r=>r.replace(/#/g,(c,i)=>([d=r.search`\n`,-d,++d,-d,++d,-d,1,-1].map((d,j)=>r[i+d]==c&&(--n,s+=j&2?1:Math.SQRT2),n=1),n||(v=w,w=i)),w=s=0)&&s/2/Math.hypot(v%--d-w%d,~(v/d)-~(w/d))

Yellow=`        ### ####           
       #   #    #          
       #       #          #
       #       #         # 
       #       #        #  
      #         #      #   
##   #          # #####    
  ##  #          #         
    ##                     `

Nile=`         #     
         #     
          #    
           #   
           #   
          #    
         #     
        #      
        #  #   
        # # #  
         #  #  
            #  
          ##   
         #     
         #     
        #      
        #      
       #       
       #       
       #       
       #       
   #  #        
  # ##         
  #            
  #            
   #           
    #          
     #         
     #         
      #        
     #         
    #          
     #         
      #        `

Missi=` ###            
#   #           
     #          
     #          
    #           
   #            
  #             
  #             
  #             
   #            
    #           
     #          
      #         
       #        
        #       
        #       
        #       
         #      
          #     
           #    
          #     
       ###      
      #         
       #        
      #         
     #          
    #           
    #           
    #           
    #           
     #          
      ##        
        #       
        #       
         ##     
           ##   
             ## 
               #
              # 
             #  
            #   
           #    
          #     
         #      
        #       
        #       
        #       
        #       
        #       
       #        
      #         
     #          
      #         
       #        
        ####    
            #   
             #  `
console.log('Yellow River',F(Yellow))
console.log('Nile River',F(Nile))
console.log('Mississippi River',F(Missi))

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.