転倒しますか?


36

概要

3行の文字列が与えられたら、構造が左に落ちるか、バランスを取るか、または右に落ちるかを判断します。

入力構造

構造は、上部に物が置かれた金属棒であり、すべてが垂直棒の上にバランスが取れていると想像できます。

1  7 4        a
===============
        |

最初の行はアイテムです。各アイテムの重量は、文字のASCII値から32を引いた値として計算されます(32未満の文字は考慮されず、スペースの重量は0です)。ロッドに対するアイテムの力は、その重量にピボットポイントまでの距離を掛けたものであることに注意してください。

2行目はロッドです。ロッドの各長さは、それ自体で1ユニットの重量があります。この行は排他的に等号(=)です。

3行目はピボットポイントです。これはどこにでも配置でき、複数のスペースとそれに続く単一のパイプ(|)文字で表されます。

入力:

=====
  |

出力:バランス

入力:

=====
   |

出力:左に落ちる

入力:

    %
=====
   |

出力:バランス(%ロッドの左側の重量を打ち消すのに十分な重量があるため)

入力:

 ああ
=======
   |

出力:右に倒れます(a右側がピボットポイントからさらに離れているため)

入力:

1  7 4        A
===============
        |

出力:左に落ちる

入力:

1  7 4        a
===============
        |

出力:正しく落ちる(小文字が重い!)

入力:

            $ ~
===============
             |

出力:バランス

ノート

  • 末尾の空白は許可されますが、先頭の空白は許可されません。
  • 左、バランス、右の3つの異なる出力がある限り、プログラムは任意の形式で出力できます。
  • プログラムは、入力として表示される形式を受け入れる必要があります。


プログラムは、3行を3つの別個の文字列として(たとえば、関数への3つの引数として、または3つの要素リストとして)取ることができますか?
-notjagan

@notjagan入力は、改行文字で区切られた単一の文字列でなければなりません。
ダフィー

関連、可能性のあるdu。
xnor

@xnorその質問は大文字のみを扱い、その目標はピボットを見つけることであるため、だまされません。私の質問は、すべてのASCII文字> = 32についてであり、私のものはピボットを提供し、構造が倒れるかどうかを尋ねます。基本的に、リンクしたものの逆です。
ダフィー

回答:


8

JavaScript(ES6)、116 111 108 106バイト

eval(array.join`+`)代わりに経由して合計することにより、-5バイトarray.reduce()
デフォルトでは-3バイトで1あり32 - 31、カッコを削除できます。
ピボットポイントは最後の行の長さなので-2バイト-1

(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))

出力-10または1それぞれ、左のため、バランス、または右、。最終的にはChas Brownのpython answerと同様になりました。

を使用して、ロッドの長さに一致するように最初の行がパディングされる場合、4バイト節約できます
(31-t.charCodeAt(i))*(b.length+~i)

テストスニペット

数値とともに追加の出力(Left/ Balanced/ Right)が含まれます。

f=
(s,[t,r,b]=s.split`
`)=>Math.sign(eval([...r].map((_,i)=>(t.charCodeAt(i)-31||1)*(i-b.length+1)).join`+`))
<textarea id=I rows=3 cols=20></textarea><br><button onclick="O.value=I.value?`${x=f(I.value)} (${['Left','Balanced','Right'][x+1]})`:''">Run</button> <input id=O disabled>

別の106バイト方式

(s,[t,r,b]=s.split`
`)=>Math.sign(eval(r.replace(/./g,(_,i)=>"+"+(t.charCodeAt(i)-31||1)*(i-b.length+1))))

sのjoin配列+を作成する代わりに、数字の文字列を作成します+。各文字列の先頭にはが付きます。先頭+は無視されます。


1
(b.length+~i)バイトを節約するのに役立つと思います。(また、なぜあなたは||1。を持っているのか理解できません。)
ニール

1
@Neilはのb.length+~i負を返しますi-b.length+1。私が他の部分を否定することができれば、それは助けになるでしょう。については||1、最初の行がロッドの長さに一致するようにパディングされていないと仮定していたため、最初の行の終わりを超えてt.charCodeAt(i)戻りNaNます。
ジャスティンマリナー

しかし、パッドなしのテストケースを試す必要はありませんでした。説明してくれてありがとう。
ニール

