Mais um blog inútil.

Arvorezinha

Julho 4, 2011

BrainFucker

Arquivado em: arvorezinha, coding, osx, useless — falso @ 22:54

Ora viva!!!

Há uns tempos atrás vi nas internets um projecto verdadeiramente inutil, do calibre das coisas que vão aparecendo por aqui, chamado Brainfuck Developer, que é um IDE para programar e debugar Brainfuck.
Senti-me um pouco cabisbaixo ao ver que alguém tinha tentado chegar aos meus calcanhares em nível de inutilidade, portanto decidi por mãos à obra para me redimir. E então à boa maneira dos projectos open sores, decidi ripar a ideia, e comecei a desenvolver o BrainFucker, um IDE de Brainfuck para OSX!
Claro que isto não foi assim feito do pé-pra-mão, até porque não sabia nada de Objective-C nem de Cocoa, mas com o tempo, e pachorra aos fins de semana e tal, finalmente está disponível a versão 0.1.

Suporta correr programas de Brainfuck que só usem OUTPUT (.), o INPUT (,) ainda não está implementado, mas provavelmente vai ser uma DialogBox a pedir o valor.
Possibilidade de correr programas STEP-BY-STEP para ver as alterações dos valores e posição do apontador de memoria.

Espero que isto sirva para alguém aprender Brainfuck, ou mesmo para aprender como não programar em Objective-C.
O codigo está disponivel no github. E um build experimental está disponível: BrainFucker.zip - Apenas testado em OSX 10.4 e 10.5 POWERPC (só para quem ama). Agradeço a alguém que reporte se também funciona em Intels.

Cumprimentos, e um bem haja!

Dezembro 14, 2010

Árvorezinha 2.0

Arquivado em: arvorezinha, assembly, coding, drama, useless — falso @ 01:07

Ora viva amigos!

Há uns tempos no trabalho um colega meu começou a fazer pouco das minhas árvorezinhas, a dizer que só eram meia árvore, e que eu devia era de fazer uma árvore completa. Eu fiquei SENTIDO com tal AFRONTA, e fiquei a MATUTAR sobre isso, até que decidi por mãos à obra, e criar a Árvorezinha 2.0.

Primeiro decidi faze-la em C porque é a linguagem STANDARD!

