Scrivi una funzione che ti dice quali DUE delle sue linee sono state rimosse


19

Nella mia precedente sfida sul codice , ti avevo chiesto di scrivere una funzione che ti dicesse quale delle sue linee è stata rimossa.

Le istruzioni erano:

Scrivi una funzione che contiene cinque righe.

Se si esegue la funzione così com'è, dovrebbe restituire 0.

Se rimuovi una delle cinque righe ed esegui la funzione, dovrebbe dirti quale delle righe è stata rimossa (ad esempio, se rimuovi l'ultima riga dovrebbe restituire 5).

Ora proviamo qualcosa di un po 'più difficile.

Seguire le stesse regole di cui sopra, ma questa volta la funzione dovrebbe restituire un array che indica quali DUE linee sono state rimosse.

Ad esempio, se rimuovo le righe 1 e 5, il valore restituito dovrebbe essere [1,5] e se rimuovo le righe 3 e 4, il valore restituito dovrebbe essere [3,4].

Ancora una volta, se nessuna riga viene rimossa, la funzione dovrebbe restituire 0. Punti bonus se puoi anche gestire il caso rimosso di una riga, ma non è strettamente necessario farlo.

Puoi utilizzare le funzioni di supporto? Sì, ma solo se devi. Una singola funzione autonoma che lo risolve è l'ideale.

Come con l'ultima sfida, vince la soluzione con il punteggio più alto. Prenderò il vincitore tra una settimana o prima se entro 24 ore non saranno pervenuti nuovi invii.


2
Restituire un elenco vuoto è OK se non vengono rimosse le righe o deve essere il numero 0?
Ilmari Karonen,

1
la linea di ritorno nella funzione è una delle linee che possono essere rimosse?
le_vine,

11
Possiamo aspettarci che domani venga pubblicata la versione "tre righe"?
Howard,

La funzione deve letteralmente restituire l'array o può modificare una variabile nell'ambito globale .etc? Non penso che ciò sia possibile in 5 righe mentre in realtà si ritorna perché non è possibile guardare avanti poiché tutte le righe devono tornare in caso di rimozione del reso. A meno che non ci siano alcune stranezze linguistiche come le funzioni di ritorno automatico che non conosco.
George Reith,

Penso che dovresti anche fornire il link alla tua domanda precedente, come per qualcuno che è interessato e non l'ha visto.
DroidDev,

Risposte:


17

Perl

sub foo {
    @a = (2..5);
    @a = grep $_ != 2, (@a ? @a : (1..5));
    @a = grep $_ != 3, (@a ? @a : (1..5));
    @a = grep $_ != 4, (@a ? @a : (1..5));
    @a = grep $_ != 5, (@a ? @a : (1..5));
}

Questo funziona effettivamente per qualsiasi numero di linee rimosse (purché non siano tutte le linee, cioè), e può essere banalmente esteso a più di 5 linee. Non viene utilizzata alcuna funzione di supporto e utilizza anche solo un'istruzione per riga. Si basa sul fatto che, in assenza di un'istruzione esplicita return, il valore restituito di una funzione Perl è il valore dell'ultima istruzione in essa.

Si noti che (nel contesto dell'elenco) questo codice restituisce un elenco vuoto anziché il numero 0 se non sono state eliminate righe. Questo potrebbe essere risolto (ad es. Aggiungendo " @a ? @a : 0;" all'ultima riga), ma renderebbe il codice più brutto. In ogni caso, a scalare contesto fa restituire il numero di righe cancellate, che saranno 0 se nessuna riga sono stati rimossi. ;-)


9

Rubino

Simile alla versione Perl, ma in Ruby. Restituisco 0 se nessuna riga viene eliminata come richiesto, ma sono d'accordo che rende il codice più brutto e non ha senso come valore di ritorno.

def which_lines_removed(arr = [*1..5])
  arr -= [1]
  arr -= [2] 
  arr -= [3] 
  arr -= [4] 
 (arr -= [5]).empty? ? 0 : arr
end

Se un array vuoto è accettabile come valore di ritorno quando non vengono eliminate righe, il codice è simile al seguente:

def which_lines_removed(arr = [*1..5])
  arr -= [1]
  arr -= [2] 
  arr -= [3] 
  arr -= [4] 
  arr -= [5]
