Resposta do Desafio do dia / 2

20 04 2007

Resposta do Desafio do dia / 2

Vamos por partes:

Um dos objetivos deste desafio era demonstrar que blocos de códigos podem ser utilizados em qualquer parte, e não apenas em estruturas de controle, decisão, etc. O seguinte trecho de código é perfeitamente válido e funcional (apesar de “estranho”)

<?php
  
{
      
$foo ‘foo’;
      echo 
$foo;
  }

Como pode se observar no desafio, coloquei o código em diversos blocos, mas apenas para isso: Demonstrar que é possível utilizar em qualquer lugar. Para resolução do desafio, é indispensável conhecimento de operações bit-a-bit. Como não é todo mundo que tem esse conhecimento, um outro objetivo do desafio era despertar a curiosidade de quem não soubesse e quisesse resolver e também falar um pouco sobre isso (na resposta). Segue agora então o mesmo código, comentado, com a resposta do desafio:


<?php
  
// desafio2.php

  // para acompanhar, segue alguns numeros binarios:
  //
  // 000 0
  // 001 1
  // 010 2
  // 011 3
  // 100 4
  // 101 5
  // 110 6
  // 111 7
  // iniciamos $x com valor 2
  $x 2;
  {
    
// aqui temos também um pequeno truque:
    // print é utilizado para exibir uma mensagem,
    // e sempre retorna 1. Logo, sera exibida a
    // mensagem ‘Iniciando ‘ e $x sera incrementado
    // em 1. Neste momento temos:
    // $x = 3
    
$x += print(‘Iniciando ‘);
    {
        
// aqui sera exibido ‘desafio 2’
        
echo ‘desafio 2’;
        
        
// aqui temos a primeira operacão bit-a-bit,
        // um ‘left shift’ de $x em 1 passo. Vejamos
        // o que tinhamos e o que sera retornado para $y
        // 
        // $x = 011 (3)
        //
        // deslocando 1 bit a esquerda teremos 110 (6)
        //
        // nesse momento temos:
        //
        // $x = 3 (nao modificamos $x)
        // $y = 6
        
$y $x << 1;
    }
    
// aqui são feitas várias operações. Vamos começar
    // pelas mais internas e com maior prioridade:
    //
    // $y^$x
    //
    // Aqui temos um $y xor $x. XOR – exclusive or – retornará
    // os bits que estão ativos em $y e os que estão ativos
    // em $x,  mas não os que estão ativos em ambos: veja:
    //
    // $x = 011
    // $y = 110
    // —- 101
    //
    // observe que como o segundo bit estava ativo em ambos,
    // ele nao estara ativo na saída. Entao após esta operação, 
    // o retorno será 5 (101)
    //
    // logo após esta operação, temos um “not”:
    //
    // ~($y^$x), ou seja ~(5) ou ~5.
    //
    // aqui ocorre uma inversão de cada bit: Os que estão ativos
    // serão desativados e os que estão desativados serão ativados:
    //
    // 5 – 101
    // — 010
    //
    // o resultado desta operação então seria 2 (010)
    //
    // Mas tem um pequeno “problema”: A operacao deve ser feita em
    // todos os bits. Logo, ~5 = 11111111111111111111111111111010 e
    // 11111111111111111111111111111010 = -6
    //
    // temos entao que o resultado da operacao ~($y^$x) = -6
    // o resultado disso tudo é retornado por sprintf.
    // 
    // Aproxima operação, por ordem dos operadores, é $y + (-6), ou 
    // seja $y + sprintf(‘%d’,~($y^$x)). Isso porque o operador ‘+’ tem
    // precedência ante ao ‘|’. Então temos
    //
    // $6 + (-6) = 0
    //
    // apos isto, temos “$x | 0”. Aqui o os bits que estão ativos ou 
    // em $x ou em 0 (ou ambos, diferentemente do xor) estarão ativos na
    // saída. Como 0 não tem bits ativos, o resultado da operação sera o
    // própio valor de $x:
    //
    // $x = 011
    // 0  = 000
    // —- 011 (3)
    //
    // finalmente, temos que $y = 3
    //
    // ao final disso entao:
    //
    // $x = 3
    // $y = 3
    
$y $x $y sprintf(‘%d’,~($y^$x));

    // apenas exibimos um “\n”. O $z não é utilizado mais
    
$z = print(“\n”);
    
    
// verificamos se $x é menor do que $y (não é)
    
if ($x $y) {
        
$x ^= $x;
    
// observe que aqui não temos um else. Então esse trecho
    // será executado de qualquer forma (mesmo que o if anterior
    // fosse verdadeiro. Foi utilizado apenas para “confundir” : )
    
} {
        
// Fazemos um xor de $y em $y. Lembre-se que no xor, o retorno
        // são os bits que estão ativos ou em um ou em outro número, mas
        // não em ambos. Como o xor está sendo feito no mesmo número, o que
        // estiver ativo em um também estará ativo em outro. Logo, o retorno
        // será 0 (este tipo de operação é bastante utilizada em assembly, 
        // quando se deseja zerar o valor de algum registrador: “xor eax, eax”
        // “xor ebx, ebx”, …)
        //
        // $y = 011
        // $y = 011
        // —- 000
        //
        //
        
$y ^= $y;
    
// novamente utilizamos um bloco, que será executado de qualquer forma
    
} {
        
// verificamos se $x (3) é maior do que $y (0). Como sabemos que é,
        // será exibido ‘$y menor do que $x’
        
if ($x $y) {
            echo 
‘$y menor do que $x’;
        
// e este trecho será ignorado : )
        
} else {
            echo 
‘$y maior do que $x’;
        }
    }
  }
  
