Seja respeitoso no banheiro


35

Obviamente, a rede SE tem muito conhecimento de como ser respeitoso no banheiro, mas para aqueles que precisam de uma recapitulação, ser respeitoso significa liberar o vaso sanitário, etc. dos outros quanto possível.

O desafio

Dado o plano de um conjunto de barracas com indicações de quais estão em uso como uma sequência, você deve retornar ou imprimir a partir de uma função ou programa em que seja o local mais respeitoso para fazer seus negócios.

A entrada

 0 1 2 3 4 5    <- The stall number which is not actually visible in the input. 
| | |-| |-|-|   <- the stalls

As barracas são numeradas em ordem crescente da esquerda para a direita. Sempre haverá pelo menos uma barraca vazia. Pode haver até 50 barracas em uma entrada. Você também pode tirar a entrada como uma matriz ou string de 0s e 1s ou booleans se preferir fazê-lo.

As barracas em uso têm -nelas (entre os canos).

A saída

A barraca mais respeitosa de se ir é a que fica, em média, mais distante das que estão em uso. A distância entre duas barracas é o valor absoluto da diferença dos números acima delas.

Só para esclarecer: você está encontrando a distância média de todas as barracas - não apenas das vizinhas.

Você deve produzir o número mais baixo da paralisação mais respeitosa para ir para que esteja vazio .

Exemplos

Input:
|-| |-| OR 101
Output:
1

Input:
| | |-| |-|-| OR 001011
Output:
0

Input:
|-| |-| | | | |-|-| OR 101000011
Output:
1

Input: 
|-| | | | | |-|-| | | | | OR 100000110000
Output:
11

Input:
|-|-|-|-| | | | | | |-| OR 11110000001
Output:
9

Input:
|-| | OR 10
Output:
1

Input:
|-| | |-| OR 1001
Output:
1

Isso é , então o código mais curto em bytes vence!

Você pode usar a indexação baseada em 0 ou 1 em sua resposta - o que você preferir; se você usa uma indexação baseada em 1, deve dizê-lo explicitamente em sua resposta.


35
" Claro, a rede SE é muito bem informados sobre como ser respeitoso no banheiro " [carece de fontes?]
Alex A.

7
@AlexA .: Dê uma olhada nas perguntas e respostas do banheiro sobre travel.stackexchange para avaliar o nível de educação da rede SE (ou para se educar).
Jonas

30
Mas todos sabem que o critério respectfulness é maximizar a minima distância, e não a média :-)
Luis Mendo

2
@ Dopapp Você deve adicionar [1,0,0,1]como um caso de teste. Nenhum dos casos de teste atuais verifica se os vínculos foram interrompidos corretamente.
Dennis

8
Por que 101000011retornar 1 (em vez de 4 ou 5)?
Amani Kilumanga

Respostas:


11

Geléia , 10 9 bytes

JạþTS׬MḢ

Usa indexação baseada em 1. Experimente online! ou verifique todos os casos de teste .

Como funciona

JạþTS׬MḢ  Main link. Argument: A (array of Booleans)

J          Yield all indices of A.
   T       Yield all truthy indices of A.
 ạþ        Compute the table of absolute differences.
    S      Compute the sums of all columns.
           For each index, this yields the sum of all distances to occupied stalls.
     ׬    Multiply each sum by the logical NOT of the corresponding Boolean in A.
           This zeroes sums that correspond to occupied stalls.
       M   Maximal; yield an array of all indices of maximal sums.
        Ḣ  Head; extract the first index.

Acredito que são 9 caracteres, não 9 bytes.
René Nyffenegger 11/08/16

O Jelly usa uma página de código personalizada que codifica os únicos caracteres que entende como um único byte cada. O link de bytes no cabeçalho aponta para ele.
Dennis

Eu não sabia disso ... obrigado por apontar.
René Nyffenegger 11/08/16

@Dennis Você fez um auto-comentário do usercript para poder clicar em "Jelly bytes comment" e ele será publicado?
NoOneIsHere

@NoOneIsHere tenho esse script de usuário ( não o meu ), mas ainda não o adicionei. Eu provavelmente deveria ...
Dennis

6

Swift, 158, 157, 128, 100 bytes

Pega a entrada da Array<Bool>variável i, retorna resposta da última expressão.

let e=i.characters.map{$0>"0"}.enumerate()
e.flatMap{$1 ?nil:$0}.map{a in(a,e.flatMap{$1 ?$0:nil}.map{abs(a-$0)}.reduce(0){$0+$1})}.maxElement{$0.1 < $1.1}!.0

Editar 1:

Salva um byte convertendo para bools via comparação de string

let e=i.characters.map{$0=="1"}.enumerate()
e.flatMap{$1 ?nil:$0}.map{a in(a,e.flatMap{$1 ?$0:nil}.map{abs(a-$0)}.reduce(0){$0+$1})}.maxElement{$0.1 < $1.1}!.0

