Palavras de equilíbrio


33

Esse desafio foi publicado no subreddit DailyProgrammer e imaginei que seria um ótimo candidato para um desafio de golfe com código. Determinar se uma letra é equilibrada é baseada em sua distância do ponto de equilíbrio e no valor da letra. O valor de uma letra pode ser determinado assumindo sua posição de um índice no alfabeto ou subtraindo 64 de seu valor ASCII. Além disso, o valor de uma letra é multiplicado pela sua distância do ponto de equilíbrio. Vamos dar uma olhada em um exemplo 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.

No entanto, deve-se notar que nem todas as palavras se equilibram. Por exemplo, a palavra WRONGnão se equilibra em nenhuma configuração. Além disso, as palavras devem se equilibrar em uma letra, não entre duas letras. Por exemplo, SAASseria equilibrado se houvesse uma letra no meio dos dois As, mas como não há nenhuma, ela não será equilibrada.

A tarefa

Você deve criar um programa ou função que receba uma palavra em maiúscula como argumentos de entrada ou função e, em seguida, produza uma das duas saídas:

  1. Se a palavra se equilibrar, ela deverá ser impressa com o lado esquerdo, um espaço, a letra âncora, outro espaço e o lado direito.

    function (STEAD) -> S T EAD

  2. Se a palavra não se equilibrar, você deve imprimi-la, seguida de DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

Você pode supor que todas as entradas serão maiúsculas e haverá apenas caracteres alfa.

Exemplo de E / S

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

Isso é , então a resposta mais curta em bytes vence.


Podemos omitir os espaços na saída de palavras de uma letra, por exemplo function (A)- - em Avez de -> `A`?
nimi

1
@nimi Sim, você pode omitir espaços.
Kade

A entrada de caracteres únicos deve ser considerada equilibrada?
algum usuário

1
@someuser Sim, porque o "peso" de ambos os lados é 0.
Kade

14
BALANCE DOES NOT BALANCE
Optimizer

Respostas:


6

Pitão, 49 bytes

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

Demonstração.

Explicação:

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 (sem coreutils ou outros utilitários), 125

Cálculo padrão do centro de massa usando momentos sobre a origem:

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}

Saída de teste:

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

Esse código não testa fulcros em potencial, mas encontra o "centro de massa" e verifica se é um número inteiro. Fá-lo somando a massa total ae a massa ponderada pela posição b, para encontrar o centro de massa m=b/a. Em seguida, imprime a sequência dividida na posição mou a sequência mais "DOES NOT BALANCE", escolhida pelo [_::2]truque de fatiar a lista.


8

CJam, 57 bytes

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

Isso ainda pode ser um pouco jogado de golfe.

Experimente online aqui


Isso conserta. '@fmé mais curto que 64f-:i.
217 Dennis

Sim .. esqueceu que CJam age estranho em caso de subtrações de char ..
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`}

Tentativa anterior, 200 bytes

Obrigado a edc56 e nderscore por me ajudarem a jogar este

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 e Edge apenas por enquanto, pois é o 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'));


3
Tente variedade compreensão [para (v de w) v.charCode ....], é geralmente 1 byte mais curto do que .map para cordas
edc65

@ edc65 Obrigado! Aprenda algo novo todos os dias
rink.attendant

1
@ compreensão variedade edc65 é tecnicamente empurrado para o projecto ES7 agora :(
nderscore

1
-1 byte: movimento j=0dentro da chamada para 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");}

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

Verificação:

$ ./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
Minha solução foi muito semelhante ao seu para deixar uma resposta, mas eu era capaz de chegar até 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: usa um comportamento indefinido :)
Cole Cameron

Eu acho que você deve publicá-lo de qualquer maneira. Também percebi que deveria me livrar do meu #define, pois está desperdiçando bytes.
algum usuário

Estou tentando muito bater C com PHP, mas ainda estou a um byte off
rink.attendant

6

CJam, 50 bytes

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

Usando o interpretador Java, isso é encerrado com um erro no STDERR para palavras que não estão em equilíbrio.

Se você tentar o código no interpretador CJam , ignore tudo, menos a última linha de saída.

Idéia

Minha "idéia original" acabou sendo a mesma abordagem que o @xnor postou várias horas antes de mim. No entanto, aqui vai:

Dada uma lista de valores (v 0 ,… v n ) , temos que v_t é a âncora da lista se e somente se alguma das seguintes condições equivalentes for válida:

  • 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 ) é um número inteiro.

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.

Nesta parte, começamos a nos divertir um pouco com operadores sobrecarregados.

Para o quociente, isso acontece:

)     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 a sequência, isso acontece:

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

Nesse momento, ocorre um erro de tempo de execução, pois ""não possui um último caractere. A pilha é impressa e a execução é interrompida imediatamente.


O código é ligada parece diferente (e melhor?)
aditsu

@aditsu: Ah, link errado. É mais curto e mais limpo, sim, mas tem espaços à direita ...
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")

Isso cria uma função sem nome que aceita uma string como entrada e retorna uma string. Para chamá-lo, dê um nome, por exemplo f=s->....

Tratamos a palavra como um sistema unidimensional para o qual precisamos encontrar o centro de massa. O centro de massa é calculado como o produto escalar das massas com suas localizações, dividido pela massa total do sistema. Se o centro computado for um número inteiro, ele corresponderá a uma das letras da palavra. Caso contrário, a palavra não se equilibra.

Ungolfed + explicação:

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

Exemplos:

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

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

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

5

PHP, 249 174 bytes

Leva um argumento de linha de comando.

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

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

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

Exemplo de uso:

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

Como funciona: fchama a função auxiliar !que utiliza dois parâmetros, a parte esquerda e direita da palavra em uma determinada posição. Para se ambas as partes tiverem o mesmo peso (função v) ou se chamar recursivamente com a primeira letra da parte direita movida para a esquerda. Termina com a DOES NOT BALANCEmensagem se a parte direita estiver vazia.


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

Nova versão explicada:

Como as outras duas entradas, utiliza adição constante de um lado e subtração do outro para chegar a zero, que é a indicação do equilíbrio. Minha saída original é reutilizada na primeira resposta, embora ligeiramente 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);}

Versão antiga explicada:

O primeiro loop (h) é o iterador principal para o comprimento da string. O segundo loop (i) acumula (b) até h == i. Quando isso acontece, (b) é armazenado em (a), redefina para 0 e continua até o final da string ser alcançado, onde (a) é comparado a (b). Se houver uma correspondência, o loop do iterador principal é interrompido e a saída é impressa.


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}

Teste on-line: http://ideone.com/G403Fv

Esta é uma implementação Ruby bastante direta. Aqui está o programa legível:

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

Como uma função sem nome. Acho que posso conseguir mais um pouco, mas isso terá 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 um pouco com breve explicação

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
}

Não coloca uma nova linha no final.

Execução de teste

> 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

Crédito a algum usuário por ter me batido nele :)

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 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";}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.