Riscrivere le funzioni built-in

Stato
Discussione chiusa ad ulteriori risposte.

fojeaf

Utente Silver
3 Marzo 2008
235
8
0
95
quello che secondo me è un buon esercizio è riscrivere le funzioni built-in dei vari linguaggi.

Porto come esempio 2 funzioni molto usate in python come range e xrange che metto in ot (per nn fare da spoiler).

[ot]
ecco range
Codice:
def range(start,stop,maxsplit=1):
    l=[]
    while start<stop:
        l.append(start)
        start+=maxsplit
    return l
ed ecco xrange
Codice:
def xrange(start,stop,maxsplit=1):
    if start>=stop:
        raise ValueError,"cannot generate generator from %g to %g" % (start,stop)
    c=start
    b=maxsplit
    while c<stop:
        c+=b
        yield c-b
[/ot]
Inoltre saprei già come fare la funzione sum ma attualmente nn ho tempo.

detto questo apro questo topic perchè vengano postate le vostre idee per riscrivere (magari anche migliorandola) una funzione built-in in un determinato linguaggio.

L'unica regola è quella di usare meno possibile funzioni built-in, usare solo keywords se possibile.
 
Funzione count di PHP:
PHP:
function my_count($array){
$i=0;
foreach ($array as $t){
$i++;
}
return $i;
}
Vabbè, era semplice, domani ne faccio delle altre.
 
In D
(reverse e split)
Codice:
import std.stdio;
import std.string;

string reverse(string i) {
	string o="";
	for(int j=(i.length-1);j>=0;j--)
		o~=i[j];
	return o;
}

string[] split(string s, char c) {
	string[] buffer=new string[1];
	string[] app;
	int z=0;
	for(int i=0;i<s.length;i++) {
		if(s[i]==c) { 
			z++; 
			app = new string[z];
			inA(buffer,app);
			buffer=new string[z+1];
			inA(app,buffer);
		}
		else  buffer[z]~=s[i]; 
	}
	return buffer[];
}

void inA(string[] a, string[] b) {
	for(int i=0;i<a.length;i++)
		b[i]=a[i];
}

int main(string[] args) {
	writefln("%s",reverse("ciao"));
	string[] s = split("Ciao|ciao|ciaO|cIaO",'|');
	foreach(g; s)
		writefln("%s",g);
	return 0;
}
 
Visto che Razor si è lamentato del mio uso della funzione count per risolvere un altro esercizio, la reimplemento qui.
Codice:
def my_count(string, search, start=None, end=None):
	counter = 0
	if start==None: start=0
	if end==None: end=len(string)
	for char in string[start:end]:
		counter += 1 if char==search else 0
	return counter
 
Ecco una serie di funzioni built-in del PHP, che sono usate dalla funzione finale lower_case_array() che converte un array in caratteri lower-case.
Divertitevi.
PHP:
function my_count($array){
$i=0;
foreach ($array as $t){
$i++;
}
return $i;
}
function my_array_keys($array) {
$return=array();
foreach ($array as $key => $value){
$return[] = $key;
}
return $return;
}
function my_strlen($string) {
$think=str_split($string,1); // Perdonatemi, ho usato una funzione built-in.
$count=0;
foreach ($think as $lettera){
$count++;
}
return $count;
}

function my_strtolower($string){
$lower=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');
$upper=array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
$final='';
$final = str_replace($upper,$lower,$string); // Come my_strlen, ho usato una funzione built-in...
return $final;
}
function lower_case_array($array) {
$keys=my_array_keys($array);
for ($i=0;$i<my_count($keys);$i++){
$array[$keys[$i]] = my_strtolower($array[$keys[$i]]);
}
return $array;
}
var_dump(lower_case_array(array('QuesToTeStoVerra\'','ConVerTiToInMiNUSCOlo')));
 
Ho riscritto alcune funzioni del php in php :)lol:):
PHP:
function _strpos($s,$c,$o=0) {
	$r = false;
	for($i=$o;$i<strlen($s);$i++)
		$ss .= $s[$i];
	for($i=0;$i<strlen($ss);$i++) {
		if($ss[$i] == $c) {
			$r = $i;
			break;
		}
	}
	return $r + $o;
}
function _implode($c,$a) {
	for($i=0;$i<sizeof($a);$i++)
		$r .= ($i == sizeof($a)-1) ? $a[$i] : $a[$i].$c;
	return $r;
}
function _strlen($s) {
	for($i=0; ;$i++)
		if(!isset($s[$i]))
			break;
	return $i;
}
function _strstr($s,$c) {
	$o = array_search($c,str_split($s,1));
	$ss = false;
	for($i=$o;$i<strlen($s);$i++)
		$ss .= $s[$i];
	return $ss;
}
 
