Se respetuoso en el baño


35

Por supuesto, la red SE está muy bien informada sobre cómo ser respetuoso en el baño, pero para aquellos de ustedes que necesitan un resumen, ser respetuoso significa tirar la cadena del inodoro, etc. Lo más importante, sin embargo, es usar el puesto lo más lejos posible de otros como sea posible.

El reto

Dado un plano de un conjunto de puestos con indicaciones de cuáles están en uso como una cadena, debe devolver o imprimir desde una función o programa donde esté el lugar más respetuoso para hacer su negocio.

La entrada

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

Los puestos están numerados en orden ascendente de izquierda a derecha. Siempre habrá al menos un puesto vacío. Puede haber hasta 50 puestos en una entrada. También puede tomar la entrada como una matriz o cadena de 0sy 1s o booleanos si lo prefiere.

Los puestos en uso tienen -en ellos (entre las tuberías).

La salida

El puesto más respetuoso es el que, en promedio, está más alejado de los que están en uso. La distancia entre dos puestos es el valor absoluto de la diferencia de los números por encima de ellos.

Para ser claros: está encontrando la distancia promedio de todos los puestos, no solo de los vecinos.

Debe generar el número más bajo del puesto más respetuoso para ir a que esté vacío .

Ejemplos

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

Este es el , por lo que gana el código más corto en bytes.

Puede usar indexación basada en 0 o 1 en su respuesta, lo que prefiera; si usa una indexación basada en 1, debe decirlo explícitamente en su respuesta.


35
" Por supuesto, la red SE está muy bien informada sobre cómo ser respetuoso en el baño " [cita requerida]
Alex A.

77
@AlexA .: Eche un vistazo a las preguntas y respuestas sobre el baño en travel.stackexchange para evaluar el nivel de educación de la red SE (o para educarse).
Jonas

30
Pero todos saben que el criterio de respeto es maximizar la distancia mínima , no el promedio :-)
Luis Mendo

2
@Dopapp Debe agregar [1,0,0,1]como un caso de prueba. Ninguno de los casos de prueba actuales verifica si los lazos se rompen correctamente.
Dennis

8
¿Por qué 101000011devuelve 1 (en lugar de 4 o 5)?
Amani Kilumanga

Respuestas:


11

Jalea , 10 9 bytes

JạþTS׬MḢ

Utiliza indexación basada en 1. Pruébalo en línea! o verificar todos los casos de prueba .

Cómo 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.

Creo que son 9 caracteres, no 9 bytes.
René Nyffenegger

Jelly usa una página de códigos personalizada que codifica los únicos caracteres que entiende como un solo byte cada uno. El enlace de bytes en el encabezado apunta a él.
Dennis

No estaba al tanto de esto ... gracias por señalarlo.
René Nyffenegger

@Dennis ¿Hiciste un script de usuario con comentarios automáticos para que puedas hacer clic en "Comentario Jelly bytes" y lo publicará?
NoOneIsHere

@NoOneIsAquí tengo ese script de usuario ( no el mío ), pero aún no agregué este. Aunque probablemente debería ...
Dennis

6

Swift, 158, 157, 128, 100 Bytes

Toma información de la Array<Bool>variable i, devuelve la respuesta de la última expresión.

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:

Guardado un byte mediante la conversión a bools mediante la comparación de cadenas

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

Edición 2:

Reelaborado mi 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

Edición 3:

Aprovechó la nueva regla que permite tomar datos directamente de una 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

Sin golf:

// 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
Me gustan las respuestas rápidas
downrep_nation

Es divertido aprender :) Aunque tiende a ser un lenguaje bastante doloroso para el golf. La biblioteca estándar es realmente mínima (está destinado a usar Foundation la mayor parte del tiempo), el lenguaje está destinado a ser muy expresivo y está estáticamente escrito. La sintaxis de cierre es realmente bueno
Alexander - Restablecer Mónica

Probablemente debería explicar cómo funciona este código jajaja
Alexander - Reinstale a Monica el

1
@downrep_nation Agregué la versión sin golf, en caso de que estés interesado
Alexander - Restablece a Mónica el

Quizás ahorre 3 bytes quitando el idk "let" si lo necesita o no, pero por lo que entiendo no necesita "let", que solo sirve como indicador de un valor constante
Rohan Jhunjhunwala

5

Jalea , 13 bytes

1 indexado.

³Tạ⁸S
JUÇÞḟTṪ

Pruébalo en línea!

Algoritmo

Implementación ingenua de la pregunta.


lol alrededor de 16 veces más corto que mi respuesta + 1! (1! == 1)
Rohan Jhunjhunwala

@RohanJhunjhunwala ¿Qué dijiste?
Leaky Nun

