言葉のバランスをとる


33

このチャレンジはDailyProgrammer subredditに投稿されており、コードゴルフチャレンジの素晴らしい候補になると思いました。レターのバランスが取れているかどうかの判断は、バランス点からの距離とレターの価値に基づいています。文字の値は、アルファベットの1インデックス位置を取得するか、ASCII値から64を引くことで決定できます。さらに、文字の値には、バランスポイントからの距離が乗算されます。例を見てみましょうSTEAD

STEAD   -> 19, 20, 5, 1, 4 ASCII values
           This balances at T, and I'll show you why!
S T EAD -> 1*19 = 1*5 + 2*1 + 3*4
           Each set of letters on either side sums to the same value, so
           T is the anchor.

ただし、すべての単語のバランスが取れているわけではないことに注意してください。たとえばWRONG、どの構成でも単語のバランスが取れていません。また、単語は2つの文字の間ではなく、文字でバランスを取る必要があります。たとえばSAAS、2つAの中間に文字があった場合はバランスが取れますが、何もないためバランスが取れません。

タスク

入力または関数の引数として大文字の単語を取り込んで、次の2つの出力のいずれを生成するプログラムまたは関数を作成する必要があります

  1. 単語のバランスが取れている場合、単語は左側、スペース、アンカー文字、別のスペース、右側で印刷する必要があります。

    function (STEAD) -> S T EAD

  2. 単語のバランスが取れていない場合は、単語を印刷してから、 DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

すべての入力が大文字で、アルファベット文字のみが存在すると想定できます。

I / Oの例

function (CONSUBSTANTIATION) -> CONSUBST A NTIATION
function (WRONGHEADED)       -> WRO N GHEADED
function (UNINTELLIGIBILITY) -> UNINTELL I GIBILITY
function (SUPERGLUE)         -> SUPERGLUE DOES NOT BALANCE

これはであるため、バイト単位の最短回答が優先されます。


我々は、単一の文字の単語、例えばの出力にスペースを省略することができますfunction (A)> - A代わりに- > `A`?
nimi

1
@nimiはい、スペースは省略できます。
カデ

単一の文字入力は、まったくバランスが取れていると見なされるべきですか?
一部のユーザー

1
はい@someuser、いずれかの側に「重み」が0であるので
カーデ

14
BALANCE DOES NOT BALANCE
オプティマイザー

回答:


6

Pyth、49バイト

jd.xcz,Jhf!s*Vm-Cd64zr_TlzUzhJ,z"DOES NOT BALANCE

デモンストレーション。

説明:

jd.xcz,Jhf!s*Vm-Cd64zr_TlzUzhJ,z"DOES NOT BALANCE

                                    Implicit: z = input(), d = ' '
         f                Uz        Filter T over range(len(z)).
              m     z               Map the characters in z to
               -Cd64                their ASCII values - 64.
            *V                      Vectorized multiplication by
                     r_Tlz          range(-T, len(z)).
                                    This is equivalent to putting the fulcrum at T.
           s                        Sum the weights.
          !                         Logical not - filter on sum = 0.
        h                           Take the first result.
                                    This throws an error if there were no results.
       J                            Save it to J.
      ,J                    hJ      Form the list [J, J+1].
    cz                              Chop z at those indices, 
                                    before and after the fulcrum.
  .x                                If no error was thrown, return the above.
                              ,z".. If an error was thrown, return [z, "DOES N..."]
jd                                  Join the result on spaces and print.

12

純粋なbash(coreutilsまたは他のユーティリティなし)、125

原点に関するモーメントを使用した標準的な重心計算:

