Додайте вагу в одну сторону пилочки, щоб збалансувати її


13

Закон про балансування

Пиляльна пилка (нібито від французької «ci-ça», що означає «це-те») утворює третину святої трійці обладнання дитячих майданчиків, а також подібні всюдисущі гірки та гойдалки. Пилка-пила знаходиться в ідеальному рівновазі, якщо і лише тоді, коли сума моментів з кожного боку рівнозначна. Отже, пилка може врівноважуватися, додаючи певну кількість ваги в бік із сумою нижнього моменту; досягти цього - ваша мета цього завдання.

Виклик

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

Вхідні дані

Ваша програма повинна приймати в будь-якому розумному форматі пильну пилку ASCII, таку як:

100             100
-------------------
         ^         

Перший рядок містить два числа, кожне з яких представляє ваги на пилорізі. Рівно одна вага присутня на кожній стороні, кожна виступає в самому кінці своєї сторони дошки. Ваги гарантуються цілими числами, і завжди вирівнюють їх відповідним кінцем дошки. Ці числа ніколи не перекриють опорну точку ( ^).

Другий рядок являє собою «дошку» пилорами. Кожен тире ( -) являє собою рівну довжину один до одного тире, за винятком тире безпосередньо над опорою ( ^), яка не має довжини.

Третій рядок являє собою основу пилорами. Ця опорна точка позначена єдиним символом, який не є пробілом на цій лінії, circflex ('^'). Орієнтир може бути розміщений в будь-якому місці по всій довжині дошки на дійсному вході, поки залишається достатньо місця, щоб цифри, що представляють ваги, не перекривали опорну точку ні на вході, ні на виході.

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

Вихідні дані

Для виведення однакового зображення пилки слід роздруковувати у вигин, але одна (і лише одна) ваг замінюється більшою вагою, щоб врівноважувати пилку. Гарантовані введення дозволяють зробити це можливим, використовуючи лише цілі числа. Тому ваги повинні бути показані без десяткових знаків або будь-яких інших подібних позначень. Якщо у вашій мові не використовується stdout, вам слід пройти спільну / мета-консенсус щодо виводу. Нові рядки є непоганими, але будь-які інші зміни формату зображення, ймовірно, не в порядку.

Зразки

Тестові входи та відповідні результати

Введення 1

12                22
--------------------
             ^      

Вихід 1

12                26
--------------------
             ^      

Введення 2

42       42
-----------
     ^     

Вихід 2

42       42
-----------
     ^     

Введення 3

3             16
----------------
        ^      

Вихід 3

14            16
----------------
        ^      

Введення 4

1                56
-------------------
    ^              

Вихід 4

196              56
-------------------
    ^              

Реалізація посилань - Python 3

# Takes a list of strings as input
def balance_seesaw(lines):
    weights = [int(w.strip()) for w in lines[0].split()]

    length  = len(lines[1])
    pivot   = lines[2].find("^")
    left_length    = pivot
    right_length   = length - 1 - pivot

    left_torque  = weights[0] * left_length
    right_torque = weights[1] * right_length

    if left_torque > right_torque:
        weights[1] = left_torque // right_length
    elif right_torque > left_torque:
        weights[0] = right_torque // left_length

    weights = [str(w) for w in weights]

    string_gap = " " * (length - sum(len(w) for w in weights))
    lines[0] = weights[0] + string_gap + weights[1]

    print("\n".join(lines))

balance_seesaw(["1                56",
                "-------------------",
                "    ^              "])

Правила

  • Це , тому найкоротший виграш коду рахується в байтах. Перевірте мета, чи підрахунок байтів незручно у вашій мові.

  • Застосовуються стандартні правила / лазівки.

  • Введення даних слід приймати у розумному форматі. Невичерпний перелік відповідних форматів подається наступним чином:

    • Одина рядок з рядками, розділеними символами нового рядка
    • Список рядків, кожен рядок являв собою рядок
    • 2D масив або матриця символів

Супутні виклики



Чи є якась причина, яку ви хочете вивести в stdout? Зазвичай ми дозволяємо функціям виводити через їх повернене значення.
corvus_192

@ corvus_192 Я передбачив це як виклик типу "дисплей", як мистецтво ASCII або "Намалюйте прапор" чи будь-що інше. Список рядків як вихідних насправді не є «людським». Якщо мова не має вбудованої підтримки stdout, допускаються інші форми виводу.
FourOhFour

Ласкаво просимо до PPCG! Гарний перший виклик. (і реквізит для використання пісочниці на ньому теж!)
AdmBorkBork

