Blog infoarena

Interviu cu romanii acceptati in YCombinator

Cosmin
Cosmin Negruseri
10 aprilie 2014

Razvan si Radu de la stanga la dreapta

Radu Spineanu si Razvan Roman sunt fondatorii companiei Two Tap. Ei au format prima echipa de romani acceptati in YCombinator, cel mai renumit incubator de startups din Silicon Valley. Prin YCombinator au mai trecut companii ca reddit, AirBNB sau dropbox. Acum sunt si in faza de crestere a echipei tehnice, cauta ingineri foarte buni la inceputul carierei. Puteti sa ii contactati la [email protected]

1. Spuneti-ne putin despre voi si despre TwoTap.

Radu: Backgroundul meu este de Network Engineer (am lucrat 5 ani la RoEduNet). Am inceput sa fac companii in timpul facultatii. Printre multe am fondat 2Parale, cea mai mare retea de afiliere din RO. De asemenea am creat prima aplicatie care permitea crearea de cinemagraphs pe iOS, care a fost featured de Apple si a avut in jur de 1 milion de downloaduri). In timpul liber sunt Developer Debian (o distributie Linux).

Razvan: Am invatat sa scriu si sa citesc cand aveam 5 ani pe un HC91 pe care am petrecut mult timp datorita Lode Runner, Dizzy si altele. Odata cu o conexiune broadband multi ani mai tarziu am avut acces la tot ce inseamna knowledge despre startupuri, in perioada in care Napster era hot. Dupa ce am pornit primul startup in liceu a urmat o lunga serie de eforturi cu rezultate mixte dar din care am invatat foarte mult despre factorii care influenteaza succesul unui startup, vazuti din multe perspective: am facut tot, de la copywriting si marketing la sales si programare sau recrutare, atat in RO cat si EU/UK sau US.

Two Tap rezolva o problema fundamentala a ecommerce-ului: in mod traditional daca vrei sa cumperi un produs trebuie sa mergi pe site-ul merchant-ului. Dar cum userii petrec timp pe diverse device-uri in prezent e foarte dificil sa faci o tranzactie oriunde in afara unui browser conventional. Two Tap permite userilor sa cumpere produsele atunci cand iau decizia respectiva, fie ca sunt intr-un FB app, intr-un app nativ sau pe mobile web, practic oriunde se afla. Asta se datoreaza API-ului care sta la baza Two Tap, API care poate plasa comenzi pe platformele retailerilor.

2. Piata angajatorilor in domeniu software e foarte activa. Corporatiile concureaza acerb pentru oameni foarte competenti. Ati refuzat traseul corporatist si ati ales sa fondati un startup. Cum ati luat decizia?

Radu: Intr-o corporatie esti doar o rotita dintr-un sistem enorm. Oportunitatea de a face ceva meaningful pornind de la zero e aproape inexistenta. In final avem doar o viata, si viata trebuie traita. De asta facem ceea ce facem. Pentru ca vrem ca atunci cand avem 80 de ani sa ne numaram cicatricile si traumele psihologice sa radem de fericire fara nici un regret.

Razvan: Impartasim mult perspectiva asta. Cand am o decizie importanta de facut intotdeauna ma gandesc daca voi regreta faptul ca nu am incercat optiunea care pare riscanta peste cativa ani. Daca raspunsul e da atunci las frica deoparte si merg inainte, oricat de dificil poate parea initial. Cred ca e mai dificil decat o cariera conventionala dar asta ma face fericit. Cred totodata ca lucrand cu un startup 2 ani inveti foarte mult fata de acelasi timp petrecut intr-o corporatie.

3. De ce Silicon Valley si nu Romania sau Europa?

Radu: Nu e nimic rau in a face o companie in Romania sau Europa. Prima companie fondata de mine a fost in Romania (se numeste 2Parale) si a fost una din cele mai misto experiente pe care le-am avut.

In acelasi timp e important sa 'always shoot for the stars'. Cand am inceput 2Parale nu stiam nimic despre startupuri, in nici o secunda nu m-am gandit ca as putea sa incep o companie in US. Si apoi incet incet am invatat tot mai multe, lucrurile au devenit mai clare, si drumul a fost evident.

