Добавьте вес одной стороне качелей, чтобы уравновесить


13

Уравновешивание

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

Вызов

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

вход

Ваша программа должна иметь в любом приемлемом формате качели ASCII, такие как:

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

Первая строка содержит два числа, каждое из которых представляет вес на качелях. Ровно один вес присутствует на каждой стороне, каждый действует на самом конце своей стороны доски. Веса гарантированно являются целыми числами и всегда совпадают с соответствующим концом доски. Эти числа никогда не будут перекрывать точку опоры ( ^).

Вторая строка представляет «доску» качелей. Каждый тире ( -) представляет одинаковую длину для каждого другого тире, за единственным исключением тире непосредственно над точкой опоры ( ^), которая не имеет длины.

Третья строка представляет точку опоры качели. Эта точка опоры помечена единственным символом, который не является пробелом в этой строке, - окружностью ('^'). Точка опоры может быть расположена в любом месте по всей длине доски на допустимом входном сигнале, если остается достаточно места, чтобы числа, представляющие веса, не перекрывали точку опоры ни на входе, ни на выходе.

Входные данные гарантированно состоят из трех строк и не имеют пробелов до или после символов, составляющих качели (за исключением, конечно, третьей строки, которая этого требует).

Выход

Для вывода такое же изображение качелей должно быть напечатано на стандартный вывод, но с заменой одного (и только одного) веса на больший, чтобы сбалансировать качели. Входные данные гарантированно сделают это возможным, используя только целые числа. Следовательно, веса должны быть показаны без десятичных точек или любых других аналогичных обозначений. Если ваш язык не использует стандартный вывод, вы должны прийти к общему / мета-консенсусу по выводу. Конечные переводы строки хороши, но любые другие изменения в формате описания, вероятно, не в порядке.

заверенная копия

Тестовые входы и соответствующие выходы

Вход 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-массив или матрица символов

Связанные проблемы



Есть ли причина, по которой вы хотите выводить на стандартный вывод? Обычно мы разрешаем функциям выводить через их возвращаемое значение.
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.
Emigna

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

1
Спасибо за объяснение. Я вижу, что он очень похож на эталонный алгоритм (не так уж и плохо), но там есть и некоторые хитрые приемы. Что-то в 05AB1E означает, что он предлагает более умные ответы, чем некоторые другие языки игры в гольф - это, пожалуй, мой любимый, особенно когда есть включенное объяснение.
FourOhFour

1
Хороший ответ! Вы можете заменить 31SÍна 1®‚:)
Adnan

1
Может быть, вы также можете заменить / ïна ÷.?
Emigna

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, поэтому по умолчанию мы получим все входные данные в переменной, $_которая используется для регулярных выражений и т. Д.
  • Мы начнем с регулярного выражения, которое анализирует входные данные (между первым и вторым слэшем). Есть несколько способов, которыми мы могли бы проанализировать первый вес (например .+?), но я не могу получить его ниже 3 символов, поэтому я могу также использовать очевидный \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ý

@ Захари, боюсь, нет. По крайней мере, одна из этих стрелок необходима, иначе она потерпит неудачу, когда левый крутящий момент> правый крутящий момент (например, первый тестовый пример). Другой, >я думаю, был просто оставлен по эстетическим причинам. Тем не менее, у меня, кажется, есть 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+'^'

Довольно просто. Просто возьмите скорректированные веса для настройки обеих сторон, посмотрите, какая из них больше, чем оригинал, и измените эту, и выведите.

РЕДАКТИРОВАТЬ Переключение умножения и деления, потому что целочисленное деление - зло (спасибо @JonathanAllan за то, что заметил это)

РЕДАКТИРОВАТЬ -1 байт Изменено i().index('^')наi().find('^') (благодаря @JonathanAllan [снова!])


Вы должны поменять местами умножение и деление, так как деление - это целочисленное деление, т. Е. a=[w[1]*R/I,w[0]*I/R](Простой пример, который не сработает, будет a 1and 2with 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

Питон 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.