シーソーで一連の重みのバランスをとる


32

綱渡り

概要

重みのセットを表す3つの1桁の正の整数の入力が与えられた場合、レバーの効果を考慮して、中央のピボットの周りでバランスが取れるように、重みが配置されたシーソーのASCII表現を出力します。

各数値には、その値に等しい重みがあります。各数値のトルクは、重量にその中心からの距離を文字で乗算したものです。シーソーのバランスを保つために、シーソーの左側のウェイトの合計トルクは、このように右側のウェイトの合計トルクと等しくなければなりません。

入力

1〜9の範囲の3つの整数。ただし、タプル、3つのコンマ区切り値など、整数を入力するのは便利です。ただし、プログラムは任意の順序で数値入力を処理できる必要があります(つまり、値がソートされることを前提としない)。重複する番号を入力できます(2,3,2など)。

入力は常に数学的に有効な出力を許可します。そうでない場合、入力は無効です。

出力

出力は、シーソーの2行のASCII表現で、重みが設定されている必要があります。最初の行には数字があり、シーソー上でバランスを取るために間隔が空いています。

距離はトルクのゼロになる、スケールの真ん中に数字を配置することはできません。ピボットの左または右を含む1〜10文字の中心範囲からの有効な距離。

数字で占められていないスペースには、18個の下線文字があります(中央のアンダースコアと各辺に10個あり、数字で占められている3つの位置を差し引いています)。最後の行には、ピボットを表すスケールの中心に揃えられた単一のキャレット文字があります。

入力:

4,7,2

出力:

________7___42_______
          ^

7 * 2 = 4 * 2 + 2 * 3

数値はどちらの側にも出力できます。たとえば、これも有効です。

_______24___7________
          ^

2 * 3 + 4 * 2 = 7 * 2

数字は、バランスが取れている限りはかりのどこにでも配置できます。例:

入力:

3,1,5

出力:

_____5________1__3___
          ^

5 * 5 = 1 * 4 + 3 * 7

または

____5________1_____3_
          ^

5 * 6 = 1 * 3 + 3 * 9

または

____5___________1_3__
          ^

5 * 6 = 1 * 6 + 3 * 8

プログラムは、有効な出力の1つを出力するだけです。入力が無効な場合、エラーを出力する必要はありません。

ノート

  • これはので、バイト単位の最短プログラムが勝ちます
  • プログラムは、数値を入力として受け入れ、文字列を返すスタンドアロンまたは関数です。
  • 最後の行の末尾の改行と空白はオプションです
  • シーソーが何かわからない場合は、シーソーまたはシーソーとも呼ばれます。

ここだペースト(一部重複あり)有効な入力とソリューション示す
samgak

11
素晴らしい最初の挑戦!興味深い問題と徹底した仕様。
-xnor

2
アルゴリズム的に、整数のベクトルが与えられると、これはすべての異なるエントリを持つ整数の直交ベクトルを見つけるように求めます。
誇りに思ってhaskeller

回答:


13

CJam、40 39 38バイト

q~21Ue]e!{21,Af-Aest.*:+!}=0'_erNAS*'^

オンラインでお試しください。

使い方

q~                                     e# Read and evaluate the input.
  21Ue]                                e# Append zeroes to achieve a length of 21.
       e!                              e# Push all unique permutations.
         {               }=            e# Find the first permutation such that:
          21,                          e#  Push [0 ... 20].
             Af-                       e#  Subtract 10 from each.
                Aest                   e#  Replace the element at index 10 with the
                                       e#  current time (ms since epoch) to push
                                       e#  [-10 ... -1 <big number> 1 ... 10].
                    .*                 e#  Multiply each number of the permutation
                                       e#  by the corresponding distance.
                      :+               e#  Add the products.
                                       e#  The timestamp makes sure that this sum
                                       e#  is non-zero for a non-zero element in
                                       e#  the middle of the permutation.    
                        !              e#  Push the logical NOT of the sum.
                           0'_er       e# Replace zeroes with underscores.
                                NAS*'^ e# Push a linefeed, ten spaces and a caret.

5

CJam、46 44バイト

'_21*q~K,Am3m*{___&=*Afm1$.*:+!}=.{\t}NAS*'^

ここでテストしてください。

説明

まず、観察:シーソーの端に2桁を置く必要はありません。それが有効な解決策であるときはいつでも、少なくとも1つの他の有効な解決策があります(チャレンジに関するコメントのペーストビンによる)。