Razvan: Starea economiei impiedica dezvoltarea unui startup pe o traiectorie normala de crestere. Oricat de bun esti exista limite date de piata locala care te obliga sa te plafonezi destul de repede. In Romania (si de multe ori Europa) greu te lovesti de problema de a scala produsul tau la zeci de milioane de useri, pe cand in SV asta e un given, te vei lovi de asta.
E foarte contraintuitiv dar din multe puncte de vedere e mai usor sa faci un startup in SV decat RO odata ce treci de barierele initiale. Daca ai product market fit ai din start o piata locala de 300M de consumatori care vor produsul tau, vorbesc aceeasi limba si au venituri substantiale pe care le pot cheltui.

4. Interviurile pentru intrarea in YCombinator sunt renumite. Povestiti-ne experienta voastra.

Radu: Am aplicat in total de cinci ori si am fost invitat la interviu de trei ori. PG scrie esee despre ceea ce cauta, dar probabil varianta scurta ar fi: echipa (accomplishments notabile, track record, fara accent, a cultural fit cu comunitatea YC), traction (daca compania ta face milioane de dolari pe zi that trumps everything), perseveranta, si un mod specific de a gandi asupra lucrurilor (foarte importanta e intrebarea about hacking a non-computer system).

YC a nimerit perfect momentul in care sa ne accepte ca sa folosim la maxim potentialul programului. O companie poate sa fie prea devreme in dezvoltarea ei, prea tarziu, sau poate sa fie nepotrivita cu viziunea YC. E greu sa iti dai seama cand e acel moment, dar probabil e atunci cand realizezi ca proiectul s-ar putea descurca bine-mersi si fara sa fie acceptat.

Natura interviului si interactiunea depinde de foarte multi factori si e greu de prezis.

5. Cum se compara experienta YCombinator cu munca pe cont propriu?

Razvan: Cel mai mare impact al YCombinator asupra companiei tale e faptul ca iti elimina toate lucrurile care iti pot distrage atentia timp de 3 luni. Elementul asta de focus extrem dublat de faptul ca esti inconjurat de alte echipe care trec prin aceeasi experienta e foarte motivant. Multe din companiile care trec prin program ajung sa fie lideri pe segmentul lor de piata in cele 3 luni.
Imaginati-va cum e sa lucrati la un mail client si sa aveti ca mentor pe Paul Buccheit (creatorul Gmail) sau Geoff Ralston care a fondat Rocket Mail, devenit mai tarziu Yahoo Mail.
In fiecare marti YCombinator organizeaza o cina pentru fondatori, eveniment unde participa oameni foarte influenti din SV, de la Marc Andreessen (creatorul Netscape, primul browser) pana la Ron Conway sau Mark Zuckerberg. Totul intr-o atmosfera casual, off the record si multe discutii la liber. Doar cateva sute de oameni au avut acces la resursele astea pana acum prin YCombinator.

6. Care sunt problemele cele mai grele pe care le rezolvati? Sunt de natura tehnica sau pe partea de business?

Radu: Two Tap rezolva o problema tehnica foarte complicata: cum abstractionezi mii de magazine prost facute intr-un API curat si reliable fara ca ele sa faca nimic (0 integrare). Iar dupa ce ai API-ul cum creezi cea mai buna experienta de shopping din lume pe orice platforma.

La Two Tap creem un layer care sta deasupra tot ce inseamna online ecommerce, care intelege mii de magazine. La core e un scraper hiper inteligent, iar posibilitatile cu ce putem face cu el sunt endless.

7. Ce sfaturi aveti pentru programatorii din comunitatea infoArena?

Radu: Sa nu se angajeze la o multinationala. Cand eram la RoEduNet cineva imi povestea ca cel mai mare pericol de a avea un job e ca devii comfortabil. Te obisnuiesti sa iesi in oras in fiecare seara, sa iti iei haine scumpe, sa mergi in vacante de doua ori pe an, sa iti iei rate, sa te casatoresti.