end

Entrambi i metodi funzionano per qualsiasi numero di righe eliminate tra 0 e 5.


4

JavaScript, 152 caratteri giocati a golf

function t() {
    var fa = (f + '').match(/\d/g)
    var ra = []
    for (var i = 0; i < 5; i++) {
        if (fa.indexOf(i + '') < 0) ra.push(i + 1)
    }
    return ra
}

function f() {
    0; return t()
    1; return t()
    2; return t()
    3; return t()
    4; return t()
}

golfed:

function t(){for(a=[],i=0;++i<5;)if((f+'').indexOf(i)<0)a.push(i+1);return a}function f(){
return t(0)
return t(1)
return t(2)
return t(3)
return t(4)
}

Autonomo (ma brutto):

function f() {
    0; var ra = []; for (var i = +![]; i < 5; i++) if ((f + '').match(/\d/g).indexOf(i + '') < +![]) ra.push(i); return ra
    1; var ra = []; for (var i = +![]; i < 5; i++) if ((f + '').match(/\d/g).indexOf(i + '') < +![]) ra.push(i); return ra
    2; var ra = []; for (var i = +![]; i < 5; i++) if ((f + '').match(/\d/g).indexOf(i + '') < +![]) ra.push(i); return ra
    3; var ra = []; for (var i = +![]; i < 5; i++) if ((f + '').match(/\d/g).indexOf(i + '') < +![]) ra.push(i); return ra
    4; var ra = []; for (var i = +![]; i < 5; i++) if ((f + '').match(/\d/g).indexOf(i + '') < +![]) ra.push(i); return ra
}

Fondamentalmente sfrutta la funzione toStringnumerando ogni riga. Nota che devi effettivamente rimuovere la linea per questo (commentarla non funzionerà).

Questo funziona effettivamente per qualsiasi numero di linee rimosse ! Restituirà una matrice delle linee rimosse o una matrice vuota se nessuna è stata rimossa. (Potrei facilmente cambiarlo per restituire zero (sostituendolo return racon return ra || 0), ma mi piace la soluzione array vuota poiché sarebbe più utile nel mondo reale.)

Ad esempio, la rimozione della prima riga restituisce [1]e la rimozione di tutto tranne la prima riga [2,3,4,5]. (Naturalmente, non funziona se si rimuovono tutte le linee;-) )


3

Rubino

def f
    a = [ 2, 3, 4, 5 ]
    defined?(a) ? a = a.select { |num|    num != 2 } : a = [ 1, 3, 4, 5 ]
    defined?(a) ? a = a.select { |num|    num != 3 } : a = [ 1, 2, 4, 5 ]
    a = a.select { |num|    num != 4 }
    (a = a.select { |num|    num != 5 }) == [] ? a = 0 : a
end

Come funziona: la mia idea era: creare un array e, su ogni riga, rimuovere un valore specifico. Quindi, sulla prima riga, ho effettivamente l'array [ 1, 2, 3, 4, 5], con l'elemento 1rimosso. Alla seconda riga, se aè già definito, rimuovere l'elemento 2. Altrimenti, crea un nuovo array con l'elemento 2rimosso. Fare lo stesso per la riga 3. Alla riga 4, si può essere sicuri che sia già stata creata una matrice, quindi rimuovere l'elemento 4. Alla riga 5, rimuovere prima l'elemento 5, e se aè quindi un array vuoto, restituire 0. Altrimenti, ritorna a.


3

Pitone

f=lambda:{1,2,3,4,5}-{
1,
2,
3,
4,
5,
} or 0

Restituisce 0 se nessuna riga viene rimossa, altrimenti restituisce le righe rimosse. Puoi rimuovere da 1 a 5 righe, tranne la 0a e la 6a riga ;-).


2

JavaScript, autonomo, funziona per 0, 1, 2 righe rimosse ( 607  315 186 caratteri)

demo live

Abusare del sollevamento variabile JS e delle perdite globali, come nell'altra sfida :)

function(r){
r.shift();
r.splice(r.indexOf(2),1)
r.splice(r.indexOf(3),1);a=b=1;if(this.a&&this.b)return r
var a;r.splice(r.indexOf(4),1);b=1;if(this.b)return r
var b;r.pop();return r[0]?r:0
}