@TimmyD дякую, було весело бачити, як люди вирішують проблему.
FourOhFour

Відповіді:


5

05AB1E ,60 51 50 49 47 45 байт

Збережено 10 байт завдяки Еміньї та 1 байт завдяки Аднану.

Усі рядки введення повинні мати однакову кількість символів.

#õKD³'^¡€gDŠ*¬-Os÷1®‚*D0›*+¬?DJg²gs-ð×?¤,²,³,

#                                             Split the first input line on spaces
 õKD                                          Push [first weight, second weight] twice
    ³'^¡€gD                                   Push both lengths from either side of the pivot '^' as an array [left, right] twice
           Š*                                 Multiply by weights to get torque
             ¬-O                              Evaluate rightTorque-leftTorque
                s÷                            Divide by each side's length to get the weights to add: [deltaLeft, deltaRight], keep integer values
                  1®‚                         Push [1,-1]
                     *D                       Yield [deltaLeft, -deltaRight]
                       0›*                    Replace the negative value by 0
                          +                   Add weights: old + deltaWeight
                           ¬?                 Print left weight
                             DJg              Take the size of total decimal representation
                                ²gs-ð×?       Print a string composed of filler spaces between both new weights
                                       ¤,     Print right weight and newline
                                         ²,³, Print the last two lines from input (unchanged)

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

Повинно бути правило, наприклад, "якщо ваш код 05AB1E довший 40 байт, ви, ймовірно, робите це неправильно". Це здається таким поважним, будь-яка ідея вітається!


1
Для початку ¬s¤s\‚можна õK.
Емінья

1
kD²g->(‚може бути, ¡€gякщо ви додасте пропуски в нижньому ряду тестового випадку
Emigna

1
Дякую за пояснення. Я бачу, що він досить схожий на довідковий алгоритм (не погано), але в цьому є і деякі хитрі хитрощі. Щось про 05AB1E означає, що, здається, пропонують розумніші відповіді, ніж деякі інші мови для гольфу - це, мабуть, моя улюблена, особливо коли є пояснення.
FourOhFour

1
Гарна відповідь! Ви можете замінити 31SÍз 1®‚:)
Аднана

1
Ви можете також , можливо , замінити / ïз ÷.?
Емінья

5

JavaScript (ES6), 136

Ймовірно, не працює в Chrome, оскільки він використовує деструктуровані параметри призначення та за замовчуванням.

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