for((;i<${#1};w=36#${1:i:1}-9,m+=w,M+=w*++i)){ :;}
((M%m))&&echo $1 DOES NOT BALANCE||echo ${1:0:M/m-1} ${1:M/m-1:1} ${1:M/m}

テスト出力:

$ for t in \
> STEAD \
> CONSUBSTANTIATION \
> WRONGHEADED \
> UNINTELLIGIBILITY \
> SUPERGLUE
> do ./wordbal.sh $t; done
S T EAD
CONSUBST A NTIATION
WRO N GHEADED
UNINTELL I GIBILITY
SUPERGLUE DOES NOT BALANCE
$ 

10

Python 3、124

w=input()
i=a=b=0
for c in w:n=ord(c)-64;a+=n;b+=n*i;i+=1
m=b//a
print(*[w[:m],w,w[m],"DOES NOT BALANCE",w[m+1:]][b%a>0::2])

このコードは、潜在的な支点をテストするのではなく、「重心」を見つけて整数かどうかをチェックします。これは、総質量合計することによって、そうaと位置加重質量をb質量の中心を見つけるために、m=b/a。次に、位置mで分割された文字列、またはリストスライストリック"DOES NOT BALANCE"によって選択された文字列plusを出力します[_::2]



7

JavaScriptの(ES6)、211の 200 160バイト

f=w=>{for(j=-w.length;j++;)if(![...w].reduce((p,v,i)=>p+(parseInt(v,36)-9)*(j+i),0))return w.slice(0,-j)+` ${w[-j]} `+w.slice(1-j);return w+` DOES NOT BALANCE`}

前回の試行、200バイト

ゴルフを手伝ってくれたedc56とnderscoreに感謝します

f=w=>{for(j=0,r=(a,z)=>[...a][z||`reverse`]().reduce((p,v,i)=>p+(parseInt(v,36)-9)*++i,0);j++<w.length;)if(r(a=w[s=`slice`](0,j))==r(b=w[s](j+1),s))return a+` ${w[j]} `+b;return w+` DOES NOT BALANCE`}

デモ

現在のところES6であるFirefoxおよびEdge

f=w=>{for(j=1-w.length;j++;)if(!([...w].reduce((p,v,i)=>p+(parseInt(v,36)-9)*(j+i),0)))return w.slice(0,-j)+` ${w[-j]} `+w.slice(1-j);return w+` DOES NOT BALANCE`}

// DEMO
console.log = function(a) {
  document.body.innerHTML += a + "<br>";
}

console.log(f('STEAD'));
console.log(f('CONSUBSTANTIATION'));
console.log(f('WRONGHEADED'));
console.log(f('UNINTELLIGIBILITY'));
console.log(f('SUPERGLUE'));


3
[(ワットのV)v.charCode ....のための]配列内包してみてください、それは通常の文字列のための.mapより1バイト短いです
edc65

@ edc65ありがとう!毎日何か新しいことを学ぶ
rink.attendant.6

1
@ edc65配列の理解は、現在技術的にES7ドラフトにプッシュされています:(
nderscore

1
-1バイト:j=0呼び出し内でcharCodeAt:)に移動します
nderscore

6

C、236の 198 192 188 180 173バイト

a,i,j,k,L;f(char*s){L=strlen(s);for(;i<L;i++){for(a=j=0;j<L;j++)a+=(s[j]-64)*(i-j);if(!a)break;}for(;k<L;k++)printf(k-i?"%c":" %c ",s[k]);if(a)printf(" DOES NOT BALANCE");}

main()で展開:

#define p printf    
a,i,j,k,L;
f(char*s)
{
    L=strlen(s);
    for(;i<L;i++){
        for(a=j=0;j<L;j++)
            a+=(s[j]-64)*(i-j);
        if(!a)
            break;
    }
    for(;k<L;k++)
        printf(k-i?"%c":" %c ",s[k]);
    if(a)
        printf(" DOES NOT BALANCE");
}
// 83 bytes below
int main(int argc, char **argv)
{
    f(argv[1]);
    printf("\n");
}

検証:

$ ./a.out CONSUBSTANTIATION
CONSUBST A NTIATION
$ ./a.out WRONGHEADED
WRO N GHEADED
$ ./a.out A
 A 
$ ./a.out WRONG
WRONG DOES NOT BALANCE
$ ./a.out SUPERGLUE
SUPERGLUE DOES NOT BALANCE

1
私のソリューションは、答えを投稿することがあなたにあまりにも似ていたが、私は146文字まで取得することができた:i,l=1,j;g(char*v){for(;v[i]&&l;++i)for(j=l=0;v[j];++j)l+=(i-j)*(v[j]-64);l?printf("%s DOES NOT BALANCE",v):printf("%.*s %c %s",--i,v,v[i],v+i+1);}注意:用途未定義の動作:)
コールキャメロン

とにかく投稿すべきだと思います。また、バイトを浪費しているため、#defineを削除する必要があることにも気付きました。
一部のユーザー

PHPでCに勝つために一生懸命努力していますが、それでもまだ1バイトの
余裕

6

CJam、50バイト

r_'@f-_ee::*:+\:+md"X DOES NOT BALANCEX"@?)/()@]S*

Javaインタープリターを使用すると、これは非平衡語のSTDERRへのエラーで終了します。

CJamインタープリターでコードを試す場合、出力の最後の行以外はすべて無視してください。

アイディア

私の「オリジナルのアイデア」は、@ xnorが私の数時間前に投稿したのと同じアプローチであることが判明しました。それにもかかわらず、ここにそれが行きます:

値のリストを考えると(V 0、... V N、我々はその持っているV_Tをのみ、次のいずれかの場合には、同等の条件が成立する場合は、リストのアンカーであります:

  • tv 0 +…+ 1v t-1 == 1v t + 1 +…tv n

  • (0-t)v 0 +…+(n-t)v n == 0

  • 0v 0 +…+ nv n == t(v 0 +…+ v n

  • t:=(0v 0 +…+ nv n)/(v 0 +…+ v nは整数です。

コード

r     e# Read a whitespace separated token from STDIN.
_'@f- e# Push a copy and subtract '@' from each char (pushes code point - 64). 
_ee   e# Push a copy of the array of values and enumerate them.
::*   e# Multiply each value by its index.
:+    e# Add all results.
\:+   e# Add the unmodified values.
md    e# Perform modular division. Pushes quotient and residue.

"X DOES NOT BALANCEX"

@     e# Rotate the quotient on top of the string.
?     e# If the residue is 0, select the quotient. Otherwise, select the string.

この部分では、オーバーロードされた演算子を少し楽しんでいます。

商では、これが起こります:

)     e# Add 1 to the quotient.
/     e# Split the input string into chunks of that length.
(     e# Shift out the first chunk.
)     e# Pop the last character of the first chunk.
@     e# Rotate the rest of the string on top of the stack.
]S*   e# Wrap all three parts in an array and join them, separating by spaces.

文字列については、これが起こります:

)     e# Pop out the last char: "X DOES NOT BALANCE" 'X'
/     e# Split the remainder at X's: ["" " DOES NOT BALANCE"]
(     e# Shift out the first chunk: [" DOES NOT BALANCE"] ""
)     e# Pop out the last char.

この時点で""、最後の文字がないため、実行時エラーが発生します。スタックが印刷され、実行はすぐに中止されます。


リンクしたコードは異なっているようです(より良いですか?)
aditsu

@aditsu:ああ、間違ったリンク。はい、短くてきれいですが、末尾にスペースがあります
デニス

5

ジュリア、122バイト

s->(v=[int(i)-64for i=s];m=dot(v,1:length(s))/sum(v);m==int(m)?join([s[1:m-1],s[m],s[m+1:end]]," "):s*" DOES NOT BALANCE")

これにより、入力として文字列を受け取り、文字列を返す名前のない関数が作成されます。呼び出すには、名前を付けf=s->...ます。

単語を1次元のシステムのように扱い、重心を見つける必要があります。重心は、質量とその位置の内積をシステムの総質量で割ったものとして計算されます。計算された中心が整数の場合、単語の文字の1つに対応します。そうしないと、言葉のバランスが取れません。

Ungolfed +説明:

function f(s)
    # Create a vector of ASCII code points -- these are the "masses"
    v = [int(i)-64 for i in s]

    # Compute the center of mass, taking the locations to be the indices
    m = dot(v, 1:length(s)) / sum(v)

    # Check whether the center corresponds to a letter's position
    if m == int(m)
        join([s[1:m-1], s[m], s[m+1:end]], " ")
    else
        m * " DOES NOT BALANCE"
    end
end

例:

julia> f("WRONG")
"WRONG DOES NOT BALANCE"

julia> f("STEAD")
"S T EAD"

julia> f("CONSUBSTANTIATION")
"CONSUBST A NTIATION"

5

PHP、249 174バイト

コマンドライン引数を1つ取ります。

<?for($i=-$l=strlen($w=$argv[1]);$i++;){for($k=$q=0;$l>$k;)$q+=($i+$k)*(ord($w[$k++])-64);$q?:exit(substr($w,0,-$i)." {$w[-$i]} ".substr($w,1-$i));}echo"$w DOES NOT BALANCE";

最初の試行:

<?function r($a){for($i=$q=0;strlen($a)>$i;){$q+=(ord($a[$i])-64)*++$i;}return$q;}for($i=0;$i++<strlen($w=$argv[1]);)(strlen($w)<2?exit($w):(r(strrev($a=substr($w,0,$i)))==r($b=substr($w,$i+1)))?exit("$a {$w[$i++]} $b"):0);echo"$w DOES NOT BALANCE";

4

Haskell、161 135バイト

a#b=a*(fromEnum b-64)
v=sum.zipWith(#)[1..]
h![]=h++" DOES NOT BALANCE"
h!(x:y)|v(reverse h)==v y=h++' ':x:' ':y|1<2=(h++[x])!y
f=([]!)

使用例:

*Main> putStr $ unlines $ map f ["CONSUBSTANTIATION","WRONGHEADED","UNINTELLIGIBILITY","SUPERGLUE"]
CONSUBST A NTIATION
WRO N GHEADED
UNINTELL I GIBILITY
SUPERGLUE DOES NOT BALANCE

仕組み:fヘルパー関数!を呼び出します。ヘルパー関数は、指定された位置にある単語の左右の部分の2つのパラメーターを受け取ります。両方の部分の重みが等しい場合(関数v)、または右部分の最初の文字が左に移動して再帰的に呼び出されると停止します。DOES NOT BALANCE正しい部分が空の場合、メッセージで終了します。


4

C、183 134バイト

h,i,a=1;c(char*s){for(;s[i++]&&a;)for(a=h=0;s[h];)a+=(s[h]-64)*(h++-i);printf(a?"%.*s DOES NOT BALANCE":"%.*s %c %s",i,s,s[--i],s+i);}

新しいバージョンの説明:

他の2つのエントリと同様に、一方の定数加算と他方の減算を利用して、うまくいけばバランスの指標であるゼロに到達します。私の元の出力は、わずかに変更されていますが、最初の回答から再利用されます。

l,h,i,a,b;c(char*s){for(l=strlen(s);h++<l&&(a^b|!a);)for(i=a=b=0;i<l;i++)i==h?a=b,b=0:(b+=(s[i]-64)*abs(i-h));printf(a==b?"%.*s %c %s":"%.*s DOES NOT BALANCE",a==b?h:l,s,s[--h],s+h);}

旧バージョンの説明:

最初のループ(h)は、文字列の長さのメインイテレータです。2番目のループ(i)は、h == iまで累積(b)します。それが起こると、(b)は(a)に格納され、0にリセットされ、(a)と(b)が比較される文字列の終わりに達するまで続けられます。一致する場合、メインイテレータのループが壊れ、出力が出力されます。


3

ルビー175

F=->s{v=->s{(0...s.size).map{|i|(i+1)*(s[i].ord-64)}.inject :+}
r="#{s} DOES NOT BALANCE"
(0...s.size).map{|i|b,a=s[0...i],s[i+1..-1]
v[b.reverse]==v[a]&&r=b+" #{s[i]} "+a}
r}

オンラインでテストする:http : //ideone.com/G403Fv

これは非常に簡単なRuby実装です。読み取り可能なプログラムは次のとおりです。

F=-> word {
  string_value = -> str {
    (0...str.size).map{|i|(i+1) * (str[i].ord - 64)}.inject :+
  }

  result = "#{word} DOES NOT BALANCE"

  (0...word.size).map {|i|
    prefix, suffix = word[0...i], word[i+1..-1]
    if string_value[prefix.reverse] == string_value[suffix]
      result = prefix + " #{word[i]} " + suffix
    end
  }

  result
}

3

R、190バイト

名前のない関数として。もう少し手に入れることができると思いますが、それは待たなければなりません。

function(A){D=colSums(B<-(as.integer(charToRaw(A))-64)*outer(1:(C=nchar(A)),1:C,'-'));if(!length(E<-which(B[,D==0]==0)))cat(A,'DOES NOT BALANCE')else cat(substring(A,c(1,E,E+1),c(E-1,E,C)))}

簡単な説明で少しゴルフを解いた

function(A){
D=colSums(  #column sums of the outer function * character values
    B<-(
       as.integer(charToRaw(A))-64)    # character values
       * outer(1:(C=nchar(A)),1:C,'-') # matrix of ranges eg -3:2, -1:4, etc
       )
if(!length(
    E<-which(B[,D==0]==0) # where the colsum = 0, get the index of the zero
    ))
    cat(A,'DOES NOT BALANCE')
else 
    cat(substring(A,c(1,E,E+1),c(E-1,E,C)))  #cat the substrings
}

最後に改行を入れません。

試運転

> f=
+ function(A){D=colSums(B<-(as.integer(charToRaw(A))-64)*outer(1:(C=nchar(A)),1:C,'-'));if(!length(E<-which(B[,D==0]==0)))cat(A,'DOES NOT BALANCE')else cat(substring(A,c(1,E,E+1),c(E-1,E,C)))}
> 
> f('CONSUBSTANTIATION')
CONSUBST A NTIATION
> f('WRONGHEADED')
WRO N GHEADED
> f('UNINTELLIGIBILITY')
UNINTELL I GIBILITY
> f('SUPERGLUE')
SUPERGLUE DOES NOT BALANCE
> 

2

C、142バイト

私にそれを打つためのいくつかのユーザーにクレジット:)

i,l=1,j;g(char*v){for(;v[i]&&l;++i)for(j=l=0;v[j];++j)l+=(i-j)*(v[j]-64);printf(l?"%.*s DOES NOT BALANCE":"%.*s %c %s",l?i:--i,v,v[i],v+i+1);}

1

Java、240バイト

String b(String s){for(int i=-1,a=s.length(),l=0,r,m;++i<a;){for(r=i;--r>=0;l+=(s.charAt(r)-64));for(m=r=0;++m+i<a;r+=(s.charAt(m+i)-64)*m);if(l==r)return s.substring(0,i)+" "+s.charAt(i)+" "+s.substring(i+1);}return s+" DOES NOT BALANCE";}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.