Balancing Words


33

Diese Herausforderung wurde auf dem DailyProgrammer-Subreddit veröffentlicht, und ich dachte, es wäre ein großartiger Kandidat für eine Code-Golf-Herausforderung. Das Bestimmen, ob ein Buchstabe ausgeglichen ist, basiert auf seiner Entfernung vom Gleichgewichtspunkt und dem Wert des Buchstabens. Der Wert eines Buchstabens kann bestimmt werden, indem entweder seine Position im Alphabet mit einem Index angegeben wird oder indem 64 von seinem ASCII-Wert subtrahiert wird. Darüber hinaus wird der Wert eines Buchstabens mit seinem Abstand vom Gleichgewichtspunkt multipliziert. Schauen wir uns ein Beispiel an 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.

Es ist jedoch zu beachten, dass nicht alle Wörter ausgewogen sind. Beispielsweise WRONGstimmt das Wort in keiner Konfiguration überein. Wörter müssen sich auch in einem Buchstaben befinden, nicht in zwei Buchstaben. Zum Beispiel SAASwürde balancieren, wenn es einen Buchstaben in der Mitte der beiden As gäbe, aber da es keinen gibt, wird es nicht balanciert.

Die Aufgabe

Sie sollten ein Programm oder eine Funktion erstellen , die ein Wort in Großbuchstaben als Eingabe- oder Funktionsargumente verwendet und anschließend eine von zwei Ausgaben erzeugt:

  1. Wenn das Wort ausgeglichen ist, sollte das Wort mit der linken Seite, einem Leerzeichen, dem Ankerbuchstaben, einem weiteren Leerzeichen und der rechten Seite gedruckt werden.

    function (STEAD) -> S T EAD

  2. Wenn das Wort nicht ausgeglichen ist, sollten Sie das Wort ausdrucken, gefolgt von DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

Sie können davon ausgehen, dass alle Eingaben in Großbuchstaben erfolgen und es nur Buchstaben gibt.

Beispiel I / O

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

Das ist , also gewinnt die kürzeste Antwort in Bytes.


Können wir die Leerzeichen in der Ausgabe einzelner Buchstaben weglassen, zB function (A)-> Astatt -> `A`?
Nimi

1
@nimi Ja, Sie können Leerzeichen weglassen.
Kade

Sollte die Eingabe einzelner Zeichen überhaupt als ausgewogen angesehen werden?
Einige Benutzer

1
@someuser Ja, weil das "Gewicht" auf beiden Seiten 0 ist.
Kade

14
BALANCE DOES NOT BALANCE
Optimierer

Antworten:


6

Pyth, 49 Bytes

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

Demonstration.

Erläuterung:

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

Pure Bash (keine Coreutils oder andere Dienstprogramme), 125

Standardschwerpunktberechnung unter Verwendung von Momenten über den Ursprung:

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}

Testausgang:

$ 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])

Dieser Code testet keine potenziellen Drehpunkte, sondern findet den "Schwerpunkt" und prüft, ob es sich um eine Ganzzahl handelt. Dies geschieht durch Summieren der Gesamtmasse aund der positionsgewichteten Masse b, um den Massenmittelpunkt zu finden m=b/a. Anschließend wird entweder die an der Position geteilte Zeichenfolge moder das "DOES NOT BALANCE"vom [_::2]List-Slicing-Trick ausgewählte Zeichenfolge-Plus gedruckt .



7

JavaScript (ES6), 211 200 160 Byte

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`}

Vorheriger Versuch, 200 Bytes

Vielen Dank an edc56 und nderscore, die mir dabei geholfen haben, Golf zu spielen

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`}

Demo

Firefox und Edge erstmal, da es sich um ES6 handelt

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
Versuchen Sie Array-Verständnis [für (v von w) v.charCode ....], es ist in der Regel 1 Byte kürzer als .map für Zeichenfolgen
edc65

@ edc65 Danke! Lerne jeden Tag etwas Neues
rink.attendant.6

1
@ edc65 Das Array-Verständnis wird jetzt technisch auf den ES7-Entwurf übertragen :(
nderscore

1
-1 Byte: Bewegen Sie sich j=0innerhalb des Anrufs zu charCodeAt:)
nderscore

6

C 236 198 192 188 180 173 Bytes

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");}

Erweitert mit 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");
}

Nachprüfung:

$ ./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
Meine Lösung war zu ähnlich wie Ihre, um eine Antwort zu schreiben, aber ich konnte 146 Zeichen erhalten: 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);}Hinweis: verwendet undefiniertes Verhalten :)
Cole Cameron

