Sii rispettoso nel bagno


35

Certo, la rete SE è molto ben informata su come essere rispettosi nel bagno, ma per quelli di voi che hanno bisogno di un riassunto, essere rispettosi significa sciacquare il gabinetto, ecc. Ancora più importante, tuttavia, significa usare la stalla lontano dagli altri possibile.

La sfida

Dato un progetto di una serie di bancarelle con le indicazioni di quali sono in uso come stringa, è necessario tornare o stampare da una funzione o un programma in cui si trova il luogo più rispettoso per fare affari.

L'input

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

Le bancarelle sono numerate in ordine crescente da sinistra a destra. Ci sarà sempre almeno una bancarella vuota. In un ingresso possono essere presenti fino a 50 bancarelle. Si può anche prendere l'input come una matrice o una stringa di 0s e 1s o booleani, se si preferisce farlo.

Le bancarelle in uso hanno -al loro interno (tra i tubi).

L'output

La bancarella più rispettosa a cui andare è quella che è in media la più lontana da quelle in uso. La distanza tra due bancarelle è il valore assoluto della differenza dei numeri sopra di essi.

Giusto per essere chiari: stai trovando la distanza media da tutte le bancarelle, non solo da quelle vicine.

È necessario emettere il numero più basso dello stallo più rispettoso per passare a quello vuoto .

Esempi

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

Questo è , quindi vince il codice più breve in byte!

Puoi utilizzare l'indicizzazione basata su 0 o 1 nella tua risposta, a seconda di quale preferisci; se usi l'indicizzazione basata su 1, devi dirlo esplicitamente nella tua risposta.


35
" Certo, la rete SE è molto ben informata su come essere rispettosi nel bagno " [citazione necessaria]
Alex A.

7
@AlexA .: Dai un'occhiata alle domande e alle risposte sulla toilette su travel.stackexchange per valutare il livello di istruzione della rete SE (o per educare te stesso).
Jonas,

30
Ma tutti sanno che il criterio di rispetto è quello di massimizzare la distanza minima , non la media :-)
Luis Mendo

2
@Dopapp Dovresti aggiungere [1,0,0,1]come test case. Nessuno dei casi di test attuali verifica se i legami sono rotti correttamente.
Dennis,

8
Perché 101000011restituisce 1 (anziché 4 o 5)?
Amani Kilumanga,

Risposte:


11

Gelatina , 10 9 byte

JạþTS׬MḢ

Utilizza l'indicizzazione basata su 1. Provalo online! o verifica tutti i casi di test .

Come funziona

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.

Credo che siano 9 caratteri, non 9 byte.
René Nyffenegger,

Jelly utilizza una tabella codici personalizzata che codifica gli unici caratteri che comprende come un singolo byte ciascuno. Il collegamento byte nell'intestazione punta ad esso.
Dennis,

Non ne ero a conoscenza ... grazie per averlo sottolineato.
René Nyffenegger,

@Dennis Hai creato un commento utente con commento automatico in modo da poter semplicemente fare clic su "Commento byte Jelly" e lo pubblicherà?
NoOneIsHere

@NoOneIsHere Ho quello script utente ( non mio ), ma non l'ho ancora aggiunto. Probabilmente dovrei però ...
Dennis,

6

Rapido, 158, 157, 128, 100 byte

Prende input dalla Array<Bool>variabile i, restituisce la risposta dall'ultima espressione.

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

Modifica 1:

Salvato un byte convertendolo in bool tramite il confronto delle stringhe

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

Modifica 2:

Rielaborato il mio 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

Modifica 3:

Ha sfruttato la nuova regola che consente di ricevere input direttamente da un array booleano.

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
Mi piacciono le risposte rapide
downrep_nation

È divertente da imparare :) Anche se tende a essere un linguaggio piuttosto doloroso per il golf. La libreria standard è davvero minimale (si intende utilizzare Foundation il più delle volte), la lingua è pensata per essere molto espressiva ed è tipizzata staticamente. La sintassi di chiusura è DAVVERO buona
Alexander - Reinstalla Monica il

Probabilmente dovrei spiegare come funziona questo codice lol
Alexander - Reinstate Monica il

1
@downrep_nation Ho aggiunto la vergogna ungolf, nel caso in cui tu sia interessato
Alexander - Reinstate Monica

Forse salva 3 byte rimuovendo "let" idk se ne hai bisogno o no, ma da quello che capisco non hai bisogno di "let" che serve solo come indicatore di un valore costante
Rohan Jhunjhunwala

5

Gelatina , 13 byte

1-indicizzati.

³Tạ⁸S
JUÇÞḟTṪ

Provalo online!

Algoritmo

Implementazione ingenua della domanda.