3

パイソン2112の 110バイト

def f(s):w,b,p=s.split('\n');return cmp(sum((ord((w+' '*-~i)[i])-31)*(i-p.find('|'))for i in range(len(b))),0)

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

EDIT:最後に排除するために管理enumerateし、rjustちっぽけな2バイトのために... MEH!

文字列を受け取ります。左へのフォール、バランス、右へのフォールに対して、それぞれ-1、0、または1を出力します。

112バイトでの最初のパスは次のとおりです。

def f(s):w,b,p=s.split('\n');return cmp(sum((ord(c)-31)*(i-p.find('|'))for i,c in enumerate(w.rjust(len(b))),0)

(ord(c)-31)これが実際にロッド自体の重量とアイテムを組み込んでいることに気づくまでしばらくかかりました。非常に賢い!
ダフィー

1
メタにつきとして、あなたは置き換えることができreturnprint(それは本当に現在のTIOコードとうまく再生されないが)のために-1バイト。
-notjagan

3

Haskell、212 171バイト(入力を1つの文字列として取得する場合は188)

o!p=map(fst)(zip[p-0,p-1..]o)
x#p=sum(zipWith(\c w->(max(fromEnum c-32)0)*w)x(x!p))+sum(x!p)
x?c=length(takeWhile(==c)x)

171バイトのバリアント

r a b c=signum(take(b?'=')(a++repeat ' ')#(c?' '))

188バイトのバリアント

x%y=lines x!!y
r i=signum(take(i%1?'=')(i%0++repeat ' ')#(i%2?' '))

説明

o!p=map(fst)(zip[p-0,p-1..]o)        Creates weights coefs list. 
                                     o - list, p - pivot position
                                     for list "abcdf" and p=3 (pivot under 'd')
                                     outputs [3,2,1,0,-1]

x#p                                  Calculates total balance
                                     x-list of "objects" on lever, p-pivot place
  sum(zipWith                        sum of zipped lists
   (\c w->(max(fromEnum c-32)0)*w)   weight of ascii "object" times
                                     distance from pivot
    x(x!p))                          x-ascii objects, 
                                     (x!p)-distances list(weight coefs)
  +sum(x!p)                          balance of lever ("==") itself

x?c=length(takeWhile(==c)x)          length of list before non c element met
                                     used to find '|' position
                                     and length of "===" lever
                                     before right whitespaces met

r a b c=                             Sums it all up =)
                                     a-ascii objects, b-lever, c-pivot line
   signum(                           1-tips left, 0-balance, -1-tips right
     take(b?'=')(a++repeat ' ')      takes all object on lever 
                                     plus whitespaces up to length of the lever
      #                              calculate the balance
       (c?' ')                       determine place of pivot

1
fromEnum代わりに使用して、ordをドロップできますimport。(またはで)c単純化できます。一度だけ使用するので、インライン化します。c p=max(ord p-32)0fromEnum
-nimi

または、(Lambdabot)をタイトルに追加することもできます。これにより、必要なものすべてがインポートされます。こちらを参照してください
ბიმო

1
この関数cは、さらに単純化することもできます(32未満の文字は考慮されません)c p=ord p-32。またp、基本的にlength(マイナス1)ですので、p x=length x-1同様に機能します(インライン化することもできます)。また、私のソリューション、私がどのように使用するかを見てください-B、L、Rのどちらを返すsignumことができますか?r o l s = signum $ 2 * z ...0,1,-1
ბიმო

1
それとは別に、このソリューションはテストケースに失敗するよう[3,4,7]で、1つではなく3つの文字列を使用します。(を参照lines)。
ბიმო

1
ここにいくつかのヒントを適用したバージョンがあります(29バイト節約できます;))。
ბიმო

2

ゼリー、30バイト

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ
ỴṪLç@ỴḢ$

テストスイート

バランスの場合は0、右の場合は1、左の場合は-1を出力します。

使い方

O_31×J_¥A+\sṪ€µ÷ḢṪ_2Ṡ - helper function. Arguments position of pivot and first line
O                        - char codes of first line
 _31                     - subtract 31 to get weight
    ×                    - elementwise product with:
     J_¥                 - distances from the pivot
        A                - absolute value
         +\              - cumulative sum
           s             - split to get [[...,left weight],...,[..., right + left weight]]
            Ṫ€           - last element of each sublist: [left weight, ... right weight]
              µ÷Ḣ        - get ratio of each element over left weight: ratio n indicates
                              right + left = n × left ===> right = left if n = 2
                 _2      - subtract 2: positive is right>left and negative is right<left
                   Ṡ     - return the sign of this


ỴṪLç@ỴḢ$              - main link. Argument: 3 line string.
   ç@                  - apply helper function with arguments:
Ỵ                        - split by linefeeds
 Ṫ                       - last line
  L                      - length (returns position of pivot)
       $               - and
     Ỵ                   - split by linefeeds
      Ḣ                  - first line              

2

ゼリー、24バイト

ṪO_31
ỴµṪLạЀṪL$×Çṣ0S€IṠ

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

-1左に0倒す、バランスを取る、1右に倒す(フルプログラム)。
[-1]左下がり、[0]バランス、[1]右下がり(機能)。

最初の行には末尾のスペースが必要ですが、最後の行にはできません。

説明(一番下の行から始めます):

まず第一に、私たちは個々の行で作業しているので、何らかの方法でそれらを取得する必要があります。それはの仕事です。次に、\n入力の-splitバージョンを元の入力であるかのように扱う必要があるためµ、現在の値に適用される単項連鎖を作成するために使用します。

これで実際の作業を開始し、最初の仕事は重みの係数を計算することです。基本的に、これは範囲です(左からピボットまでの距離..0 ..ピボットから右端までの距離)。まず、ピボットの1から始まるインデックスを見つける必要があります。これは、基本的に末尾のスペースを含まない最後の行の長さです。そこで、元のリストから最後の行(ピボット行)をでポップします。これはもう必要ないので、で長さを取得しLます。次に、ロッドの長さを取得する必要があります。そのために、で最後のライン(ロッドライン)に同じことを行いṪL$ます。最後に、範囲を取得するために、マッピングします| x - y | [1..rod length]に、xはピボットインデックス、yはyマップするリストの各要素です。私たちは、この使用しないạЀ場合は、計算| x - y | Ѐ1からロッドの長さまでの範囲を作成します。これで、必要な範囲ができました。

その後、棒の一部を表す各整数とそれに対応する重みを掛ける必要があります。重みを計算するにÇは、コードの最上行にあるを使用します。で残りの行を取得し、その文字コードでを使用し、O次にx -31を計算します。xは各文字コードです。次に、ウェイト1(0 +ロッドピース= 1)、ウェイト2(1 + 1)などにスペースを割り当てます。トップラインで作業が完了したので、ウェイトのリストを返します。で棒片を表す整数。_31!Ç×

その後ṣ0、ピボットポイントで分割し、0で表されます(重みは結果に影響しないため)。結果は[[1st weight、2nd weight ... weight直前の重み]という形式のリストになります。 、[ピボット直後の重量、前の重量の後...最後の重量]]。これらのリストは、ロッドの左右を表します。ここで、各リストをS€合計して、各辺の合計重量を取得しI、デルタを取得するために使用します。デルタは、左側が重い場合は負、等しい重量の場合はゼロ、右側が重い場合は正になります。 。したがって、これを適切に使用して最終結果を適切に返すには、でサインを取ります。


2

APL(Dyalog)、43バイト*

{×(¯31+⎕UCS⊃⍵)+.×(⍳≢⊃⍵)-'|'⍳⍨⊃⌽⍵}⎕TC[2]∘≠⊆⊢

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

⊆⊢ 引数を次の文字の実行に分割します

⎕TC[2]∘≠ 異なる2 回目 T erminal C ontrol文字(改行)**

{} 文字列のリストに次の匿名関数を適用します。

⊃⌽⍵ 逆順リストの最初の文字列(最後の文字列)

'|'⍳⍨ 見つけɩピボットポイントのNDEXを

()- 次のリストからそれを引きます:

  ⊃⍵ 最初の文字列

   その長さ

   すべてɩそのndices

()+.× それらの重みと次の値の重み付き合計:

  ⊃⍵ 最初の文字列

  ⎕UCSU niversal C haracter S etの コードポイント

  ¯31+ 負の31を追加します(必要なオフセットの場合は32、ロッドの場合は1

× そのサイン


* 1文字につき1バイトの場合{×(¯31+⎕UCS↑⍵)+.×(⍳≢↑⍵)-'|'⍳⍨↑⌽⍵}⎕TC[3]∘≠⊂⊢、と共に使用し⎕ML←3ます。オンラインでお試しください!
** ⎕TCは非推奨であり、ゴルフの目的でのみ使用されます。本番コードでは、を使用する必要があります⎕UCS 10


2

Haskell(Lambdabot)、142バイト

l=length
g[a,c,b]=splitAt(l b)$a++(' '<$[1..l c-l a])
k e=sum$zipWith((*).(-31+).ord)e[1..]
f=signum.uncurry(-).(k.drop 1.reverse***k).g.lines

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

ゴルフされていないバージョン:

-- for readability, allows reading top-down/left-right
(.>) = flip (.)

ungolfed =
     lines                                 -- separate out lines into..
  .> (\[a,b,c] ->                          -- a,b,c (first,second,third)
                                           -- ' ' pad the first line & split on pivot
       splitAt (length c) (a ++ replicate (length b - length a) ' ')
     )
  .> (weight.drop 1.reverse *** weight)    -- reverse left half, drop element above pivot & get weight for both
  .> uncurry (-)                           -- subtract right from left
  .> signum                                -- get sign

-- get ord of the character subtract 31 ('=' char from bar),
-- then multiply with scales ([1..]) and sum it all up
weight es = sum $ zipWith (ord .> subtract 31 .> (*)) es [1..]

2

Python 2バイト

def f(s):L=len(s)/3;print cmp(sum((ord(s[i])-31)*(i-s[-L:].find('|'))for i in range(L)),0)

入力行が(スペースを使用して)正しい長さに埋め込まれることを期待します。出力-1のための滝は、左0のためにバランスの取れた、と1のための右落ちます

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


94バイト

+4バイトの場合、whileループを使用して、パディング行ではなくストリップ行を必要とするバージョンを作成できます。

def f(s):
 i=r=0
 while''<s[i]:r+=(ord(s[i])-31)*(i-s[-3::-1].find('='));i+=1
 print cmp(r,0)

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


1

ルビー、543バイト

def willittip(s)
leftw=0;
rightw=0;
arr=[];
fields=s.split("\n")
pos=fields[2].index("|")
fields[0].split("").each do |i|
arr << i.ord-32
end
arr[pos+1..-1].each_with_index do |x,y|
rightw=rightw+1
if x>0
if pos>0
rightw=rightw+x*(pos-y).abs
else
rightw=rightw+x
end
end
end
arr[0..pos-1].each_with_index do |x,y|
leftw=leftw+1
if x>0
if pos>0
leftw=leftw+x*(pos-y).abs
else
leftw=leftw+x
end
end
end
if leftw==rightw
return "Equal"
elsif leftw<rightw
return "Right"
elsif leftw>rightw
return "Left"
end
end

10
PPCGへようこそ!:D code-golfチャレンジの目標は、コードをできるだけ小さくすることです。すべての変数と関数名を単一の文字にし、可能な限り空白を削除することにより、コードサイズを縮小できます。
ダフィー

1

C(gcc)、106107 121 123 124 129 131 バイト

c,b,l,i;f(char*a){l=strlen(a)/3;for(i=b=c=0;32/a[l*2+c];++c);for(;i<l-1;b+=(a[i]-31)*(i++-c));a=b>0?2:!b;}

左下がりの場合は0、バランスの場合は1、右下がりの場合は2を返します。

\n文字列の長さを決定するには、3行すべてが同じ長さで終了することを要求します。

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


1

Mathematica、91 92 バイト

Sign[(v=(g=ToCharacterCode)@#&@@(d=#~StringSplit~"
")-31).(Range@(l=Length)@v-l@g@Last@d)]&

最初の線は、ロッドと同じ長さでなければなりません。3行目には、末尾のスペースを含めないでください。

左下がり、バランス、右下がりの場合は-1、0、1を返します。


1

C#(.NET Core)127 95 90 + 18 = 108バイト

この関数の場合、最初の行はロッドと同じ長さになるようにスペースで右にパディングする必要があり、3番目の行には試行スペースを入れてはなりません。この条件は許可されています(質問のコメントを参照)。

s=>s.Split('\n')[0].Select((c,i)=>(c-31)*(i-s.Split('\n')[2].Length+1)).Sum().CompareTo(0)

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

出力:

チップ左に-1、
バランス
右に1、チップ右に0


1

Python 3、217バイト

Python 2.7でも動作します

def f(s):i,b,p=s.split('\n');c=p.find('|');l=sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1,c+1));r=sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])));return(l>r)-(r>l)