Edição 2:

Retrabalhei meu algoritmo:

let e=i.characters.map{$0=="1"}.enumerate()
e.map{x in(x.0,x.1 ?0:e.reduce(0){$1.1 ?$0+abs(x.0-$1.0):$0})}.max{$0.1<$1.1}!.0

Edição 3:

Aproveitou a nova regra que permite receber entradas diretamente de uma matriz booleana.

let e=i.enumerated()
e.map{x in(x.0,x.1 ?0:e.reduce(0){$1.1 ?$0+abs(x.0-$1.0):$0})}.max{$0.1<$1.1}!.0

Ungolfed:

// for the sake of easier copy/pasting of input, take it as string
let s = "100000110000"

// convert input to true for taken, false for free
// this is the input the golfed version actually uses
let input = s.characters.map{$0>"0"}

// Returns an array of tuples storing the array values (vacancy of the stall) and their index (their location)
let valueIndexPairs = bools.enumerated()

// Returns an array of pairs of locations and their avg distance to others
let locationDistancePairs = valueIndexPairs.map{(valueIndexPair: (Int, Bool)) -> (Int, Int) in

    let averageDistance = valueIndexPairs.reduce(0) {partialSum, otherStall in

        let otherStallIsTaken = otherStall.1

        if otherStallIsTaken {
            //don't let other stalls effect average if they're taken
            return partialSum
        }
        else {
            let thisStallLocation = valueIndexPair.0
            let otherStallLocation = otherStall.0
            let distanceToOtherStall = abs(thisStallLocation - otherStallLocation)
            return partialSum + distanceToOtherStall 
        }       
    }

    //if this stall is taken, treat its average distance to others as 0
    let thisStallsLocation = valueIndexPair.0
    let isThisStallTaken = valueIndexPair.1
    return (thisStallsLocation, isThisStallTaken ? 0 : averageDistance)
}

//find location where average distance is maxiumum
let bestLocationIndexPair = locationDistancePairs.max{$0.1 < $1.1}!

let bestLocation = bestLocationIndexPair.0

print(bestLocation)

2
Eu gosto de respostas rápidas
downrep_nation

É divertido aprender :) Embora tenda a ser uma linguagem bastante dolorosa para o golfe. A biblioteca padrão é realmente mínima (você deve usar o Foundation na maioria das vezes), o idioma deve ser muito expressivo e está estaticamente digitado. A sintaxe de fechamento é REALMENTE boa
Alexander - Reinstate Monica

Provavelmente eu deveria explicar como esse código funciona lol
Alexander - Reinstate Monica

11
@downrep_nation Adicionei a versão ungolfed, no caso de você estar interessado #
Alexander - Reinstate Monica

Talvez salve 3 bytes removendo o "let" idk se você precisar ou não, mas pelo que entendi você não precisa de "let", que serve apenas como um indicador de valor constante
Rohan Jhunjhunwala

5

Gelatina , 13 bytes

1 indexado.

³Tạ⁸S
JUÇÞḟTṪ

Experimente online!

Algoritmo

Implementação ingênua da questão.


lol cerca de 16 vezes mais curto que minha resposta + 1! (1! == 1)
Rohan Jhunjhunwala

@RohanJhunjhunwala O que você disse?
Leaky Nun

Essencialmente, o Java nunca pode competir com o Jelly. Ver respostas com 12 bytes de comprimento (menor que qualquer programa java possível) é hilário. Então, tenha um upgoat ..
Rohan Jhunjhunwala

@LeakyNun lol perdeu o golfe: D
Rohan Jhunjhunwala

2
1001 gera 3 quando deve retornar 2 #
Daniel Daniel

5

"Apenas" Java 270 200 196 187 196 138 148 146 bytes!

economizou 4 13 inúmeros bytes graças ao Leaky Nun! 1 byte graças a Micheal Golfed

int m(boolean[]b){int r=0,l=b.length,i,j,k=0,z=r;for(i=0;i<l;i++){if(b[i])for(j=0,k=0;j<l;j++)if(!b[j])k+=i>j?i-j:j-i;if(k>z){r=i;z=k;}}return r;}

Ungolfed

int m(int[] s) {
        int l=s.length,i,j=0,k=0;
    boolean[] b = new boolean[l];
    int[] a = new int[l];
    //see what stalls are open
    for (i = 0; i < s.length; i++) {
        if (s[i] == 0){
            b[i] = true;
        }
    }
    //assign the sum of distance to the a[]
    for (i = 0; i < l; i++) {
        if (b[i]) {
            for (j = 0; j < l; j++) {
                if (!b[j]) {
                    a[i]+= Math.abs(i - j);
                }
            }
        }
    }
    //find the stall the greatest distance away breaking ties based on the furthest left
    for (i = 0; i < l; i++) {
        if (b[i] && (a[i] > k || k == 0)) {
            k = a[i];
            j=i;
        }
    }
    //return the index
    return j;
}