[sourcecode language="c"]
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
        int altura;
        int i,x;
        int lul;

        if (argc < 2)
        {
                return(0);
        }
        altura = atoi(argv[1]);

        /* Ciclo da altura da Arvore */
        for(i = 1; i <= altura; i++)
        {

                /*
                        Numero de Espaços
                        Começa em 0 porque existem linhas com 0 espaços
                        Algoritmo: altura - linha
                */
                for(x = 0 ; x < (altura-i); x++)
                {
                        putchar(' ');
                }

                /*
                        Numero de Asteriscos
                        Começa em 1 porque não existem linhas sem *
                        Algoritmo: (2 * linha) - 1
                */
                for (x = 1; x <= (2*i)-1; x++)
                {
                        putchar('*');
                }

                putchar('\n');
        }

        /* Largura ultima linha */
        lul = (altura * 2) - 1;

        /*
                Ciclo da altura do tronco
                Algoritmo: altura / 2
        */
        for(i = 1; i <= (altura/2); i++)
        {
                /*
                        Por causa do ASCII nao permitir meio char
                        tive de fazer duas implementacoes diferentes,
                        uma para quando o  valor da altura do tronco
                        e' par, e outra para quando e' impar.
                */
                if (altura % 2)
                {
                        /* Impar */

                        /*
                                Numero de Espaços
                                Algoritmo: (lul / 4) - 1
                        */
                        for(x = 0; x <= (lul/4)-1; x++)
                        {
                                putchar(' ');
                        }


                        /*
                                Numero de # (tronco)
                                Algoritmo: lul / 2
                        */
                        for(x = 0; x <= (lul/2); x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
                else
                {
                        /* Par */

                        /*
                                Numero de Espaços
                                Algoritmo: lul / 4
                        */
                        for(x = 0; x <= (lul/4); x++)
                        {
                                putchar(' ');
                        }


                        /*
                                Numero de # (tronco)
                                Algoritmo: (lul / 2) - 1
                        */
                        for(x = 0; x <= (lul/2)-1; x++)
                        {
                                putchar('#');
                        }

                        putchar('\n');
                }
        }

}

[/sourcecode]

A pedido de muitas famílias, foi me imposta a tarefa de fazer um RFC da nova árvorezinha, mas não tenho muito jeito para escrever algoritmos em pseudo-código. Então tal obra heróica fica para o caro leitor, façam me um baseado no código em C e enviem-me!

Segundo as próprias leis já pré-estabelecidas da Árvorezinha, tem de existir uma implementação em Assembly! Então não podia cá faltar a minha versão em x86 Assembly.

[sourcecode language="plain"]

;
; Arvorezinha 2.0
; x86 Assembly
; Copyright (C) 2010 Pedro de Oliveira
; //blol.org
;
; this assembly can never fail
;
        BITS            32
        GLOBAL          main

; Vou usar duas funcoes da libc para o codigo nao crescer gigantescamente
; com rotinas que nao interessam nada para aqui.
        EXTERN          atoi
        EXTERN          printf

; Definicao das Variaveis
SECTION         .data

        argc    dd      0
        argv    dd      0

        erro    db      "ERRO! Executar: %s <altura da arvore>",10,0

        card    db      '#'
        newl    db      0xa
        aste    db      '*'
        espa    db      ' '

        altura  dd      0
        i       dd      1
        x       dd      0
        lul     dd      0

; He cometh!
SECTION         .text

main:
        pop     eax                     ; Ignorar...

        pop     eax                     ; Saca o argc da Stack
        mov     dword [argc], eax       ; Guarda o valor na variavel argc

        pop     ebx                     ; Saca a posicao de memoria do
                                        ; argv[0] da Stack
        mov     eax, dword [ebx]        ; Mete a posicao em EAX
        mov     [argv], eax             ; Guarda-a em argv

        add     ebx,0x4                 ; Salta 4 bytes para a frente
                                        ; para o argv[1] ficar em EBX

        mov     eax, [argc]             ; Mete o argc em EAX
        cmp     eax, 0x2                ; Verifica se e' diferente de 2
        jne     jafoste                 ; Se for sai com erro

        push    dword [ebx]             ; Mete o valor de argv[1] na Stack
        call    atoi                    ; Corre o atoi com esse valor
        mov     [altura], eax           ; O resultado fica em EAX, guarda
                                        ; na variavel altura

ciclo_linhas:
        ; INICIO - CICLO DAS LINHAS DA ARVORE
        mov     eax, [i]                ; i em EAX
        mov     ebx, [altura]           ; altura em EBX

        cmp     ebx, eax                ; Compara
        jb      prepara_tronco          ; i > altura ? proximo passo
        mov     dword [x], 0            ; Mete x a 0

ciclo_espacos:
        ; INICIO - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS
        mov     eax, [x]                ; x em EAX

        ; pretende-se (altura - i) em EBX
        mov     ebx, [altura]           ; altura em EBX
        mov     ecx, [i]                ; i em ECX
        sub     ebx, ecx                ; EBX - ECX

        cmp     ebx, eax                ; Compara
        jbe     prepara_asteriscos      ; x >= (altura - i) ? proximo passo

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_espacos           ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ESPAÇOS ANTES DOS ASTERISCOS

prepara_asteriscos:
        mov     dword [x], 1            ; Mete x a 1

ciclo_asteriscos:
        ; INICIO - CICLO DE ASTERISCOS (ARVORE)
        mov     ebx, [x]                ; x em EBX

        ; pretende-se (2 * i) - 1 em EAX
        mov     eax, 2                  ; 2 em EAX
        mov     ecx, [i]                ; i em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX

        cmp     eax, ebx                ; Compara
        jb      fim_ciclo_linhas        ; x > (2*i)-1 ? proximo passo

        push    aste                    ; Asterisco
        call    print                   ; write()

        call    incrementa_x
        jmp     ciclo_asteriscos        ; Volta para o inicio do ciclo
        ; FIM - CICLO DE ASTERISCOS (ARVORE)

fim_ciclo_linhas:
        push    newl                    ; Newline
        call    print                   ; write()

        call    incrementa_i
        jmp     ciclo_linhas            ; Volta para o inicio
        ; FIM - CICLO DAS LINHAS DA ARVORE

prepara_tronco:
        ; pretende-se (altura * 2) - 1 em EAX
        mov     eax, [altura]           ; altura em EAX
        mov     ecx, 2                  ; 2 em ECX
        mul     ecx                     ; Multiplica EAX por ECX
        dec     eax                     ; Subtrai 1 a EAX
        mov     dword [lul], eax        ; Guarda a largura da ultima linha
                                        ; em lul


        mov     dword [i], 1            ; Mete o i a 1

ciclo_linhas_tronco:
        ; BEGIN - CICLO DAS LINHAS DO TRONCO
        mov     ecx, [i]                ; i em ECX

        ; pretende-se (altura / 2)
        mov     eax, [altura]           ; altura em EAX
        shr     eax, 1                  ; divide por 2

        cmp     ecx, eax                ; Compara ECX com EAX
        jg      sair                    ; i > (altura / 2) ? Adeus!

        mov     eax, [altura]           ; altura em EAX
        test    eax, 1
        je      pc_tronco_par_espacos   ; e' par?

; --------------------------- IMPAR -------------------------------
pc_tronco_impar_espacos:
        mov     dword [x], 0            ; Mete-se x a 0

c_tronco_impar_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em EAX

        ; pretende-se (lul / 4) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; Divide por 4
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_impar_cardinal; x > (lul/4)-1 ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_impar_espacos  ; Volta para o inicio
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (IMPAR)

pc_tronco_impar_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_impar_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (IMPAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x > (lul/2) ? Next!

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_impar_cardinal ; Volta para o inico
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (IMPAR)

; --------------------- FIM IMPAR --------------------------------


; ----------------------------- PAR ------------------------------
pc_tronco_par_espacos:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_espacos:
        ; INICIO - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 4) em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 2                  ; divide por 4

        cmp     eax, ecx                ; Compara
        jb      pc_tronco_par_cardinal  ; x > (lul / 4) ? Next!

        push    espa                    ; Espaço
        call    print                   ; write()

        call    incrementa_x
        jmp     c_tronco_par_espacos    ; Volto para o inico do ciclo
        ; FIM - CICLO DOS ESPAÇOS ANTES DO TRONCO (PAR)

pc_tronco_par_cardinal:
        mov     dword [x], 0            ; Mete x a 0

c_tronco_par_cardinal:
        ; INICIO - CICLO DOS CARDINAIS DO TRONCO (PAR)
        mov     ecx, [x]                ; x em ECX

        ; pretende-se (lul / 2) - 1 em EAX
        mov     eax, [lul]              ; lul em EAX
        shr     eax, 1                  ; Divide por 2
        dec     eax                     ; Subtrai 1

        cmp     eax, ecx                ; Compara
        jb      fim_ciclo_linhas_tronco ; x > (lul / 2) - 1 ? uhuhuh

        push    card                    ; Cardinal
        call    print                   ; write()

        call    incrementa_x

        jmp     c_tronco_par_cardinal   ; Volta para o inicio do ciclo
        ; FIM - CICLO DOS CARDINAIS DO TRONCO (PAR)
; ----------------------- FIM PAR ----------------------------------

fim_ciclo_linhas_tronco:
        push    newl
        call    print

        call    incrementa_i
        jmp     ciclo_linhas_tronco     ; Volta para o inico do ciclo
        ; FIM - CICLO DAS LINHAS DO TRONCO

jafoste:
        mov     eax, [argv]             ; Mete o apontador de argv em EAX
        push    dword eax               ; Mete o endereço de argv na Stack
        push    dword erro              ; Mete o endereço da String na Stack
        call    printf                  ; Escreve no ecra!


sair:
        mov     ebx,0x0                 ; valor de saida
        mov     eax,0x1                 ; sys_exit
        int     0x80

print:
        mov     ecx,[esp+4]             ; Mete o argumento em ECX
        mov     edx,1                   ; Length
        mov     ebx,1                   ; stdout
        mov     eax,4                   ; sys_write
        int     0x80
        ret

incrementa_x:
        mov     eax, [x]
        inc     eax
        mov     dword [x], eax
        ret

incrementa_i:
        mov     eax, [i]
        inc     eax
        mov     dword [i], eax
        ret
[/sourcecode]

E aqui vai a prova dos nove:

[sourcecode language="plain"]
falso@lemonparty:~/src/zbr$ make
rm -f arvore2 arvore.o
nasm -f elf arvore.asm -o arvore.o
gcc -g -o arvore2 arvore.o
falso@lemonparty:~/src/zbr$ ./arvore2 4
   *
  ***
 *****
*******
  ###
  ###
falso@lemonparty:~/src/zbr$ ./arvore2 5
    *
   ***
  *****
 *******
*********
  #####
  #####
falso@lemonparty:~/src/zbr$
[/sourcecode]

Espero lançar futuramente um género de Unit Tests, para testar as varias implementações da Arvorezinha 2.0 que possam surgir, para ver se cumprem o standard ou não.

Espero que tenham gostado do post, até à proxima, fiquem bem e joguem muito! Chuuuuuuack!

Novembro 4, 2010

Arvorezinha --- C++ Templates 2

Arquivado em: arvorezinha, coding, useless — dcoder @ 03:00

Viva. Há demasiado tempo que não são adicionadas novas entradas à nossa já lendária colecção de arvorezinhas em várias linguagens e dialectos de todo o mundo.

Assim sendo, hoje trago-vos uma arvorezinha feita com templates de C++. Sim, eu sei. Já temos uma. Mas isto não me impede de utilizar outras capacidades de C++ para cumprir o mesmo objectivo. Ora vejam lá:

#include <iostream>

using namespace std;

template<int i>
struct SemiArvorezinha : public SemiArvorezinha<i-1>
{
	SemiArvorezinha(){cout << "*";}
};

template<> struct SemiArvorezinha<0> {};

template<int i>
struct Arvorezinha : public Arvorezinha<i-1>, SemiArvorezinha<i>
{
	Arvorezinha(){ cout << endl; }
};

template<> struct Arvorezinha<0>{};

int main(int argc, char **argv)
{
	Arvorezinha<5> A;
	return 0;
}

Em vez de funções com templates, temos nesta encarnação classes e multiple inheritance. Bem haja a todos.

Agosto 11, 2010

Arvorezinha – POSTSCRIPT

Arquivado em: arvorezinha — jsaramago @ 16:42

Boas,

depois de ver estas novas arvorezinhas, deu-me uma vontade de fazer uma. O postscript é muito marado, é uma maquina de stack, e ainda por cima, a origem das coordenadas é no canto inferior esquerdo. Aqui vai…

%!PS

/cm {28.34645669 mul} def %definir centrimetros
/size{2 cm}def %definir uma constante
/w{595}def %width da folha em pontos
/h{842}def %height da folha em pontos
/PageSize [ w h ]
/movetoTop{
	/yy exch def
	/xx exch def

	h yy sub
	/aux2 exch def

	xx aux2 moveto
}def % O (0,0) é no canto inferior esquerdo, então esta função transforma o (0,0) no canto superior esquerdo com as coordenadas positivas para baixo

/Courier             % Nome do tipo de letra
size selectfont      % Definir o tamanho da letra

0 1 4{
	/i exch def
	i size mul
	size add
	/yy exch def
	0 1 i{
		/j exch def
		j size mul
		size add
		/xx exch def
		xx yy movetoTop
		(*) show
		clear
	}for %colunas
}for %linhas

showpage             % imprimir página

O resultado final é este:

Arvorezinha em Windows PowerShell

Arquivado em: arvorezinha, coding, windows — amg @ 14:17

Após colocar a ideia da arvorezinha, vi muitos ports a aparecerem aqui. No entanto não estão mesmo na RFC da “primeira”, pois é pedido o numero maximo de bases da arvore (ler N e ir com um for ate N).

Hoje lembrei-me que ainda não colocaram aqui uma em Windows PowerShell, por isso aqui vai:

# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.

$str = “*”
$max = read-host “Num: "
For ($i=1;$i -le $max;$i++)
{
echo $str
$str += “*”
}

Agosto 10, 2010

Arvorezinha em AppleScript

Arquivado em: arvorezinha, coding, lulz, osx — gatuno @ 15:52

Boas tardes a todos,

Ontem à noite, pelas 4 ou 5 e tal da matina, provavelmente devido aos líquidos de Baco e afins, não consegui, por questões várias, colocar aqui a primeira versão da arvorezinha em AppleScript. Como poderá ver o leitor, trata-se de uma linguagem de programação altamente sofisticada e complexa, que não é para qualquer um…
Quem quiser faço um bundle para correr como aplicação :-)

