Napisz funkcję, która powie, które DWIE wiersze zostały usunięte

19

W poprzednim wyzwaniu dla kodu poprosiłem cię o napisanie funkcji, która poinformuje cię, która z linii została usunięta.

Instrukcje były:

Napisz funkcję zawierającą pięć wierszy.

Jeśli uruchomisz funkcję taką, jaka jest, powinna zwrócić 0.

Jeśli usuniesz jeden z pięciu wierszy i uruchomisz funkcję, powinna ona powiedzieć, która z linii została usunięta (np. Jeśli usuniesz ostatnią linię, powinna ona zwrócić 5).

Spróbujmy teraz czegoś nieco trudniejszego.

Postępuj zgodnie z tymi samymi zasadami, co powyżej, ale tym razem funkcja powinna zwrócić tablicę informującą, które DWIE wiersze zostały usunięte.

Na przykład, jeśli usunę linie 1 i 5, wartość zwracana powinna wynosić [1,5], a jeśli usunę linie 3 i 4, wartość zwracana powinna wynosić [3,4].

Ponownie, jeśli żadne linie nie zostaną usunięte, funkcja powinna zwrócić 0. Punkty bonusowe, jeśli możesz również obsłużyć przypadek usunięty z jednej linii, ale nie jest to absolutnie konieczne.

Czy umiesz korzystać z funkcji pomocniczych? Tak, ale tylko jeśli musisz. Idealna jest pojedyncza, niezależna funkcja, która to umożliwia.

Podobnie jak w przypadku ostatniego wyzwania, wygrywa najwyżej ocenione rozwiązanie. Wybiorę zwycięzcę za tydzień lub wcześniej, jeśli nie otrzymamy nowych zgłoszeń w ciągu 24 godzin.

jawns317
źródło
2
Czy zwracanie pustej listy jest prawidłowe, jeśli nie zostaną usunięte żadne wiersze, czy też musi to być liczba 0?
Ilmari Karonen,
1
czy linia powrotna w funkcji jest jedną z linii, które można usunąć?
le_vine
11
Czy możemy się spodziewać, że jutro zostanie opublikowana wersja „trzywierszowa”?
Howard,
Czy funkcja musi dosłownie zwrócić tablicę, czy może edytować zmienną w zasięgu globalnym .etc? Nie sądzę, że jest to możliwe w 5 liniach, podczas gdy faktycznie wraca, ponieważ nie mogę patrzeć w przyszłość, ponieważ wszystkie linie muszą wrócić, ponieważ zwrot zostanie usunięty. Chyba że są jakieś dziwactwa językowe, takie jak automatyczne funkcje powrotu, o których nie wiem.
George Reith,
Myślę, że powinieneś również podać link do swojego poprzedniego pytania, jak dla kogoś, kto jest zainteresowany i go nie widział.
DroidDev,

Odpowiedzi:

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

To faktycznie działa na dowolną liczbę usuniętych linii (o ile nie wszystkie linie, to znaczy) i może być trywialnie przedłużone do więcej niż 5 linii. Nie są używane żadne funkcje pomocnicze, a nawet używa tylko jednej instrukcji w wierszu. Opiera się na fakcie, że przy braku wyraźnegoreturn instrukcji zwracana wartość funkcji Perl jest wartością ostatniej instrukcji w niej zawartej.

Zauważ, że (w kontekście listy) ten kod zwraca pustą listę zamiast liczby 0, jeśli nie zostały usunięte żadne wiersze. Można to naprawić (np. Dodając „ @a ? @a : 0;” do ostatniego wiersza), ale sprawi, że kod będzie brzydszy. W każdym przypadku, w skalarnego kontekście nie zwróci ilość usuniętych linii, która będzie wynosić 0, jeśli żadne linie zostały usunięte. ;-)

Ilmari Karonen
źródło
9

Rubin

Podobne do wersji Perla, ale w Rubim. Zwracam 0, jeśli żadne wiersze nie są usuwane zgodnie z żądaniem, ale zgadzam się, że kod jest brzydszy i nie ma sensu jako wartość zwracana.

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

Jeśli pusta tablica jest akceptowana jako wartość zwracana, gdy nie zostaną usunięte żadne wiersze, kod wygląda następująco:

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

Obie metody działają dla dowolnej liczby linii usuniętych między 0 a 5.

OI
źródło
4

JavaScript, 152 znaki w golfa

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

Gra w golfa:

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

Samodzielny (ale brzydki):

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
}

Zasadniczo wykorzystuje funkcję toString, numerując każdą linię. Pamiętaj, że z tego powodu musisz usunąć linię (komentowanie jej nie zadziała).