entrada como uma matriz booleana em que true implica uma paralisação aberta.


Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
9788 Alex A.

Você não precisa da matriz a.
Freira vazada

@LeakyNun como removê-lo?
Rohan Jhunjhunwala

Ao encontrar o mínimo em uma iteração (combinar o exterior para loops)
Leaky Nun

oh @LeakyNun vai fazer quando eu voltar hoje
Rohan Jhunjhunwala

4

Ruby, 79 78 76 + nsinalizador = 77 bytes

A saída é indexação baseada em 0. A entrada é a linha STDIN de 0 e 1.

p (r=0...~/$/).max_by{|i|k=0;$_[i]>?0?0:r.map{|j|k+=$_[j]<?1?0:(j-i).abs};k}

11
0...~/$/é um bom truque. 👍🏻
Jordan

2

MATL , 14 bytes

~ftGf!-|Xs&X>)

Experimente online!

A saída é baseada em 1.

Explicação

~f     % Implicitly take input. Compute row vector with indices of zeros
t      % Duplicate that
Gf!    % Push input again. Compute column vector of indices of ones
-|     % Absolute differences with broadcast. Gives 2D array with all combinations
Xs     % Sum of each column
&X>    % Arg max. Gives the index of the first maximizer if there are several
)      % Index into row vector of indices of zeros. Implictly display

2

Perl 84 + 3 ( -alpsinalizadores) = 87 bytes

