Позиционный Ванные Этикет


24

Задний план

В этикете ванной комнаты, касающемся имеющихся писсуаров, указывается, что следующий писсуар, который необходимо заполнить, должен быть таким, который сводит к минимуму общий дискомфорт. Общее уравнение дискомфорта задается следующей системой уравнений:

dist (x, y) = линейное расстояние между человеком x и человеком y в мочевых единицах
 дискомфорт (x) = сумма (1 / (dist (x, y) * dist (x, y))) для всех людей y, за исключением человека x
 total_Discomfort = сумма (дискомфорт (х)) для всех х

Более подробный документ, посвященный аналогичной (не точно такой же) проблеме, можно найти здесь: (Спасибо @Lembik за то, что предупредили меня об этом удивительном техническом описании!)


Ввод, вывод

Учитывая ввод пустых и полных писсуаров, выведите итоговый набор писсуаров с добавлением одного человека. Если есть галстук для позиции, писсуары должны заполнять слева направо. Вывод должен быть в том же формате, что и ввод.

  • Если дан случай с полными писсуарами, верните ввод.
  • На входе всегда будет определен хотя бы один писсуар.


Тестовые случаи

ВХОД -> ВЫХОД
1000001 -> 1001001
101010101 -> 111010101
100 -> 101
00000 -> 10000
1111111 -> 1111111
0100 -> 0101
101000 -> 101001


правила

Это , поэтому выигрывает самый короткий код в байтах. Стандартные лазейки запрещены.



1
Рекомендуется подождать около недели, прежде чем принять ответ. Принятие менее чем за день может уменьшить количество ответов, которые получает ваш вызов.
Emigna

1
Я бы предложил добавить 0100и 101000в тестовых случаях (некоторые основанные на регулярных выражениях подходы работают на реальных тестовых случаях, но не будут работать на тех, которые все еще должны быть обработаны)
Дада


@TheBitByte Как это оскорбительно? Это довольно точное описание того, как мужчины выбирают писсуары в ванной комнате.
mbomb007

Ответы:


3

Желе , 13 12 байт

J_þTݲSiṂ$Ṭo

Попробуйте онлайн! или Проверьте все контрольные примеры.

объяснение

J_þTݲSiṂ$Ṭo  Input: boolean array A
J             Indices, returns [1, 2, ..., len(A)]
   T          Truthy indices, returns the indices which have a truthy value
 _þ           Form the subtraction (_) table (þ) between them
    İ         Inverse, find the reciprocal of each
     ²        Square each
      S       Sum the sublists column-wise
         $    Monadic chain
        Ṃ       Minimum
       i        Find the first index of that
          Ṭ   Untruth indices, returns a boolean array with 1's at those indices
           o  Logical OR between that and A, and return

10

MATL , 19 18 17 байт

