π
<-
Chat plein-écran
[^]

L'épopée du fameux PP08

:32tins: :32tinsktpb: :32tinsktpn: :32tinscas: :32tinstpkc: :32tinstpktpb: :32tinstp: :32tinscastp: :32tinscmc: :32tinscx: :32tinscxcas:

L'épopée du fameux PP08

Message non lude Excale » 19 Mai 2013, 23:18

Bonjour à tous,

Suite à ma participation au concours Palprem qui allait étrangement trop vite par rapport à ce qu'il est possible de faire en Basic, beaucoup de personnes m'ont demandé d'expliquer comment j’avais fait pour calculer si rapidement le 5000è palindrome premier.

La réponse est pourtant simple, j'ai utilisé ndless.
Le classeur est en fait un programme ndless qui va lui-même ouvrir un "vrai" classeur Nspire.

En pratique voilà ce qu'il se passe:
  • L'utilisateur ouvre le faux classeur, qui est en fait un programme ndless
  • Le programme copie le vrai classeur dans un fichier bidon
  • Le programme demande à l'OS d'ouvrir le classeur bidon en question
  • Le programme va créer un hook dans la fonction qui évalue une expression mathématique (c'est à dire qu'il prend la main dans cette fonction, fait quelque chose, et laisse la fonction continuer à s’exécuter normalement).
  • L'utilisateur voit un classeur Nspire ouvert
  • Il tape palprem(42)
  • L'OS arrive dans la fonction qui évalue l'expression mathématique, ce qui donne la main à mon programme
  • Le programme regarde si l'expression rentrée est de la forme palprem(nombre) (si il ne trouve pas ça, il ne fait rien et redonne la main à l'OS qui va évaluer le calcul)
  • Si il trouve le motif, il récupère le nombre et calcule le nombrième palindrome premier, et ce bien plus rapidement qu'en Basic
  • Le programme place ensuite le nombrième palindrome à la place de "palprem(nombre)", et redonne la main à l'OS
  • L'OS se retrouve alors avec un nombre à évaluer, et renvoie tout simplement ce nombre
  • L'utilisateur voit ce nombre et va alors pouvoir l'utiliser pour.... (zut, ça sert à quoi les palindromes premiers?)

Le code pour ceux que ça intéresse:
Show/Hide spoilerAfficher/Masquer le spoiler
Quelques définitions dont l'adresse du hook
Code: Tout sélectionner
#include <os.h>
#include <libndls.h>
#include <stdint.h>
#include <inttypes.h>

static const unsigned int addr_exdoc_openclass[] = {0x10009B48, 0x10009B20, 0x10009AE8, 0x10009AE8};
#define EXDOC_OPENCLASS ((int(*)(char*, char*, int))nl_osvalue((int*)addr_exdoc_openclass, sizeof(addr_exdoc_openclass)/sizeof(addr_exdoc_openclass[0])))
static const unsigned int hook_addr_newclass[] =   {0x10027558, 0x100274C4, 0x10026C54, 0x10026BEC};
#define HOOK_NEWCLASS nl_osvalue((int*)hook_addr_newclass, sizeof(hook_addr_newclass)/sizeof(hook_addr_newclass[0]))
static const unsigned int hook_addr_calc[] =       {0x1006CBBC, 0x1006CAEC, 0x1006C2B8, 0x1006C210};
#define HOOK_ADDR_CALC nl_osvalue((int*)hook_addr_calc, sizeof(hook_addr_calc)/sizeof(hook_addr_calc[0]))

Le "vrai" classeur, qu'on inclut directement dans le binaire
Code: Tout sélectionner
extern void* __file_start__;
extern void* __file_end__;
asm(".globl __file_start__          \n"
    ".globl __file_end__            \n"
    "__file_start__:                \n"
    ".incbin \"palprem_class.tns\"  \n"
    "__file_end__:                  \n");

Code pour trouver le n-ième palindrome premier. Adapté de : http://www.programmingsimplified.com/c/source-code/c-program-find-next-prime-palindrome
Code: Tout sélectionner
uint32_t palprime(uint32_t m)
{
    uint32_t n, t, r = 0, c, z = 0;

    if(m<=5)
    {
        const int y[] = {0,2,3,5,7,11};
        return y[m];
    }
    else
    {
        n = 101-2;
        z = 5;
    }

    while(z<m)
    {
        printf("%" PRId32 " %" PRId32 "\n",z,n);
        while (TRUE)
        {
            n+=2;
            t = n;

            /* Calculating reverse of number */

            while(t)
            {
                r *= 10;  /* Compound assignment operator r*=10 => r=r*10 */
                r += t%10;
                t /= 10;
            }

            /* if reverse equals original then it is palindrome */

            if (r == n)
            {
                /* Checking prime */

                if ((n%2 == 0) || (n%3 == 0) || (n%5 == 0))
                goto suite;
                c = 7;
                while( c*c<=n)
                {
                    if ((n%c == 0) || (n%(c+4) == 0))
                    break;
                    c+=6;
                }
                if (c*c>n)
                break;
            }
            suite:
            r = 0;
        }
        z++;
    }

    return n;
}