Parecchie funzioni della clib riscritte in asm :)

Queste potrebbero anche servire a qualche pazzo che decide di scrivere qualcosa usando sole syscall xD

Seguono lo standard cdecl, quindi con la compilazione adatta sarebbero fuzionanti anche in un programma C :)
Codice:
/***************************************************************************/ 
/*              DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE                */
/*                        Version 3, April 2009                            */
/*                                                                         */
/*  Copyleft meh.                                                          */
/*                                                                         */
/*              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.                              */
/*  1. ????                                                                */
/*  2. PROFIT                                                              */
/***************************************************************************/
/* DO WHAT YOU WANT CAUSE A PIRATE IS FREE, YOU ARE A PIRATE!              */
/***************************************************************************/

.data
    random_32: .long 0x23421337

.text

/* int __isdigit (char ch) */
__isdigit:
    push    %ebp
    mov     %esp, %ebp

    xorl    %eax, %eax

    cmpb    $0x30, 8(%ebp)
    jl      __isdigit_end
    cmpb    $0x39, 8(%ebp)
    jg      __isdigit_end

    movl    $1, %eax

    __isdigit_end:

    pop     %ebp
    ret

/* string.h */

/* int __strlen (char* str) */
__strlen:
    push    %ebp
    movl    %esp, %ebp
    push    %edi
    push    %ecx

    movl    8(%ebp), %edi
    xorl    %eax, %eax
    xorl    %ecx, %ecx
    notl    %ecx
    cld
    repne   scasb
    notl    %ecx
    decl    %ecx

    movl    %ecx, %eax

    pop     %ecx
    pop     %edi
    pop     %ebp
    ret

/* char* __strchr (char* str, char ch) */
__strchr:
    push    %ebp
    movl    %esp, %ebp
    push    %edi
    push    %ebx
    push    %ecx

    push    8(%ebp)
    call    __strlen
    addl    $4, %esp

    movl    %eax, %ebx
    incl    %ebx
    movl    %eax, %ecx
    addl    $2, %ecx

    movl    8(%ebp), %edi
    movzbl  12(%ebp), %eax
    cld
    repne   scasb

    cmp     $0, %ecx
    je      __strchr_error

    movl    8(%ebp), %eax
    subl    %ecx, %ebx
    addl    %ebx, %eax
    jmp     __strchr_end

    __strchr_error:
    xorl    %eax, %eax

    __strchr_end:

    pop     %ecx
    pop     %ebx
    pop     %edi
    pop     %ebp
    ret

/* char* strcpy (char* dest, const char* src) */
__strcpy:
    push    %ebp
    movl    %esp, %ebp
    push    %ebx
    push    %ecx
    push    %edx

    push    12(%ebp)
    call    __strlen
    add     $4, %esp
    movl    %eax, %ecx
    incl    %ecx

    movl    8(%ebp), %ebx
    movl    12(%ebp), %edx
    
    __strcpy_loop:
        movzbl  (%edx), %eax
        movb    %al, (%ebx)
        incl    %edx
        incl    %ebx
    loop __strcpy_loop

    movl    8(%ebp), %eax

    pop     %edx
    pop     %ecx
    pop     %ebx
    pop     %ebp
    ret

/* char* strncpy (char* dest, const char* src, int n) */
__strncpy:
    push    %ebp
    movl    %esp, %ebp
    push    %ebx
    push    %ecx
    push    %edx

    movl    8(%ebp), %ebx
    movl    12(%ebp), %edx
    movl    16(%ebp), %ecx
    
    __strncpy_loop:
        movzbl  (%edx), %eax
        movb    %al, (%ebx)

        cmpb    $0, %al
        je      __strncpy_fill_zero

        incl    %edx
        incl    %ebx
    loop __strncpy_loop

    jmp     __strncpy_end

    __strncpy_fill_zero:
        movb    $0, (%ebx)
        incl    %ebx
    loop __strncpy_fill_zero

    __strncpy_end:

    movl    -4(%ebx), %eax

    pop     %edx
    pop     %ecx
    pop     %ebx
    pop     %ebp
    ret

/* stdlib.h */

/* int __rand (void) */
__rand:
    push    %edx

    movl    random_32, %eax
    movl    $0x0019660D, %edx
    mull    %edx
    addl    $0x3C6EF35F, %eax
    movl    %eax, random_32

    pop     %edx
    ret

