Pi # 2 ธรรมชาติ - แม่น้ำ


12

เป้าหมาย

กำหนดสตริงที่มีแฮชการคำนวณคำนวณความยาวทั้งหมดและหารด้วยระยะทางตั้งแต่ต้นจนจบ

การจำลอง

เราจำลองอะไร ตามบทความนี้อัตราส่วนของความยาวของแม่น้ำต่อระยะทางระหว่างจุดเริ่มต้นและจุดสิ้นสุดอยู่ที่ประมาณ Pi! (สิ่งนี้อาจได้รับการพิสูจน์ประจักษ์ แต่ฉันสามารถค้นหาข้อมูลและสำหรับความท้าทายนี้เราจะถือว่ามันเป็นจริง)

เราจำลองสิ่งนี้ได้อย่างไร

  • รับข้อมูลสตริงของช่องว่างและแฮช
  • แฮชแต่ละอันจะมีอีกสองตัวติดกัน
    • ยกเว้นแฮชตัวแรกและตัวสุดท้ายซึ่งจะมีเพียง 1 ตัวเท่านั้น
  • ตัวละครแต่ละตัวอยู่บนจุดขัดแตะ (x, y)
  • x เป็นดัชนีของตัวละครในบรรทัด
    • เช่นcเป็นอักขระตัวที่ 4 ใน0123c567
  • y เป็นหมายเลขบรรทัดของตัวละคร
    • เช่นcอยู่ในบรรทัดที่ 3:
      0line
      1line
      2line
      3c...
  • รวมระยะทางระหว่างแฮชที่อยู่ติดกันเรียกว่า S
  • ใช้ระยะห่างระหว่างแฮชแรกและแฮชสุดท้ายเรียกว่า D
  • กลับ S/D

ป้อนคำอธิบายรูปภาพที่นี่

สเปค

  • อินพุต
    • ยืดหยุ่นรับอินพุตในรูปแบบมาตรฐานใด ๆ (เช่นพารามิเตอร์ฟังก์ชัน STDIN) และในรูปแบบมาตรฐาน (เช่น String, Binary)
  • เอาท์พุต
    • ยืดหยุ่นให้ผลลัพธ์ในรูปแบบมาตรฐาน (เช่นผลตอบแทนการพิมพ์)
    • พื้นที่สีขาวพื้นที่ต่อท้ายและพื้นที่สีขาวชั้นนำเป็นที่ยอมรับ
    • ความแม่นยำโปรดระบุความแม่นยำอย่างน้อย 4 ตำแหน่ง (เช่น3.1416)
  • เกณฑ์การให้คะแนน
    • รหัสที่สั้นที่สุดชนะ!

กรณีทดสอบ

นี่คือการประมาณของฉันของแม่น้ำ การประมาณของฉันอาจจะแย่หรือสิ่งเหล่านี้เป็นตัวอย่างที่ไม่ดีของประชากรแม่น้ำ นอกจากนี้ฉันทำการคำนวณด้วยมือ ฉันอาจคิดถึงการคำนวณ

แม่น้ำเหลือง

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

แม่น้ำไนล์

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

แม่น้ำมิสซิสซิปปี

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

TL; DR

ความท้าทายเหล่านี้เป็นการจำลองอัลกอริธึมที่ต้องการเพียงแค่ธรรมชาติและสมองของคุณ หากคุณต้องการ Pi ในระหว่างการเปิดเผยซอมบี้วิธีการเหล่านี้จะไม่เปลืองกระสุน ! มีเก้าความท้าทายทั้งหมด


3
พวกเขาเรียกว่าแฮชด้วยตัวเอง "Hashtag" เป็นเพียงคำสำหรับแท็กอินไลน์ที่มีความหมายด้วย#<tag>
FlipTack

1
ฉันคิดว่าควรคำนวณระยะทางโดยใช้ทฤษฎีบทพีทาโกรัส ถูกต้องหรือไม่
Loovjo

นอกจากนี้เราสามารถรับอินพุตเป็นรายการบรรทัดได้หรือไม่?
Loovjo

@ Loovjo ^^ สามารถเป็นได้มันคือเรขาคณิตแบบยุคลิดดังนั้นคุณต้องการคำนวณว่ามันดี ^ ใช่อินพุตมีความยืดหยุ่น
NonlinearFruit

1
@NonlinearFruit ขอบคุณ อาจเป็นไปได้ว่ารุ่น ASCII นั้นไม่ได้เป็นสิ่งที่ไม่ดีพอ :)
Luis Mendo

คำตอบ:


6

MATL , 48 44 42 37 33 ไบต์

