Escriba una función que le indique cuáles DOS de sus líneas se han eliminado.

19

En mi desafío de código anterior , le pedí que escribiera una función que le diga cuál de sus líneas se ha eliminado.

Las instrucciones fueron:

Escribe una función que contenga cinco líneas.

Si ejecuta la función tal como está, debería devolver 0.

Si elimina cualquiera de las cinco líneas y ejecuta la función, debería indicarle cuál de las líneas se ha eliminado (por ejemplo, si elimina la línea final, debería devolver 5).

Ahora, intentemos algo un poco más difícil.

Siga las mismas reglas que anteriormente, pero esta vez, la función debería devolver una matriz que le indica qué DOS líneas se han eliminado.

Entonces, por ejemplo, si elimino las líneas 1 y 5, el valor de retorno debería ser [1,5], y si elimino las líneas 3 y 4, el valor de retorno debería ser [3,4].

Nuevamente, si no se eliminan líneas, la función debería devolver 0. Puntos de bonificación si también puede manejar el caso de eliminación de una línea, pero no es estrictamente necesario que lo haga.

¿Puedes hacer uso de las funciones de ayuda? Sí, pero solo si es necesario. Una única función autónoma que lo lleva a cabo es lo ideal.

Al igual que con el último desafío, gana la solución más votada. Elegiré al ganador en una semana, o antes si no se han recibido nuevos envíos en 24 horas.

jawns317
fuente
2
Está volviendo una lista vacía bien si se eliminan sin líneas, o se tiene que ser el número 0?
Ilmari Karonen
1
¿Es la línea de retorno en la función una de las líneas que se pueden eliminar?
le_vine
11
¿Podemos esperar que mañana se publique la versión "tres líneas"?
Howard
¿Debe la función devolver literalmente la matriz o puede editar una variable en el ámbito global .etc? No creo que esto sea posible en 5 líneas mientras se regresa debido a que no se puede mirar hacia adelante, ya que todas las líneas deben regresar en caso de que se elimine la devolución. A menos que haya algunas peculiaridades del lenguaje como las funciones de retorno automático que no conozco.
George Reith
Creo que también debe proporcionar el enlace a su pregunta anterior, como para alguien que está interesado y no lo ha visto.
DroidDev

Respuestas:

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

En realidad, esto funciona para cualquier número de líneas eliminadas (siempre que no sean todas las líneas, es decir), y puede extenderse trivialmente a más de 5 líneas. No se utilizan funciones auxiliares, e incluso solo utiliza una instrucción por línea. Se basa en el hecho de que, en ausencia de una returndeclaración explícita , el valor de retorno de una función Perl es el valor de la última declaración en ella.

Tenga en cuenta que (en el contexto de la lista) este código devuelve una lista vacía en lugar del número 0 si no se han eliminado líneas. Esto podría solucionarse (por ejemplo, agregando "@a ? @a : 0; " a la última línea), pero haría el código más feo. En cualquier caso, en escalar contexto se hace devolver el número de líneas eliminadas, lo que será 0 si no se ha eliminado ninguna línea. ;-)

Ilmari Karonen
fuente
9

Rubí

Similar a la versión de Perl, pero en Ruby. Devuelvo 0 si no se eliminan líneas según lo solicitado, pero estoy de acuerdo en que hace que el código sea más feo y no tiene sentido como valor de retorno.

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

Si una matriz vacía es aceptable como valor de retorno cuando no se eliminan líneas, el código se ve así:

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

Ambos métodos funcionan para cualquier número de líneas eliminadas entre 0 y 5.

OI
fuente
4

JavaScript, 152 caracteres golfizados

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

Golfizado:

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

Autocontenido (pero feo):

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
}

Básicamente explota la función toString numerando cada línea. Tenga en cuenta que realmente tiene que eliminar la línea debido a esto (comentarlo no funcionará).

¡Esto realmente funciona para cualquier número de líneas eliminadas ! Devolverá una matriz de las líneas eliminadas, o una matriz vacía si no se ha eliminado ninguna. (Podría cambiar fácilmente eso para devolver cero (reemplazando return racon return ra || 0), pero me gusta la solución de matriz vacía, ya que sería más útil en el mundo real).

