Mais um blog inútil.

Arvorezinha

Agosto 3, 2018

Arvorezinha em Progress 4GL

Arquivado em: arvorezinha, coding, drama, fail, serious-business, useless, work — madinfo @ 16:35

Boa tarde,

Já não blolava á anos… resolvi blolar sobre uma linguagem que se chama Progress 4GL ou OpenEdge Advanced Business Language (OpenEdge ABL).
É uma linguagem linda que mais se devia chamar REGRESS em vez de Progress.

Aqui fica o código:

DEFINE VARIABLE i AS INTEGER NO-UNDO.
&SCOPED-DEFINE NumLoops  5    
DEFINE VARIABLE charz AS CHARACTER NO-UNDO INITIAL "*".

 REPEAT i = 1 TO {&NumLoops}:
     
     DISPLAY charz.
     charz = charz + "*".
END.


MESSAGE "Fim!!"
    VIEW-AS ALERT-BOX INFO BUTTONS OK.

Digam lá que não é a melhor coisa do mundo ?

Fevereiro 13, 2015

Arvorezinha em R

Arquivado em: arvorezinha, coding — joli @ 12:03

Viva,

Para celebrarem o Carnaval em força, e também porque me deram acesso ;) resolvi trazer-vos uma implementação da arvorezinha em R.
Para quem não sabe, e deixando de lado pormenores técnicos que não interessam nem ao menino jesus, R foi criado por um Cavalheiro no cu do mundo. Sim, na Nova Zelândia!

Apraz-me dizer que R é aprovada pelo RMS, pelo que o seu uso não interfere com a liberdade das pessoas.

Sem mais delonga deixem-me brindar-vos com a minha implementação.

littletree <- function(len) {
 for(i in 1:len) {
 y <- rep(' ',len-i)
 z <- paste(c(y, rep('*',(2*i)-1)), sep="", collapse = "")
 print(z)
 }

 lll <- (len * 2) - 1;
 empty <- ifelse(len %% 2 == 0, (lll/4)+1, (lll/4))
 stern <- ifelse(len %% 2 == 0, (lll/2), (lll/2)+1)
 for(x in 1:as.integer(len/2)) {
 y <- rep(' ', empty)
 z <- paste(c(y, rep('#',stern)), sep="", collapse = "")
 print(z)
 }
}

Como ver uma arvorezinha?

  • Instalar o R (O, pois refiro-me ao ambiente e não à linguagem de programação)
  • Fazer source da função.
  • Executar a função, passando como parâmetro a altura.

Nota: A implementação tem um bug quando a árvore tem altura 1. Fica para o caro leitor como exercício a sua correção.

Muito obrigado e um grande bem haja!

Janeiro 20, 2015

Arvorezinha 2.0 em JavaScript

