シーソーの片側に重量を加えてバランスを調整します


13

綱渡り

シーソー(おそらく「this-that」を意味するフランス語の「ci-ça」から)は、同様に遍在するスライドとスイングとともに、遊具の神聖な三位一体の3分の1を形成します。シーソーは、各側のモーメントの合計が等しい場合にのみ、完全なバランスになります。したがって、シーソーは、モーメントの合計が小さい側に特定の量の重量を追加することでバランスを取ることができます。これを達成することがこの挑戦の目標です。

チャレンジ

あなたの課題は、入力としてシーソーの描写を取り、それを再び出力し、バランスをとるためにシーソーの一端に重みを追加することです。

入力

プログラムは、合理的な形式で、次のようなASCIIシーソーを取る必要があります。

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

最初の行には2つの数値が含まれ、それぞれがシーソー上の重みを表します。それぞれの側にちょうど1つの重りがあり、それぞれが厚板の側の端に作用します。重みは整数であることが保証されており、常に対応する厚板の端に合わせられます。これらの数値が支点(^)と重なることはありません。

2行目は、シーソーの「プランク」を表します。各ダッシュ(-)は、長さの^ない支点()のすぐ上のダッシュを除いて、各ダッシュと同じ長さを表します。

3行目は、シーソーの支点を表します。この支点は、この行のスペースではない唯一の文字、サーカムフレックス( '^')によってマークされます。支点は、有効な入力の板の長さに沿った任意の場所に配置できます。ただし、十分なスペースが残っていれば、重みを表す数値が入力または出力の支点と重ならないようにできます。

入力には3行が含まれ、シーソーを構成する文字の前後に空白がないことが保証されます(もちろん、必要な3行目を除きます)。

出力

出力の場合、同じシーソーの描写を標準出力に印刷する必要がありますが、シーソーのバランスをとるために、重量の1つ(1つのみ)をより大きい重量に置き換えます。入力は、整数のみを使用してこれを可能にすることが保証されています。したがって、重みは小数点やその他の同様の表記なしで表示する必要があります。あなたの言語が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配列またはマトリックス

関連する課題



標準出力に出力する理由はありますか?通常、関数は戻り値を介して出力できます。
corvus_192

@ corvus_192これは、ASCIIアートの1つや「フラグを描く」など、「ディスプレイ」タイプのチャレンジと考えています。出力としての文字列のリストは、実際には「人間に優しい」ものではありません。言語に組み込みの標準出力サポートがない場合でも、他の出力形式が許可されます。
-FourOhFour

PPCGへようこそ!素敵な最初の挑戦。(そして、その上にサンドボックスを使用するための小道具も!)
AdmBorkBork

@TimmyDおかげで、人々がどのように問題に取り組んでいるかを見るのは楽しかったです。
FourOhFour

回答:


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
エミグナ

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です(これにより、プログラム自体の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を許可しないため$_、デフォルトで正規表現などに使用される変数に入力全体を取得します。
  • 入力(最初と2番目のスラッシュの間)を解析する正規表現から始めます。最初の重み(たとえば.+?)を解析する方法はいくつかありますが、3文字未満にはできないため、明らかなを使用することもできます\d+。2番目の数値は行の末尾にあるため、.+(2文字)として解析できます。中心線は、スケールの幅を決定するために使用されます。として解析されます-+(他の多くの表現が機能します)。最後の行のキャレットの前のスペースは+です。キャレット(または実際には非スペース)が表示されたら、残りの入力を無視します。
  • Perlは自動的に正規表現(第1の重み、第2の重み、ハイフンの行、キャレット前スペース)の四つのグループをキャプチャ$1$2$3$4。正規表現を引数として与えると、mapそれらのグループの配列をマッピングする配列としてさらに使用します。したがって、それらの長さを取ります。これは、長格納するための便利な方法である$3とを$4記述することなく、length二回。また$_$1; の長さで上書きします。私たちはこれの値を本当に気にしません(左の入力の桁数は無意味です)が、それが短いという事実($_の長さは今ではの桁数の桁数ですスケールの幅と比較して必然的に非常に小さい最初の重量)。
  • $rスケールが分割される比率を測定します。
  • $1*$r>$2どちらが重いかを確認します。新しい重みを$xとに保存し$yます。重みの比率がわかれば、これらの計算は非常に簡単になります。
  • 当社は連結$x$,$y$_トップの列を生成する、そして、(空白を追加し続ける$"デフォルトで単一のスペースが含まれており、文字通りのスペースがより短い' '上になります)$,(すなわち長さを持っている、それは中央の列と同じ長さになるまで$c)。($,このコンテキストで安全に変更でき、デフォルトで空で始まる組み込み変数であるため、変数を選択しました。)デフォルトでlength動作$_するように、明示的に引数を与える必要はありません。正しく解析するために構文の曖昧さを大幅に減らす必要があるため、ヨーダ条件を使用しました。
  • 最後に、出力行の終了規則($\)のPerlの考え方を再定義して、残りのスケールセット(入力と同じであるため、単純に使用$3して$4直接バルクの大部分を生成できます)。これは、3行目に末尾の空白がないことを意味することに注意してください。それを追加すると、プログラムが少し長くなり、目的を果たさないように見えるので、私はそれを省きました。
  • プログラムの最後に、-pスイッチが再びトリガーします。今回は、$_その後に「改行」($\)が出力されます。出力の改行を再定義したため、これら2つの暗黙の印刷は、それらの間に新しいスケールのセットを生成します(副作用として、出力には改行はありません)。
  • -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ý私は怖くない。これらの矢印の少なくとも1つが必要です。それ以外の場合、左トルク>右トルク(たとえば、最初のテストケース)で失敗します。もう一つ>は、審美的な理由で残されたと思います。とはいえ、メモには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に感謝します)

EDIT -1バイトに変更i().index('^')するi().find('^')(@JonathanAllanに感謝[再び!])


除算は整数除算であるため、乗算と除算を交換する必要がありますa=[w[1]*R/I,w[0]*I/R](つまり、動作しない単純な例はa 12with IおよびRbothになります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

例外として、196,56の代わりに0,56を提供する代わりに機能しません。
ender_scythe
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.