Por ejemplo, eliminar la primera línea devuelve [1]y eliminar todo excepto la primera línea [2,3,4,5]. (Por supuesto, no funciona si elimina todas las líneas ;-))

Pomo de la puerta
fuente
3

Rubí

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

Cómo funciona esto: mi idea era: crear una matriz y, en cada línea, eliminar un valor específico. Entonces, en la primera línea, realmente tengo la matriz [ 1, 2, 3, 4, 5], con el elemento 1eliminado. En la segunda línea, si aya está definido, elimine el elemento 2. De lo contrario, cree una nueva matriz con el elemento 2eliminado. Haga lo mismo para la línea 3. En la línea 4, puede estar seguro de que ya hay una matriz creada, así que simplemente elimine el elemento 4. En la línea 5, primero elimine el elemento 5, y si aes una matriz vacía, regrese 0. De lo contrario, regrese a.

ProgramFOX
fuente
3

Pitón

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

Devuelve 0 si no se elimina ninguna línea; de lo contrario, devuelve las líneas eliminadas. Puede eliminar de 1 a 5 líneas, excepto la línea 0 y 6 ;-).

Daniel
fuente
2

JavaScript, autónomo, funciona para 0, 1, 2 líneas eliminadas ( 607  315 186 caracteres)

demostración en vivo

Abusar de la elevación variable JS y la fuga global, como en el otro desafío :)

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
}

para ser llamado con la matriz [1,2,3,4,5] como parámetro.

315 caracteres

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
}

para ser llamado con una matriz vacía como parámetro.



versión sin golf

(también funciona para 3 y 4 líneas eliminadas):

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

para ser llamado con una matriz vacía como parámetro.

xem
fuente
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
}

violín

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

Llámalo como quieras, pero creo que es bonito .

Le permite saber qué líneas se eliminaron (1 o más) o 0 si no se eliminan las líneas. Las 5 líneas se pueden eliminar.

EDITAR:

Debido a que se me hizo notar que mi código en realidad podría constar de 6 líneas y viola las reglas, lo ajusté a lo siguiente:

(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 mismo se aplica: devolverá una matriz de líneas eliminadas que van desde 1- Todo o 0 si no hay ninguna.

lógica8
fuente
No estoy seguro de si va a ayudar, pero noté que otros lo hacían, así que ... El mío tiene 149 caracteres con espaciado y 128 sin él.
logic8
Como no es un código de golf, no necesita eliminar el espacio en blanco.
Timtech
1
La línea de "retorno" está dentro de la función, por lo que la función en realidad tiene seis líneas de código, lo que viola las reglas del desafío.
jawns317
@ jawns317, no estoy seguro de cómo se define una "línea". ¿Podría alguien proporcionar una definición clara?
logic8
@ logic8 Eliminar function(){y }(y cualquier función auxiliar). Cuenta el número de líneas.
Pomo de la puerta
1

Lisp común

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

Funciona para la eliminación de 1-4 líneas. Si elimina todas las líneas, devolverá lo mismo que si no eliminara ninguna.

NB: Tener paréntesis finales en su propia línea se considera un mal estilo, pero dado que otros idiomas lo tienen endy }supongo que está permitido.

Sylwester
fuente
1

Pitón

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

Funciona para todas las líneas, pero solo si se eliminan dos. Si solo se elimina una línea, imprimirá la línea eliminada y la línea 5. Si se eliminan demasiadas líneas, no imprimirá nada.

Esto usa una función auxiliar porque la palabra clave del no se puede usar en una línea con a; (que yo sepa)

Básicamente, cada línea se elimina a sí misma en la matriz que se declara en el constructor, luego, si se han eliminado suficientes líneas, se imprime la matriz.