左側の場合は1、右側の場合は-1、バランスが取れている場合は0を返します。

読み取り可能なバージョン:

def f(s):
    i,b,p = s.split('\n')
    c = p.find('|')

    l = sum((ord(e)-32)*(c-i.find(e))for e in i[:c])+sum(x for x in range(1, c+1))
    r = sum((ord(e)-32)*i[c:].find(e)for e in i[c:])+sum(x for x in range(len(b[c:])))

    return(l>r)-(r>l)

1
あなたは必要ありません。sum([...])あなたは、単に持つことができ、sum(...)
氏Xcoder

@Daffyこれは、仕様および指定されたすべての入力例に100%準拠する必要があります。同意する場合は、さらに最適化できるようにお知らせください。ありがとうございました。
ベガナイズ

@veganaiZeはすべてのテストに合格し、よさそうです!:)
ダフィー

1
それを短くするもの:使用するi[c:].find(e)ことができi.find(e,c)、使用i,m,n=s.split('\n')する必要性をsまったくreturn 2*(r>l) or l>rなくすことができ、最後にテストコストを劇的に削減するために使用することができます(戻り値は数値的に同等ですが、True代わりに1およびFalse代わりに0)、または実際に異なるリターンのセットを使用しますreturn (l>r)-(r>l)古いcmp関数と同じように、1、0、または-1を返します。
ShadowRanger

