Palabras de equilibrio

33

Este desafío fue publicado en el subreddit DailyProgrammer, y pensé que sería un gran candidato para un desafío de golf de código. Determinar si una carta se equilibra se basa en su distancia desde el punto de equilibrio y el valor de la letra. El valor de una letra se puede determinar tomando su posición indexada en el alfabeto o restando 64 de su valor ASCII. Además, el valor de una letra se multiplica por su distancia desde el punto de equilibrio. Veamos un ejemplo 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.

Sin embargo, debe tenerse en cuenta que no todas las palabras se equilibran. Por ejemplo, la palabra WRONGno se equilibra en ninguna configuración. Además, las palabras deben equilibrarse en una letra, no entre dos letras. Por ejemplo, SAASse equilibraría si hubiera una letra en el medio de las dos As, pero como no hay ninguna, no se equilibra.

La tarea

Debe crear un programa o función que tome una palabra en mayúscula como argumentos de entrada o función , y luego produzca una de dos salidas:

  1. Si la palabra se equilibra, la palabra debe imprimirse con el lado izquierdo, un espacio, la letra de anclaje, otro espacio y el lado derecho.

    function (STEAD) -> S T EAD

  2. Si la palabra no se equilibra, debe imprimirla, seguida de DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

Puede suponer que todas las entradas serán mayúsculas y solo habrá caracteres alfabéticos.

Ejemplo de E / S

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

Este es el , por lo que gana la respuesta más corta en bytes.

Kade
fuente
¿Podemos omitir los espacios en la salida de palabras de una sola letra, por ejemplo, function (A)-> en Alugar de -> `A`?
nimi
1
@nimi Sí, puedes omitir espacios.
Kade
¿Debería considerarse el ingreso de un solo carácter balanceado?
algún usuario
1
@someuser Sí, porque el "peso" en ambos lados es 0.
Kade
14
BALANCE DOES NOT BALANCE
Optimizador

Respuestas:

6

Pyth, 49 bytes

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

Demostración.

Explicación:

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.
isaacg
fuente
12

Pure bash (sin coreutils u otras utilidades), 125

Cálculo estándar del centro de masa usando momentos sobre el origen:

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}

Prueba de salida:

$ 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
$ 
Trauma digital
fuente
10

Pitón 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])

Este código no prueba posibles puntos de apoyo, sino que encuentra el "centro de masa" y comprueba si es un número entero. Lo hace sumando la masa total ay la masa ponderada por posición b, para encontrar el centro de masa m=b/a. Luego imprime la cadena dividida en la posición mo la cadena más "DOES NOT BALANCE", elegida por el [_::2]truco de corte de lista.

xnor
fuente
8

CJam, 57 bytes

l_,,_f{f-W$'@fm.*:+}0#:I){ISIW$=S++t}" DOES NOT BALANCE"?

Esto todavía se puede jugar un poco al golf.

Pruébalo en línea aquí

Optimizador
fuente
Eso lo arregla. '@fmes más corto que 64f-:i.
Dennis
Sí ... olvidé que CJam actúa de forma extraña en caso de sustracción de caracteres ...
Optimizer
7

JavaScript (ES6), 211 200 160 bytes

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

Intento anterior, 200 bytes

Gracias a edc56 y nderscore por ayudarme a jugar golf

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

Manifestación

Firefox y Edge solo por ahora, ya que es ES6

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

rink.attendant.6
fuente
3
Pruebe la comprensión de matriz [para (v de w) v.charCode ....], generalmente es 1 byte más corto que .map para cadenas
edc65
@ edc65 ¡Gracias! Aprenda algo nuevo todos los días
rink.attendant.6
1
La comprensión de la matriz @ edc65 está técnicamente impulsada al borrador de ES7 ahora :(
nderscore
1
-1 byte: moverse j=0dentro de la llamada a 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");}

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

Verificació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
algun usuario
fuente
1
Mi solución era demasiado similar a la suya para publicar una respuesta, pero pude llegar a 146 caracteres: 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);}Nota: utiliza un comportamiento indefinido :)
Cole Cameron
Creo que deberías publicarlo de todos modos. También me di cuenta de que debería haberme librado de mi #define ya que está desperdiciando bytes.
algún usuario
Estoy tratando realmente de vencer a C con PHP, pero todavía estoy sin un byte
rink.attendant.6
6

