Parole in equilibrio


33

Questa sfida è stata pubblicata sul subreddit DailyProgrammer e ho pensato che sarebbe stato un ottimo candidato per una sfida di golf di codice. Determinare se una lettera si bilancia si basa sulla sua distanza dal punto di equilibrio e sul valore della lettera. Il valore di una lettera può essere determinato prendendo la sua posizione a un indice nell'alfabeto o sottraendo 64 dal suo valore ASCII. Inoltre, il valore di una lettera viene moltiplicato per la sua distanza dal punto di equilibrio. Diamo un'occhiata a un esempio 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.

Tuttavia, va notato che non tutte le parole si bilanciano. Ad esempio, la parola WRONGnon è bilanciata in nessuna configurazione. Inoltre, le parole devono essere bilanciate su una lettera, non tra due lettere. Ad esempio, SAASsarebbe bilanciato se ci fosse una lettera nel mezzo delle due As, ma poiché non ce n'è nessuna, non è bilanciata.

L'obiettivo

È necessario creare un programma o una funzione che accetta una parola maiuscola come argomenti di input o di funzione e quindi produce uno dei due output:

  1. Se la parola si bilancia, allora la parola dovrebbe essere stampata con il lato sinistro, uno spazio, la lettera di ancoraggio, un altro spazio e il lato destro.

    function (STEAD) -> S T EAD

  2. Se la parola non è in equilibrio, è necessario stampare la parola, seguita da DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

Puoi presumere che tutti gli input saranno maiuscoli e che ci saranno solo caratteri alfa.

Esempio I / O

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

Questo è , quindi vince la risposta più breve in byte.


Possiamo omettere gli spazi nell'output di parole di una sola lettera, ad es. function (A)-> Aanziché -> `A`?
nimi,

1
@nimi Sì, puoi omettere gli spazi.
Kade,

L'immissione di un singolo carattere deve essere considerata del tutto bilanciata?
alcuni utenti il

1
@someuser Sì, perché il "peso" su entrambi i lati è 0.
Kade,

14
BALANCE DOES NOT BALANCE
Ottimizzatore

Risposte:


6

Pyth, 49 byte

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

Dimostrazione.

Spiegazione:

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 puro (no coreutils o altre utilità), 125

Calcolo del centro di massa standard usando momenti sull'origine:

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}

Uscita di prova:

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

Questo codice non verifica i potenziali fulcro, ma trova piuttosto il "centro di massa" e verifica se è un numero intero. Lo fa sommando la massa totale ae la massa ponderata in posizione b, per trovare il centro di massa m=b/a. Quindi stampa la stringa divisa in posizione m, o la stringa più "DOES NOT BALANCE", scelta dal [_::2]trucco per tagliare la lista.


8

CJam, 57 byte

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

Questo può ancora essere giocato un po 'a golf.

Provalo online qui


Questo lo risolve. '@fmè più corto di 64f-:i.
Dennis,

Sì .. ho dimenticato che CJam si comporta in modo strano in caso di sottrazioni di caratteri ..
Ottimizzatore

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

Tentativo precedente, 200 byte

Grazie a edc56 e nderscore per avermi aiutato a giocare a 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`}

dimostrazione

Firefox e Edge solo per ora, in quanto è 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
Prova la comprensione dell'array [per (v of w) v.charCode ....], di solito è 1 byte più corto di .map per le stringhe
edc65

@ edc65 Grazie! Impara qualcosa di nuovo ogni giorno
rink.attendant.6

1
La comprensione dell'array @ edc65 è ora tecnicamente spinta alla bozza ES7 :(
nderscore

1
-1 byte: sposta j=0all'interno della chiamata su charCodeAt:)
nderscore

6

C, 236 198 192 188 180 173 byte

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

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

Verifica:

$ ./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
La mia soluzione era troppo simile alla tua per pubblicare una risposta, ma sono riuscito a scendere a 146 caratteri: 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 un comportamento indefinito :)
Cole Cameron

Penso che dovresti pubblicarlo comunque. Mi sono anche reso conto che avrei dovuto sbarazzarmi del mio #define perché sta sprecando byte.
alcuni utenti l'

Sto davvero cercando di battere C con PHP ma sono ancora a un byte off
rink.attendant.6

6

CJam, 50 byte

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

Usando l'interprete Java, questo esce con un errore a STDERR per parole non bilanciate.

Se provi il codice in CJam , ignora tutto tranne l'ultima riga di output.

Idea

La mia "idea originale" si è rivelata lo stesso approccio che @xnor ha pubblicato diverse ore prima di me. Tuttavia, ecco qui:

Dato un elenco di valori (v 0 ,… v n ) , abbiamo che v_t è l'ancoraggio dell'elenco se e solo se sussiste una delle seguenti condizioni equivalenti:

  • 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 ) è un numero intero.

Codice

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.

A questa parte, iniziamo a divertirci un po 'con gli operatori sovraccarichi.

Per il quoziente, ciò accade:

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

Per la stringa, questo accade:

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

A questo punto, si verifica un errore di runtime, poiché ""non ha un ultimo carattere. La pila viene stampata e l'esecuzione viene immediatamente interrotta.


Il codice che hai collegato sembra diverso (e migliore?)
aditsu,

@aditsu: Oh, link errato. È più corto e più pulito, sì, ma ha spazi finali ...
Dennis

5

Julia, 122 byte

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

Ciò crea una funzione senza nome che accetta una stringa come input e restituisce una stringa. Per chiamarlo, dagli un nome, ad es f=s->....

Trattiamo la parola come un sistema monodimensionale per il quale dobbiamo trovare il centro di massa. Il centro di massa viene calcolato come il prodotto punto delle masse con le loro posizioni, diviso per la massa totale del sistema. Se il centro calcolato è un numero intero, corrisponde a una delle lettere nella parola. Altrimenti la parola non è in equilibrio.

Ungolfed + spiegazione:

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

Esempi:

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

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

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

5

PHP, 249 174 byte

Accetta un argomento della riga di 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";

Tentativo iniziale:

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

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

Esempio di utilizzo:

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

Come funziona: fchiama la funzione helper !che accetta due parametri, la parte sinistra e destra della parola in una determinata posizione. Si interrompe se entrambe le parti hanno lo stesso peso (funzione v) o si chiama in modo ricorsivo con la prima lettera della parte destra spostata a sinistra. Termina con il DOES NOT BALANCEmessaggio se la parte destra è vuota.


4

C, 183 134 byte

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

Spiegazione nuova versione:

Come le altre due voci, utilizza l'aggiunta costante da un lato e la sottrazione dall'altro per raggiungere, si spera, zero che è indice di equilibrio. Il mio output originale viene riutilizzato dalla prima risposta, sebbene leggermente modificato.

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

Spiegazione della vecchia versione:

Il primo loop (h) è l'iteratore principale per la lunghezza della stringa. Il secondo ciclo (i) si accumula (b) fino a quando h == i. Una volta che ciò accade, (b) viene memorizzato in (a), reimpostato su 0 e quindi continua fino a quando non viene raggiunta la fine della stringa dove (a) viene confrontato con (b). Se c'è una corrispondenza, il ciclo dell'iteratore principale viene interrotto e l'output viene stampato.


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}

Provalo online: http://ideone.com/G403Fv

Questa è un'implementazione Ruby piuttosto semplice. Ecco il programma leggibile:

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 byte

Come una funzione senza nome. Penso di poterne avere un po 'di più, ma dovrò aspettare.

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

Ungolf un po 'con una breve spiegazione

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
}

Non mette una riga alla fine.

Prova

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

Ringraziamo alcuni utenti per avermi battuto :)

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";}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.