Esta función pierde la especificación de dos maneras:

  1. no imprime 0 si se ejecuta tal cual (supone que las dos últimas líneas han sido comentadas y, por lo tanto, imprime 4, 5
  2. Asume eso printy returnson intercambiables
jcw
fuente
Sin print ''embargo, ¿no generará un personaje adicional de nueva línea?
SimonT
1

Deja Vu

Funciona para eliminar cualquier número de líneas (siempre que deje al menos una línea)

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
Jasmijn
fuente
0

R

Tengo otra versión en R que creo que es mejor (pero usa una función auxiliar):

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

O se puede evitar el uso de la función auxiliar definiéndola como un argumento predeterminado (funciona de manera idéntica pero es menos legible; sin embargo, no utiliza una función auxiliar "definida por separado"):

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

Ambos reportRemovedLines()y funnyVersion()funcionan con cualquier número de líneas eliminadas, excepto si elimina todas las líneas (en ese caso, volverán NULL). En realidad, devuelven los números de línea, no solo los imprimen, como en R, el valor de la última expresión evaluada dentro de una función se devolverá automáticamente.

¿Como funciona? El truco está en la trickfunción que toma todos los objetos de su "entorno principal" (es decir, el entorno de la función que lo llama), pone sus valores juntos en un vector y devuelve, cuyos valores del 1 al 5 no están representados.

lebatsnok
fuente
0

JavaScript (136/166 caracteres)

Una versión más pequeña con algunos valores declarados al principio:

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 versión autónoma (no necesita pasar nada; el argumento b está ahí para que pueda verificar si b está definido 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í, ambos tienen returndeclaraciones, pero eso es justo si estoy compitiendo con idiomas con retorno implícito.

Bobby Marinoff
fuente
Es cierto, es más fácil en esos idiomas, pero no es imposible en JS. No considero que ninguno de estos haya cumplido las restricciones del desafío, ya que su versión de 136 caracteres tiene siete líneas de código dentro de la función, y su versión de 166 caracteres tiene seis. El hecho de que tenga código en la misma línea que los corchetes de apertura o cierre no significa que el código no sea parte de la función.
jawns317
¿Qué pasa con las respuestas que usan ayudantes?
Bobby Marinoff
Las funciones auxiliares están explícitamente permitidas. Pero la función de la que se eliminan las líneas debe contener cinco líneas de código.
jawns317
0

R

Una versión simple (no infalible ya que obtendrá un error si elimina la línea 5):

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

Y una versión infalible:

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

Funciona con cualquier número de líneas eliminadas (excepto si elimina todas las líneas), y puede extenderse fácilmente a más de 5 líneas. Ejecutarlo "tal cual" regresará, lo integer(0)cual es conceptualmente similar a regresar solo0 . Devolver un 0 real lo haría más feo y largo, pero no sería complicado.

Finalmente, una versión que usa magia:

Función auxiliar:

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 función real:

df <- dysfunction({
1
2
3
4
5
})
lebatsnok
fuente
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;
}

Cómo usar: llame a la función con i y use func2 para comprender lo que dice la función.

Si cambia la línea int arr [] = {0,0} a int arr [] = {0,0,0,0,0} también funcionará para las cinco líneas, también es handline una línea eliminar caso de prueba automáticamente, lo que estoy haciendo es simplemente usar bits de una variable como bandera para cada línea ...

Zeeshan Mughal
fuente
¿No functiontiene seis líneas, no cinco?
Cel Skeggs
el retorno no es parte de eso, puedes ver otras respuestas también ... es la dependencia del idioma
zeeshan mughal
Vea este comentario del autor del desafío en una de las otras entradas: "Es cierto, es más fácil en esos idiomas, pero no es imposible en JS. No considero que ninguno de estos haya cumplido las limitaciones del desafío, ya que su versión de 136 caracteres tiene siete líneas de código dentro de la función, y su versión de 166 caracteres tiene seis. El hecho de que tenga código en la misma línea que los corchetes de apertura o cierre no significa que el código no sea parte de la función. - jawns317 "
Cel Skeggs
compruébalo ahora y dime tu respuesta
zeeshan mughal
C no funciona así. Da un error del compilador. Probablemente estés pensando en C ++.
Cel Skeggs