To faktycznie działa na dowolną liczbę usuniętych linii ! Zwróci tablicę usuniętych linii lub pustą tablicę, jeśli żadna nie została usunięta. (Można łatwo zmienić w celu powrotu do zera (zastępując return raz return ra || 0), ale tak jak na pustym roztworu tablicy ponieważ byłoby bardziej użyteczne w świecie rzeczywistym).

Na przykład usunięcie pierwszego wiersza zwraca [1]i usuwanie wszystkiego oprócz pierwszego wiersza [2,3,4,5]. (Oczywiście nie działa, jeśli usuniesz wszystkie linie ;-))

Klamka
źródło
3

Rubin

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

Jak to działa: moim pomysłem było: utworzyć tablicę i w każdej linii usunąć określoną wartość. Tak więc w pierwszym wierszu mam tablicę [ 1, 2, 3, 4, 5]z 1usuniętym elementem . W drugim wierszu, jeśli ajest już zdefiniowany, usuń element 2. W przeciwnym razie utwórz nową tablicę z 2usuniętym elementem . Zrób to samo dla linii 3. W linii 4 możesz mieć pewność, że tablica jest już utworzona, więc po prostu usuń element 4. W linii 5 najpierw usuń element 5, a jeśli ajest to pusta tablica, zwróć 0. W przeciwnym razie wróć a.

ProgramFOX
źródło
3

Pyton

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

Zwraca 0, jeśli żadna linia nie jest usuwana, w przeciwnym razie zwraca usunięte linie. Możesz usunąć 1 do 5 linii, z wyjątkiem linii 0 i 6 ;-).

Daniel
źródło
2

JavaScript, samodzielny, działa dla 0, 1, 2 usuniętych linii ( 607  315 186 znaków)

demo na żywo

Nadużywanie zmiennego podnoszenia JS i globalnego wycieku, jak w innym wyzwaniu :)

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
}

do wywołania z tablicą [1,2,3,4,5] jako parametrem.

315 znaków

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
}

do wywołania z pustą tablicą jako parametrem.



wersja bez golfa

(działa również dla usuniętych 3 i 4 linii):

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

do wywołania z pustą tablicą jako parametrem.

Xem
źródło
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
}

skrzypce

Briguy37
źródło
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)

Nazwij to, co lubisz, ale myślę, że tak ładne .

Informuje, które linie zostały usunięte (1 lub więcej), lub 0, jeśli nie zostały usunięte żadne linie. Wszystkie 5 linii może usunąć.

EDYTOWAĆ:

Ponieważ zwrócono mi uwagę, że mój kod może faktycznie składać się z 6 wierszy i narusza reguły, dostosowałem go do następujących elementów:

(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

To samo dotyczy - zwróci tablicę usuniętych linii od 1- Wszystkie lub 0, jeśli nie ma żadnych.

logika 8
źródło
Nie jestem pewien, czy to pomoże, ale zauważyłem, że inni to robią, więc .. Mój ma 149 znaków ze spacjami i 128 bez.
logic8
Ponieważ nie jest to golf kodowy, nie musisz usuwać białych znaków.
Timtech
1
Wiersz „return” znajduje się w obrębie funkcji, więc funkcja ma sześć linii kodu, co narusza reguły wyzwania.
jawns317
@ jawns317, nie jestem pewien, jak zdefiniowana jest „linia”. Czy ktoś mógłby podać jasną definicję?
logic8
@ logic8 Remove function(){i }(oraz wszelkie funkcje pomocnicze). Policz liczbę linii.
Klamka
1

Common Lisp

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

Działa w celu usunięcia 1-4 linii. Jeśli usuniesz wszystkie linie, zwróci to samo, jakbyś nie usunął żadnych.

Uwaga: Posiadanie końca nawiasu we własnej linii jest uważane za zły styl, ale ponieważ inne języki mają endi }zakładam, że jest to dozwolone.

Sylwester
źródło
1

Pyton

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

Działa dla wszystkich linii - ale tylko wtedy, gdy dwie zostaną usunięte. Jeśli tylko jedna linia zostanie usunięta, wydrukuje usuniętą linię i linię 5. Jeśli zostanie usuniętych zbyt wiele linii, nic nie wydrukuje.

Używa to funkcji pomocnika, ponieważ słowa kluczowego del nie można używać w linii z; (o ile wiem)

Zasadniczo każda linia usuwa się z tablicy zadeklarowanej w konstruktorze, a następnie, jeśli usunięto wystarczającą liczbę linii, tablica jest drukowana.