'_21*   e# Push a string of 21 underscores.
q~      e# Read and eval input.
K,      e# Push the array [0 1 .. 19 20]
Am      e# Remove the 10. This is now an array of all valid positions on the seesaw.
3m*     e# Get all 3-tuples of valid positions.
{       e# Select the first tuple for which the following block yields a truthy result.
  ___   e# Make three copies of the tuple.
  &=    e# Intersect the last two copies and check for equality with the first one.
        e# This yields 1 if all positions are distinct, and 0 otherwise.
  *     e# Repeat the original tuple that many times. That is, if the positions are
        e# distinct, leave the tuple unchanged. Otherwise, replace it with an empty array.
  Afm   e# Subtract 10 from each position to get its weight.
  1$    e# Copy the input digits.
  .*    e# Take the pairwise product of weights and digits. If the weights are empty
        e# (because they were not unique), this will just yield a list of the digits.
  :+    e# Sum the weighted digits. If the weights were not unique, this will just sum
        e# the digits and will always be positive.
  !     e# Logical NOT - give 1 if the sum was 0, or 0 otherwise.
}=
.{\t}   e# For each pair of digit and position, replace that position in the underscore
        e# string with the corresponding digit.
N       e# Push a newline.
AS*     e# Push ten spaces.
'^      e# Push a caret.

5

Java、519 414 321バイト

static int f(int a,int b,int c){int i,j,k;for(i=-10;i<=10;i++)for(j=i+1;j<=10;j++)for(k=j+1;k<=10;k++){if(a*i+b*j+c*k==0&&i!=0&&j!=0&&k!=0){for(int q=0;q<21;q++){if(q==10+i)p(a);else if(q==10+j)p(b);else if(q==10+k)p(c);else p('_');}p("\n          ^\n");return 0;}}return 0;}static void p(Object a){System.out.print(a);}}

ゴルフの私の最初の試み。

で呼び出すことができますf(a,b,c)ここで試してみてください

編集:チェックのizlinメソッドを使用(a*i+b*j+c*k)==0

編集:ゴルフの提案をありがとう、Jアトキン。


1
あなたはの署名変更することで、数バイトを保存することができますpにをObject aし、他の2つの代わりにそれを使用してSystem.out.print(ln)、S。
Jアトキン

1
また、aは一度しか使用されないため、インライン化できます。
Jアトキン

5

Pyth、 67 58 53 49バイト

これはPythにとっては大きな側面に少し感じられますが、私は言語をこれほど小さくすることができるほど十分に精通していません。 サブ50バイト、私はついにこれに満足しています!

V.c-KrT-011Z3FY.pQIqs*VNYZjkm?}dN@YxNd\_K+*dT\^.q

入力は、整数の配列として期待されます(例:)[1,2,3]ここで試してみてください。

説明:

V.c-KrT-011Z3FY.pQIqs*VNYZjkm?}dN@YxNd\_K+*dT\^.q
                                                       Implicit: Q = eval(input())
     rT-011                                            Create range from 10 to -10
    K                                                  Store in K
   -       Z                                           Drop 0 from the above
V.c         3                                          For N in (combinations of the above of size 3)
             FY.pQ                                     For Y in (permutations of input)
                     *VNY                              Multiply each element in N by the corresponding element in Y
                    s                                  Take the sum
                  Iq     Z                             If it's equal to zero:
                            m           K              For d in K (K = [10, ..., -10])
                             ?}dN                      Is d in N?
                                 @YxNd                 If so, get corresponding value from Y
                                      \_               Otherwise, get '_'
                          jk                           Join the resulting array into a string (implicit print)
                                         +*dT\^        Join 10 spaces and '^', implicit print
                                               .q      Break all loops and exit

最後に、入力と出力の例をいくつか示します。

[1,1,1] ->
1__________1_______1_
          ^

[2,9,5] ->
2____5_________9_____
          ^

[9,8,5] ->
5____8______________9
          ^

4

C- 237 228バイト

i,j,k;f(a,b,c){char o[]="_____________________\n          ^";for(i=-10;i<9;i+=i+1?1:2){for(j=i+1;j<11;j+=j+1?1:2){for(k=j+1;k<11;k+=k+1?1:2){if((a*i+b*j+c*k)==0){o[i+10]=a+48;o[j+10]=b+48;o[k+10]=c+48;printf("%s",o);return;}}}}}

で呼び出すことができますf(a,b,c)

ここで試してみてください

出力例:

f(4,7,2):
4_____________7_2____
          ^         

f(3,1,5)
3____1___________5___
          ^       

3

Python 2.7 235 226 219バイト