Arquivado em: arvorezinha, coding, uncategorized — nausea @ 18:06
                    _..._
 Tired of using  .-'     '-.  Are you still using
 different cli  /     _    _\  that incoherent, bug
 ent and serv  /':.  (o)  /__)  ridden, insecure mess
 er languages /':. .,_    |  | that is PHP?
 on all your |': ; /  \   /_/
 web         /  ;  `"`"    }  Would you like to use a
 projects?  ; ':.,         {  modern, general-purpose,
           /      ;        }  web-scale, optimized,
 +-----------------------+ {  object-oriented, scalable,
 |      TESTEMONIALS     |`\  dependency-free, modular,
 | "I installed nodeJS.  |  ; agnostic, baked-in, light-
 | Five seconds of tink- |  | weight, component framework,
 | ering later I solved  |  ; responsive, event-driven,
 | world hunger, effectu |  | non-blocking i/o, efficent,
 | ated peace in the mid |  | perfect for data-intensive
 | dle east and started  |  / an,--.........,-time appli-
 | the first manned miss | ;  .'           -='.sy building
 | ion to jupiter while  |/  .\               'eautiful
 | holding a cigar in one|     \             .'pplications
 | hand and a death-ray  |\~"`_ \          .'gram like its
 | in the other."        ||   `  \      ..'rock out with
 +-----------------------+|  =="''\.==''your cock out
    ~ /; ;/=""      |`| |`|  `
    ~..==`     \\   |`| / /=="` Now You Can With Node.JS!
     ~` ~      /,\ / /= )")     The Cancer of Javascript
    ~ ~~         _')")          has just spread to servers!
    ~ ~   _,=~";`
    ~  =~"|;  ;|       Node.JSbird
     ~  ~ | ;  |       ===========
  ~ ~     |;|\ |    Available via NPM
          |/  \|

Não consigo deixar de nadar contra a corrente do blol/#c, que por norma odeia JavaScript e derivados. Trago-vos uma Arvorezinha 2.0 feita em JavaScript, que à boa moda deste blog, não acrescenta rigorosamente nada de interessante ou novo em relação às implementações anteriores. Podem corre-la na consola de qualquer browser, ou se quiserem crescer alguns centimetros de barba hipster, em node.js.

Futuramente farei algo com as funcionalidades do node, como por exemplo, um servidor de arvorezinhas à moda do phalic 100% RESTful.

var LittleTree = function(altura) {
    this.altura = altura;
}

LittleTree.prototype.makeTree = function() {

    var result = "";

    for (var i = 1; i <= this.altura; i++) {

        for (var j = 0; j < this.altura - i; j++) {
            result += " ";
        }

        for (var j = 1; j <= 2*i - 1; j++) {
            result += "*";
        }

        result += "\n";
    }

    return result;

}

LittleTree.prototype.makeTrunk = function() {

    var result = "";
    var lastLineWidth = this.altura * 2 - 1;

    if (this.altura % 2 > 0) {

        for (var i = 0; i <= (this.altura / 2); i++) {

            for (var j = 0; j <= lastLineWidth / 4 - 1; j++) {
                result += " ";
            }

            for (var j = 0; j <= lastLineWidth / 2; j++) {
                result += "#";
            }

            result += "\n";

        }

    } else {

        for (var i = 0; i <= (this.altura / 2); i++) {

            for (var j = 0; j <= lastLineWidth / 4; j++) {
                result += " ";
            }

            for (var j = 0; j <= lastLineWidth / 2 - 1; j++) {
                result += "x";
            }

            result += "\n";

        }

    }

    return result;
}

LittleTree.prototype.toString = function() {
    return this.altura + ":\n" + this.makeTree() + this.makeTrunk() + "\n";
}

var sizes = {
    1 : null,
    2 : null,
    3 : null,
    4 : null,
    5 : null,
    6 : null,
    10 : null,
    20 : null,
    40 : null,
};

for (size in sizes) {
    console.log(String(new LittleTree(size)));
}

Output:

1:
*
#


2:
 *
***
 x
 x


3:
  *
 ***
*****
 ###
 ###


4:
   *
  ***
 *****
*******
  xxx
  xxx
  xxx


5:
    *
   ***
  *****
 *******
*********
  #####
  #####
  #####


6:
     *
    ***
   *****
  *******
 *********
***********
   xxxxx
   xxxxx
   xxxxx
   xxxxx


10:
         *
        ***
       *****
      *******
     *********
    ***********
   *************
  ***************
 *****************
*******************
     xxxxxxxxx
     xxxxxxxxx
     xxxxxxxxx
     xxxxxxxxx
     xxxxxxxxx
     xxxxxxxxx


...

Update: Conforme prometido, fiz um serviço RESTful baseado neste script powered by node.js + express.io. Demorou 5 minutos a fazer, só com uma mão e enquanto mandava uma cagada, conforme prometido pelo passaroco ali acima.

Novembro 11, 2013

Arvorezinha v1 e v2 - Lisp

Arquivado em: arvorezinha, coding, useless — falso @ 10:55

Ora viva amigos!

Tive uma submissão de arvorezinhas de um comparsa dos mirques, o _Lone_Wolf_ , ele presenteou-nos com as duas versões em Lisp.

v1

(defun arvorezinha (count) (loop for i from 1 to count do (princ(concatenate 'string (make-string i :initial-element #\*) (format t "~%" #\linefeed)))))

v2

(defun arvorezinha2 (height) (loop
    (loop for i from 1 to height do (princ(concatenate 'string (make-string (- height i -1) :initial-element #\ ) (make-string (- (* 2 i) 1) :initial-element #\*) (format t "~%" #\linefeed))))    
    (setf trunk (floor (/ (- (* height 2) 1) 2)))
    (loop for i from 1 to (/ height 2) do
      (if (/= (mod height 2) 0)
          (princ(concatenate 'string (make-string (+ (/ trunk 2) 1) :initial-element #\ ) (make-string (+ trunk 1) :initial-element #\#) (format t "~%" #\linefeed)))
          (princ(concatenate 'string (make-string (+ (ceiling (/ trunk 2)) 1) :initial-element #\ ) (make-string trunk :initial-element #\#) (format t "~%" #\linefeed)))
      )
    )
    (return '*****)
))

Pode-se experimentar o codigo aqui: http://www.compileonline.com/execute_lisp_online.php
Já agora, o que está aí são só funções pelo que estive a ver. Então para experimentar corre-se o seguinte:

;;v1
(arvorezinha 5)
;;v2
(arvorezinha2 5)

Outubro 2, 2013

Arvorezinha 2.0 em Oracle SQL

Arquivado em: arvorezinha, coding, uncategorized — nausea @ 15:54

Ora viva amiguinhos! Antes de mais gostava de vos saudar e agradecer por me acolherem no melhor blog inútil do mundo. Sinto-me como um ilustre convidado com as maiores honrarias, e planeio contribuir com mais postas de programação inútil (logo que seja natural e espontânea).

A minha primeira contribuição é para o projecto árvorezinha. Tenho para vós uma árvorezinha que respeita o RFC 2.0 (já existia uma 1.0) feita em Oracle SQL.

select * from (
 select 'a'||lpad(level, 5,'0') as linha,
  rpad(' ', &altura-level, ' ') || rpad('*', 2*level-1, '*') as arvorezinha
 from dual
 connect by level <= &altura
 union
 select 't'||lpad(level, 5,'0') as linha,
  rpad(' ', ((2*&altura-1)/4)+1, ' ')||rpad('#', (2*&altura-1)/2, '#')
 from dual
 where mod(&altura, 2) = 0
 connect by level <= (&altura/2)
 union
 select 't'||lpad(level, 5,'0') as linha,
  rpad(' ', ((2*&altura-1)/4), ' ')||rpad('#', (2*&altura-1)/2+1, '#')
 from dual
 where mod(&altura, 2) > 0
 connect by level <= (&altura/2)
) order by linha asc;

A implementação usa 3 queries: uma para desenhar o topo (*), e duas para desenhar o tronco (#) nos casos de termos uma arvorezinha de altura par e de altura ímpar.  Utiliza-se a função rpad para criar uma string com caracteres repetidos e foi só implementar as fórmulas presentes no programa-RFC no argumento length do rpad e na clausula connect by.

Para garantir a ordenação das linhas, criei uma segunda coluna ’linha'.

Aqui estão os magníficos resultados:


Infelizmente, não é compatível com MySQL porque a melhor base de dados livre não suporta a clausula connect by level :(

Maio 30, 2012

Arvorezinha 2.0 - No explicit loops nor conditions, C99 & POSIX Compliant

Arquivado em: arvorezinha, coding, serious-business, useless — thread @ 12:52

Cá vai uma arvorezinha 2.0 totalmente inútil em C, sem loops nem condições (pelo menos, explicitamente)… um verdadeiro apedrejamento aos rins dos recursos. No entanto, está compliant com C99 e POSIX. Não está à prova de numeros demasiado grandes para o seu tamanho… receberão um exit status 1 caso se exceda o temporary size max e uma arvorezinha bem destruida.

Deixando-me de lengalengas… aqui vai:

-- EDIT: Nova versão do code. Não valia a pena criar outro post com mais do mesmo, portanto editei aqui mesmo.

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>

#define TEMPORARY_SIZE_MAX 128

int n, l, magic = 0;

void bye(void);
void bazinga(void);
void draw_bottom(void);
void draw_top(void);

void (*magic_matrix[2][2]) (void) = { { &bazinga, &draw_top }, { &bye, &draw_bottom } };


void sigsegv_syntax(int s) {
    printf("Invalid syntax.\n");
    exit(EXIT_FAILURE);
}

void sigsegv_toolarge(int s) {
    printf("Value too large.\n");
    exit(EXIT_FAILURE);
}

void bye(void) {
    exit(EXIT_SUCCESS);
}

void bazinga(void) {
    n = l;
    magic++;

    draw_bottom();
}

void draw_bottom(void) {
    printf("\x1b[%dC\x1b[%dD", (l / 2) * (n & 1) + 1, !(n & 1));
    fwrite(memset((char [TEMPORARY_SIZE_MAX]) { }, 0x23, TEMPORARY_SIZE_MAX), n & 1, l - !(l & 1), stdout);
    fwrite("\n", n & 1, 1, stdout);

    magic_matrix[magic][!!--n]();
}

void draw_top(void) {
    printf("\x1b[%d%c", n - 1, 0x43 + !(n - 1));
    fwrite(memset((char [TEMPORARY_SIZE_MAX]) { }, 0x2A, TEMPORARY_SIZE_MAX), 1, (((l - n) + 1) * 2) - 1, stdout);
    putchar('\n');

    magic_matrix[magic][!!--n]();
}


int main(int argc, char *argv[]) {
    signal(SIGSEGV, &sigsegv_syntax);

    n = l = atoi(argv[1]);

    signal(SIGSEGV, &sigsegv_toolarge);

    draw_top();

    return EXIT_SUCCESS;
}

PoC:

# gcc -Wall --std=c99 -o arv2 arv2.c
# ./arv2 15
              *
             ***
            *****
           *******
          *********
         ***********
        *************
       ***************
      *****************
     *******************
    *********************
   ***********************
  *************************
 ***************************
*****************************
       ###############
       ###############
       ###############
       ###############
       ###############
       ###############
       ###############
       ###############
# echo $?
0
#

Maio 28, 2012

Arvorezinha 2.0 - C++11 Templates

Arquivado em: arvorezinha, coding, serious-business, useless — dcoder @ 17:02

Ora viva!

Desde a minha última submissão, tem havido vasto progresso no estado da arte da Arvorezinha. Foi lançado um novo standard, e tem havido um renovado interesse em criar arvorezinhas cada vez mais obscuras e intricadas.

Isto traz-nos a este post. Um dos problemas fundamentais com as arvorezinhas anteriores em templates de C++ era que cada caracter era impresso de cada vez. Era muito mais interessante se pudéssemos gerar a string completa da arvorezinha durante a compilação, após o qual imprimir seria apenas uma questão de enviar a string para a função adequada (printf, cout, etc). Uma das novidades no novo standard de C++, oficializado o ano passado, são os variadic templates. Estes são uma versão em templates das funções com número de argumentos variável, como já existiam em C(++) e no pré-processador de C, que nos permite “construir” uma string caracter a caracter, e despejá-la numa initializer list quando acabamos.

Para simplificar a apresentação, desacoplei a lógica da arvorezinha da lógica que constrói a string, para ser mais fácil compreender a implementação. Também incluí uma versão não variádica opcional, caso não estejam satisfeitos.

#include <cstdio>

struct NullType {};
 
template<size_t N>
struct Arvorezinha2
{
    static const size_t NC = 2*N * (N + N/2);

    template<bool B, size_t L, size_t C> struct Pedaco;

    template<size_t L, size_t C>
    struct Pedaco<true, L, C> // Arvore
    {

        template<bool B, typename D>
        struct Ramo
        {
            static const char value = ' ';
        };              

        template<typename D>
        struct Ramo<true, D>
        {
            static const char value = '*';
        };

        static const size_t len = N*2 - 1;
        static const size_t beg = N-(L+1);
        static const size_t end = 2*(L+1)-1;
        static const char value = Ramo<C >= beg && C < beg + end, NullType>::value;
    };

    template<size_t L, size_t C>
    struct Pedaco<false, L, C> // Tronco
    {
        template<bool B, typename D>
        struct Lenha
        {
            static const char value = ' ';
        };

        template<typename D>
        struct Lenha<true,D>
        {
            static const char value = '#';
        };

        static const size_t len = N*2 - 1;
        static const size_t beg = len/4 - N%2 + 1;
        static const size_t end = len/2 - !(N%2);
        static const char value = Lenha<C >= beg && C <= beg + end, NullType>::value;
    };

    template<size_t L>
    struct Pedaco<true, L, 2*N-1>
    {
        static const char value = '\n';
    };

    template<size_t L>
    struct Pedaco<false, L, 2*N-1>
    {
        static const char value = '\n';
    };


    template<size_t X>
    struct Arvorezinha
    {
        static const size_t L = X / (2*N);
        static const size_t C = X % (2*N);
        static const char value = Pedaco<L < N, L, C>::value;
    };

    template<size_t I>
    struct AT
    {
        static const char value = Arvorezinha<I>::value;
    };    
};

template<template<size_t> class T, size_t N, bool V/*ariadic*/ = true>
struct Desenhar
{
    template<char... Str>
    static inline const char (&str())[sizeof...(Str)+1]
    {
        static const char value[sizeof...(Str)+1] = {Str..., 0};
        return value;
    }

    template<size_t I, typename D, char...Str>
    struct StringBuilder
    {
        static inline const char *toStr()
        {
            return StringBuilder<I+1, D, Str..., T<N>::template AT<I>::value>::toStr();
        }
    };

    template<typename D, char...Str>
    struct StringBuilder<T<N>::NC, D, Str...>
    {
        static inline const char *toStr()
        {
            return str<Str...>();
        }
    };

    static inline const char *toString()
    {
        return StringBuilder<0,NullType>::toStr();
    }

    static inline void desenhar()
    {
        puts(toString());
    }

};

template<template<size_t> class T, size_t N>
struct Desenhar<T, N, false>
{
    template<size_t i, typename D/*ummy*/>
    struct Rec
    {
        static inline void desenhar()
        {
            Rec<i-1,D>::desenhar();
            putchar(T<N>::template AT<i>::value);
        }
    };
 
    template<typename D>
    struct Rec<0,D>
    {
        static inline void desenhar()
        {
            putchar(T<N>::template AT<0>::value);
        }
    };
 
    static inline void desenhar()
    {
        Rec<T<N>::NC-1, NullType>::desenhar();
    }
};

int main(int argc, char **argv)
{
    Desenhar<Arvorezinha2, 5/*, true*/>::desenhar();
    return 0;
}

O resultado da compilação é essencialmente óptimo: o programa resume-me a carregar o endereço de uma string, e chamar a função puts:

0000000000400430 <main>:
  400430:	48 83 ec 08          	sub    $0x8,%rsp
  400434:	bf 40 06 40 00       	mov    $0x400640,%edi
  400439:	e8 d2 ff ff ff       	callq  400410 <puts@plt>
  40043e:	31 c0                	xor    %eax,%eax
  400440:	48 83 c4 08          	add    $0x8,%rsp
  400444:	c3                   	retq   
  400445:	90                   	nop
  400446:	90                   	nop
  400447:	90                   	nop

Bem haja!

Maio 14, 2012

Arvorezinha 2.0 Python

Arquivado em: arvorezinha, coding, serious-business, useless — thread @ 02:00

Ora cá vai mais uma Arvorezinha 2.0 em Python:

#!/usr/bin/python
import sys

print ("".join(map(lambda top: ((' ' * ((int(sys.argv[1])) - top / 2 - 1)) + ('*' * top)) + "\n", range(1, int(sys.argv[1]) * 2 + 1, 2))) + ((' ' * (int(sys.argv[1]) / 2)) + ('#' * (int(sys.argv[1]) - ((int(sys.argv[1]) + 1) % 2)) + "\n")) * (int(sys.argv[1]) / 2)).strip('\n')

Janeiro 4, 2012

Arvorezinha em perl

Arquivado em: arvorezinha, serious-business, useless — korn @ 16:54

Como a ultima arvorezinha era muito grande, vai aqui uma versão reduzida da v2!

#!/usr/bin/perl
$i=$ARGV[0];map{$a.=" "x($i-$_-1)."*"x($_*2+1)."\n";$b.=" "x($i/2)."#"x($i%2?$i:$i-1)."\n"if($i-$_+1)%2}(0..$i-1);print$a.$b;

Outubro 20, 2011

Novas arvorezinhas (1.0 e 2.0) em Perl

Arquivado em: arvorezinha, coding, serious-business, useless — falco @ 15:05

A arvorezinha em Perl que existe, não desenha a arvorezinha toda, com código escrito por quem faz o código da arvorezinha. Na minha opinião isso não respeitava o standard. Como tal achei que devia fazer uma arvorezinha como deve ser em Perl:

A versão 1.0:


print "*"x$_,"\n" for(1 .. 5);

Para este não ser um post demasiado parvo. Resolvi fazer uma arvorezinha em versão 2.0. em Perl. Inspirei-me no código do falso, mas não consegui resolver o bug do tronco (também não tentei muito):

use 5.010;
use strict;
use warnings;

# I'm not playing Perl Golf!

our $RAMO = "*";
our $ESPACO = qq/ /;
our $TRONCO = "#";



run();



sub run {
    my $altura = $ARGV[0] || 0;
    
    desenha_ramos($altura);
    desenha_tronco($altura);
}



sub desenha_ramos {
    my ($altura) = @_;

    for(1 .. $altura) {
        my $linha = desenha_elemento(1, ($altura - $_), $ESPACO);
        $linha .= $RAMO for( 1 .. (($_ * 2) - 1) );
        say $linha;
    }
}



sub desenha_tronco {
    my ($altura) = @_;

    my $largura = ($altura * 2) - 1;
    $altura = ($altura / 2);

    for(1 .. $altura) {
        if($altura % 2) {
            my $sombra = desenha_elemento(0, (($largura / 4) - 1), $ESPACO);
            my $tronco = desenha_elemento(0, (($largura / 2) - 1), $TRONCO);

            say $sombra.$tronco;
        }
        else {
            my $sombra = desenha_elemento(0, ($largura / 4), $ESPACO);
            my $tronco = desenha_elemento(1, (($largura / 2) - 1), $TRONCO);

            say $sombra.$tronco;
        }
    }
}



sub desenha_elemento {
    my ($min, $max, $tipo_elemento) = @_;

    my $elemento = $tipo_elemento;
    $elemento = sprintf("%s%s", $elemento, $tipo_elemento) for($min .. $max);

    return $elemento;
}