// finalmente, exibimos um último “\n”
  
echo “\n”;
?>

Ao final disso, temos então:

Iniciando desafio 2
$y menor do que $x

É isso, espero que tenha aprendido um pouco sobre bitwise operations neste desafio.





Desafio do dia / 2

18 04 2007

Depois de ter sido explicado o primeiro desafio, vamos partir para o segundo.
Que tal algumas operações bit-a-bit ?


<?php
  
// desafio2.php
  
$x 2;
  {
    
$x += print(‘Iniciando ‘);
    {
        echo 
‘desafio 2’;
        
$y $x << 1;
    }
    
$y $x $y sprintf(‘%d’,~($y^$x));

    $z = print(“\n”);
    
    if (
$x $y) {
        
$x ^= $x;
    } {
        
$y ^= $y;
    } {
        if (
$x $y) {
            echo 
‘$y menor do que $x’;
        } else {
            echo 
‘$y maior do que $x’;
        }
    }
  }
  echo 
“\n”;

A pergunta é: O que será exibido na execução do script ?
Resposta e explicação em breve.
Nota: Não vale executar para saber : )





Resposta Desafio do Dia

18 04 2007

Fala galerinha : )
Bom, existem certas pessoas ai que propoem desafios, não sabem resolver, e ai ficam me implorando no msn para que eu resolva.
Vamos então dar uma explicação aí sobre o funcionamento desse código, e demonstrar o resultado.


<?php
// desafio1.php

$n  'X';
$
$n 'N';
$m  'Y';
$
$m 'M';
$c  = (int)($n == $$n);

echo $
    {
        $c == 
    
$n:
    
$m
    
};
?>

Como todos sabem, o símbolo de $, indica a declaração de uma variável, mas muitos não conhecem a utilização do $$
O símbolo $$, significa que estamos utilizando o valor definido na váriavel, para transforma-la em variável. Hein?
Vejamos esse exemplo:


<?php

$x 'var1';

// Essa linha é o mesmo que $var1 = 'Oi, sou a variavel 1';
$$x 'Oi, sou a variavel 1';

echo $var1;

?>

Acho que esse exemplo deixa tudo bem claro né?
Acredito que outra parte que pode confundir no código, é o cast que o nosso amiguinho faz:
$c = (int)($n == $$n);
Isso ai nada mais é do que o retorno de um if. Ele verifica se $n == $$n, ou seja, está verificando se $n == $X. Caso seja, isso ai deve retornar true, caso não seja deve retornar false. Aquele (int) na frente, converte o tipo bool para o tipo int. True será convertido para 1, false será convertido para 0.
Como sabemos que $n não é igual a $X, essa sentença irá retornar 0.

Agora vem a pegadinha da coisa, a função echo. Irei escreve-la em uma só linha para ficar mais claro:

echo ${ $c == 1 ? $n : $m };

O que o rapazinho faz ai, é basicamente um if também, perguntando se $c é igual a 1 (que nós já sabemos que não é). Caso $c fosse igual a 1, essa sentença retornaria o valor de $n, mas como não é, o que ela faz é retornar o valor de $m. Sabemos que $m vale ‘Y’, logo, reescrevendo essa linha após o resultado do if, teriamos:

echo $Y;

$Y nós sabemos que vale ‘M’. Tadam! Respondido o desafio do menino E. Silva ; D
Espero que tenham achado interessante ; D

[]s





Desafio do dia

17 04 2007

O que será exibido durante a execução do seguinte script (se funcionar):


<?php
// desafio1.php

$n  ‘X’;
$
$n ‘N’;
$m  ‘Y’;
$
$m ‘M’;
$c  = (int)($n == $$n);

echo $
    {
      $c == 
        
$n:
        
$m
    
};
?>

Explicação no próximo post (junto com mais um desafio) : )