Чи врівноважить башта?


36

Вступ

Враховуючи башту ASCII і силу вітру, напишіть програму або функцію, щоб визначити, чи буде башта врівноважена або в який бік вона впаде.

Наприклад, перша вежа врівноважується, а друга падає вліво.

  # #            # #
  ###            ### 
 ###            ### 
 # #            # # 
#####          ##### 
 ###            ### 
 ###              #

Це мій перший виклик. Сподіваюся, вам сподобається.

Напрямки

Вежа складається з з'єднаних блоків, представлених #і утворює жорсткий предмет . Кожен блок - це квадрат з шириною і висотою однієї одиниці і має постійну щільність. На вежу діють дві сили, її вага та сила вітру. Усі сили діють на кожен блок окремо і проходять через центр блоку.

  • Завдяки своїй вазі кожен блок має силу опускання на одну одиницю, що діє на нього.
  • Також кожен блок, що не має іншого сусіднього до нього блоку з навітряної сторони, має на нього силу, що діє горизонтально у напрямку вітру. Величина цієї сили задається як вхід.
  • Напрямок вітру вказується прапором ASCII десь на вході. На вході буде прапор, якщо і лише якщо вітер не дорівнює нулю. Прапор не впливає на жодні сили.

Прапор буде виглядати саме так, як показано нижче.

Flag design and corresponding wind direction:

 o~~        ~~o
 |~~        ~~|

--->        <---

Для уточнення, вежа є твердим предметом і не розірветься і не прикріплена до землі. Однак ваша програма повинна обчислити сили для кожного блоку окремо, щоб визначити, чи балансує вежа.

Приклад

  o~~
  |~~
  # #              > > 
  ###              >## 
 ###              >##  
 # #              > >  
#####            >#### 
 ###              >##  
 ###              >##  

Wind force: 1    Wind direction: --->

Вітер дме праворуч і буде натискати на блоки, показані >вгорі праворуч. Зауважте, що вітер діє з внутрішньої сторони отворів.

Припустимо, у нижньому лівому куті вежі є координати (0,0). Момент навколо лівої основи вежі (0,0)становить 71 одиницю за годинниковою стрілкою, тому вежа не впаде ліворуч. Момент навколо правої основи вежі (0,3) становить 8 одиниць за годинниковою стрілкою, тому вежа впаде праворуч.

Якби вітер дме вліво, відповідні моменти становлять 2 одиниці за годинниковою стрілкою і 61 одиницю проти годинникової стрілки в тих же точках, щоб вежа врівноважувалась.

Вхідні дані

  • Ваша програма чи функція повинні приймати два входи, десятковий номер та рядок, розділений новим рядком.
  • Десяткове число буде більше нуля і позначає силу, яку чинить вітер на кожен оголений блок, як у прикладі.
  • Рядок буде представляти вежу зверху вниз і може містити пробіли, #|o~символи та нові рядки. Ви можете заздалегідь взяти на себе нову лінію та / або прокладати вежу з пробілами, щоб утворити прямокутник.
  • Башта матиме принаймні одну #в нижньому ряду.
  • Ви можете ввести число та рядок у будь-якому порядку.
  • Якщо величина сили вітру не дорівнює нулю, десь на вході буде прапор, або на землі, або підключений до вежі. Прапор матиме точну форму, показану вище.
  • Ці #блоки будуть утворювати зв'язну форму , яка може містити отвори. Іншими словами, всі блоки будуть примикати до іншого іншого блоку, якщо не буде лише одного блоку.

Вихідні дані

  • Один з персонажів B, Lабо R, в залежності від того, чи буде вежа балансу, падіння до лівої (проти годинникової стрілки), або впасти в напрямку вправо ( по годинниковою стрілкою).
  • Вихід може мати необов'язковий кінцевий новий рядок.

Це ; застосовуються стандартні правила та лазівки.

B Випробування:

Wind: 1
    ~~o
    ~~|
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0
##
# ##
###

Wind: 1.7
o~~
|~~
#
##

Wind: 0.768
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 0.1
#
#
#
#
#
# o~~
# |~~

Wind: 0
#

Wind: 0
############

Wind: 144
               o~~
############   |~~

Wind: 0
#######
 ##
 #
 ##

Wind: 0
                ############
           ############
       ############
    ############
   ############
 ############
############

Wind: 41
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

L Випробування:

Wind: 0
#####
   #


Wind: 42
                 ############
            ############
        ############
     ############
    ############
  ############     ~~o
 ############      ~~|

Wind: 4
########
    ###
 ~~o# ##
 ~~|#  #

Wind: 3
########
    ###
 o~~# ##
 |~~   #

R Випробування:

Wind: 1
      o~~
      |~~
      # #
      ###
     ###
     # #
    #####
     ###
     ###