da chiamare con l'array [1,2,3,4,5] come parametro.

315 caratteri

function(r){
var a;
var b;
var c;a=1;b=2;d=4;e=5;for(i in(z="abde".split("")))if(y=this[z[i]])r.push(y);return r.length?r:0
var d;a=1;b=2;c=3;e=5;for(i in(z="abce".split("")))if(y=this[z[i]])r.push(y);return r.length?r:0
var e;a=1;b=2;c=3;d=4;for(i in(z="abcd".split("")))if(y=this[z[i]])r.push(y);return r.length?r:0
}

da chiamare con un array vuoto come parametro.



versione non golfata

(funziona anche per 3 e 4 righe rimosse):

function(r){
var a;b=c=d=e=1;if(this.b)r.push(2);if(this.c)r.push(3);if(this.d)r.push(4);if(this.e)r.push(5);return r.length?r:0;
var b;a=c=d=e=1;if(this.a)r.push(1);if(this.c)r.push(3);if(this.d)r.push(4);if(this.e)r.push(5);return r.length?r:0;
var c;a=b=d=e=1;if(this.a)r.push(1);if(this.b)r.push(2);if(this.d)r.push(4);if(this.e)r.push(5);return r.length?r:0;
var d;a=b=c=e=1;if(this.a)r.push(1);if(this.b)r.push(2);if(this.c)r.push(3);if(this.e)r.push(5);return r.length?r:0;
var e;a=b=c=d=1;if(this.a)r.push(1);if(this.b)r.push(2);if(this.c)r.push(3);if(this.d)r.push(4);return r.length?r:0;
}

da chiamare con un array vuoto come parametro.


2

JavaScript:

var f = function(){
    1
    2
    a=[];for(i=0;i++<6;){if((f+'').indexOf(i)<0){a.push(i)}}return a.length?a:0;3
    a=[];for(i=0;i++<6;){if((f+'').indexOf(i)<0){a.push(i)}}return a.length?a:0;4
    a=[];for(i=0;i++<6;){if((f+'').indexOf(i)<0){a.push(i)}}return a.length?a:0;5
}

violino


2

Javascript

(function (i){

i += .1;     // line 1
i += .02;    // line 2
i += .003;   // line 3
i += .0004;  // line 4
i += .00005; // line 5

return (Math.round((.12345-i)*100000)/100000+'').match(/([1-5])/g) || 0 })(0)

Chiamalo come ti piace, ma penso che sia carino .

Ti consente di sapere quali linee sono state rimosse (1 o più) o 0 se nessuna linea è stata rimossa. Tutte e 5 le linee possono essere rimosse.

MODIFICARE:

Poiché è stato portato alla mia attenzione che il mio codice potrebbe effettivamente essere composto da 6 righe ed è in violazione delle regole, l'ho modificato come segue:

(Math.round((.12345 - (new (function(){

    this.i = isFinite(this.i) ? this.i + .1 : .1 ;
    this.i = isFinite(this.i) ? this.i + .02 : .02;
    this.i = isFinite(this.i) ? this.i + .003 : .003; 
    this.i = isFinite(this.i) ? this.i + .0004 : .0004;
    this.i = isFinite(this.i) ? this.i + .00005 : .00005; 

})().i || 0) )*100000)/100000+'').match(/([1-5])/g) || 0

Lo stesso vale - restituirà un array di linee rimosse vanno da 1- Tutto o 0 se nessuno.


Non sono sicuro che possa aiutare, ma ho notato che altri lo fanno, quindi ... Il mio è di 149 caratteri con spaziatura e 128 senza.
logic8,

Dal momento che non è un codice-golf, non è necessario rimuovere gli spazi bianchi.
Timtech,

1
La riga "return" è all'interno della funzione, quindi la funzione ha in realtà sei righe di codice, il che viola le regole della sfida.
Jawns317,

@ jawns317, non sono sicuro di come sia definita una "linea". Qualcuno potrebbe fornire una definizione chiara?
logic8,

@ logic8 Rimuovi function(){e }(e tutte le funzioni di supporto). Conta il numero di righe.
Maniglia della porta

