Mais um blog inútil.

Novembro 11, 2013

Arvorezinha v1 e v2 – Lisp

Filed under: 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

Filed under: Arvorezinha,Coding,Uncategorized — neofreak @ 16: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 :(

Junho 2, 2013

De onde tudo começou…

Filed under: Coding — falso @ 21:12

Ora viva!

Ultimamente tenho andado a fazer reverse engineering ao classico do Spectrum o Paradise Café, mas essa historia fica para mais para a frente, entretanto ontem andava ali de volta das minhas cassetes do Spectrum a ver o que tinha para la guardado, e lá no meio achei uma cassete que dizia "SUPER MEGA TAPE", e claro decidi investigar ;-)

Liguei a aparelhagem old school ao line in, e pus me a gravar a cena, ate conseguir uma qualidade fiável. E fiquei maravilhado com o que achei!

É uma "mix-tape" com vários jogos para o Spectrum que fiz para amigos. E em cada lado pus uma pequena "intro" com "INSTROCOES" (lol). Tudo feito com BASIC, e com altas truques que via na altura nas revistas para esconder as listagens e cenas do género. Isto foi feito quando era bues puto, e provavelmente foi daqui que veio o gosto pelas programações.

tape1 De onde tudo começou...
   0\{p0} POKE (PEEK 23635+256*PEEK 23636+1),0: REM                          \#017\#000\#017\#006OLHEM OUTRO MIRONE\#017\#007\#017\#000
   5\{p0} INK 0
  10\{p0} FOR a=0 TO 21
  20\{p0} LET b=RND*6
  30\{p0} PRINT AT a,0; INK b;"\::!!!!!!!!!!INSTROCOES!!!!!!!!!!\::": BEEP .01,a
  40\{b1p0} BEEP .01,a
  50\{p0} NEXT a
  60\{p0} PAUSE 0
  70\{p0} CLS 
  80\{p0} FOR a=0 TO 6
  90\{p0} PRINT AT 10,1; INK a;"INSTROCOES DA SUPER MEGA TAPE": PAUSE 5
 100\{p0} NEXT a
 110\{p0} PAUSE 0
 120\{p0} CLS 
 130\{p0} PRINT AT 0,0; INK 0;"\{p7}INSTROCOES DO";AT 0,15; INK 7; PAPER 0; FLASH 1; BRIGHT 1;"SUPER TROLLEY !!!"
 140\{p0} INK 0: PRINT AT 2,0;"\{p0p7p6}SUPER TROLLEY\{p7p7p7p7p7p7p6p4p3p2p1p1p2p3p4p5p6p7b0b1} um jogo com bons graficos(de porcaria).O jogo serve para a gente ir as compras..No primeiro nivel tem que se logo encher os barris de tracinhos(como este{-}).O segundo nivel ja' e' nas compras ,isso e que eu nao sei o que e' para fazer....": PRINT "\{p1p2p3p4p5p6p7b0b1}  Teclado redefenivel!!!"
 150\{p0} PRINT #0;"PULSA UMA TECLA PARA CONTINUAR!!"
 160\{p0} PAUSE 0
 170\{p0} INK 0: CLS 
 180 INK 0:\{p0} PRINT AT 0,0;"INSTROCOES DO";AT 0,15; INK 7; PAPER 0; FLASH 1; BRIGHT 1;"SKATE WARS !!!"
 190\{p0} PRINT AT 2,0;"\{p6}SKATE WARS\{p7p1p2p3p4p5p6p7b0b1} e' o desporto do futuro!A gente vamos jogar num estadio de gelo.Voces como sao estupidos nao vao chegar ao nivel 9..As teclas do Jugador 1 sao:X=ESQUERDA..C=DIREITA..J=CIMA..N=BAIXO..K=FOGO E SALTO..As teclas do jugador 2 sao:Z=ESQUERDA..X=DIREITA..K=CIMA..M=BAIXO..L=FOGO E SALTO"
 200 PRINT #0;"PULSE UMA TECLA PARA CONTINUAR!!"
 210 INK 0:\{b0b0b0p6p5p0} PAUSE 0
 220 INK 9: CLS 
 230 PRINT AT 0,0;"INSTROCOES DO";AT 0,15; INK 7; PAPER 0; FLASH 1; BRIGHT 1;"ARKANOID !!!"
 240 PRINT AT 2,0;"\{p6}ARKANOID\{p7p1p2p3p4p5p6p7b0b1} um jogo que e' para derrubar paredes, o jogo se eu me lembro tem 32 niveis,mas a partir do 30 sao bue dificeis como o caracas..As teclas sao:1=ESQUERDA..2=DIREITA..A S D F G H J K L=AMANDAR A BOLA.Aquelas letras todas sao para atirar a bola,mas a que da' mais jeito e' o {G}...\{p7p7p7p7p6p5p6p7p6p5p4p3p2p1p2p3p4p5p6p6p7b0}"
 250\{p0} PRINT #0;"PULSE UMA TECLA PARA CONTINUAR!!"
 260\{p0} PAUSE 0
 270 INK 0:\{p0} CLS 
 280\{p0} FOR a=0 TO 64
 290\{p0} BEEP .01,a
 300\{p0} NEXT a
 310\{p0} PRINT AT 10,8;"SUPER MEGA TAPE"
 320\{p0} PAUSE 0
 330\{p0} RANDOMIZE USR 0: PRINT USR 0: NEW 