Wind: 2
o~~
|~~
#

Wind: 0.001
                 ############
            ############
        ############
     ############
    ############
  ############     o~~
 ############      |~~

Wind: 145
               o~~
############   |~~

Wind: 1
#
#
#
#
#
# o~~
# |~~

Wind: 0.26
#######
 ##
 #   o~~
 ##  |~~

Довідкове рішення (JavaScript)

Спробуйте в Інтернеті.

function balanced(tower, wind) {
    var rows = tower.split('\n').reverse(); // Reverse so row index matches height of row.
    var height = rows.length;
    var leftEdge = rows[0].indexOf('#'); // Find bottom left corner of tower.
    var rightEdge = rows[0].lastIndexOf('#') + 1; // Find bottom right corner of tower.
    var leftMoment = 0, rightMoment = 0; // Moments around the bottoms corners of tower.
    wind *= tower.indexOf('~o')>-1 ? -1 : 1; // Find direction of the wind.

    // Sum the moments for each block in the tower.
    for (var i = height - 1; i >= 0; i--) {
        rows[i].split('').map(function(ch, index, arr) {
            if (ch=='#') {
                // If there's not a block toward the windward side of the current one.
                if ((wind < 0 && arr[index-1] != '#') || (wind > 0 && arr[index+1]!='#')) {
                    // Add moments from wind.
                    leftMoment += (i+0.5)*-wind;
                    rightMoment += (i+0.5)*-wind; 
                }

                leftMoment += leftEdge - (index + 0.5);
                rightMoment += rightEdge - (index + 0.5);
            }
        }, 0);
    }
    if (leftMoment > 0) return 'L';
    else if (rightMoment < 0) return 'R';
    else return 'B';
}

Таблиця лідерів

Ось фрагмент стека для створення як звичайного табло, так і огляду переможців за мовою.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Якщо ви хочете включити у свій заголовок декілька чисел (наприклад, тому що ваш результат становить суму двох файлів або ви хочете окремо вказати штрафні санкції для перекладача), переконайтесь, що фактичний результат - це останнє число у заголовку:

# Perl, 43 + 2 (-p flag) = 45 bytes

Ви також можете зробити ім'я мови посиланням, яке потім з’явиться у фрагменті таблиць лідерів:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes


17
Ласкаво просимо до PPCG; це чудово написаний перший виклик! :)
Дверна ручка

Відповіді:


2

JavaScript (ES6), 239 байт

Я гольфував свою контрольну реалізацію. Мені вдалося зберегти байти, змінивши цикл for на a map, використовуючи &&і ||для короткого замикання, якщо оператори, і використовуючи ,оператор, щоб підходити все до одного оператора, щоб уникнути явного повернення функції.

(a,b)=>((c=a.split`
`.reverse(),d=c[f=g=0].indexOf`#`,e=c[0].lastIndexOf`#`+1),a.match`o~`&&(b*=-1),c.map((h,i)=>h.replace(/#/g,(j,k,l)=>(b>0&l[k-1]!='#'|b<0&l[k+1]!='#'&&(f+=(i+=0.5)*b,g+=i*b),f+=d-k-0.5,g+=e-k-0.5))),f>0?'L':g<0?'R':'B')

Це все ж можливо більше пограти в гольф. Пропозиції вітаються.


+1 набагато краще, ніж моє наївне рішення
Conor O'Brien

1

JavaScript ES6, 297 293 байт

В основному стислий варіант даної реалізації.

b=(n,e)=>{r=n.split`
`.reverse(),t=r.length,a=r[0].indexOf`#`,f=r[i=l=0].lastIndexOf`#`+1;e*=n.indexOf`~o`>-1?-1:1;for(d=t-1;d>=0;d--)r[d].split``.map((n,r,t)=>{(j="#")==n&&((0>e&&j!=t[r-1]||e>0&&j!=t[r+1])&&(i+=(d+.5)*-e,l+=(d+.5)*-e),i+=a-(r+.5),l+=f-(r+.5))},0);return i>0?"L":0>l?"R":"B"}

Напіврозширений:

b = (n, e) => {
    r = n.split `
`.reverse(), t = r.length, a = r[0].indexOf `#`, f = r[i = l = 0].lastIndexOf `#` + 1;
    e *= n.indexOf `~o` > -1 ? -1 : 1;
    for (d = t - 1; d >= 0; d--) r[d].split ``.map((n, r, t) => {
        (j = "#") == n && ((0 > e && j != t[r - 1] || e > 0 && j != t[r + 1]) && (i += (d + .5) * -e, l += (d + .5) * -e), i += a - (r + .5), l += f - (r + .5))
    }, 0);
    return i > 0 ? "L" : 0 > l ? "R" : "B"
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.