(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

Менше гольфу

( m,n,o, // input parameters, 3 strings
  // default parameters used as local variables
  [p,q] = m.split(/ +/), // left and right weight
  l = n.length, // bar length
  h = o.indexOf`^`, // left length
  g = l-h-1, // right length
  // p*h left torque
  // q*g right torque
  c = p*h<q*g ? q*g : p*h // max torque
) => alert( (c/h+o).slice(0,h)+(o+c/g).slice(h-l) // o has enough spaces to pad left and right
     +`\n${n}\n`+o )

Тест

F=
(m,n,o,[p,q]=m.split(/ +/),l=n.length,h=o.indexOf`^`,g=l-h-1,c=p*h<q*g?q*g:p*h)=>alert((c/h+o).slice(0,h)+(o+c/g).slice(h-l)+`
${n}
`+o)

function go()
{
  var [a,b,c]=I.value.split('\n')
  if(a.length!=b.length || a.length < c.length)
    alert('The strings are not of the same length')
  else 
  {  
    if (a.length > c.length)
      c = c+' '.repeat(a.length-c-length)
    F(a,b,c)
  }  
}
<textarea id=I>3             16
----------------
        ^      </textarea>
<button onclick='go()'>go</button>


За даними kangax.github.io/compat-table/es6 , Chrome 54 повністю підтримує параметри за замовчуванням та руйнування, тому я не думаю, що вам доведеться не надто переживати.
ETHproductions

Для мене працює Chrome.
DLosc

3

Perl, 149 + 2 = 151 символ

Потрібні параметри командного рядка -p0(це дає мені 2-байтний штраф над 149 байтами самої програми).

($_,$b,$c,$d)=map length,/(\d+) +(.+)
(-+)
( +)/;$r=$d/($c-$d-1);($x,$y)=$1*$r>$2?($1,$1*$r):($2/$r,$2);$_="$x$,$y",$,.=$"while$c>length;$\="
$3
$4^"

Пояснення:

  • -p0Перемикач зчитує весь введення до першого байта NUL або EOF. Ця проблема не дозволяє NUL, тому ми отримаємо весь вхід у змінну, $_яка використовується для регулярних виразів тощо, за замовчуванням.
  • Почнемо з регулярного вираження, який аналізує вхід (між першою та другою косою рисою). Існує кілька способів розібрати перший вагу (наприклад .+?), але я не можу отримати його нижче трьох символів, щоб я міг також використовувати очевидний \d+. Друге число знаходиться в кінці рядка, щоб його можна було розібрати як .+(2 символи). Центральна лінія використовується для визначення, наскільки широкі шкали; він розбирається як -+(багато інших представлень працювали б). Пробіли перед каретою в останньому рядку є +. Як тільки карета (або взагалі будь-яка пробіл) з’являється, ми ігноруємо решту введених даних.
  • Perl автоматично захоплює чотири групи в регулярному виразі (перший вагу, другий вага, рядки дефісів, прогалини перед кареткою) в $1, $2, $3, $4. Надання регулярного вираження в якості аргументу mapдодатково використовує масив цих груп як масив для відображення на карті. Тому ми приймаємо їх довжину; це зручний спосіб зберігання довжин $3та $4без необхідності писати lengthдвічі. Ми також переписуємо $_довжиною $1; нас не дуже цікавить значення цього значення (кількість цифр на лівому вході є нічим не потрібним), але той факт, що він короткий ( $_довжина тепер - це кількість цифр у кількості цифр у перша вага, яка обов'язково дуже мала в порівнянні з шириною ваг).
  • Виміряємо співвідношення, $rв якому поділяються шкали.
  • $1*$r>$2перевіряє, чия сторона важча. Ми зберігаємо нові ваги в $xі $y; вони мають дуже прості обчислення, коли відомо співвідношення ваг.
  • Ми конкатенація $x, $,і $yв $_виробляти верхній ряд, а потім зберегти додавання простору ( $"містить єдиний простір за замовчуванням, і коротше , ніж буквальне простір ' 'буде) на $,доти, поки ті ж довжини , як і в середній лінії (тобто має довжину $c). (Я вибрав змінну, $,оскільки це вбудована змінна, яку можна безпечно змінити в цьому контексті і запустити порожньою за замовчуванням.) Оскільки вона lengthпрацює $_за замовчуванням, нам не потрібно чітко давати їй аргумент. Я використовував умовний Yoda, оскільки для правильного розбору потрібен значно менший розбір синтаксису.
  • Нарешті, я переосмислюю ідею Perl про те, що вихідний рядок закінчується конвенцією ( $\), щоб містити решту набору шкал (це те саме, що і у вхідних даних, тому я можу просто використовувати $3та $4безпосередньо для створення більшої частини). Зверніть увагу, що це означає, що у третьому рядку немає пробілів; додавши це, це зробить програму трохи довше і, здається, не служить ніякій меті, тому я її покинув.
  • В кінці програми -pперемикач спрацьовує знову; на цей раз, він виводить, $_після чого слід "новий рядок" ( $\). Оскільки я переосмислив вихідний новий рядок, ці два неявні відбитки генерують новий набір масштабів між ними (хоча в якості побічного ефекту немає нового рядка на виході).
  • Тепер -pперемикач намагається знову прочитати вхід, але ми вже промазали весь файл, тож він читає EOF і закінчує програму.

1

PHP, 212 209 205 байт

ймовірно, гольф

preg_match("#(\d+)( +)(\d+)\s*(-+)[\r\n]+( +)\^#",$s=$argv[1],$m);echo preg_replace("#\d+( +)\d+#",(($r=$m[3])>($q=$m[1]*($p=strlen($m[5]))/(-$p-1+$e=strlen($m[4])))?$r*$e/($p+1)-$q=$r:$m[1]).$m[2].$q,$s);

Бере вхід з аргументу командного рядка; вийти з нових рядків. Бігайте з -r.


Заміна на заповнювач не пройшла так, як очікувалося; тому мені довелося додати більше паренів до першого регексу.


1

Befunge, 223 217 байт

&:00p&10p~$0>~#<2#+%#1_:20p0~>8#~%#+!#1_:3v
v\g01/g03*g01_v#!\g04`*g01g04:*g03p04-1-p0<
>#g>#0>#0>#/>#<:.2\5>5>#\+/#1:#\_$50p:50g\5>5>#\+/#1:#\_$20g\-v>
1#,>#*-#4:#8_$.55+,20g>:#,1#*-#9\#5_55+,30g>:#,1#*-#8\#4_"^",@>>

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


215 байт , я думаю
Zacharý

@ Zacharý Боюся, що ні. Принаймні одна з цих стрілок потрібна, інакше вона вийде з ладу кожен раз, коли лівий крутний момент> правий крутний момент (наприклад, перший тестовий випадок). Інше, на >мою думку, було просто залишене з естетичних причин. При цьому, мабуть, у моїх замітках є рішення 215 байт, тож це може бути можливим (у мене також є помилки, які пояснювали б, чому я ніколи його не подав - зараз не встигаю перевірити його).
Джеймс Холдернесс

1

Python 2, 184 183 байт

Однозначно пограбаючи

i=raw_input
j=int
w=map(j,i().split())
W=len(i())
I=i().find('^')
R=W-I-1
a=[w[1]*R/I,w[0]*I/R]
h=a[1]>w[1]
w[h]=j(a[h])
k='\n'
print(' '*(W-len(str(w))+4)).join(map(str,w))+k+'-'*W+k+' '*I+'^'

Досить прямо. Просто візьміть відрегульовані ваги для регулювання обох сторін, подивіться, яка з них більша за оригінальну, і змініть цю, і виведіть.

EDIT Перемикання множення та ділення, оскільки ціле ділення є рівним (спасибі @JonathanAllan, що помітив це)

EDIT -1 байт Змінено i().index('^')на i().find('^')(дякую @JonathanAllan [знову!])


Вам слід поміняти множення і ділення, оскільки ділення - це ціле ділення - тобто a=[w[1]*R/I,w[0]*I/R](простий приклад, який би не працював, був би 1і 2з, Iі тим і Rіншим 3). В даний час 194 НЕ 184, до речі , так як нові рядки вважаються байтами кожним, але jі kбільш вартість байт , ніж вони економлять.
Джонатан Аллан

Ви можете використовувати I=i().find('^')та коротку форму __repr__зворотних посилань, щоб зробити останній рядок print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'і перейти до 182 - repl.it/EW8f
Джонатан Аллан

0

C ++ 14, 482 байти

include<iostream>#include<string>#include<math.h>usingnamespacestd;intmain(){stringa,b,c,d;intj=0;inte[2];getline(cin,a);getline(cin,b);getline(cin,c);for(inti=0;i<a.size();i){if(isdigit(a.at(i))){while(i<a.size()&&isdigit(a.at(i))){d=a.at(i);i;}e[j]=stoi(d);d="";}}strings(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,'');intl1=(c.size()-1);intl2=(b.size()-c.size());intl=e[0]*l1;intr=e[1]*l2;if(l>r)e[1]=l/l2;elsee[0]=r/l1;cout<<e[0]<<s<<e[1]<<endl;cout<<b<<endl;cout<<c;return0;}

більш читана версія:

#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main() {
    string a,b,c,d;
    int j=0;
    int e[2];
    // input
    getline(cin,a);// 1st line
    getline(cin,b);// 2nd line
    getline(cin,c);// 3rd line
    for (int i=0;i<a.size();i++) {
        if(isdigit(a.at(i))){
            while(i<a.size() && isdigit(a.at(i))){
                d+=a.at(i);
                i++;
            }
            e[j++]=stoi(d);
            d="";
        }
    }
    // amount of white space in between 2 numbers
    string s(b.size()-(int)log10(e[0])-(int)log10(e[1])-2,' ');
    int l1 = (c.size()-1);
    int l2 = (b.size()-c.size());
    int l = e[0]*l1;
    int r = e[1]*l2;
    // change the side with smaller torque
    if (l>r)
        e[1]=l/l2;
    else
        e[0]=r/l1;
    // output
    cout<<e[0]<<s<<e[1]<<endl;// 1st line
    cout<<b<<endl;// 2nd line
    cout<<c;// 3rd line
    return 0;
}

0

Python 3, 235 230 байт (мінімізована посилання)

Я просто мінімізував посилання, оскільки я дуже новачок у коді-гольфінгу.

def s(l):
 w,i,t=[int(z.strip())for z in l[0].split()],len(l[1]),l[2].find("^");k,o=i-1-t,w[0]*t;p=w[1]*k
 if o>p:w[1]=o//k
 else:w[0]=p//t
 w=[str(z)for z in w];s=" "*(i-sum(len(z)for z in w));l[0]=w[0]+s+w[1];print("\n".join(l))

Ви використовуєте його точно так само, як приклад, але функція sзамість цього balance_seesaw.


Рядки 5 і 6 можуть стати w[o>p]=[o//k,p//t][o>p]. Крім того, більшість ліній можна було б з'єднати, щоб позбутися зайвого простору.
Джеймс

Спасибі, як я вже сказав, я дуже новачок, тому я не помічаю навіть найпростіші виправлення.
ender_scythe

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