1

Lisp comune

(defun which-lines-are-removed (&aux (x (list 1 2 3 4 5))) 
  (setq x (remove-if #'(lambda (x) (eql x 1)) x))
  (setq x (remove-if #'(lambda (x) (eql x 2)) x))
  (setq x (remove-if #'(lambda (x) (eql x 3)) x))
  (setq x (remove-if #'(lambda (x) (eql x 4)) x))
  (setq x (remove-if #'(lambda (x) (eql x 5)) x))
)

Funziona per la rimozione di 1-4 linee. Se rimuovi tutte le righe, verrà restituito come se non ne rimuovessi nessuna.

NB: Avere la parentesi finale sulla propria riga è considerato un cattivo stile, ma dal momento che altre lingue hanno ende }presumo che sia permesso.


1

Pitone

def function(a = [1,2,3,4,5]):
    delete(a, len(a)-5)#1
    delete(a, len(a)-4)#2
    delete(a, len(a)-3);print a if len(a)==2 else '',#3
    delete(a, len(a)-2);print a if len(a)==2 else '',#4
    delete(a, len(a)-1);print a if len(a)==2 else '',#5

def delete(a, i):
    del a[i]
    return a

Funziona per tutte le righe, ma solo se due vengono eliminate. Se viene eliminata solo una riga, verranno stampate la riga e la riga eliminate 5. Se vengono eliminate troppe righe, non verrà stampato nulla.

Questo utilizza una funzione di supporto perché la parola chiave del non può essere utilizzata in una riga con un; (per quanto ne so)

Fondamentalmente, ogni riga si elimina nell'array dichiarato nel costruttore, quindi se sono state eliminate abbastanza righe l'array viene stampato.

Questa funzione non soddisfa le specifiche in due modi:

  1. non stampa 0 se viene eseguito così com'è (presuppone che le ultime due righe siano state commentate e quindi stampa 4, 5
  2. Presuppone che printe returnsono intercambiabili

Will facendo print ''non generare un carattere aggiuntivo a capo però?
SimonT,

1

Già visto

Funziona per rimuovere qualsiasi numero di righe (purché si lasci almeno una riga)

local line n:
    try:
        dup
    catch stack-empty:
        dup set{ 1 2 3 4 5 }
    delete-from swap n

func which-gone:
    line 1
    line 2
    line 3
    line 4
    line 5

0

R

Ho un'altra versione in R che penso sia migliore (ma usa una funzione di supporto):

trick <- function(sym, value) {
  assign(sym, value, envir=parent.frame())
  values <- unlist(as.list(parent.frame()))
  if(length(values)==5) 0 else which(!1:5 %in% values)
}

reportRemovedLines <- function(){
  trick("a", 1)
  trick("b", 2)
  trick("c", 3)
  trick("d", 4)
  trick("e", 5)
}

Oppure si può evitare di usare la funzione helper definendola come argomento predefinito (funziona in modo identico ma è meno leggibile, tuttavia non utilizza una funzione helper "definita separatamente"):

funnyVersion <- function(trick = function(sym, value) {
  assign(sym, value, envir=parent.frame())
  values <- unlist(as.list(parent.frame()))
  if(length(values)==5) 0 else which(!1:5 %in% values)
}){
  trick("a", 1)
  trick("b", 2)
  trick("c", 3)
  trick("d", 4)
  trick("e", 5)
}

Sia reportRemovedLines()e funnyVersion()lavorare con qualsiasi numero di linee rimossi - tranne se si rimuove tutte le linee (in quel caso, torneranno NULL). In realtà restituiscono i numeri di riga, non solo stampandoli - come in R, verrà restituito automaticamente il valore dell'ultima espressione valutata all'interno di una funzione.

Come funziona? Il trucco sta nella trickfunzione che prende tutti gli oggetti dal suo "ambiente genitore" (cioè, l'ambiente della funzione che lo chiama), riunisce i loro valori in un vettore e restituisce, i cui valori da 1 a 5 non sono rappresentati.


0

JavaScript (136/166 caratteri)

Una versione più piccola con alcuni valori dichiarati all'inizio:

function(){b=[1,2,3,4,5],i=0
    b.splice(0,1);i++
    b.splice(1-i,1);i++
    b.splice(2-i,1);i++
    b.splice(3-i,1);i++
    b.splice(4-i,1);i++
return b}

Una versione autonoma (non è necessario passare nulla: l'argomento b è lì, quindi posso verificare se b è definito con ||)

function(b){
    b=[2,3,4,5],i=1
    b=b||[1,2,3,4,5],i=i||0,b.splice(1-i,1);i++
    b=b||[1,2,3,4,5],i=i||0,b.splice(2-i,1);i++
    b.splice(3-i,1);i++
    b.splice(4-i,1);i++
return b}

Sì, entrambi hanno returndichiarazioni, ma questo è giusto solo se sono in competizione con le lingue con ritorno implicito.


È vero, è più facile in quelle lingue, ma non è impossibile in JS. Non ritengo che nessuno di questi abbia soddisfatto i vincoli della sfida, poiché la tua versione da 136 caratteri ha sette righe di codice all'interno della funzione e la versione da 166 caratteri ha sei. Il fatto che tu abbia il codice sulla stessa riga delle parentesi aperte o chiuse non significa che il codice non faccia parte della funzione.
Jawns317,

Che dire delle risposte che usano gli helper?
Bobby Marinoff,

Le funzioni di supporto sono esplicitamente consentite. Ma la funzione da cui vengono rimosse le righe dovrebbe contenere cinque righe di codice.
jawns317,

0

R

Una versione semplice (non infallibile in quanto si otterrà un errore se si rimuove la riga 5):

doit <- function() setdiff(1:5, c(
       1,
       2,
       3,
       4,
       5
    ))

E una versione infallibile:

doit<-function() setdiff(1:5, scan(text="
1
2
3
4
5
"))

Funziona con qualsiasi numero di linee rimosse (tranne se si rimuovono tutte le linee) e può essere facilmente esteso a più di 5 linee. Eseguendolo "così com'è" verrà restituito integer(0)che è concettualmente simile al ritorno giusto 0. Restituire uno 0 reale lo renderebbe più brutto e più lungo ma non sarebbe complicato.

Finalmente una versione che usa la magia:

Funzione di supporto:

dysfunction <- function(E){
    FUN <- function(){}
    e <- substitute(E)
    e[[1]] <- as.name("list")
    nb <- quote(setdiff(as.list(1:5), x))
    nb[[3]] <- e
    body(FUN) <- nb
    FUN
    }

La funzione attuale:

df <- dysfunction({
1
2
3
4
5
})

0

C ++

void function(int & i)
{
        i=i|1;
        i=i|2;
        i=(i|4);
        i=(i|8);
        i=(i|16);
} 


int[] func2(int i)
{
    int arr[]={0,0};
    int k=0,l=1;
    for(int j=1;j<=16;j*=2,l++)
    {
        if((i&j)==0)
        {
             arr[k++]=l;
        }
    }
    return arr;
}

Come usare: chiama la funzione con i e usa func2 per capire quale funzione sta dicendo.

Se modifichi la riga int arr [] = {0,0} in int arr [] = {0,0,0,0,0} funzionerà anche per tutte e cinque le righe, verrà anche descritto come una riga rimuovi test case automaticamente, quello che sto facendo è semplicemente usare un po 'di una variabile come bandiera per ogni linea ....


Non functionha sei righe, non cinque?
Cel Skeggs,

il ritorno non fa parte di questo, puoi vedere anche altre risposte ... è dipendenza dalla lingua
zeeshan mughal

Vedi questo commento dell'autore della sfida su una delle altre voci: "Vero, è più facile in quelle lingue, ma non è impossibile in JS. Non considero nessuno di questi aver incontrato i vincoli della sfida, dal momento che la tua versione da 136 caratteri ha sette righe di codice all'interno della funzione e la versione da 166 caratteri ne ha 6. Il fatto che tu abbia il codice sulla stessa riga delle parentesi aperta o chiusa non significa che il codice non faccia parte di la funzione. - jawns317 "
Cel Skeggs

controllalo ora e dimmi la tua risposta
Zeeshan Mughal,

C non funziona così. Dà un errore del compilatore. Probabilmente stai pensando al C ++.
Cel Skeggs,
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.