(*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.

*)

set title to “\\m/ 4rV0R321NH4 4ppL3scR1p7 V1.0 H4rD3N3D \\m/”
set sloc to text returned of (display dialog “How many lines?
RFC is lines=5” with title title with icon 1 default answer “5” buttons {“Generate!”} default button 1)
set arv to ""
set j to sloc
set i to 1
try
repeat j times
repeat i times
set arv to arv & “*”
end repeat
set i to i + 1
set arv to arv & "
"
end repeat

display dialog arv with title title buttons {“Save the arvorezinha!”} default button 1
on error
display dialog “7H3R3 w42 4 3RR0r P4RS1N’ 73h NUMb3R 0f l1N32. 7ry 4941n!” with title title buttons {“OK”} default button 1
end try

Finalmente, ao executarmos o script, de acordo com o RFC, obtemos o seguinte resultado:

Salvem a arvorezinha!…

source

Junho 14, 2010

Arvorezinha - OCTAVE

Arquivado em: arvorezinha — jsaramago @ 22:04

Boas,

Noutro dia, estava eu muito bem a trabalhar para middleware na faculdade, até que veio ter comigo uma gaja das quimicas a perguntar se eu sabia como chamar uma função em octave. Tive que dizer que não sabia, mas pensei, ainda não existe uma arvorezinha em octave. Aqui vai ela.