1000 POKE PEEK 23635+256*PEEK 23636,1

  10 IF INKEY$="1" THEN GO TO 110
  20 IF INKEY$="2" THEN GO TO 140
  30 IF INKEY$="3" THEN GO TO 170
  40 GO TO 10
  50 RESTORE : PAPER 1: CLS : FLASH 0: BORDER 5: INPUT "": LET a$=" SUPER MEGA TAPE ": LET b$=a$
  60 INK 7: PLOT 0,0: DRAW 255,0: DRAW 0,175: DRAW -255,0: DRAW 0,-175
  70 PRINT AT 5,4;"INSTROCOES DO :"
  80 PAPER 5: INK 0: PRINT AT 6,4;"1=GREAT ESCAPE";AT 8,4;"2=CAVEMANIA";AT 10,4;"3=JUNGLE WARRIOR"
  90 FOR i=1 TO 26: PRINT #0; PAPER 6; BRIGHT 1;AT 1,7;b$: GO SUB 20: BEEP .0004,45: GO SUB 20: BEEP .0006,55: GO SUB 20: NEXT i
 100 GO TO 90
 110 INK 7: PAPER 0: BORDER 0: CLS 
 120 PRINT "GREAT ESCAPE-Um jogo fixe so que para mim custa muito a passar...": PRINT "Da para redefinir as teclas": PRINT "Cuidado com os guardas."
 130 PAUSE 0: CLS : GO TO 50
 140 INK 7: PAPER 0: BORDER 0: CLS 
 150 PRINT "CAVEMANIA-Um jogo bue facil como o caracas tem-se 99vidas,o jogo e' para apanhar ovos num ninho,e mete-los na nossa casa.": PRINT "Teclado redefenivel": PRINT "Cuidado com os vulcoes."
 160 PAUSE 0: CLS : GO TO 50
 170 INK 7: PAPER 0: BORDER 0: CLS 
 180 PRINT "JUNGLE WARRIOR-Um jogo que eu nao sei o que e' para fazer mas eu acho que e' para salvar o mulher que esta pendurada numa arvore.Quando a gente perdemos uma vida,a gente transforma-se em um anjinho.": PRINT "Teclado redefenivel.": PRINT "Cuidado com os fantasmas."
 190 PAUSE 0: CLS : GO TO 50

tape3 De onde tudo começou...
   1 BORDER 0: INK 0: PAPER 0: CLS 
  10 REM \#017\#007EI OLHEM OUTRO MIRONE\#017\#000
  20 REM \#017\#007ESTUPIDO COMO OS\#017\#000
  30 REM \#017\#007CAMELOS,ANDA CAMELO!!\#017\#000
  40 REM \#017\#007NAO VEZ UM BOI!!!\#017\#000
  50 REM \#017\#007ESPECIAL/////\#017\#000
  60 REM \#017\#007NAO BEZ UM VOI!!!\#017\#000
  70 REM \#017\#007SEUS BORRADAS\#017\#000
  80 REM \#017\#007SEUS CAGADAS\#017\#000
  90 REM \#017\#007DAQUI FALA\#017\#000
 100 REM \#017\#007O PEDRO\#017\#000
 110 REM \#017\#007DA\#017\#000
 120 REM \#017\#007SUPER MEGA TAPE\#017\#000

- Lado A - WAV - TZX
- Lado B - WAV - TZX
- Extra - WAV - TZX

Janeiro 27, 2013

Refeitórios da UNL no Google Calendar

Filed under: Coding,Serious Business — falso @ 4:07

Ora viva!
Após pedidos de muitas famílias venho desta vez blogar sobre algo útil!

