在跷跷板的一侧增加重量以使其平衡


13

平衡技术

跷跷板(据说来自法国的“ci-ça”,意思是“ this-that”)构成了游乐场设备的三位一体的三分之一,以及类似的无处不在的滑梯和秋千。当且仅当两边的力矩之和相等时,跷跷板才能达到完美的平衡。因此,可以通过在力矩总和较低的一侧增加一定数量的重量来平衡跷跷板。实现这一目标是您应对这一挑战的目标。

挑战

您面临的挑战是将跷跷板描述为输入并再次输出,并在跷跷板的一端增加重量以使其平衡。

输入值

您的程序必须采用任何合理格式的ASCII跷跷板,例如:

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

第一行包含两个数字,每个数字代表跷跷板上的重量。每侧恰好有一个重物,每个重物都作用在木板一侧的末端。权重保证为整数,并始终与其相应的木板末端对齐。这些数字永远不会与支点(^)重叠。

第二行代表跷跷板的“木板”。每个破折号(-)代表彼此的破折号长度相等,唯一的例外是破折号直接位于支点(^)上方,没有长度。

第三行代表跷跷板的支点。该支点由唯一的字符而不是该行上的空格(抑扬符('^'))标记。支点可以在有效输入中沿木板长度放置的任何位置,只要保留足够的空间,以使表示重量的数字在输入或输出中都不会与支点重叠。

确保输入有三行,并且在构成跷跷板的字符之前或之后没有空格(当然,第三行除外)。

输出量

为了输出,应该在标准输出上打印相同的跷跷板图,但是要用一个(只有一个)砝码替换为较大的砝码,以平衡跷跷板。确保仅使用整数就可以使输入成为可能。因此,显示的重量必须没有小数点或任何其他类似的符号。如果您的语言不使用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",
                "-------------------",
                "    ^              "])

规则

  • 这是,因此最短的代码获胜数以字节为单位。检查meta是否在您的语言中计数字节不方便。

  • 适用标准规则/漏洞。

  • 输入必须采用合理的格式。适当格式的非详尽列表如下:

    • 由换行符分隔的行的单个字符串
    • 字符串列表,每个字符串代表一行
    • 二维字符数组或矩阵

相关挑战



您有什么理由要输出到stdout吗?我们通常允许函数通过其返回值输出。
corvus_192 2016年

@ corvus_192我将其设想为“显示”类型的挑战,例如ASCII艺术作品或“绘制标志”之类的东西。这样的输出字符串列表并不是真正的“人类友好”。如果语言没有内置标准输出支持,则允许使用其他输出形式。
FourOhFour 2016年

欢迎来到PPCG!不错的第一个挑战。(以及使用它的沙箱的道具!)
AdmBorkBork

@TimmyD谢谢,很高兴看到人们如何解决问题。
FourOhFour 2016年

Answers:


5

05AB1E60 51 50 49 47 45字节

Emigna节省了10个字节,Adnan节省了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 '16

1
kD²g->(‚¡€g如果您在测试用例的底部行中添加了缺失的空格,则可能是这样
Emigna

1
感谢您的解释。我看到它与参考算法非常相似(没什么不好的),但是那里也有一些巧妙的技巧。关于05AB1E的信息意味着它似乎比其他一些高尔夫语言提供了更好的答案-也许这是我的最爱,尤其是当包含说明在内时。
FourOhFour 2016年

1
好答案!您可以替换31SÍ1®‚:)
Adnan

1
您也许也可以/ ï÷。代替吗?
Emigna '16

5

JavaScript(ES6),136

Chrome可能无法正常运行,因为它使用的是结构化分配和默认参数。

请注意alert,由于使用了比例字体,因此标准JS输出方法特别不适合该任务。

(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 2016年

适用于我的Chrome。
DLosc

3

Perl,149 + 2 = 151个字符

需要命令行选项-p0(在程序本身的149个字节之上,这给了我2个字节的罚款)。

($_,$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字节的解决方案,因此这是可能的(我也有一些错误可以解释为什么我从未提交过该问题-现在没有时间对其进行测试)。
James Holderness

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 Iand Rboth 3)。目前,194不是由路184,因为新行算作每一个字节,但是jk正在花费更多的字节比他们保存。
乔纳森·艾伦

您可以使用反引号I=i().find('^')和的短格式__repr__来制作最后一行print`w[0]`+' '*(W-len(`w`)+4)+`w[1]`+'\n'+'-'*W+'\n'+' '*I+'^'并下降到182-repl.it/EW8f
Jonathan Allan

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.