57
Programozz kézenállva! Magyar Attila (@athoshun) PHP Meetup, 2013. 02. 26.

Programming in handstand

Embed Size (px)

DESCRIPTION

My talk at PHPMeetup Budapest about doing the FizzBuzz kata with some weird constraints, such as not using loops, if statements and ternaries, and what can be learnt from such an exercise. (Slides are in Hungarian but most of them contains nothing but code.)

Citation preview

Page 1: Programming in handstand

Programozz kézenállva!

Magyar Attila (@athoshun)PHP Meetup, 2013. 02. 26.

Page 2: Programming in handstand

FizzBuzz

Write a program that iterates through the numbers between 1 and 100:

For multiples of 3 print "Fizz" For multiples of 5 print "Buzz" For numbers which are multiples of both 3 and 5

print "FizzBuzz" For others, print the number itself

Page 3: Programming in handstand

FizzBuzz

Write a program that iterates through the numbers between 1 and 100:

For multiples of 3 print "Fizz" For multiples of 5 print "Buzz" For numbers which are multiples of both 3 and 5

print "FizzBuzz" For others, print the number itself

1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz,11, Fizz, 13, 14, FizzBuzz, 16, 17, Fizz, 19,Buzz, Fizz, 22, 23, Fizz, Buzz, 26, Fizz, 28,29, FizzBuzz, ...

Page 4: Programming in handstand

Triviális megoldás

for ($i = 1; $i <= 100; ++$i) {    if ($i % 3 == 0) print "Fizz";    if ($i % 5 == 0) print "Buzz";    if ($i % 3 && $i % 5) print $i;    print ", ";}

Page 5: Programming in handstand

Ciklus nélkül!

Page 6: Programming in handstand

Ciklus nélkül!

Page 7: Programming in handstand

Ciklus nélkül!

function fizzbuzz($i = 1){    if ($i > 100) return;

    if ($i % 3 == 0) print "Fizz";    if ($i % 5 == 0) print "Buzz";    if ($i % 3 && $i % 5) print $i;    print ", ";

    fizzbuzz($i + 1);}

Page 8: Programming in handstand

Ciklus nélkül!

function fizzbuzz($i = 1){    if ($i > 100) return;

    if ($i % 3 == 0) print "Fizz";    if ($i % 5 == 0) print "Buzz";    if ($i % 3 && $i % 5) print $i;    print ", ";

    fizzbuzz($i + 1);}

PHP Fatal error:  Maximumfunction nesting levelof '100' Reached, aborting!

Page 9: Programming in handstand

Ciklus nélkül!

Page 10: Programming in handstand

Ciklus nélkül!

Page 11: Programming in handstand

Ciklus nélkül!

$fizzbuzz = function ($i) {    if ($i % 3 == 0) print "Fizz";    if ($i % 5 == 0) print "Buzz";    if ($i % 3 && $i % 5) print $i;    print ", ";};

array_map($fizzbuzz, range(1, 100));

Page 12: Programming in handstand

Elágazás nélkül!

Page 13: Programming in handstand

Elágazás nélkül!

$id = function ($x) { return $x; };

Page 14: Programming in handstand

Elágazás nélkül!

$id = function ($x) { return $x; };

$fizz = function ($x) { return "Fizz"; };$buzz = function ($x) { return "Buzz"; };$fizzbuzz = function ($x) {    return "FizzBuzz";};

Page 15: Programming in handstand

Elágazás nélkül!

$functions = array(   $fizzbuzz,   $id,    $id,    $fizz,  $id,    $buzz,   $fizz,  $id,    $id,    $fizz,  $buzz,   $id,    $fizz,  $id,    $id);array_map(   function ($x) use ($functions) {      print $functions[$x % 15]($x) . ", ";   },   range(1, 100));

Page 16: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = function ($x) { return "Fizz"; };$buzz = function ($x) { return "Buzz"; };$fizzbuzz = function ($x) {    return "FizzBuzz";};

Page 17: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = function ($x) { return "Fizz"; };$buzz = function ($x) { return "Buzz"; };$fizzbuzz = function ($x) {    return "FizzBuzz";};

Page 18: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = function ($x) { return "Fizz"; };$buzz = function ($x) { return "Buzz"; };$fizzbuzz = function ($x) {    return "FizzBuzz";};

function const_($const) {    return function ($x) use ($const) {        return $const;    };}

Page 19: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = const_("FizzBuzz");

function const_($const) {    return function ($x) use ($const) {        return $const;    };}

Page 20: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = const_("FizzBuzz");

DON'T REPEAT YOURSELF!!!

Page 21: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = const_("FizzBuzz");

function concat($f, $g){    return function ($x) use ($f, $g) {        return $f($x) . $g($x);    };}

Page 22: Programming in handstand

Redundancia

$id = function ($x) { return $x; };

$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = concat($fizz, $buzz);

function concat($f, $g){    return function ($x) use ($f, $g) {        return $f($x) . $g($x);    };}

Page 23: Programming in handstand