Este enorm de mult timp sa faci asta la 35-40 de ani. La 20 de ani e momentul sa fii curajos, sa faci chestii care schimba lumea, chiar daca unii le considera idioate sau a long shot. E important sa nu ai nici un regret mai incolo.

Razvan: La ce a zis Radu as adauga faptul ca e important sa se gandeasca foarte bine la parcursul profesional. Barierele lingvistice sau de distanta devin din ce in ce mai insignifiante si e mult mai usor decat pare la prima vedere sa lucreze la ceva care poate avea un impact major si deschide niste drumuri necalcate in loc de a invata o tehnologie proprietara a unei corporatii mari care tot ce vrea e sa maximizeze profiturile.

Mult curaj! Si luati legatura cu noi daca putem ajuta, am fost la randul nostru ajutati de multi oameni de-alungul anilor si ne face mare placere sa pay it forward.

Radu si Razvan, va multumim pentru interviu! Pentru orice startup problema angajarii de oameni buni e esentiala. Two Tap cauta oameni buni la inceputul carierei. Ii puteti contacta pe [email protected]

 Comentarii (0)

Categorii:

Zece

Cosmin
Cosmin Negruseri
28 martie 2014

Infoarena aniverseaza luna aceasta 10 ani!

 Comentarii (16)

Categorii:

Lansarea concursului naţional de algoritmică MindCoding

S7012MY
Petru Trimbitas
20 ianuarie 2014

Lansarea concursului naţional de algoritmică MindCoding

Concursul Naţional MindCoding este un proiect care vine în atenţia pasionaţilor de informatică din întreaga ţară, indiferent de vârstă, încurajând dezvoltarea unei comunităţi de persoane pasionate de algoritmică, şi nu numai.
Concursul va avea 4 runde online ce se vor desfăşura pe site-ul competiţiei www.mindcoding.ro , urmând ca runda finală să aibă loc în perioada 11-13 aprilie 2014 în municipiul Cluj Napoca.
Fiecare rundă online va fi alcătuită din 4 probleme cu dificultate gradată în 90 de minute.
Prima rundă va avea loc în data de 30 ianuarie 2014, incepând cu orele 19.

Organizatorul acestui concurs este Societatea Hermes (Organizaţia Studenţilor din cadrul Facultăţii de Matematică şi Informatică Cluj Napoca). Mai multe detalii sunt disponibile aici De asemenea ne puteţi urmări pe facebook

 Comentarii (0)

Categorii:

Transpose

Cosmin
Cosmin Negruseri
29 octombrie 2013

Here's an interesting interview question I've heard recently.

You are given an 100G size file on disk which represents a square matrix of 32 bit integers. Design an efficient way to transpose that matrix given that you only have 1G of available memory.

 Comentarii (3)

Categorii:

Distance

Cosmin
Cosmin Negruseri
08 octombrie 2013

Here's a neat problem I solved in 8th grade during the preparation for the high school entrance exam:

Let A1B1C1D1A2B2C2D2 be a cube with A1B1C1D1 being the bottom face and A2B2C2D2 the top face. Given that A1A2 is of length 1 what's the distance between D2A1 and A2B1.

 Comentarii (10)

Categorii:

Solutii la concursul ACM ICPC 2013 etapa nationala partea a doua

S7012MY
Petru Trimbitas
21 iunie 2013

Revin cu partea a doua a articolului cu soluţii la problemele de la faza naţională a concursului ACM ICPC. Acestea sunt problemele grele şi au fost rezolvate de foarte puţine echipe. Vă invit să discutaţi soluţiile la comentarii.

A. Cubic Eight-Puzzle

Problema ne dă un grid de 3×3 acoperit cu 8 cuburi fiecare aşezat într-una din celule. Fiecare are două dintre feţele opuse colorate cu albastru(B) iar celelalte două colorate cu alb(W) şi cu roşu( R ) . La o mutare poate fi rostogolit unul din cuburi în celula liberă. Problema ne cere să aflăm numărul minim de mutări necesare pentru a ajunge într-o configuraţie dată. Se ştie că iniţial cuburile sunt cu faţa albă in sus iar faţa albastră e în dreapta. Celula goală se află în stânga-jos. Dacă numărul de mutări e mai mare de 30 se va afişa -1

