Балансування слів


33

Цей виклик був розміщений на subreddit DailyProgrammer, і я подумав, що це буде чудовим кандидатом на виклик з кодовим гольфом. Визначення того, чи буква врівноважується, базується на його відстані від точки балансу та значенні букви. Значення букви можна визначити або зайнявши її одноіндексовану позицію в алфавіті, або віднявши 64 від її значення ASCII. Крім того, значення листа множиться на відстань від точки балансу. Давайте розглянемо приклад 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не врівноважує жодну конфігурацію. Також слова повинні врівноважуватися на букві, а не між двома літерами. Наприклад, SAASбуло б врівноважено, якби в середині двох As був лист , але оскільки немає жодного, він не врівноважує.

Завдання

Вам слід створити програму або функцію, яка бере велике слово як аргументи вводу або функції , а потім виробляє один з двох виходів:

  1. Якщо слово врівноважує, то слово слід друкувати лівою стороною, пробілом, буквою якоря, іншим пробілом та правою стороною.

    function (STEAD) -> S T EAD

  2. Якщо слово не врівноважує, слід роздрукувати слово, за яким слід DOES NOT BALANCE

    function (WRONG) -> WRONG DOES NOT BALANCE

Ви можете припустити, що весь вхід буде великим і в ньому будуть лише альфа-символи.

Приклад вводу / виводу

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

Чистий баш (без 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

Пітон 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", обраний [_::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`}

Демо

Firefox і Edge поки що лише, як це 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
Спробуйте зрозуміти масив [for (v of w) v.charCode ....], зазвичай це на 1 байт коротше .map для рядків
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, оскільки він витрачає байти.
якийсь користувач

Я дуже намагаюся перемогти C з PHP, але я все одно перебуваю на байті
rink.attendant.6

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

Ми ставимось до слова як до одновимірної системи, для якої нам потрібно знайти центр маси. Центр маси обчислюється як крапковий добуток мас з їх розташуванням, поділений на загальну масу системи. Якщо обчислений центр є цілим числом, він відповідає одній із літер у слові. Інакше слово не врівноважує.

Недоліковані + пояснення:

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 байт

Бере один аргумент командного рядка.

<?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викликає функцію помічника, !яка приймає два параметри, ліву та праву частину слова в заданій позиції. Він зупиняється, якщо обидві частини мають однакову вагу (функцію 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);}

Пояснена нова версія:

Як і в інших двох записах, він використовує постійне додавання з одного боку та віднімання з іншого, щоб сподіватися досягти нуля, що є показником балансу. Мій оригінальний вихід повторно використовується з першої відповіді, хоч і дещо змінений.

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) - головний ітератор довжини рядка. Другий цикл (i) накопичується (b), поки h == i. Як тільки це станеться, (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

This is a pretty straightforward Ruby implementation. Here's the readable program:

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

As an unnamed function. I think I can get a few more, but that'll have to wait.

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 a bit with brief explanation

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
}

It doesn't put a newline at the end.

Test run

> 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

Credit to some user for beating me to it :)

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";}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.