$id = function ($x) { return $x; };$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = concat($fizz, $buzz);$functions = array(    $fizzbuzz,    $id,    $id,    $fizz,  $id,    $buzz,    $fizz,  $id,    $id,    $fizz,  $buzz,    $id,    $fizz,  $id,    $id);array_map(    function ($x) use ($functions) {        print $functions[$x % 15]($x) . ", ";    },    range(1, 100));

Page 24: Programming in handstand

$id = function ($x) { return $x; };$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = concat($fizz, $buzz);$functions = array(    $fizzbuzz,    $id,    $id,    $fizz,  $id,    $buzz,    $fizz,  $id,    $id,    $fizz,  $buzz,    $id,    $fizz,  $id,    $id);array_map(    function ($x) use ($functions) {        print $functions[$x % 15]($x) . ", ";    },    range(1, 100));

Page 25: Programming in handstand

3 többszörösei

function multiples_of_3(){    return array_map(        function ($x) { return $x * 3; }        range(1, 10)    );}

var_dump( multiples_of_3() );// 3, 6, 9, 12, 15, 18, 21, 24, 27, 30

Page 26: Programming in handstand

3 többszörösei

function multiples_of_3(){    return array_map(        function ($x) { return $x * 3; }        range(1, 10)    );}

var_dump( multiples_of_3() );// 3, 6, 9, 12, 15, 18, 21, 24, 27, 30

Page 27: Programming in handstand

3 többszörösei

function multiples_of_3(){    return array_map(        multiply_by_3(),        range(1, 10)    );}function multiply_by_3(){    return function ($x) {        return $x * 3;    }}

Page 28: Programming in handstand

3 többszörösei

function multiples_of_3(){    return array_map(        multiply_by_3(),        range(1, 10)    );}function multiply_by_3(){    return function ($x) {        return $x * 3;    }}

Page 29: Programming in handstand

3 többszörösei

function multiples_of_3(){    return array_map(        multiply_by(3),        range(1, 10)    );}function multiply_by($n){    return function ($x) use ($n) {        return $x * $n;    }}

Page 30: Programming in handstand

3 többszörösei

function multiples_of($n){    return array_map(        multiply_by($n),        range(1, 10)    );}function multiply_by($n){    return function ($x) use ($n) {        return $x * $n;    }}

Page 31: Programming in handstand

3 többszörösei

function multiples_of($n){    return array_map(        multiply_by($n),        range(1, 10)    );}

var_dump( multiples_of(5) );// 5, 10, 15, 20, 25, 30, 35, 40, 45, 50

Page 32: Programming in handstand

A 3 első öt többszöröse

function take($n, array $from){    return array_slice($from, 0, $n);}

Page 33: Programming in handstand

A 3 első öt többszöröse

function take($n, array $from){    return array_slice($from, 0, $n);}

var_dump( multiples_of(3) );// 3, 6, 9, 12, 15, 18, 21, 24, 27, 30

var_dump( take(5, multiples_of(3)) );// 3, 6, 9, 12, 15

Page 34: Programming in handstand

A többi szám

function subtract(array $from, array $what){    return array_diff($from, $what);}

Page 35: Programming in handstand

A többi szám

function subtract(array $from, array $what){    return array_diff($from, $what);}

var_dump(    subtract(        range(1, 15),        take(5, multiples_of(3))    ));

// 1, 2, 4, 5, 7, 8, 10, 11, 13, 14

Page 36: Programming in handstand

4 halmaz, modulo 15

$multiples_of_3 = take(4, multiples_of(3));$multiples_of_5 = take(2, multiples_of(5));$multiples_of_both = array(0);$others = subtract(    range(1, 14),    array_merge($multiples_of_3, $multiples_of_5));

Page 37: Programming in handstand

4 halmaz, modulo 15

$multiples_of_3 = take(4, multiples_of(3));$multiples_of_5 = take(2, multiples_of(5));$multiples_of_both = array(0);$others = subtract(    range(1, 14),    array_merge($multiples_of_3, $multiples_of_5));

var_dump(    array_merge(        $multiples_of_3, $multiples_of_5,        $multiples_of_both, $others    ));// 3, 6, 9, 12, 5, 10, 0, 1, 2, 4, 7, 8, 11, 13, 14

Page 38: Programming in handstand

Érték → tömb

function repeat($value, $times){    return array_fill(0, $times, $value);}

var_dump( repeat(42, 4) );

// 42, 42, 42, 42

Page 39: Programming in handstand

Érték → tömb

function repeat($value, $times){    return array_fill(0, $times, $value);}

var_dump( repeat(function () {}, 4) );

// object(Closure)#1 (0) {},// object(Closure)#1 (0) {},// object(Closure)#1 (0) {},// object(Closure)#1 (0) {}

Page 40: Programming in handstand

( Tömb, tömb ) → tömb

Page 41: Programming in handstand

( Tömb, tömb ) → tömb

$keys = array(42, 43, 44);$values = array(    "Forty­two",    "Forty­three",    "Forty­four");