บันทึกได้ค่อนข้างน้อยเนื่องจากความคิดของ rahnema1 (คำตอบแบบคู่)ของการยุบสอง convolutions เป็นหนึ่ง

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

สิ่งนี้ใช้อินพุตเป็นเมทริกซ์ไบนารีโดยมี;ตัวคั่นแถว 1สอดคล้องกับแฮและ0พื้นที่

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

นี่คือตัวแปลงรูปแบบที่ใช้อินพุตเป็นอาร์เรย์ถ่าน 2D (อีกครั้งโดยมี;ตัวคั่น) และสร้างการแทนค่าสตริงของเมทริกซ์ไบนารีที่เกี่ยวข้อง

คำอธิบาย

สนุกมาก! รหัสใช้การสนทนาสองมิติสองแบบสามแบบเพื่อวัตถุประสงค์ที่แตกต่างกัน:

  1. ในการตรวจจับเพื่อนบ้านแนวตั้งและแนวนอนซึ่งมีส่วนร่วมในระยะทาง1หน้ากากที่ต้องการจะเป็น

    0 1 0
    1 0 1
    0 1 0
    

    แต่เราต้องการให้เพื่อนบ้านแต่ละคู่ตรวจพบเพียงครั้งเดียว ดังนั้นเราจึงใช้หน้ากากครึ่งหนึ่ง (และสามารถลบค่าศูนย์สุดท้าย):

    0 1 0
    1 0 0
    

    ในทำนองเดียวกันเพื่อตรวจจับเพื่อนบ้านในแนวทแยงซึ่งมีส่วนร่วมในระยะทางของsqrt(2)หน้ากากจะ

    1 0 1
    0 0 0
    1 0 1
    

    แต่ด้วยเหตุผลเดียวกับที่กล่าวมามันก็จะกลายเป็น

    1 0 1
    0 0 0
    

    หากมาสก์นี้ถูกคูณด้วยsqrt(2)และเพิ่มเข้าไปในอันแรก, ทั้งสอง convolutions สามารถถูกแทนที่ด้วยหนึ่ง convolution ด้วยมาสก์แบบรวม

    sqrt(2) 1  sqrt(2)
    1       0        0
    
  2. จุดเริ่มต้นและจุดสิ้นสุดคือตามคำนิยามจุดที่มีเพื่อนบ้านเพียงคนเดียว ในการตรวจจับพวกเราเรามีความมั่นใจด้วย

    1 1 1
    1 0 1
    1 1 1
    

    และดูว่าคะแนนใดให้1ผล

ในการสร้างมาสก์รวมของไอเท็ม 1 มันสั้นกว่าในการสร้างสแควร์แล้วนำสแควร์รูท มาสก์ในรายการ 2 เป็นตัวอักษรที่กำหนดไว้ล่วงหน้า

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
บางคนเคยพูดว่าการบิดเป็นกุญแจสู่ความสำเร็จ !
ข้อบกพร่อง

4

อ็อกเทฟ, 99 ไบต์

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

วิธีการเกือบเหมือนกันกับคำตอบ MATLแต่ที่นี่เคอร์เนลของ convolutions คือ

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

นั่นsqrt(2) =1.41คือเพื่อนบ้านที่เป็นแนวทแยงและ1 สำหรับเพื่อนบ้านโดยตรงดังนั้นเมื่อเราหาค่าผลรวมของผลลัพธ์เหนือแม่น้ำเราจะได้ระยะทางที่แท้จริงสองเท่า
เวอร์ชันที่ไม่ถูกปรับแต่ง :

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 

ลอง (วาง) บนOctave Online


ความคิดของคุณก้อนสอง convolutions แรกเป็นหนึ่งในบันทึกฉันไม่กี่ไบต์ :)
หลุยส์ Mendo

{[x y]=find(c<2&c>0),pdist([x y])}{2}มันช่างฉลาดจริงๆ !!!
ข้อบกพร่อง

ข่าวดีก็คือว่าเราไม่ได้มีข้อ จำกัด ของ MATLAB!
rahnema1

2
@flawr เห็นด้วย ว่าควรจะไปที่เคล็ดลับการเล่นกอล์ฟคู่ !
Luis Mendo

@LuisMendo มีบางรายการที่รวมอยู่ในเคล็ดลับ
rahnema1

2

JavaScript (ES6), 178

ป้อนเป็นสตริงที่มีการขึ้นบรรทัดใหม่ในรูปแบบสี่เหลี่ยมผืนผ้า : แต่ละบรรทัดมีช่องว่างที่มีความยาวเท่ากัน (เช่นในตัวอย่าง)

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

น้อย golfed

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

ทดสอบ

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.