Esencialmente, Java nunca puede competir con Jelly. Ver respuestas de 12 bytes de longitud (más cortas que cualquier programa Java posible) es muy gracioso. Así que ten un optimista ..
Rohan Jhunjhunwala

@LeakyNun lol se perdió el golf: D
Rohan Jhunjhunwala

2
1001 salidas 3 cuando debería regresar 2
Daniel

5

Java "sólo" 270 200 196 187 196 138 148 146 bytes!

ahorrado 4 13 innumerables bytes gracias a Leaky Nun! 1 byte gracias 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;}

Sin golf

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

input como una matriz booleana donde true implica una parada abierta.


Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Alex A.

No necesitas la matriz a.
Leaky Nun

@LeakyNun, ¿cómo lo elimino?
Rohan Jhunjhunwala

Al encontrar el mínimo en una iteración (combine el exterior para los bucles)
Leaky Nun

oh @LeakyNun lo hará cuando regrese hoy
Rohan Jhunjhunwala

4

Ruby, 79 78 76 + nbandera = 77 bytes

La salida es indexación basada en 0. La entrada es la línea STDIN de 0 y 1.

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

1
0...~/$/Es un buen truco. 👍🏻
Jordan

2

MATL , 14 bytes

~ftGf!-|Xs&X>)

Pruébalo en línea!

La salida está basada en 1.

Explicación

~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 ( -alpbanderas) = ​​87 bytes

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

Necesita -alpbanderas para correr. Toma una cadena de 1 y 0 separados por espacios como entrada. Por ejemplo :

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"

Tenga en cuenta que agregué $m=0al principio, pero eso es solo para probarlo en varias entradas.


Cuento +7: F'' alp. -s no se cuentan.
NoOneIsHere

@NoOneIsHere Hum, de hecho, ese sería mi mal. Gracias
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 una variedad de unos y ceros; usa indexación basada en 1.
Como algunas otras respuestas, maximiza la distancia total, no la media.
Probablemente hay más golf posible ...


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 una matriz booleana (verdadero / falso o 1/0). No tiene sentido calcular la distancia promedio ya que todos usan el mismo factor común, así que solo calcula la distancia total para cada puesto y encuentra el primer índice del más alto. Editar: guardado 1 byte usando en *lugar de &&. Ahorró 5 bytes al encontrar la distancia más alta manualmente en base a un comentario de @Dendrobium. Se guardaron 7 bytes reutilizándolos ucomo el acumulador de pseudo-reducción basado en un comentario 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 La pregunta pide una distancia absoluta; parece que estás calculando la distancia RMS.
Neil

1
Usar una matriz como entrada: buena idea. Cálculo del total en lugar del promedio: buena idea. Uso en reducelugar 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 No es exactamente RMS, solo distancias al cuadrado, lo que no debería afectar el resultado de la solución a menos que haya vínculos en las distancias totales de las entradas no simétricas (por ejemplo, 1100011101vínculos en 2y 8cuando se usa absoluto, 8cuando se usa al cuadrado), no es importante ya que parece que las reglas se han aclarado y los lazos ahora se resuelven con el puesto más a la izquierda ...
Dendrobium


1

Ruby, 87 76 bytes

Lancé este primer borrador rápidamente, pero mientras tanto Value Ink ya había publicado una respuesta de Ruby de 80 bytes ...

editar: despegó algunos bytes con la ayuda de Value Ink:

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

Es una función anónima que toma una serie de valores de verdad / falsedad, como por ejemplo:

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

1
Asignar el rango inicial a una variable (r=0...a.size)y, a continuación mapear en que en lugar de utilizar with_index: r.map{|j|a[j]?(i-j).abs: 0}. Esto debería darte 78 bytes.
Value Ink el

@ValueInk Impresionante, gracias! Con solo la función, sin asignación, obtengo 76 bytes
daniero

1

Mathematica, 53 bytes

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

Utiliza la indexación basada en 1 y toma la entrada como una lista de 0s y 1s.


0

Javascript ES6 - 98 95 91 86 84 88 bytes

Editar: Parece que el puesto más a la izquierda debe usarse en caso de empate. Las distancias al cuadrado ya no funcionan, revertidas a la distancia 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)

Sin golf:

(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

Pruebas de funcionamiento:

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

Esto engaña un poco usando el hecho de que, generalmente, lua pasa una tabla llamada arg que contiene cualquier entrada de línea de comando.

Estoy un poco decepcionado de haber usado un bucle for, pero no se me ocurrió una forma más pequeña de lograrlo.

Además, debido a lua, se usó 1 indexación basada.

Editar Snipped 15 bytes de un gsub derrochador.


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

Banco de pruebas

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();}
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.