Природний Пі №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
Їх називають хешами самостійно. "Хештег" - це лише термін для вбудованого тегу, який позначається#<tag>
FlipTack

1
Я припускаю, що відстань слід обчислювати, використовуючи теорему Піфагора. Це правильно?
Loovjo

Також, чи можемо ми вважати вкладення списком рядків?
Loovjo

@Loovjo ^^ Це може бути, це євклідова геометрія, тому ви хочете обчислити це нормально. ^ Так, введення гнучко.
нелінійний

1
@NonlinearFruit Дякую Тоді, мабуть, версії ASCII недостатньо зграбні :)
Луїс Мендо

Відповіді:


6

MATL , 48 44 42 37 33 байт

Досить кілька байтів, збережених завдяки ідеї rahnema1 (відповідь Октави) про згортання двох згортків в один

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)і додати до першої, два згортки можна замінити на одну згортку комбінованою маскою

    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, але тут ядро ​​згортків

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


Ваша ідея об'єднати перші два згортки в одну врятувала мені кілька байтів :)
Луїс Мендо

{[x y]=find(c<2&c>0),pdist([x y])}{2}такий проклятий розумний !!!
недолік

гарна новина полягає в тому, що у нас немає обмежень MATLAB!
rahnema1

2
@flawr Погодився. Це повинно йти до порад з гольфу в Octave !
Луїс Мендо

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.