lyf!Gn:-H_^Xs&X<(

Попробуйте онлайн! Или проверьте все контрольные примеры (слегка измененный код).

объяснение

Достаточно рассчитать расстояние от каждой потенциальной новой позиции до уже занятой. Остальные расстояния не зависят от потенциальной новой позиции и поэтому составляют постоянный член, который можно игнорировать.

Давайте возьмем входные данные [1 0 0 0 0 0 1]в качестве примера.

l      % Push 1
       % STACK: 1
y      % Take input implicitly. Duplicate from below
       % STACK: [1 0 0 0 0 0 1], 1, [1 0 0 0 0 0 1]
f!     % Indices of nonzero elements, as a column array
       % STACK: [1 0 0 0 0 0 1], 1, [1 7]
Gn:    % Push [1 2 ... n], where n is input size (array of possible positions)
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [1 2 3 4 5 6 7]
-      % Matrix with all pairs of differences 
       % STACK: [1 0 0 0 0 0 1], 1, [1; 7], [0 -1 -2 -3 -4 -5 -6;
                                             6  5  4  3  2  1  0]
H_^    % Raise each entry to -2
       % STACK: [1 0 0 0 0 0 1], 1, [   Inf 1.0000 0.2500 0.1111 0.0625 0.0400 0.0278;
                                     0.0278 0.0400 0.0625 0.1111 0.2500 1.0000    Inf]
Xs     % Sum of each column
       % STACK: [1 0 0 0 0 0 1], 1, [Inf 1.04 0.3125 0.2222 0.3125 1.04 Inf]
&X<    % Index of minimum. Takes the first if there is a tie
       % STACK: [1 0 0 0 0 0 1], 1, 4
(      % Assign: write 1 at the position of the minimizer
       % STACK: [1 0 0 1 0 0 1]
       % Implicitly display

4

JavaScript (ES6), 89 байт

a=>a[a.map((e,i)=>!e&&(t=0,a.map((e,j)=>t+=(j-=i)&&e/j/j),t<m&&(m=t,k=i)),k=0,m=1/0),k]=1

Выходы путем изменения входного массива.


4

R 83 76 67 байт

Просто понял, что я могу сэкономить несколько байтов, не потрудившись проверить, пустые ли писсуары кандидата. Непустые писсуары всегда возвращают Infзначение дискомфорта, поэтому они исключаются в ходе расчета. Кроме того, просто используется прямое индексирование, а не replace, так что это короче, но не так элегантно.

x=scan()
x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1
x

объяснение

x=scan()

Мы читаем текущее состояние из стандартного ввода и называем его x . Мы предполагаем, что входные данные представляют собой последовательность 1s и 0s, разделенных пробелами или символами новой строки. Для целей объяснения, скажем, мы вводим 1 0 0 0 0 0 1.

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

Мы заменяем значение xв определенном индексе на 1. Все, что [ ]находится между, определяет , какой индекс лучше.

Поскольку существующие писсуары неизменны, нам не нужно учитывать расстояния между ними. Нам нужно только рассмотреть расстояния между занятыми писсуарами и возможным новым. Таким образом, мы определяем показатели занятых писсуаров. Мы используем whichфункцию для возврата индексов логического вектора, которые есть TRUE. При приведении к типу все числа в R logicalравны TRUEнулю и FALSEнулю. Простое выполнение which(x)приведет к ошибке типа argument to 'which' is not logical, как xи числовой вектор. Поэтому мы должны привести его к логическому. !является функцией логического отрицания R, которая автоматически приводит к логическому. Применяя его дважды, !!xполучаем вектор TRUEиFALSEуказывая, какие писсуары заняты. (Альтернативные побайтно-эквивалентные приведения к логическому включают в себя логические операторы &и |и встроенные функции Tи F, например, F|xили T&xи т. Д. !!xВыглядит более восклицательным, поэтому мы будем использовать это.)

                                 which(!!x)

Это в паре с seq(x), который возвращает целочисленную последовательность от 1длины x, то есть все места писсуара (и, следовательно, все возможные места для рассмотрения).

                          seq(x)

Теперь у нас есть индексы наших занятых писсуаров: 1 7и наших пустых писсуаров 1 2 3 4 5 6 7. Мы передаем `-`функцию вычитания в outerфункцию для получения «внешнего вычитания», которое представляет собой следующую матрицу расстояний между всеми писсуарами и занятыми писсуарами:

[, 1] [, 2]

[1,] 0 -6

[2,] 1 -5

[3,] 2 -4

[4,] 3 -3

[5,] 4 -2

[6,] 5 -1

[7,] 6 0

                    outer(seq(x),which(!!x),`-`)

Мы возносим это к -2власти. (Для тех, кто немного потерян, в ОП «дискомфорт» определяется как 1 / (distance(x, y) * distance(x, y)), что упрощает 1/d(x,y)^2, т d(x,y)^-2. Е. )

                    outer(seq(x),which(!!x),`-`)^-2

Возьмите сумму каждой строки в матрице.

            rowSums(outer(seq(x),which(!!x),`-`)^-2)

Получите индекс наименьшего значения, то есть оптимальный писсуар. В случае нескольких наименьших значений возвращается первое (т.е. самое левое) значение.

  which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))

И вуаля, у нас есть индекс оптимального писсуара. Мы заменяем значение в этом индексе в xс 1. В случае 1111ввода, не имеет значения, какой из них мы заменим, у нас все равно будет действительный вывод.

x[which.min(rowSums(outer(seq(x),which(!!x),`-`)^-2))]=1