/* int __atoi (char* str) */
__atoi:
    push    %ebp
    movl    %esp, %ebp

    /* is_negative @ -4(%ebp) */
    sub     $4, %esp

    push    %ebx
    push    %ecx
    push    %edx

    movl    8(%ebp), %ecx

    cmpb    $'-', (%ecx)
    je      __atoi_neg
    cmpb    $'+', (%ecx)
    je      __atoi_pos
    jmp     __atoi_P1

    __atoi_neg:
    movl    $1, -4(%ebp)
    incl    %ecx
    jmp     __atoi_P1

    __atoi_pos:
    movl    $0, -4(%ebp)
    incl    %ecx
    
    __atoi_P1:

    push    (%ecx)
    call    __isdigit
    addl    $4, %esp

    cmp     $0, %eax
    je      __atoi_end

    xorl    %ebx, %ebx
    xorl    %edx, %edx

    movb    (%ecx), %dl
    subb    $0x30, %dl
    movl    %edx, %ebx
    incl    %ecx

    __atoi_loop:
        push    (%ecx)
        call    __isdigit
        addl    $4, %esp

        cmp     $0, %eax
        je      __atoi_loop_end

        movl    $10, %eax
        mull    %ebx
        movl    %eax, %ebx

        movzbl  (%ecx), %edx
        subb    $0x30, %dl
        addl    %edx, %ebx

        incl    %ecx

        jmp     __atoi_loop
    __atoi_loop_end:

    movl    %ebx, %eax

    cmp     $1, -4(%ebp)
    jne     __atoi_end

    neg     %eax

    __atoi_end:

    pop     %edx
    pop     %ecx
    pop     %ebx
    addl    $4, %esp
    pop     %ebp
    ret

/* void* __memset (void* s, char c, unsigned n) */
__memset:
    push    %ebp
    movl    %esp, %ebp
    push    %ebx
    push    %ecx
    push    %edx

    movl    16(%ebp), %ecx
    movzbl  12(%ebp), %ebx
    movl     8(%ebp), %edx

    __memset_loop:
        movb    %bl, (%edx)
        incl    %edx
    loop __memset_loop

    movl    8(%ebp), %eax

    pop     %edx
    pop     %ecx
    pop     %ebx
    pop     %ebp
    ret

/* void* __memcpy (void* dest, const void* src, unsigned n) */
__memcpy:
    push    %ebp
    movl    %esp, %ebp
    push    %ebx
    push    %ecx
    push    %edx

    movl    16(%ebp), %ecx
    movl    12(%ebp), %ebx
    movl     8(%ebp), %edx

    __memcpy_loop:
        movb    (%ebx), %al
        movb    %al, (%edx)

        incl    %ebx
        incl    %edx
    loop __memcpy_loop

    movl    8(%ebp), %eax

    pop     %edx
    pop     %ecx
    pop     %ebx
    pop     %ebp
    ret

/* arpa/inet.h */

/* short __htons (short port) */
/* ((n & 0xFF) << 8) | ((n & 0xFF00) >> 8) */
__htons:
    push    %ebp
    movl    %esp, %ebp
    push    %edx

    xorl    %eax, %eax

    movw    8(%ebp), %ax
    andw    $0xff, %ax
    salw    $8, %ax
    movw    %ax, %dx

    movw    8(%ebp), %ax
    andw    $0xff00, %ax
    sarw    $8, %ax
    orw     %dx, %ax

    pop     %edx
    pop     %ebp
    ret

/* int __htonl (int port) */
/* ((n & 0xFF) << 24) | ((n & 0xFF01) << 8) | ((n & 0xFF0000) >> 8) | ((n & 0xFF000000) >> 24) */
__htonl:
    push    %ebp
    movl    %esp, %ebp
    push    %edx

    movl    8(%ebp), %eax
    andl    $0xff, %eax
    sall    $24, %eax
    movl    %eax, %edx

    movl    8(%ebp), %eax
    andl    $0xff00, %eax
    sall    $8, %eax
    orl     %eax, %edx

    movl    8(%ebp), %eax
    andl    $0xff0000, %eax
    sarl    $8, %eax
    orl     %eax, %edx

    movl    8(%ebp), %eax
    andl    $0xff000000, %eax
    sarl    $24, %eax
    orl     %edx, %eax

    pop     %edx
    pop     %ebp
    ret