Desde que fiz o post sobre a Cantina da FCT/UNL no Google Calendar já tive alguns pedidos para fazer o mesmo para outras escolas da UNL, então hoje decidi por mãos à obra e aqui vai o resultado.

Local Almoço Jantar
Faculdade de Ciências e Tecnologia | Refeitório Adicionar Adicionar
Faculdade de Ciências Médicas | Cafetaria Adicionar Adicionar
Faculdade de Ciências Sociais e Humanas | Refeitório Adicionar Adicionar
Faculdade de Ciências Sociais e Humanas | Snack Adicionar Adicionar
Residência Alfredo de Sousa | Refeitório Adicionar Adicionar

Os eventos nos calendários são inseridos todos os dias úteis às 4:30.
Já agora para quem não sabe, a grande utilidade destes calendários é que no Google Calendar existe uma opção para nos alertar de eventos através de uma SMS, então com essa funcionalidade pode-se meter a enviar uma SMS todos os dias a avisar o que é a comida na cantina.

Novembro 8, 2012

A Água

Filed under: lulz,Useless — sadik @ 22:58

Boas noites caros amigos das internets.

Venho por este meio, usar este lindo blol para publicar o seguinte poema do grande Bocage.

"A Água"
Meus senhores eu sou a água
que lava a cara, que lava os olhos
que lava a rata e os entrefolhos
que lava a nabiça e os agriões
que lava a piça e os colhões
que lava as damas e o que está vago
pois lava as mamas e por onde cago.

Meus senhores aqui está a água
que rega a salsa e o rabanete
que lava a língua a quem faz minete
que lava o chibo mesmo da raspa
tira o cheiro a bacalhau rasca
que bebe o homem, que bebe o cão
que lava a cona e o berbigão.

Meus senhores aqui está a água
que lava os olhos e os grelinhos
que lava a cona e os paninhos
que lava o sangue das grandes lutas
que lava sérias e lava putas
apaga o lume e o borralho
e que lava as guelras ao caralho

Meus senhores aqui está a água
que rega rosas e manjericos
que lava o bidé, que lava penicos
tira mau cheiro das algibeiras
dá de beber ás fressureiras
lava a tromba a qualquer fantoche e
lava a boca depois de um broche.

Junho 20, 2012

Blocos de endereçamento IP por país

Filed under: Coding,Useless — thread @ 6:46

Bom dia malta das inutilidades.

Venho aqui partilhar mais uma das minhas muitas inutilidades... um escripe em pitão inútil que faz a consulta online de ip address blocks atribuidos a um determinado pais e devolve uma lista dos mesmos.
No site onde faço o request, têm a versão csv disponivel também... mas isso não tem piada e não é inútil pois não poderia usar um html parser e a coisa ia ficar assim meia deslavada e desenquadrada no blol.

A sintaxe não poderia ser mais simples:

$ ./escripe.py acronimo

Eg:

$ ./escripe.py pt
(e receberão uma lista de blocos (um bloco por linha) no formato "from X to Y")

Cá vai:


#!/usr/bin/python

import sys
import httplib
import re
from HTMLParser import HTMLParser

raw_block_list = []

class ORHTMLParser(HTMLParser):
        def handle_data(self, data):
                pat = re.search(r"^((\d{1,3}\.){3,3}\d{1,3})$", data.strip(' '))

                if pat:
                        raw_block_list.append(pat.group(1))

if len(sys.argv) != 2:
        print "Usage: %s <country acronym>\nExamples:\n\t%s pt\n\t%s fr\n\t%s us" % (eval("sys.argv[0]," * 4))
        sys.exit(1)

try:
        rhost = httplib.HTTPConnection("www.nirsoft.net")
        rhost.request("GET", "/countryip/%s.html" % sys.argv[1])
        pbody = rhost.getresponse().read()
        rhost.close()
except:
        print "Ops..."
        sys.exit(1)

ORHTMLParser().feed(pbody)

paired_block_list = map(lambda start, end: (start, end), raw_block_list[0::2], raw_block_list[1::2])

for pair in paired_block_list:
        print "from", pair[0], "to", pair[1]

Saudações

Maio 30, 2012

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

Filed under: Arvorezinha,Coding,Serious Business,Useless — thread @ 13: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

Filed under: Arvorezinha,Coding,Serious Business,Useless — dongs @ 18: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

Filed under: Arvorezinha,Coding,Serious Business,Useless — thread @ 3: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

Filed under: 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;
« Posts anteriores
widgeon
widgeon
widgeon
widgeon