def s(n,p=__import__("itertools").permutations):
 l=["_"]*21
 for p,q in[[(a,x+10),(b,y+10),(c,10-z)]for a,b,c in p(n,3)for x,y,z in p(range(1,11),3)if x!=y and a*x+b*y==c*z][0]:l[q]=`p`
 return`l`[2::5]+"\n"+" "*10+"^"

いくつかの基本的な例(1,1,1),(1,2,1),(3,1,5),(4,7,2)を使ってテストすると、結果は次のようになります。

(1, 1, 1)
_______1___11________
          ^
(1, 2, 1)
_____1_____12________
          ^
(3, 1, 5)
________5__3_____1___
          ^
(4, 7, 2)
_2_________47________
          ^

ここに貼り付けられすべての可能な入力の出力


"".join(l) -> 'l'[2::5]1バイト短くなります(引用符をバッククォートに置き換えます)。
カデ

また、アプローチを関数からプログラムに変更する場合は、これを222バイトまでゴルフできます。
カデ

@samgakおっと。私の悪い、私は質問を適切に読んだと思った。もう2バイト:(
カメハメハ

@ Vioz-素晴らしいヒント。について知りませんでしたrepr。:)
カメハメハ

3

PHP、278バイト

ネストされたループの束といくつかのテストを使用するブルートフォースソリューション。

$p=explode(',',$argv[$i=1]);for(;$i<=10;$i++)for($j=1;$j<=10;$j++)
for($k=1;$k<=10;$k++)if($j-$k)for($l=0;$l<3;$l++){$q=array_shift($p);
if($i*$q==$j*$p[0]+$k*$p[1]){$o=str_repeat('_',21);$o[10-$i]=$q;$o[10+$j]=$p[0];
$o[10+$k]=$p[1];echo($o."\n          ^\n");}array_push($p,$q);}

いつものように、ファイルに入れて(名前を付けましょうseesaw.php)、行を結合し(読みやすくするためにここで分割します)、<?phpファイルの先頭にPHPマーカー()を置きます(技術的にはプログラムの一部ではありません)。行って良かった。

実行の例:

$ php seesaw.php 9,2,1
_________9_2_____1___
          ^
_________9__2__1_____
          ^
_________9_1__2______
          ^
________9_____2_____1
          ^
________9______2__1__
          ^
________9_____1__2___
          ^
________9___1_____2__
          ^
_______9_________1__2
          ^
____2______9_1_______
          ^
___2_______9___1_____
          ^
__2________9_____1___
          ^
_2_________9_______1_
          ^

すべてのソリューションを生成して表示します(反射なし)が、重複を除去しません(入力値に重複が含まれる場合)。


3

ジュリア、154バイト

f(a,b,c)=(x=replace(join(first(filter(p->p⋅[-10:-1,1:10]==0,permutations([a,b,c,zeros(Int,17)])))),"0","_");print(x[1:10]*"_"*x[11:20]*"\n"*" "^10*"^"))

Ungolfed +説明:

function f(a,b,c)
    # Create a 20-element array of the input with 17 zeros
    z = [a,b,c,zeros(Int,17)]

    # Get the set of all permutations of z such that the dot product
    # of the permutation with the distances is 0
    d = filter(p -> p  [-10:-1,1:10] == 0, permutations(z))

    # Join the first element of d into a string and replace all of
    # the zeros with underscores
    x = replace(join(first(d)), "0", "_")

    # Print the output
    print(x[1:10] * "_" * x[11:20] * "\n" * " "^10 * "^")
end

2

C、252(214)バイト

コマンドラインで引数としてa、b、cを呼び出します。

e=48;main(_,v,x,y,z,a,b,c)char**v;{char s[]="_____________________\n          ^";x=*v[1]-e;y=*v[2]-e;z=*v[3]-e;for(a=-1;a+11;--a)for(b=-10;b-11;++b)_=a*x+b*y,!b|b==a|_%z?0:(c=-_/z,c&c<11&c>-11?s[a+10]=x+e,s[b+10]=y+e,s[c+10]=z+e,puts(s),exit(0):0);} 

mainを省略できる場合、関数のバイトカウントは214に低下します。

a,b,c;f(x,y,z){char s[]="_____________________\n          ^";for(a=-1;a+11;--a)for(b=-10;b-11;++b)!b|b==a|(a*x+b*y)%z?0:(c=-(a*x+b*y)/z,c&&c<11&&c>-11?s[a+10]=x+48,s[b+10]=y+48,s[c+10]=z+48,puts(s),b=10,a=-b:0);}

どちらも同じ戦略を使用して、最初のウェイトを左側に配置し、次に可能な2番目のウェイト位置に沿ってスキャンし、3番目のウェイトを計算します。これにより、内側のループを削除できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.