Soluţie oferită de Adrian Budau

O primă soluţie ar fi să facem o parcurgere în lăţime din starea iniţială făcând maxim 30 mutări. La fiecare pas avem 4 mutări posibile dintre care una ne va duce înapoi deci doar 3 ne interesează. În total vom trece prin 3 30 stări.
Pentru a reduce numărul de stări prin care trecem vom folosi Meet in the middle. În loc să pornim o parcurgere doar din sursă, vom porni una şi din destinaţie şi făcând maxim 15 mutări. Astfel vom încerca să întâlnim din sursă un nod vizitat din destinaţie sau invers. Astfel vom vizita doar 2*3 15 stări.

B. Manhattan Wiring

În această problemă ni se dă o matrice de NxM ( N<=9 M<=9 ) cu unele celule ocupate. Două dintre celulele matricei sunt marcate cu 2 şi două cu 3. Trebuie afişată suma minimă a lungimii a două lanţuri care nu se intersectează şi unesc cele două celule cu 2 şi cele două cu 3 fără a ieşi din matrice sau a trece prin celulele ocupate.

Recomand citirea acestui articol înainte de citirea soluţiei.

O problemă asemănătoare s-a dat la CEOI 2006. Soluţia ei se găseşte aici

Soluţie

În scrierea soluţiei m-am inspirat de aici

Fiecare celulă poate fi în următoarele stări: goală, ocupată cu un cablu vertical/orizontal sau cu un cablu în L(4 stări). Vom calcula lungimea minima a cablurilor poziţionate până la linia i iar cele din stare sunt legate de linia anterioară( 0 nu există legătură, 1 există legătură iar cablul va fi legat de 2, 2 există legătură iar cablul va fi legat de 3). Pentru a calcula tanziţiile vom genera cu backtracking starea cablurilor de pe coloana următoare şi vom avea grijă să păstrăm următoarea stare corectă.

C. Power Calculus

Problema ne cere să aflăm numărul minim de operaţii pentru a calcula x n ( n <= 1000 ) pornind de la x fără a folosi puteri negative şi făcând înmulţiri cu numere calculate deja. De exemplu x 31 poate fi calculat cu 7 înmulţiri:
x 2 = x × x, x 4 = x 2 × x 2, x 8 = x 4 × x 4 , x 10 = x 8 × x 2 , x 20 = x 10 × x 10, x 30 = x 20 × x 10 , x 31 = x 30 × x
Acesta poate fi calculat şi cu 6 operaţii (5 înmulţiri şi o împărţire)
x 2 = x × x, x 4 = x 2 × x 2, x 8 = x 4 × x 4 , x 16 = x 8 × x 8 , x 32 = x 16 × x 16 , x 31 = x 32 ÷ x

Soluţie

Deşi iniţial pare complicată, problema se rezolvă cu o parcurgere în lăţime. Se observă că nu are sens să calculăm pentru numere mai mari de 2000. Într-o poziţie din coadă vom reţine toate puterile calculate până la numărul curent. Când dorim să trecem într-o stare nouă trebuie doar să adunăm sau să scădem ultima putere calculată cu una calculată anterior.

#include <iostream>
#include <queue>
#include <cstdlib>
using namespace std;

struct drum{
  int lst,sz,cst;
  int fol[32];
};

int n=-1,dmin[3005];

void ins(queue<drum> &c,drum fr,int nxt) {
  if(nxt<2 || nxt>2000) return;
  drum next=fr;
  ++next.cst;
  if(next.cst==dmin[nxt]) {
    next.fol[++next.sz]=next.lst=nxt;
    c.push(next);
  }
  if(dmin[nxt]>next.cst) {
    dmin[nxt]=next.cst;
    next.fol[++next.sz]=next.lst=nxt;
    c.push(next);
  }
}

