Natürlicher Pi # 2 - Fluss

12

Tor

Berechnen Sie bei einer Zeichenfolge mit einer Folge von Hashes deren Gesamtlänge und dividieren Sie diese durch die Entfernung vom Anfang bis zum Ende.

Simulation

Was simulieren wir? Nach dieser Arbeit beträgt das Verhältnis der Länge eines Flusses zur Entfernung zwischen Anfang und Ende ungefähr Pi! (Dies wurde möglicherweise empirisch widerlegt, aber ich konnte die Daten finden und für diese Herausforderung gehen wir davon aus, dass sie wahr sind.)

Wie simulieren wir das?

  • Nehmen Sie eine Zeichenfolgeeingabe von Leerzeichen und Hashes
  • Jedem Hash sind zwei weitere benachbart
    • Mit Ausnahme des ersten und letzten Hashs, der nur 1 hat
  • Jeder Charakter liegt auf einem Gitterpunkt (x, y)
  • x ist der Index des Charakters in seiner Zeile
    • zB cist das 4. Zeichen in0123c567
  • y ist die Zeilennummer des Zeichens
    • zB csteht in der 3. Zeile:
      0line
      1line
      2line
      3c...
  • Summieren Sie die Entfernungen zwischen benachbarten Hashes, nennen Sie es S
  • Nehmen Sie den Abstand zwischen dem ersten und letzten Hash, nennen Sie es D
  • Rückkehr S/D

Bildbeschreibung hier eingeben

Spezifikation

  • Eingang
    • Flexibel, Eingaben auf eine der Standardarten (zB Funktionsparameter, STDIN) und in einem beliebigen Standardformat (zB String, Binary)
  • Ausgabe
    • Flexibel, Ausgabe auf eine der Standardarten (z. B. Rückgabe, Druck)
    • Leerzeichen, nachfolgende und führende Leerzeichen sind zulässig
    • Genauigkeit, geben Sie bitte mindestens 4 Dezimalstellen Genauigkeit (dh 3.1416)
  • Wertung
    • Kürzester Code gewinnt!

Testfälle

Dies sind meine Annäherungen an die Flüsse. Meine Annäherungen könnten schlecht sein oder dies könnte eine schlechte Stichprobe der Flussbevölkerung sein. Auch diese Berechnungen habe ich von Hand gemacht; Ich hätte es vermissen können.

Gelber Fluss

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

Nil

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

Mississippi

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

TL; DR

Diese Herausforderungen sind Simulationen von Algorithmen, für die nur die Natur und Ihr Gehirn (und möglicherweise einige wiederverwendbare Ressourcen) erforderlich sind, um sich dem Pi anzunähern. Wenn Sie Pi während der Zombie-Apokalypse wirklich brauchen, verschwenden diese Methoden keine Munition ! Insgesamt gibt es neun Herausforderungen .

NichtlinearFruit
quelle
3
Sie werden von sich aus Hashes genannt. "Hashtag" ist nur die Bezeichnung für ein Inline-Tag, das mit gekennzeichnet ist#<tag>
FlipTack
1
Ich gehe davon aus, dass die Entfernung mit dem Satz von Pythagoras berechnet werden sollte. Ist das richtig?
Loovjo
Können wir die Eingabe auch als eine Liste von Zeilen annehmen?
Loovjo
@Loovjo ^^ Es kann sein, es ist eine euklidische Geometrie, also ist es in Ordnung, wie auch immer Sie es berechnen möchten. ^ Ja, die Eingabe ist flexibel.
NichtlinearFruit
1
@NonlinearFruit Danke. Dann ist es wahrscheinlich, dass die ASCII-Versionen nicht kurvenreich genug sind :)
Luis Mendo

Antworten:

6

MATL , 48 44 42 37 33 Bytes

Dank der Idee von rahnema1 (Oktavenantwort), zwei Windungen in eine zu brechen, konnten einige Bytes gespart werden

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

Dies nimmt die Eingabe als binäre Matrix mit ;als Zeilentrennzeichen. 1entspricht Hash und 0Space.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Hier ist ein Formatkonverter, der Eingaben als 2D - Zeichen - Arrays akzeptiert (wieder mit; als Trennzeichen) verwendet und Zeichenfolgendarstellungen der entsprechenden binären Matrizen erstellt.

Erläuterung

Das hat Spaß gemacht! Der Code verwendet drei zwei 2D-Faltungen, jede für einen anderen Zweck:

  1. Um vertikale und horizontale Nachbarn zu erkennen, die einen Abstand von sich geben 1, wäre die erforderliche Maske

    0 1 0
    1 0 1
    0 1 0
    

    Aber wir wollen nur jedes Paar von Nachbarn einmal erkannt werden. Also nehmen wir die halbe Maske (und die letzte Nullenreihe kann entfernt werden):

    0 1 0
    1 0 0
    

    Ähnlich wäre es, diagonale Nachbarn zu erkennen, die einen Abstand von sqrt(2)der Maske beitragen

    1 0 1
    0 0 0
    1 0 1
    

    aber durch die gleiche Überlegung wie oben wird es

    1 0 1
    0 0 0
    

    Wenn diese Maske sqrt(2)mit der ersten multipliziert und zu dieser addiert wird, können die beiden Windungen durch eine Windung mit der kombinierten Maske ersetzt werden

    sqrt(2) 1  sqrt(2)
    1       0        0
    
  2. Start- und Endpunkt sind per Definition die Punkte mit nur einem Nachbarn. Um sie zu entdecken, arbeiten wir mit

    1 1 1
    1 0 1
    1 1 1
    

    und sehen, welche Punkte 1als Ergebnis geben.

Um die kombinierte Maske von Punkt 1 zu erzeugen, ist es kürzer, das Quadrat zu erzeugen und dann die Quadratwurzel zu ziehen. Die Maske in Punkt 2 ist ein vordefiniertes Literal.

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
Luis Mendo
quelle
2
Einige Leute pflegten zu sagen, dass Faltung der Schlüssel zum Erfolg ist !
Fehler
4

Oktave, 99 Bytes

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

fast die gleiche Methode wie MATL Antwort, aber hier Kernel von Windungen ist

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

, Das sqrt(2) =1.41ist für diagonale Nachbarn und 1 ist für die direkten Nachbarn so , wenn wir Werte des Ergebnisses über den Fluss fassen wir zweimal die genaue Entfernung zu bekommen.
ungolfed version :

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 

Probieren Sie es auf Octave Online aus (fügen Sie es ein)

rahnema1
quelle
Ihre Idee, die ersten beiden Windungen zu einer zu machen, hat mir ein paar Bytes erspart :)
Luis Mendo
{[x y]=find(c<2&c>0),pdist([x y])}{2}ist so verdammt schlau !!!
Fehler
Eine gute Nachricht ist, dass wir keine Einschränkungen von MATLAB haben!
Rahnema1
2
@flawr Einverstanden. Das sollte zu den Octave Golftipps gehen !
Luis Mendo
@ LuisMendo einige Einträge in Tipps enthalten
rahnema1
2

JavaScript (ES6), 178

Eingabe als Zeichenfolge mit Zeilenumbrüchen in rechteckiger Form : Jede Zeile wird mit Leerzeichen auf die gleiche Länge aufgefüllt (wie in den Beispielen).

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

Weniger golfen

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

Prüfung

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

edc65
quelle