Ce bout permet d'enlever le hook quand on quitte le classeur
Code: Tout sélectionner
HOOK_DEFINE(newclass) {

    HOOK_UNINSTALL(HOOK_ADDR_CALC, calc_change);
    HOOK_UNINSTALL(HOOK_NEWCLASS , newclass);
    HOOK_RESTORE_RETURN(newclass);
}

Vérifie si l'utilisateur a tapé palstring(nombre), et appelle si besoin palprime()
Code: Tout sélectionner
char resultstring[0x100];
const unsigned char palstring[] = {0x70, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x70, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6D, 0x00, 0x28, 0x00};

HOOK_DEFINE(calc_change) {

    char* calcul = (char *) HOOK_SAVED_REGS(calc_change)[2];
    if( !memcmp( calcul, &palstring, sizeof(palstring) ) )
    {
        uint32_t input = 0;
        int offset = 0;
        unsigned char currentn = calcul[sizeof(palstring)];
        while( currentn>=0x30 && currentn<=0x39 )
        {
            input = input*10 + (currentn-0x30);
            offset+=2;
            currentn = calcul[sizeof(palstring)+offset]; 
        }
        if( offset!=0 && calcul[sizeof(palstring)+offset]==')' && calcul[sizeof(palstring)+offset+2]==0)
        {
            uint32_t result = palprime(input);
            char resultstringbuf[0x80];
            memset(resultstring   , 0x0, 0x100);
            memset(resultstringbuf, 0x0, 0x80);
            sprintf(resultstringbuf, "%" PRId32 "", result);
            int i;
            for( i=0; i<0x80; i++ )
            {
                resultstring[2*i] = resultstringbuf[i];
            }
            HOOK_SAVED_REGS(calc_change)[2] = (int) resultstring;
        } else
        {
            HOOK_SAVED_REGS(calc_change)[2] = (int) palstring;
        }
    } else
    {
        int i;
        for( i=0; i<0x100; i++ )
        {
            if( calcul[2*i]=='p' && !memcmp( calcul+2*i, &palstring, sizeof(palstring)-2 ))
            {
                HOOK_SAVED_REGS(calc_change)[2] = (int) palstring;
                break;
            }
        }
    }
    HOOK_RESTORE_RETURN(calc_change);
}

Ouvre le classeur et définit les hooks.
Code: Tout sélectionner
int main()
{
   nl_set_resident();
    FILE *tns_file;
    tns_file = fopen("/logs/palprem.tns","wb");
    fwrite (&__file_start__ , sizeof(char) , 4*(&__file_end__-&__file_start__), tns_file );
    fclose(tns_file);
    EXDOC_OPENCLASS("/logs","palprem.tns",1);
    HOOK_INSTALL(HOOK_ADDR_CALC, calc_change);
    HOOK_INSTALL(HOOK_NEWCLASS, newclass);
    return 0;
}

Je suis ouvert à toutes questions si besoin :).

...et si vous voulez télécharger le programme, c'est par ici: http://tiplanet.org/forum/archives_voir.php?id=14699
Avatar de l’utilisateur
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 3.9%
 
Messages: 2955
Images: 3
Inscription: 10 Sep 2010, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: L'épopée du fameux PP08

Message non lude critor » 19 Mai 2013, 23:30

En gros, si je traduis bien pour nos lecteurs:

Tu viens d'inventer l'exécution d'un programme Ndless en tant que fonction depuis un classeur TI-Nspire, sans avoir à l'enregistrer/fermer! :bj:


C'est révolutionnaire et visionnaire, avec des utilités pour nombres de calculs mathématiques complexes! :bj:
Outre la recherche des nombres premiers qui est ici ultra-rapide et satellise le programme de Bisam, on pourrait imaginer bien d'autres choses, comme les décimales de Pi ou encore un moteur CAS...


Jusqu'à présent, Ndless ne pouvait pas aider aux calculs de l'OS, et son intérêt pédagogique était donc limité.
Ce temps est désormais révolu! :bj:
Image
Avatar de l’utilisateur
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Prochain niv.: 42.6%
 