/* int __inet_addr (char* address) */
/* a.b.c.d <=> (a << 24) | (b << 16) | (c << 8) | d */
__inet_addr:
    push    %ebp
    movl    %esp, %ebp

    /* str_end @ -4(%ebp) */
    sub     $4, %esp

    push    %ebx
    push    %ecx
    push    %edx

    push    8(%ebp)
    call    __strlen
    addl    $4, %esp

    /* str_end @ -16(%ebp) */
    movl    8(%ebp), %edx
    movl    %edx, -4(%ebp)
    addl    %eax, -4(%ebp)

    xorl    %ebx, %ebx
    movl    8(%ebp), %ecx

    __inet_addr_loop:
        push    (%ecx)
        call    __isdigit
        addl    $4, %esp

        cmp     $0, %eax
        je      __inet_addr_check_dot

        jmp     __inet_addr_loop_continue

        __inet_addr_check_dot:
        cmpb    $'.', (%ecx)
        jne     __inet_addr_error

        cmp     $3, %ebx
        jge     __inet_addr_error
        incl    %ebx

        __inet_addr_loop_continue:
        incl    %ecx
        cmpl    %ecx, -4(%ebp)
        je      __inet_addr_loop_end /* if (end of string reached) end loop */
        jmp     __inet_addr_loop
    __inet_addr_loop_end:

    movl    8(%ebp), %ecx
    xorl    %ebx, %ebx

    /* Check first number */
    push    %ecx
    call    __atoi
    addl    $4, %esp

    cmp     $255, %eax
    jg      __inet_addr_error

    sall    $24, %eax
    movl    %eax, %ebx

    push    $'.'
    push    %ecx
    call    __strchr
    addl    $8, %esp

    movl    %eax, %ecx
    incl    %ecx

    /* Check second number */
    push    %ecx
    call    __atoi
    addl    $4, %esp

    cmp     $255, %eax
    jg      __inet_addr_error

    sall    $16, %eax
    orl     %eax, %ebx

    push    $'.'
    push    %ecx
    call    __strchr
    addl    $8, %esp

    movl    %eax, %ecx
    incl    %ecx

    /* Check third number */
    push    %ecx
    call    __atoi
    addl    $4, %esp

    cmp     $255, %eax
    jg      __inet_addr_error

    sall    $8, %eax
    orl     %eax, %ebx

    push    $'.'
    push    %ecx
    call    __strchr
    addl    $8, %esp

    movl    %eax, %ecx
    incl    %ecx

    /* Check last number */
    push    %ecx
    call    __atoi
    addl    $4, %esp

    cmp     $255, %eax
    jg      __inet_addr_error

    orl     %eax, %ebx
    movl    %ebx, %eax
    bswap   %eax

    jmp     __atoi_end

    __inet_addr_error:
    mov     $-1, %eax

    __inet_addr_end:

    pop     %edx
    pop     %ecx
    pop     %ebx
    addl    $4, %esp
    pop     %ebp
    ret
 
Altre funzioni, questa volta sugli array, riscritte:
PHP:
<?php
function combine($ks,$vs) {
	if(count($ks) != count($vs) || empty($ks) || empty($vs))
		return false;
	for($i=0;$i<count($ks);$i++)
		$r[$ks[$i]] = $vs[$i];
	return $r;
}
function shift(&$arr) {
	$a = $arr[0];
	unset($arr[0]);
	return $a;
}
function pop(&$arr) {
	$a = $arr[count($arr)-1];
	unset($arr[count($arr)-1]);
	return $a;
}
function pad($arr, $s, $v) {
	if($s < 0) {
		$mp = $s;
		settype($mp, "string");
		$a = str_split($mp);
		unset($a[0]);
		$ss = join("",$a);
	} else
		$ss = $s;
	if(!is_numeric($s))
		return false;
	if($ss <= count($arr))
		return;
	if($s > 0)
		for($i=0;$i<$ss;$i++)
			array_push($arr, $v);
	else
		for($i=0;$i<$ss;$i++)
			array_unshift($arr, $v);
	return $arr;
}
function size($arr) {
	for($i=0;$arr[$i]!=0x00;$i++)
		$a++;
	return $a;
}
function fill($in, $n, $v) {
	for($i=$in;$i<=$n;$i++)
		$r[$i] = $v;
	return $r;
}
function product($arr) {
	$r = 1;
	for($i=0;$i<count($arr);$i++)
		$r *= $arr[$i];
	return $r;
}
?>
 
Ho riscritto la funzione echo, che però funziona solo da terminale XD
PHP:
function _echo ($string) {
	fwrite (STDOUT, $string);
}
_echo ("Funfa");
 
asd, è da un po' che nn ritornavo su questo topic.

Appena ne avrò tempo (e nn appena ritrovo dove le ho scritte) vi posto le mie.......
 