lol circa 16 volte più breve della mia risposta + 1! (1! == 1)
Rohan Jhunjhunwala

@RohanJhunjhunwala Che cosa hai detto?
Leaky Nun,

Essenzialmente Java non può mai competere con Jelly Vedere risposte lunghe 12 byte (più brevi di qualsiasi possibile programma java) è esilarante. Quindi abbi un upgoat ..
Rohan Jhunjhunwala il

@LeakyNun lol ha mancato il golf: D
Rohan Jhunjhunwala

2
1001 genera 3 quando dovrebbe restituire 2
Daniel

5

Java "solo" 270 200 196 187 196 138 148 146 byte!

salvato 4 13 innumerevoli byte grazie a Leaky Nun! 1 byte grazie 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;
}

input come un array booleano in cui true implica uno stallo aperto.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Alex A.

Non è necessario l'array a.
Leaky Nun,

@LeakyNun come lo rimuovo?
Rohan Jhunjhunwala,

Trovando il minimo in una iterazione (combina l'esterno per i loop)
Leaky Nun

oh @LeakyNun farà quando torno oggi
Rohan Jhunjhunwala

4

Ruby, 79 78 76 + nbandiera = 77 byte

L'output è indicizzato in base 0. L'input è la linea STDIN di 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}

1
0...~/$/è un bel trucco. 👍🏻
Giordania,

2

MATL , 14 byte

~ftGf!-|Xs&X>)

Provalo online!

L'output è basato su 1.

Spiegazione

~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 ( -alpflag) = 87 byte

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

Ha bisogno delle -alpbandiere per funzionare. Accetta una stringa di 1 e 0 separati da spazi come input. Per esempio :

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"

Si noti che ho aggiunto $m=0all'inizio, ma questo è solo per testarlo su più voci.


Io conto +7: F'' alp. -non vengono conteggiati.
NoOneIsHere

@NoOneIsHere Hum, davvero, sarebbe il mio male. Grazie
Dada,

2

Matlab, 87 byte

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

Accetta array di uno e zeri; utilizza l'indicizzazione basata su 1.
Come alcune altre risposte massimizza la distanza totale non media.
Probabilmente c'è più golf possibile ...


2

JavaScript (ES6), 87 86 82 75 byte

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

Accetta un array booleano (true / false o 1/0). Non ha senso calcolare la distanza media poiché usano tutti lo stesso fattore comune, quindi basta calcolare la distanza totale per ogni stallo e trovare il primo indice di quello più alto. Modifica: 1 byte salvato utilizzando *invece di &&. Hai salvato 5 byte trovando manualmente la distanza massima in base a un commento di @Dendrobium. Salvato 7 byte riutilizzandoli ucome accumulatore pseudo-ridotto sulla base di un commento di @ edc65.


79 byte: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 domanda richiede una distanza assoluta; sembra che tu stia calcolando la distanza RMS.
Neil,

1
Utilizzo di un array come input - buona idea. Calcolo del totale anziché della media - buona idea. Usando reduceinvece di 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 Non proprio RMS, ma solo distanze quadrate, che non dovrebbero influire sul risultato della soluzione a meno che non ci siano legami nelle distanze totali di input non simmetrici (ad esempio 1100011101legami con 2e 8quando si usa assoluto, 8quando si usa il quadrato), non che contino dal sembra che le regole siano state chiarite e che i legami siano ora risolti con lo stallo più a sinistra ...
Dendrobium


1

Rubino, 87 76 byte

Ho lanciato questa prima bozza rapidamente insieme, ma nel frattempo Value Ink aveva già pubblicato una risposta Ruby da 80 byte ...

modifica: rimosso alcuni byte con l'aiuto di Value Ink:

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

It's an anonymous function that takes an array of truthy/falsy values, like for instance so:

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
Assign the initial range to a variable (r=0...a.size) and then map on that instead of using with_index: r.map{|j|a[j]?(i-j).abs: 0}. This should get you 78 bytes.
Value Ink

@ValueInk Awesome, thanks! With only the function, no assignment, I get 76 bytes
daniero

1

Mathematica, 53 bytes

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

Uses 1-based indexing and takes input as a list of 0s and 1s.


0

Javascript ES6 - 98 95 91 86 84 88 bytes

Edit: Seems that the leftmost-stall should be used in the case of a tie. Squared distances no longer work, reverted to absolute distance.

(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

Test runs:

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

This cheats a little using the fact that generally, lua passes a table called arg containing any command line inputs to it.

I'm a bit disappointed that I used a for in loop, but I couldn't think of a smaller way to pull it off.

Also, Because lua, 1 based indexing was used.

Edit Snipped 15 bytes from a wasteful gsub.


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

Test Bed

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();}
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.