int main() {
  for(int i=2; i<=1000; ++i) dmin[i]=(1<<30);
  queue<drum> c;
  drum fr; fr.sz=0; fr.lst=1; fr.cst=0; fr.fol[++fr.sz]=1;
  for(c.push(fr);c.size(); c.pop()) {
    fr=c.front();
    for(int i=1; i<=fr.sz; ++i) {
      ins(c,fr,fr.lst+fr.fol[i]);
      ins(c,fr,fr.lst-fr.fol[i]);
    }
  }
  while(1) {
    cin>>n;
    if(n==0) break;
    cout<<dmin[n]<<'\n';
  }
  return 0;
}

D. Polygons on the Grid

În această problemă trebuie să aflăm aria maximă a unui poligon cu colţurile în puncte laticeale care are lungimile laturilor date. Poligonul are maxim 6 laturi iar lungimea maximă a unei laturi e 300

Soluţie oferită de Mugurel-Ionut Andreica

Ideea soluţiei este încercarea tuturor variantelor: se poate fixa o latură ca fiind prima şi îi încercăm toate orientările spre "dreapta-sus": orizontal, vertical, si, eventual, "oblic" dacă se poate aşeza cu capetele într-un punct întreg). Pe urmă variem ordinea celorlalte laturi ( 5! ) şi pentru fiecare dintre celelalte laturi încercăm orientările posibile care pastrează convexitatea poligonului. În plus mai trebuie folosită următoarea optimizare: Fixăm cea mai mare lungime ca fiind prima latură. Dacă lungimile rămase nu ne ajung să "închidem" poligonul atunci ne oprim.

 Comentarii (4)

Categorii:

Solutii la concursul ACM ICPC 2013 etapa nationala partea I

S7012MY
Petru Trimbitas
17 iunie 2013

Duminică, 16 iunie a avut loc faza naţionala a concursului acm icpc. Pagina concursului o gasiţi aici
iar clasamentul aici
La concurs au participat peste 50 echipe iar setul de probleme a fost unul echilibrat.

Înainte de concurs au mai avut loc 3 concursuri de pregătire. Problemele le găsiţi aici aici şi aici

Voi prezenta in continuare o parte din probleme şi soluţiile acestora. Vă invit să contribuiţi la comentarii cu soluţiile voastre

G. Election Time

Aceasta a fost cea mai simplă problemă din concurs, fiind rezolvată de marea majoritate a echipelor.
Problema ne cerea să determinăm câştigătorul alegerilor dupa 2 tururi ştiind cate voturi va obţine fiecare candidat in cele 2 tururi. În plus în al doilea tur se calificau doar primii k candidati.

O soluţie ar fi sortarea candidaţilor descresrescător după numărul de voturi primite în primul tur, iar pe urmă sortarea primilor k după numărul de voturi din al doilea tur. Pentru a nu complica implementarea am ales sortarea unui vector de indici in funcţie de numărul de voturi.

#include <iostream>
#include <algorithm>
#define DN 50005
using namespace std;

int n,k,ind[DN],a[DN],b[DN];

bool cmp(int x,int y) {
	return a[x]>a[y];
}

bool cmp2(int x,int y) {
	return b[x]>b[y];
}

int main() {
	cin>>n>>k;
	for(int i=1; i<=n; ++i) {
		cin>>a[i]>>b[i];
		ind[i]=i;
	}
	sort(ind+1,ind+n+1,cmp);
	sort(ind+1,ind+k+1,cmp2);
	cout<<ind[1]<<'\n';
}

H. Stones II

A doua problema ca dificultate din concurs ne dădea N (N <= 100 000) grămezi de pietre şi ne cerea să le reunim cu un cost cât mai mic. Pentru a putea reuni grămezile putem lipi la un pas două grămezi cu un cost egal cu numărul de pietre din cele două grămezi la un loc.

Pentru a rezolva problema putem aplica o strategie de tip greedy în care la fiecare pas luăm cele mai mici două grămezi şi le reunim. Pentru a se încadra în timp şi pentru a fi corect e necesară folosirea unui multiset şi a tipului de date long long.

F. Average distance

După cum îi spune şi numele această problemă ne cere sa calculăm costul mediu al muchiilor dintr-un arbore.