Ta funkcja nie spełnia specyfikacji na dwa sposoby:

  1. nie wypisuje 0, jeśli jest uruchamiany w obecnej postaci (zakłada, że ​​ostatnie dwa wiersze zostały skomentowane, a więc wypisuje 4, 5
  2. Zakłada to printi returnsą wymienne
jcw
źródło
Czy print ''jednak nie wygeneruje dodatkowego znaku nowej linii?
SimonT
1

Déjà Vu

Działa w celu usunięcia dowolnej liczby linii (pod warunkiem pozostawienia co najmniej jednej linii)

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
źródło
0

R

Mam inną wersję w R, która moim zdaniem jest lepsza (ale używa funkcji pomocnika):

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

Można też uniknąć korzystania z funkcji pomocniczej, definiując ją jako domyślny argument (działa identycznie, ale jest mniej czytelny - jednak nie używa funkcji pomocniczej „oddzielnie zdefiniowanej”):

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

Oba reportRemovedLines()i funnyVersion()działają z dowolną liczbą usuniętych linii - chyba że usuniesz wszystkie linie (w takim przypadku zostaną zwrócone NULL). W rzeczywistości zwracają numery wierszy, a nie tylko je drukują - tak jak w R, wartość ostatniego wyrażenia obliczonego w funkcji zostanie automatycznie zwrócona.

Jak to działa? Sztuczka polega na trickfunkcji, która pobiera wszystkie obiekty ze swojego „środowiska nadrzędnego” (tj. Środowiska funkcji, która ją wywołuje), łączy ich wartości w wektorze i zwraca, których wartości od 1 do 5 nie są reprezentowane.

lebatsnok
źródło
0

JavaScript (136/166 znaków)

Mniejsza wersja z niektórymi wartościami zadeklarowanymi na początku:

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}

Samodzielna wersja (nie musisz niczego przekazywać - jest tam argument b, więc mogę sprawdzić, czy zdefiniowano b ||)

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}

Tak, oba mają returnstwierdzenia, ale jest to uczciwe tylko wtedy, gdy konkuruję z językami z niejawnym zwrotem.

Bobby Marinoff
źródło
To prawda, że ​​w tych językach jest łatwiej, ale w JS nie jest to niemożliwe. Nie uważam, aby którykolwiek z nich spełniał ograniczenia wyzwania, ponieważ twoja 136-znakowa wersja zawiera siedem linii kodu w funkcji, a twoja 166-znakowa wersja ma sześć. Fakt, że masz kod w tym samym wierszu co nawiasy otwierające lub zamykające, nie oznacza, że ​​kod nie jest częścią funkcji.
jawns317
Co z odpowiedziami, które wykorzystują pomocników?
Bobby Marinoff
Funkcje pomocnicze są wyraźnie dozwolone. Ale funkcja, z której usuwane są wiersze, powinna zawierać pięć wierszy kodu.
jawns317
0

R

Prosta wersja (nie jest niezawodna, ponieważ jeśli usuniesz wiersz 5, pojawi się błąd):

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

I niezawodna wersja:

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

Działa z dowolną liczbą usuniętych linii (chyba że usuniesz wszystkie linie) i może być łatwo przedłużony do więcej niż 5 linii. Uruchomienie go „tak, jak jest” powróci, integer(0)co jest koncepcyjnie podobne do powrotu właśnie 0. Zwrócenie rzeczywistego 0 uczyniłoby go brzydszym i dłuższym, ale nie byłoby skomplikowane.

Wreszcie wersja wykorzystująca magię:

Funkcja pomocnika:

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
    }

Rzeczywista funkcja:

df <- dysfunction({
1
2
3
4
5
})
lebatsnok
źródło
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;
}

Sposób użycia: wywołaj funkcję za pomocą i i użyj func2, aby zrozumieć, co mówi funkcja.

Jeśli zmienisz wiersz int arr [] = {0,0} na int arr [] = {0,0,0,0,0}} to będzie działało również dla wszystkich pięciu wierszy, jest to również przypadek usunięcia wiersza testowego z jednej linii automatycznie, po prostu używam bitów zmiennej jako flagi dla każdej linii ....

zeeshan mughal
źródło
Nie functionma sześciu linii, a nie pięciu?
Cel Skeggs
powrót nie jest częścią tego, można zobaczyć także inne odpowiedzi ... to zależność językowa
zeeshan mughal 31.01.14
Zobacz komentarz autora wyzwania w jednym z pozostałych wpisów: „To prawda, w tych językach jest łatwiej, ale w JS nie jest to niemożliwe. Nie uważam, aby którykolwiek z nich spełniał ograniczenia wyzwania, ponieważ twoja 136-znakowa wersja zawiera siedem wierszy kodu w funkcji, a twoja 166-znakowa wersja ma sześć. Fakt, że masz kod w tym samym wierszu co nawiasy otwierające lub zamykające, nie oznacza, że ​​kod nie jest częścią funkcja. - jawns317 "
Cel Skeggs
sprawdź to teraz i powiedz mi swoją odpowiedź
zeeshan mughal
C tak nie działa. Daje błąd kompilatora. Prawdopodobnie myślisz o C ++.
Cel Skeggs