Natural Pi#2-川


12

ゴール

一連のハッシュを持つ文字列を指定して、その全長を計算し、開始から終了までの距離で除算します。

シミュレーション

何をシミュレートしていますか?この論文によると、川の長さと開始点と終了点の間の距離の比率はおよそPi!(これは経験的に反証されたかもしれませんが、データを見つけることができたので、この挑戦​​のためにそれが真実であると仮定します)。

これをどのようにシミュレートしますか?

  • 空白とハッシュの文字列入力を取得します
  • 各ハッシュには、他の2つのハッシュが隣接しています
    • 1つだけを持つ最初と最後のハッシュを除いて
  • 各キャラクターは格子点上にあります (x, y)
  • x はその行のキャラクターのインデックスです
    • たとえばc、4番目の文字は0123c567
  • y 文字の行番号です
    • たとえばc、3行目にあります。
      0line
      1line
      2line
      3c...
  • 隣接するハッシュ間の距離を合計して呼び出します S
  • 最初と最後のハッシュ間の距離を取り、それを呼び出します D
  • 戻る S/D

ここに画像の説明を入力してください

仕様

  • 入力
    • 柔軟で、標準的な方法(関数パラメーター、STDINなど)および標準的な形式(文字列、バイナリなど)で入力を取得します。
  • 出力
    • 柔軟性があり、標準的な方法(例:返品、印刷)で出力する
    • 空白、末尾および先頭の空白は許容されます
    • 精度、小数点以下4桁以上の精度を指定してください(例3.1416
  • 得点
    • 最短のコードが勝ちます!

テストケース

これらは私の川の近似値です。私の近似は貧弱かもしれませんし、これらは河川人口の貧弱なサンプルかもしれません。また、この計算は手作業で行いました。計算ミスがあったかもしれません。

黄河

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

ナイル川

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

ミシシッピ川

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

TL; DR

これらの課題は、Piを概算するために自然と脳(およびおそらく再利用可能なリソース)のみを必要とするアルゴリズムのシミュレーションです。ゾンビの黙示録中に本当にPiが必要な場合、これらの方法は弾薬を無駄にしません!合計9つの課題があります。


3
独自にハッシュと呼ばれています。「ハッシュタグ」が意味さとインラインタグのためだけの用語である#<tag>
FlipTack

1
ピタゴラスの定理を使用して距離を計算する必要があると思います。これは正しいです?
Loovjo

また、入力を行のリストとして取得できますか?
Loovjo

@Loovjo ^^可能性があります、それはユークリッドジオメトリですので、計算したいが、それは結構です。^はい、入力は柔軟です。
NonlinearFruit

1
@NonlinearFruitありがとう。それから、おそらくASCIIバージョンが十分にうねりがないということでしょう:)
ルイスメンドー

回答:


6

MATL48 44 42 37 33バイト

2つの畳み込みを1つに折り畳むというrahnema1のアイデア(Octaveの答え)のおかげで、かなりの数バイトが節約されました。

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

これは、;行セパレーターとして、入力をバイナリ行列として受け取ります。1ハッシュと0スペースに対応します。

オンラインでお試しください!または、すべてのテストケースを確認します

ここにあります(と、再び2次元チャー配列として入力を受け取り、フォーマットコンバータ;セパレータとして)は、対応するバイナリ行列の文字列表現を生成します。

説明

これは楽しかった!コードは3つを使用します、それぞれ異なる目的のためにつの2つの2Dコンボリューションを。

  1. の距離に寄与する垂直および水平の近隣を検出するに1は、必要なマスクは次のようになります。

    0 1 0
    1 0 1
    0 1 0
    

    ただし、近隣の各ペアを1回だけ検出する必要があります。そのため、マスクの半分を使用します(ゼロの最後の行は削除できます)。

    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)最初のマスクを乗算して追加すると、2つの畳み込みは、結合されたマスクを持つ1つの畳み込みに置き換えることができます

    sqrt(2) 1  sqrt(2)
    1       0        0
    
  2. 開始点と終了点は、定義上、隣人が1人だけの点です。それらを検出するために、

    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
畳み込みが成功の鍵だと言う人もいました
flawr 16

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の答えとほぼ同じ方法ですが、ここでは畳み込みのカーネルは

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

これsqrt(2) =1.41は対角線上の隣人と1 直接の隣人のためであり、川の結果の値を合計すると、実際の距離の2倍になります。
改変されていないバージョン

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で試して(貼り付け)


最初の2つの畳み込みを1つにまとめるというあなたのアイデアにより、数バイト節約できました:)
ルイスメンドー

{[x y]=find(c<2&c>0),pdist([x y])}{2}とても賢い!!!
flawr 16

良いニュースは、MATLABの制限がないことです!
rahnema1 16

2
@flawr同意した。それはに行くべきオクターブゴルフのヒント
ルイスメンドー

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

少ないゴルフ

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.