for$i(0..$#F){$t=0;map{$t+=abs($i-$_)*$F[$_]}0..$#F;($m,$_)=($t,$i)if$m<$t&&!$F[$i]}

Precisa de -alpsinalizadores para executar. Pega uma sequência de 1 e 0 separada por espaços como entrada. Por exemplo :

perl -alpe '$m=0;for$i(0..$#F){$t=0;map{$t+=abs($i-$_)*$F[$_]}0..$#F;($m,$_)=($t,$i)if$m<$t&&!$F[$i]}' <<< "1 0 1
0 0 1 0 1 1
1 0 1 0 0 0 0 1 1
1 0 0 0 0 0 1 1 0 0 0 0
1 1 1 1 0 0 0 0 0 0 1
1 0"

Observe que eu adicionei $m=0no início, mas isso é apenas para testá-lo em várias entradas.


Conto +7: F'' alp. -s não são contados.
NoOneIsHere

@NoOneIsHere Hum, de fato, isso seria ruim. Obrigado
Dada

2

Matlab, 87 bytes

n=input('');k=numel(n);[a b]=ndgrid(1:k);[x y]=max(sum(abs(a-b).*repmat(n,k,1)').*~n);y

Toma matriz de uns e zeros; usa indexação baseada em 1.
Como algumas outras respostas, maximiza a distância total e não a média.
Provavelmente há mais possibilidades de golfe ...


2

JavaScript (ES6), 87 86 82 75 bytes

a=>a.map((u,i)=>u||(a.map((v,j)=>u+=v*(i>j?i-j:j-i)),u>x&&(x=d,r=i)),x=0)|r

Toma uma matriz booleana (verdadeiro / falso ou 1/0). Não faz sentido calcular a distância média, pois todos eles estão usando o mesmo fator comum; portanto, basta calcular a distância total de cada estol e encontrar o primeiro índice do mais alto. Editar: salvou 1 byte usando em *vez de &&. Economizou 5 bytes localizando a maior distância manualmente com base em um comentário de @Dendrobium. Economizou 7 bytes reutilizando ucomo acumulador de pseudo-redução com base em um comentário de @ edc65.


79 bytes:a=>(x=0,a.map((o,i)=>x<(t=a.reduce((r,u,j)=>r+(b=i-j)*b*u*!o,0))&&(x=t,r=i)),r)
Dendrobium

@Dendrobium A pergunta pede distância absoluta; você parece estar calculando a distância do RMS.
Neil

11
Usando uma matriz como entrada - boa ideia. Cálculo do total em vez da média - boa ideia. Usandoreduce vez de map- mmmm
edc65

75:s=>s.map((u,i)=>u||(s.map((w,j)=>u-=w*Math.abs(j-i)),u<x&&(x=u,r=i)),x=0)|r
edc65

@ Neil Não é exatamente o RMS, apenas as distâncias ao quadrado, que não devem afetar o resultado da solução, a menos que haja ligações nas distâncias totais das entradas não simétricas (por exemplo1100011101 ligações em2 e 8quando se usa absoluto, 8quando se usa o quadrado), não que isso importe, pois parece que as regras foram esclarecidas e os laços estão agora resolvidos com mais à esquerda tenda ...
Dendrobium


1

Ruby, 87 76 bytes

Jogamos esse primeiro rascunho rapidamente juntos, mas, enquanto isso, o Value Ink já havia postado uma resposta Ruby de 80 bytes ...

edit: tirou alguns bytes com a ajuda do Value Ink:

->a{(r=0...a.size).max_by{|i|a[i]?0:r.map{|j|a[j]?(i-j).abs: 0}.reduce(:+)}}

É uma função anônima que recebe uma matriz de valores de verdade / falsidade, como por exemplo:

f=->->a{(r=0...a.size).max_by{|i|a[i]?0:r.map{|j|a[j]?(i-j).abs: 0}.reduce(:+)}}
# Test case number 5:
p f[[1, 1, 1, 1, nil, nil, nil, nil, nil, nil, 1]] # => 9

11
Atribuir a gama inicial de uma variável (r=0...a.size)e, em seguida, o mapa em que em vez de utilizar with_index: r.map{|j|a[j]?(i-j).abs: 0}. Isso deve lhe dar 78 bytes.
Value Ink

@ValueInk Awesome, obrigado! Com apenas a função, nenhuma atribuição, fico com 76 bytes
daniero

1

Mathematica, 53 bytes

MaximalBy[a=PositionIndex@#;a@0,Tr@Abs[#-a@1]&][[1]]&

Usa indexação baseada em 1 e recebe a entrada como uma lista de 0s e 1s.


0

Javascript ES6 - 98 95 91 86 84 88 bytes

Edit: Parece que o estol mais à esquerda deve ser usado em caso de empate. As distâncias quadradas não funcionam mais, revertidas para a distância absoluta.

(r,x=0,f=g=>r.reduce(g,0))=>f((p,o,i)=>x<(o=f((p,c,j)=>p+c*!o*Math.abs(i-j)))?(x=o,i):p)

Ungolfed:

(r,                            // string input
 x=0,                          // current max distance
 f=g=>r.reduce(g,0))=>         // iterator function
   f((p,o,i)=>                 // for each stall
     x<(o=f((p,c,j)=>          // iterate through all stalls and
       p+c*!o*Math.abs(i-j)))? //   calculate sum of distances from current stall
     (x=o,i):                  // if total dist is greater than x, update x, return index
     p)                        //   else return previous max index

Execuções de teste:

f=(r,x=0,f=g=>r.reduce(g,0))=>f((p,c,i)=>x<(c=+c?0:f((p,c,j)=>p+c*Math.abs(i-j)))?(x=c,i):p)
f([1,0,1])                   // 1
f([0,0,1,0,1,1])             // 0
f([1,0,1,0,0,0,0,1,1])       // 1
f([1,0,0,0,0,0,1,1,0,0,0,0]) // 11
f([1,1,1,1,0,0,0,0,0,0,1])   // 9
f([1,0])                     // 1

0

Lua, 165 150 Byes

n=arg[1]n=n:gsub("%|%-","1"):gsub("%| ","0")i=0 for s in n:gmatch("0+")do i=(i<#s)and(#s)or(i)end n,l=n:find(("0"):rep(i))print(n+math.floor((l-n)/2))

Isso engana um pouco usando o fato de que geralmente lua passa uma tabela chamada arg que contém quaisquer entradas de linha de comando para ela.

Estou um pouco decepcionado por ter usado um loop for, mas não consegui pensar em uma maneira menor de fazer isso.

Além disso, como lua, 1 indexação baseada foi usada.

Editar 15 bytes de um gsub desperdiçado.


0

C #, 127 bytes

public int G(char[]s){int i=0;var l=s.ToLookup(b=>b,b=>i++);return l['0'].OrderBy(j=>l['1'].Average(p=>Math.Abs(p-j))).Last();}

Cama de teste

public static void Main() {
    var respectful = new Respectful();
    foreach (var kvp in testCases) {
        $"{kvp.Key}: Expected {kvp.Value} Actual {respectful.G(kvp.Key.ToCharArray())}".Dump();
    }
}

public static readonly List<KeyValuePair<string, int>> testCases = new List<KeyValuePair<string, int>> {
    new KeyValuePair<string, int>("101", 1),
    new KeyValuePair<string, int>("001011", 0),
    new KeyValuePair<string, int>("101000011", 1),
    new KeyValuePair<string, int>("100000110000", 11),
    new KeyValuePair<string, int>("11110000001", 9),
    new KeyValuePair<string, int>("10", 1),
    new KeyValuePair<string, int>("1001", 1),
};

public class Respectful {
    public int G(char[]s){int i=0;var l=s.ToLookup(b=>b,b=>i++);return l['0'].OrderBy(j=>l['1'].Average(p=>Math.Abs(p-j))).Last();}
}
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.