Pentru a rezolva problema observăm că costul mediu e egal cu suma costurilor drumurilor din arbore împărţită la numărul total de drumuri.
Numărul de drumuri e egal cu N*(N-1)/2 (Combinări de N luate câte doua, fiecare drum fiind definit de 2 noduri).
Pentru a calcula suma costurilor drumurilor ne interesează fiecare muchie în câte drumuri apare.
O muchie (A,B) apare in orice drum definit de un nod din subarborele lui A(inclusiv A) şi de un nod care nu e in subarborele lui A.

//Cristian Lambru
#include<iostream>
#include<vector>
using namespace std;

typedef vector<pair<int,int> >::iterator it;

#define MaxN 110000
#define ld long double

int N;
ld Suma = 0;
int Fii[MaxN],viz[MaxN];
vector<pair<int,int> > A[MaxN];

inline void parcurgere(int nod)
{
    viz[nod] = 1;
    Fii[nod] = 1;
    
    for(it i=A[nod].begin();i<A[nod].end();i++)
        if(!viz[i->first])
        {
            parcurgere(i->first);
            Fii[nod] += Fii[i->first];

            Suma += (ld)(i->second)*Fii[i->first]*(N-Fii[i->first]);
        }
}

int main()
{
    citire();    
    parcurgere(0);

    cout << Suma/((ld)N*(N-1)/2);
}

E. Slim Span

Această problemă cere pentru un graf cu N (N<=100) noduri să aflăm diferenţa minimă dintre muchia de cost maxim şi cea de cost minim dintr-un arbore de acoperire al grafului.

Dimensiunea datelor de intrare ne permite ca pentru fiecare muchie să alegem doar muchii de cost mai mare până când obţinem un arbore de acoperire şi să alegem cea mai bună diferenţă dintre toţi arborii de acoperire obţinuţi.

I. More lumber is required

Problema aceasta ne dădea un graf ponderat şi ne cerea să aflăm timpul minim în care putem traversa graful din nodul S în nodul D şi în care strângem cel putin k unităţi de lemn. Atunci când traversăm o muchie primim 10 unităţi de lemn in plus.

În ciuda faptului că problema e o problemă clasică de drum minim, ea a fost rezolvată de puţine echipe. Pentru a rezolva formăm un graf în care nodurile sunt determinate de perechi de forma (nod iniţial, cantitate de lemn). În plus mai observăm că putem împărţi cantităţile de lemn la 10 şi că nu ne interesează cantităţile de lemn mai mari decât ,⌈K/10⌉. Acum trebuie doar să aplicăm un algoritm de drum minim pentru a afla timpul de parcurgere din nodul (S,0) în nodul (D,⌈K/10⌉). Pentru a lua AC era suficienta folosirea algoritmului Bellman Ford cu coadă.

J. Template Library Management

În această problemă se dă un vector V de N (N<=100 000) (V[i]<=109) elemente şi o listă de dimensiune M în care iniţial sunt numerele de la 1 la M. Pentru a trece mai departe de la poziţia i trebuie să avem în listă valoarea V[i]. La orice moment de timp putem înlocui un număr din listă cu orice alt număr care nu se află deja in ea. Problema ne cere numărul minim de înlocuiri cu care putem parcurge vectorul.

Vom încerca să aplicăm o strategie de tip greedy pentru a rezolva problema. La fiecare pas la care elementul de pe poziţia i nu se află în listă trebuie să decidem ce element trebuie să eliminăm. Se observă că este optim să eliminăm elementul din listă care apare în vector pe cea mai din dreapta poziţie sau care nu apare deloc. Pentru a calcula această informaţie vom calcula un vector next[i] cu semnificaţia: prima poziţie > i pe care apare elementul V[i]. Având această informaţie calculată putem simula lista cu un max heap în care vom ţine elementele ordonate în funcţie de poziţiile pe care urmează să apară.

K. Fast Arrangement

Aceasta a fost probabil problema cu cele mai multe submisii incorecte. Aceasta ne cerea să acoperim cu intervale axa ox ştiind că intr-un loc nu pot să se suprapună mai mult de K intervale. Pentru fiecare interval dat (cel mult 100 000) trebuia să se precizeze dacă poate fi plasat iar în caz afirmativ trebuia plasat.