Ich denke du solltest es trotzdem posten. Ich erkannte auch, dass ich mein #define hätte loswerden sollen, da es Bytes verschwendet.
Einige Benutzer

Ich versuche wirklich hart, C mit PHP zu schlagen, aber ich bin immer noch ein Byte off
rink.attendant.6

6

CJam, 50 Bytes

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

Bei Verwendung des Java-Interpreters wird dies mit einem Fehler an STDERR für nicht ausgleichende Wörter beendet.

Wenn Sie den Code im CJam-Interpreter ausprobieren , ignorieren Sie einfach alles außer der letzten Ausgabezeile.

Idee

Meine "ursprüngliche Idee" entpuppte sich als derselbe Ansatz, den @xnor mehrere Stunden vor mir gepostet hatte. Trotzdem geht es hier los:

Ausgehend von einer Liste von Werten (v 0 ,… v n ) ist v_t genau dann der Anker der Liste, wenn eine der folgenden äquivalenten Bedingungen zutrifft:

  • 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 ) ist eine ganze Zahl.

Code

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.

An dieser Stelle haben wir ein bisschen Spaß mit überlasteten Operatoren.

Für den Quotienten passiert folgendes:

)     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.

Für die Zeichenfolge geschieht Folgendes:

)     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.

Zu diesem Zeitpunkt tritt ein Laufzeitfehler auf, da ""kein letztes Zeichen vorhanden ist. Der Stapel wird gedruckt und die Ausführung wird sofort abgebrochen.


Der von Ihnen verknüpfte Code scheint anders (und besser?)
aditsu

@Aditsu: Oh, falscher Link. Es ist kürzer und sauberer, ja, aber es hat Leerzeichen ...
Dennis

5

Julia, 122 Bytes

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")

Dadurch wird eine unbenannte Funktion erstellt, die eine Zeichenfolge als Eingabe akzeptiert und eine Zeichenfolge zurückgibt. Um es zu nennen, geben Sie ihm einen Namen, z f=s->....

Wir behandeln das Wort wie ein eindimensionales System, für das wir den Schwerpunkt finden müssen. Der Massenschwerpunkt wird als Punktprodukt der Massen mit ihren Positionen berechnet, dividiert durch die Gesamtmasse des Systems. Wenn das berechnete Zentrum eine Ganzzahl ist, entspricht es einem der Buchstaben im Wort. Sonst gleicht das Wort nicht aus.

Ungolfed + Erklärung:

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

Beispiele:

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

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

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

5

PHP, 249 174 Bytes

Nimmt ein Befehlszeilenargument an.

<?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";

Anfangsversuch:

<?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 Bytes

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=([]!)

Anwendungsbeispiel:

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

So funktioniert es: fRuft die Hilfsfunktion auf !, die an einer bestimmten Position zwei Parameter, den linken und den rechten Teil des Wortes, übernimmt. Es stoppt, wenn beide Teile das gleiche Gewicht haben (Funktion v) oder ruft sich rekursiv auf, wobei der erste Buchstabe des rechten Teils nach links verschoben wird. Es endet mit der DOES NOT BALANCEMeldung, wenn der rechte Teil leer ist.


4

C 183 134 Bytes

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);}

Neue Version erklärt:

Wie bei den beiden anderen Einträgen wird eine konstante Addition auf der einen Seite und eine Subtraktion auf der anderen Seite verwendet, um hoffentlich Null zu erreichen, was die Anzeige des Gleichgewichts ist. Meine ursprüngliche Ausgabe wird von der ersten Antwort an wiederverwendet, wenn auch leicht modifiziert.

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);}

Alte Version erklärt:

Die erste Schleife (h) ist der Hauptiterator für die Länge des Strings. Die zweite Schleife (i) akkumuliert (b) bis h == i. Sobald dies geschieht, wird (b) in (a) gespeichert, auf 0 zurückgesetzt und dann fortgesetzt, bis das Ende der Zeichenkette erreicht ist, wo (a) mit (b) verglichen wird. Wenn eine Übereinstimmung vorliegt, wird die Schleife des Hauptiterators unterbrochen und die Ausgabe gedruckt.


3

Ruby 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}

Testen Sie es online: http://ideone.com/G403Fv

Dies ist eine ziemlich einfache Ruby-Implementierung. Hier ist das lesbare Programm:

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 Bytes

Als unbenannte Funktion. Ich glaube, ich kann noch ein paar besorgen, aber das muss warten.

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)))}

Ungolfed ein bisschen mit kurzer Erklärung

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
}

Es wird kein Zeilenumbruch am Ende eingefügt.

Testlauf

> 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 Bytes

Dank an einen Benutzer , der mich geschlagen hat :)

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 Byte

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";}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.