Perl:
Codice:
require "syscall.ph";

sub _print {
        my $string = join "", @_;
        syscall &SYS_write, fileno(STDOUT), $string, length $string;
}

sub _join {
        my $merger = shift;
        my @array = shift;
        my $string;
        $string.=$_.$merger foreach @array;
        return $string;
}

sub _split {
        my $regex = shift;
        my $string = shift;

        $regex =~ m/^\/(.*?)\/$/ ? $regex = $1 :  die "Suca\n";
        my @array;

        push @array, $1 while ($string =~ m/(.+?)$regex/g);
        push @array, $1 if $string =~ m/$regex(.+?)$/;
        
        return @array;
}
 
mmh, ho rifatto la xrange e il metodo reverse per le stringhe di python
la xrange in falcon :D
Codice:
function xRange( start_, end__, step_ )
   static
      start = nil
      end_  = nil
      step  = 1
   end

   if start_ != nil and end__ != nil
      if step_ 
         step = step_
      end
      start = start_ - step
      end_  = end__
      return xRange
   end

   if start >= end_
      return oob( 0 )
   else
      start += step
      return start
   end
end

// esempio..
for x in xRange( 0, 10, 2 )
   > x
end

la reverse in C++
Codice:
#include <iostream>
#include <string>
using  namespace std;

void reverse( string &str )
{
   register char tmp;
   string::iterator lPtr;
   string::iterator rPtr;
   
   lPtr = str.begin();
   rPtr = str.end();
   
   while( lPtr < rPtr )
   {
      tmp = *lPtr;
      *lPtr++ = *--rPtr;
      *rPtr = tmp;
   } 
}

int main( void )
{
   string string = "ciao a tutti!";
   reverse( string );
   cout << string << endl;
   return 0;
}
 
Ecco il mio. Le ultime se devo usare funzioni built-in le ho re-implementate prima.
Codice:
def _join(array, sep):
    j = ''
    for x in array:
        j += (x+sep)
    return j

def _reversed(array):
    return array[::-1]

def _bin(n):
    r = []
    while n > 1:
        r += str(n%2)
        n // 2
    return _join(_reversed(r), '')

def _len(iterable):
    c = 0
    for x in iterable:
        c += 1
    return c

def _xrange(start, stop, step):
    if start >= stop:
        raise ValueError('Cannot generate values from %s to %s' % (start, stop))
    while start < stop:
        yield start
        start += step

def _enumerate(string):
    for x in _xrange(_len(stringa)):
        yield (x, string[x])

def _find(string, p):
    for i, v in _enumerate(string):
        if v == p:
            return i
    return -1
 
gaurda che puoi anche scriverle senza l'underscore: sono *non*-reserved keywork, quindi puoi tranquillamente overloadare le precedenti

alcune precisazioni: nel join nn fai alcun controllo sul tipo assegnato, pertanto un join("mo","ia") farebbe sì di ottenere miao, cosa che non dovrebbe accadere. Inoltre, reversed in realtà non è una funzione, ma un vero e proprio tipo a sè stante (almeno fino a py2.5), infatti se fay type(reversed("abc")) dovrebbe uscirti, appunto, reversed
 
Pythoner ha detto:
Si ma se io scrivo una funzione e la chiamo xrange, poi se uso xrange usa la mia funzione, questo intendevo.

sì, se sei così imbronsato da mettere la tua definizione del codice sorgente di un app. Logicamente queste funzione *spero* tu le abbia messe in un modulo separato che NON userai ******MAI*******
 
Le ho scritte nell'IDLE di Python. Quindi ora non esistono più. Ho preferito ugualmente mettere gli underscore nel caso qualcuno le prendesse.
 
Malex ha detto:
Pythoner ha detto:
Si ma se io scrivo una funzione e la chiamo xrange, poi se uso xrange usa la mia funzione, questo intendevo.

sì, se sei così imbronsato da mettere la tua definizione del codice sorgente di un app. Logicamente queste funzione *spero* tu le abbia messe in un modulo separato che NON userai ******MAI*******

muori
 
bronsa ha detto:
Malex ha detto:
Pythoner ha detto:
Si ma se io scrivo una funzione e la chiamo xrange, poi se uso xrange usa la mia funzione, questo intendevo.

sì, se sei così imbronsato da mettere la tua definizione del codice sorgente di un app. Logicamente queste funzione *spero* tu le abbia messe in un modulo separato che NON userai ******MAI*******

muori

[ot] ormai sei nel mio vocabolario quotidiano, c'è poco da fare. [/ot]
 
Stato
Discussione chiusa ad ulteriori risposte.