var_export(array_combine($keys, $values));

// array (//   42 => 'Forty­two',//   43 => 'Forty­three',//   44 => 'Forty­four',// )

Page 42: Programming in handstand

( Tömb, függvény ) → tömb

function for_all(array $values, $function) {    return array_combine(        $values,        repeat($function, count($values))    );}

Page 43: Programming in handstand

( Tömb, függvény ) → tömb

function for_all(array $values, $function) {    return array_combine(        $values,        repeat($function, count($values))    );}

$items = array(42, 43, 44);$do_something = function () {};var_dump( for_all($items, $do_something) );

// array(3) {//     [42] => object(Closure)#1 (0) {}//     [43] => object(Closure)#1 (0) {}//     [44] => object(Closure)#1 (0) {}// }

Page 44: Programming in handstand

Hol is tartunk?

$id = function ($x) { return $x; };$fizz = const_("Fizz");$buzz = const_("Buzz");$fizzbuzz = concat($fizz, $buzz);$functions = array(    $fizzbuzz,    $id,    $id,    $fizz,  $id,    $buzz,    $fizz,  $id,    $id,    $fizz,  $buzz,    $id,    $fizz,  $id,    $id);array_map(    function ($x) use ($functions) {        print $functions[$x % 15]($x) . ", ";    },    range(1, 100));

Page 45: Programming in handstand

Hol is tartunk?

$multiples_of_3 = take(4, multiples_of(3));$multiples_of_5 = take(2, multiples_of(5));$multiples_of_both = array(0);$others = subtract(    range(1, 14),    array_merge($multiples_of_3, $multiples_of_5));

$functions = for_all($multiples_of_3, $fizz)    + for_all($multiples_of_5, $buzz)    + for_all($multiples_of_both, $fizzbuzz)    + for_all($others, $id);

Page 46: Programming in handstand

Függvény → kiírás

function print_($function){    return function ($x) use ($function) {        print $function($x);    };}

Page 47: Programming in handstand

Alakul...

$functions = for_all($multiples_of_3, print_($fizz))    + for_all($multiples_of_5, print_($buzz))    + for_all($multiples_of_both, print_($fizzbuzz))    + for_all($others, print_($id));

array_map(    function ($x) use ($functions) {        print $functions[$x % 15]($x);        print ", ";    },    range(1, 100));

Page 48: Programming in handstand

Alakul...

$functions = for_all($multiples_of_3, print_($fizz))    + for_all($multiples_of_5, print_($buzz))    + for_all($multiples_of_both, print_($fizzbuzz))    + for_all($others, print_($id));

array_map(    function ($x) use ($functions) {        $functions[$x % 15]($x);        print ", ";    },    range(1, 100));

Page 49: Programming in handstand

Alakul...

$them = $id;

$functions = for_all($multiples_of_3, print_($fizz))    + for_all($multiples_of_5, print_($buzz))    + for_all($multiples_of_both, print_($fizzbuzz))    + for_all($others, print_($them));

array_map(    function ($x) use ($functions) {        $functions[$x % 15]($x);        print ", ";    },    range(1, 100));

Page 50: Programming in handstand

A végeredmény

for_all($multiples_of_3, print_($fizz)) + for_all($multiples_of_5, print_($buzz)) + for_all($multiples_of_both, print_($fizzbuzz)) + for_all($others, print_($them));

Page 51: Programming in handstand

A végeredmény

for_all($multiples_of_3, print_($fizz)) + for_all($multiples_of_5, print_($buzz)) + for_all($multiples_of_both, print_($fizzbuzz)) + for_all($others, print_($them));

Page 52: Programming in handstand

A végeredmény

for all  multiples of 3  print   fizz   for all  multiples of 5  print   buzz   for all  multiples of both  print   fizzbuzz   for all  others, print   them

Page 53: Programming in handstand

DON'T TRY THIS AT HOME!

Memória pazarló Lassú

Page 54: Programming in handstand

TRY THIS AT HOME!

Más szemlélet Mellékhatások nélkül → determinisztikus Trükkök:

Lazy evaluation (lazy iterators) Cache-elés Tail call optimization

Többszálúság? (Párhuzamos algoritmusok, skálázás)

Page 55: Programming in handstand

Köszönöm a figyelmet!

Page 56: Programming in handstand

Másik változat :-)

function fizzbuzz(){    $functions = array(        const_("FizzBuzz"), const_("Buzz"),        const_("Fizz"), id()    );    array_map(        function ($x) use ($functions) {            print $functions[                      !!($x % 3)                + 2 * !!($x % 5)            ]($x) . ", ";        },        range(1, 100)    );}

Page 57: Programming in handstand

Harmadik változat :-)

function fizzbuzz(){  array_map(    function ($x) {      print array_reduce(        array(          when(divisable_by(3), append(const_("Fizz"))),          when(divisable_by(5), append(const_("Buzz"))),          when(neither(), append(id())),        ),        apply_filter_with($x), ””      ) . ", ";    },    range(1, 100)  );}