ShadowRanger氏、Xcoder氏、Daffyに感謝します!@ShadowRanger i[c:]短い方法がいくつかのコーナーケース入力で奇妙なオフバイワンの問題を引き起こしたので、私は固執しなければなりませんでした(|ちょうど真ん中に-バーの上に置いてみてください)。
ベガナイズ

1

PHP、105バイト

for([$a,$b,$c]=explode("
",$argn);$b[$i];)$w+=(strpos($c,"|")-$i++)*8*(max(1,ord($a[$i])-31));echo$w<=>0;

-1/ 0/ 1left / balance / rightを印刷します。でパイプとして実行する-nR、オンラインで試してください

壊す

for([$a,$b,$c]=explode("\n",$argn); # import input
    $b[$i];)                        # loop through bar
    $f+=                                # add to force:
        ($i-strpos($c,"|"))             # distance (<0 if left, >0 if right of pivot)
        *8                              # *8
        *(max(1,ord($a[$i++])-31));     # *weight
echo$f<=>0;                         # print -1 if $f<0, 1 if $f>0, 0 if $f==0

1

、31バイト

A⁰ξFLθA⁺ξ×⁻ι⌕ζ|⁻℅§θι³¹ξI⁻›ξ⁰‹ξ⁰

オンラインでお試しください!リンクは、コードの詳細バージョンです。バランスの場合は0、左または右の場合は-1または1を出力します。編集:チャコールの変更は≔ΣEθ×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰24バイトで動作するようになりましたオンラインで試してみてください!リンクは、コードの詳細バージョンです。注:両方の回答にはパディング入力が必要ですが、3バイトのコストでパディングなしの入力を受け入れるように適合させることができます。≔⁰ξFLη≔⁺ξ×⁻ι⌕ζ|⁻℅§◨θLηι³¹ξI⁻›ξ⁰‹ξ⁰ オンラインで試してください! ≔ΣE◨θLη×⁻κ⌕ζ|⁻℅ι³¹ξI⁻›ξ⁰‹ξ⁰ オンラインでお試しください!リンクは、コードの詳細バージョンへのリンクです。


これに言及する必要があるかもしれませんが、これは入力行がスペースで正しい長さにパディングされることを期待しているので、パディングされていない入力機能しないかもしれません。
FlipTack

@FlipTackさらに良いことに、パッドなしの入力を受け入れるバージョンを考案しました。
ニール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.