Балансирующие Слова


33

Этот вызов был опубликован в подразделе 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было бы баланс, если бы была буква в середине двух Aс, но так как нет ни одного, это не балансирует.

Задание

Вы должны создать программу или функцию , которая принимает в качестве заглавного слова в качестве входных или функциональных аргументов , а затем производит один из двух выходов:

  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`?
Ними

1
@nimi Да, вы можете пропустить пробелы.
Каде

Должен ли ввод одного символа считаться сбалансированным вообще?
некий пользователь

1
@ someuser Да, потому что «вес» с обеих сторон равен 0.
Kade

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

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

С 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, но я все еще на
ходу

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: О, неправильная ссылка. Это короче и чище, да, но у него есть пробелы ...
Деннис

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

Мы рассматриваем слово как одномерную систему, для которой нам нужно найти центр масс. Центр масс вычисляется как произведение масс масс на их местоположения, деленное на общую массу системы. Если вычисляемый центр является целым числом, он соответствует одной из букв в слове. В противном случае слово не сбалансировано.

Ungolfed + объяснение:

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

Это довольно простая реализация Ruby. Вот читаемая программа:

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

Как неназванная функция. Я думаю, что смогу получить еще немного, но это подождет.

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

Немного разгулялся с кратким объяснением

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
}

Это не ставит новую строку в конце.

Тестовый забег

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

Благодарим какого-то пользователя за то, что он меня избил :)

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

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.