CJam, 50 bytes

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

Usando el intérprete de Java, esto sale con un error a STDERR para palabras sin equilibrio.

Si prueba el código en el intérprete de CJam , simplemente ignore todo menos la última línea de salida.

Idea

Mi "idea original" resultó ser el mismo enfoque que @xnor publicó varias horas antes que yo. Sin embargo, aquí va:

Dada una lista de valores (v 0 , ... v n ) , tenemos que v_t es el ancla de la lista si y solo si se cumple alguna de las siguientes condiciones equivalentes:

  • 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 ) es un número entero.

Código

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.

En esta parte, comenzamos a divertirnos un poco con los operadores sobrecargados.

Para el cociente, esto sucede:

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

Para la cadena, esto sucede:

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

En este punto, se produce un error de tiempo de ejecución, ya ""que no tiene un último carácter. La pila se imprime y la ejecución se interrumpe inmediatamente.

Dennis
fuente
El código que vinculó parece diferente (¿y mejor?)
aditsu
@aditsu: Oh, enlace equivocado. Es más corto y limpio, sí, pero tiene espacios finales ...
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")

Esto crea una función sin nombre que acepta una cadena como entrada y devuelve una cadena. Para llamarlo, dale un nombre, por ejemplo f=s->....

Tratamos la palabra como un sistema unidimensional para el cual necesitamos encontrar el centro de masa. El centro de masa se calcula como el producto escalar de las masas con sus ubicaciones, dividido por la masa total del sistema. Si el centro calculado es un número entero, corresponde a una de las letras de la palabra. De lo contrario, la palabra no se equilibra.

Ungolfed + explicación:

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

Ejemplos:

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

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

julia> f("CONSUBSTANTIATION")
"CONSUBST A NTIATION"
Alex A.
fuente
5

PHP, 249 174 bytes

Toma un argumento de línea de comandos.

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

Intento inicial:

<?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";
rink.attendant.6
fuente
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=([]!)

Ejemplo de uso:

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

Cómo funciona: fllama a la función auxiliar !que toma dos parámetros, la parte izquierda y derecha de la palabra en una posición determinada. Se detiene si ambas partes tienen el mismo peso (función v) o se llama recursivamente con la primera letra de la parte derecha movida a la izquierda. Termina con el DOES NOT BALANCEmensaje si la parte derecha está vacía.

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

Nueva versión explicada:

Al igual que las otras dos entradas, hace uso de la suma constante en un lado y la resta en el otro para llegar a cero, lo cual es la indicación del equilibrio. Mi salida original se reutiliza desde la primera respuesta, aunque ligeramente modificada.

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

Versión anterior explicada:

El primer bucle (h) es el iterador principal para la longitud de la cadena. El segundo bucle (i) se acumula (b) hasta que h == i. Una vez que eso sucede, (b) se almacena en (a), se restablece a 0 y luego continúa hasta llegar al final de la cadena donde (a) se compara con (b). Si hay una coincidencia, el bucle del iterador principal se rompe y se imprime la salida.

openaddr
fuente
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}

Pruébelo en línea: http://ideone.com/G403Fv

Esta es una implementación de Ruby bastante sencilla. Aquí está el programa legible:

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
}
Cristian Lupascu
fuente
3

R, 190 bytes

Como una función sin nombre. Creo que puedo conseguir algunos más, pero eso tendrá que esperar.

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 un poco con una breve explicación

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
}

No pone una nueva línea al final.

Prueba de funcionamiento

> 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
> 
MickyT
fuente
2

C, 142 bytes

Crédito para algún usuario para pegarme a él :)

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);}
Cole Cameron
fuente
1

Java, 240 bytes

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";}
ECS
fuente