C:\Octave\3.2.4_gcc-4.4.0\bin>cat arvorezinha-octave.txt
for i=1:5
	for j=1:i
		printf("*")
	endfor
	printf("\n")
endfor
C:\Octave\3.2.4_gcc-4.4.0\bin>octave.exe arvorezinha-octave.txt
GNU Octave, version 3.2.4
Copyright (C) 2009 John W. Eaton and others.
This is free software; see the source code for copying conditions.
There is ABSOLUTELY NO WARRANTY; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  For details, type `warranty'.

Octave was configured for "i686-pc-mingw32".

Additional information about Octave is available at http://www.octave.org.

Please contribute if you find this software useful.
For more information, visit http://www.octave.org/help-wanted.html

Report bugs to  (but first, please read
http://www.octave.org/bugs.html to learn how to write a helpful report).

For information about changes from previous versions, type `news'.

*
**
***
****
*****

Junho 7, 2010

Arvorezinha paralela - pthreads

Arquivado em: arvorezinha — jsaramago @ 16:12

Boas. Como meu primeiro post neste belíssimo blog decidi fazer uma arvorezinha nunca vista. Uma Arvorezinha paralela usando pthreads do C. Completamente inutil….

/*
*  arvorezinha_pthread.c
*
*  Created on: 28/5/2010
*  Author: João Saramago
*  Versão da arvorezinha paralela com pthreads
*/

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define LINHAS 5