În mod evident problema e una clasică de structuri de date. Avem nevoie de o structură de date care să ne permită adunarea unei valori asupra tuturor elementelor dintr-un interval şi aflarea valorii maxime dintr-un interval. Problema se putea rezolva cu arbori de intervale
Pentru a rezolva corect problema trebuia observat că intervalele sunt deschise, deci intervalele (3,4) şi (4,5) nu se suprapun.

 Comentarii (13)

Categorii:

C++ compiler upgrades on infoarena

pauldb
Paul-Dan Baltescu
27 aprilie 2013

We now have the --std=c++0x compiler option enabled on infoarena. We also updated our g++ compiler to 4.8.

What does it mean?

C++ users can now use a bunch of cool features, some of which are briefly described below. Keep in mind that these features are not yet available at OJI, ONI, etc., so don't use them at any of these competitions unless they are allowed explicitly by the regulations.

1. auto

You can now let the compiler infer the type of your variables with auto:

auto a = 45;
auto b = 4.5;
auto c = vector<int>(10);

auto can also be used with const auto or const auto&. In most cases, auto cannot be used in function signatures.

2. range-based for loops

In C++11, you can write less code to iterate over every element in a list of elements:

int array[5] = {1, 2, 3, 4, 5};
for (int x: array) {
  cout << x << endl;
}

If you want to modify the elements in the list, you need to get a reference to the current element:

double array[5] = {1.5, 2.7, 3.9};
for (auto &x: array) {
  x *= 2;
}

Note: This code compiles without using &, but the original array is not modified unless a reference is used.

3. initializer lists

Simple one-line initializations with lists of constant values:

vector<pair<int, int>> dirs = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};

Note that in C++11 you no longer need to introduce a space between closing right angle brackets (>>).

4. unordered_set, unordered_map

These are hash-based implementations of the well known set and map containers; the average time complexity on most operations is O(1). (These containers were previously available on infoarena under tr1, but only a small fraction of users were actually using them.)

#include <unordered_map>
...
using namespace std;
...
unordered_map<string, int> age = {
  {"john", 18}, {"mary", 21}, {"anna", 19}
};
cout << "Anna is " << age["anna"] << " years old." << endl;

Using STL vectors, pairs or user defined objects as keys is a little trickier because you also need to provide a hash function.

#include <unordered_set>
#include <vector>

using namespace std;

// Some user defined magic constants used for hashing.
const int P = 666013;

// Courtesy of Adrian Budau
struct myhash {
  size_t operator()(const vector<int>& v) const {
    size_t value = 1;
    for (auto x: v) {
      value = value * P + hash<int>()(x);
    }
    return value;
  }
};
...
unordered_set<vector<int>, myhash> s;
vector<int> v = {1, 2, 3};
s.insert(v);

You don't need to worry about collisions, unordered_set and unordered_map will take care of them for you.

5. lambda functions

You can now define anonymous functions to write less code. A common application is sorting according to multiple criteria.

#include <algorithm>

using namespace std;

...
vector<int> a = {5, 3, 1, 3};
vector<int> b = {6, 1, 7, 2};
vector<int> ind = {0, 1, 2, 3};

sort(ind.begin(), ind.end(), [&a, &b](int x, int y) -> bool {
  return a[x] < a[y] || (a[x] == a[y] && b[x] < b[y]);
});

for (int i: ind) {
  cout << a[i] << " " << b[i] << endl;
}

(Often, a cleaner alternative to using lambda functions for sorting is to define a class holding all the data for each entry and to implement the < operator.)

Let us know in the comments section what are the C++11 features that you use for programming contests. Code snippets illustrating your favorite tricks are welcome.

 Comentarii (6)

Categorii: Features

Bafta la ONI

Cosmin
Cosmin Negruseri
29 martie 2013

Bafta saptamana urmatoare la Olimpiada Nationala de Informatica!

 Comentarii (12)

Categorii:
Vezi pagina: 12345678 910111213... 3738394041 (407 rezultate)