Вернуть измененный ввод.

x

2

PHP, 135 байт

$a=explode(1,$argv[1]);$b=0;foreach($a as$c=>$d){$l=strlen($d);if($l>$b){$b=$l;$e=$c;}}if($b)$a[$e][intval($b/2)]=1;echo implode(1,$a);

Я уверен, что есть гораздо более быстрый способ сделать это, но у меня нечеткая голова и я не могу думать о ней!

Старый код

Код без минификации:

$a=explode(1,$argv[1]);
$b=0;
foreach($a as $c=>$d){
    $l=strlen($d);
    if($l>$b){
        $b=$l;
        $e=$c;
    }
}
if($b){
    $a[$e][intval($b/2)]=1;
}
echo implode(1,$a);

2

Python 3 223 222 165 байт

Ладно, я знаю, что это не самый красивый ответ, и я уверен, что его можно сыграть немного, но я просто возился и смотрел, что я могу сделать

Приветствую mbomb007 за советы по пробелам и компараторам. Кроме того, я увидел, что мой онлайн-счетчик символов берет все вкладки и превращает их в пробелы, так что количество намного меньше, чем у меня было изначально

def u(a):
 m,r,x=9,0,len(a)
 for i in range(x): 
    d=0
    if a[i]<'1':
     for j in range(x):
        if a[j]>'0':d+=float((j-i)**-2)
     if d<m:r=i;m=d
 return a[:r]+'1'+a[r+1:]

Отображение исправленного пробела:

def u(a):
<sp> m,r,x=9,0,len(a)
<sp> for i in range(x): 
<tab> d=0
<tab> if a[i]<'1':
<tab><sp> for j in range(x):
<tab><tab> if a[j]>'0':d+=float((j-i)**-2)
<tab><sp> if d<m:r=i;m=d
<sp> return a[:r]+'1'+a[r+1:]

Оригинал:

def u(a):
    m,r,x=9,0,len(a)
    for i in range(x): 
        d=0
        if a[i]!='1':
            for j in range(x):
                if a[j]=='1':d+=float(1/(j-i)**2)
            if d<m:r=i;m=d
    return a[:r]+'1'+a[r+1:]

Это ожидает, что строка, переданная ему 1 и 0, как "10001"и возвращает строку"10101"

Изменить: изменено 1/float((j-i)**2)наfloat((j-i)**-2)


!='1'может быть <'1'и =='1'может быть >'0'. Кроме того, рассмотрите этот совет
mbomb007

Спасибо за этот пробел. Я определенно не знал этого. Это потрясающе!
Биоласкаль

Думаю, этот пробельный совет работает только в Python 2. Возможно ранняя версия Python 3, но idk. Вы должны ограничить свой ответ Python 2 или какой-то конкретной версией 3, чтобы он работал.
mbomb007

У меня он работает в оболочке 3.5.2 в IDLE, и он работает без проблем, поэтому я думаю, что все в порядке
bioweasel

2

Python 3, 574 471 347 байт

Возможно, я над этим еще поработаю, учитывая, что другое решение Python похоже на пятую часть этого: [.

def a(I):
 D,l,r={},len(I),range
 for i in r(l):
  if I[i]<1:
   n,t,n[i]=I[:],[],1
   for j in r(l):
    if n[j]>0:
     q,Q=[],0
     for k in r(l):
      if k!=j and n[k]>0:q.append((k-j,j-k)[k<j])
     for i in q:Q+=1/(i**2)
    t.append(Q)
   T=sum(t)
   if T not in D.keys():D[T]=i
 if len(D)>0:I[D[min(D.keys())]]=1
 print(I)

Ну, теперь гораздо лучше, когда я узнал, что вы можете использовать одиночные пробелы.


1

Python, 165 163 158 147 141 140 139 байт

def u(p):e=enumerate;a=[(sum((i-j)**-2for j,y in e(p)if"0"<y),i)for i,x in e(p)if"1">x];return a and p[:min(a)[1]]+"1"+p[min(a)[1]+1:] or p

переписать вторую строку, if"1"*len(p)==p:return pчтобы сохранить байт
FlipTack
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.