void* arvorezinha(void*  arg){
	int i;
	int n=*(int*)arg;
	char* out = malloc(sizeof(char)*n+1);
	for (i = 0; i <n; ++i) {
		*(out+i)='*';
	}
	*(out+i)='\0';
	return (void*)out;
}

int main(int argc, char **argv) {
	int i;
	pthread_t t[LINHAS];
	
	for(i=1;i<=LINHAS;i++){
		pthread_create(&t[i-1],NULL,arvorezinha,&i);
	}

	for(i=0;i<LINHAS;i++){
		void* out;
		pthread_join(t[i],&out);
		printf("%s\n",(char*)out);
		free(out);
	}
}

Junho 4, 2010

Windows Mobile 7 - Arvorezinha

Arquivado em: arvorezinha — drune @ 17:14

Boa Tarde,

Podem já ter na vossa posse uma fantástica e mágica aplicação que vai revolucionar a nossa forma de ver e usar arvorezinhas no dia a dia. Assim que experimentarem no vosso novo telémovel com windows mobile 7 todo o vosso mundo vai mudar…

O conselho de administração deste blog está a pensar colocá-lo à venda no Windows Market Share e também no Android Market a correr em cima de wine.

PS: O código fonte não está disponível devido à complexidade

Maio 29, 2010

Portugal@Rippar - Os rippers contra-atacam

Arquivado em: arvorezinha, drama, java, serious-business — falco @ 10:51

Antes de mais, devo dizer, que estou emocionado pela quantidade de arvorezinhas que surgiram depois dos meus dois posts de arvorezinhas…

Agora vou ao assunto deste post.
O “ripanço” (desculpa dcoder), no Portugal@Rippar está de volta!
Digo de volta porque até uma arvorezinha já foi ripada. Um dia conto o drama todo como deve ser, mas vai ser difícil porque eu não ripei o texto da discussão antes dos donos do fórum o terem apagado para esconder as asneiras que fizeram e as acusações injuriosas que fizeram a mim e ao falso.

Desta vez algum “ripper” resolveu rippar uma calendário feito em java o jcalendar. O GNU Cop, já avisou os moderadores do fórum, vamos ver agora como vai decorrer o drama.

Update: O autor do software já corrigiu a situação.