Messages: 41500
Images: 14705
Inscription: 25 Oct 2008, 00:00
Localisation: Montpellier
Genre: Homme
Calculatrice(s):
MyCalcs profile
YouTube: critor3000
Twitter/X: critor2000
GitHub: critor

Re: L'épopée du fameux PP08

Message non lude mdr1 » 19 Mai 2013, 23:38

Ce ne serait pas le contraire ? Un programme ndless qui demande à l'OS d'ouvrir un classeur.

PS : Petit farceur, Excale ! :p
Image ImageImage
Avatar de l’utilisateur
mdr1Premium
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 44%
 
Messages: 1083
Images: 12
Inscription: 28 Mar 2011, 00:00
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile
Classe: Je voyage toujours en première.

Re: L'épopée du fameux PP08

Message non lude critor » 19 Mai 2013, 23:39

L'un implique l'autre ;)
Image
Avatar de l’utilisateur
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Prochain niv.: 42.6%
 
Messages: 41500
Images: 14705
Inscription: 25 Oct 2008, 00:00
Localisation: Montpellier
Genre: Homme
Calculatrice(s):
MyCalcs profile
YouTube: critor3000
Twitter/X: critor2000
GitHub: critor

Re: L'épopée du fameux PP08

Message non lude Loulou 54 » 19 Mai 2013, 23:57

Oh oui, techniquement, c'est vraiment fort ! :bj:
ça offre de sacrées possibilités !
Mes programmes => ici !
Avatar de l’utilisateur
Loulou 54Premium
Niveau 13: CU (Calculateur Universel)
Niveau 13: CU (Calculateur Universel)
Prochain niv.: 1.6%
 
Messages: 1985
Images: 8
Inscription: 02 Aoû 2009, 00:00
Localisation: 54, près de Metz
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: Ingé Logiciel chez Amazon

Re: L'épopée du fameux PP08

Message non lude Lionel Debroux » 20 Mai 2013, 06:30

Tout à fait, c'est fort :)

Maintenant, ce serait super de continuer sur ta lancée et de pouvoir descendre un niveau plus bas que la recherche / manipulation de chaînes de caractères dans le parser d'expressions: faire de la manipulation directe sur la pile d'expressions sous forme tokenizée, comme on a toujours pu le faire sur TI-68k/AMS, mieux que je l'avais fait à http://www.ticalc.org/archives/files/fi ... 43727.html .
Ce premier programme CAS Nspire avait montré que le code du CAS de TI avait très peu changé, dans les fondements, en 15 ans - mais il était non interactif, et les opérations qui stockaient vers des variables crashaient la machine, donc inutile en pratique.
Et j'ai toujours été convaincu que le crash était probablement dû au fait que le document n'était pas dans la forme qui convenait pour stocker des variables - il faudrait qu'on puisse le confirmer une bonne fois pour toutes, et des programmes comme le tien (et son prédécesseur de mai 2012 utilisant une extension Lua) sont la meilleure base dont nous disposons pour ce faire :)

La bonne solution serait évidemment que TI arrête de déconner et ouvre officiellement, après plus de six ans de grosse erreur, la machine à la programmation en code natif. Cependant, tout le monde sait très bien, hélas, qu'il n'y a quasiment aucune chance que ceci se produise, même avec l'arrivée de la HP Prime dont la puissance brute permettrait de faire pas mal mieux que les Nspire sans se fouler - et on sait que HP peut se fouler, vu que le CAS des HP-49G+ battait celui des 89 dans certains domaines il y a une décennie. TI est suffisamment bien implanté dans le marché de l'éducation pour que pas grand chose ne puisse arriver à leur position dominante, tant qu'ils ne font pas trop n'importe quoi.
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Avatar de l’utilisateur
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 11.2%
 
Messages: 6859
Inscription: 23 Déc 2009, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: -
GitHub: debrouxl

Re: L'épopée du fameux PP08

Message non lude Levak » 20 Mai 2013, 14:38

La seule opportunité d'avoir modification du langage Nspire Basic intégré est de faire un projet qui est le seul à utiliser ce langage modifié. En effet, il offrira une interactivité avec le Nspire-Basic et le "classeur" sera donc l'environnement modifié. Par contre, si, ce qui est publié sont des classeurs-patchs pour rajouter telle ou telle fonction, on va très vite voir des problèmes tels que "fonction non définie" / "erreur invalide dans une fonction ou programme" etc ... faisant encore plus ressentir les compatibilités de versions qu'on connait déjà, ajouté aux incompatibilités de patchs que l'on ne connait pas encore très bien sur TI-Nspire (car trop peu nombreuses).
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)


Retourner vers News TI-Nspire

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 168 invités

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
Phi NumWorks jailbreak
123
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1411 utilisateurs:
>1384 invités
>21 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)