Avatar billede billeschou Nybegynder
28. juni 2002 - 16:57 Der er 16 kommentarer og
1 løsning

Finpudsning af algoritme

med udgangspunkt i http://www.eksperten.dk/spm/114306 har jeg den sidste uge (cirka) kæmpet med at lave en løsning i perl.

Idag blev jeg så så godt som færdig.

Køres nedenstående algoritme skriver den at summen er 2080, men den skulle være 1990. Tilsyneladende (det er i hvert fald min konklusion efter at studere tallene), så lægger den 90 til en gang for meget. Nogen der kan forklare mig hvorfor?

http://www.billeschou.net/rom2arab.txt
Avatar billede jakoba Nybegynder
28. juni 2002 - 18:29 #1
i funktionen convert forstår jeg ikke linierne:
        my $k = 5;
        $k = 5;
Den initialværdi bliver ødelagt hver gang for di $k kort efter benyttes som housekeeping-variabel.

Hvis $k oprindeligt var ment som en algoritmespecifik variabel kunne det måske være at der er en rest af kode der bruger den sådan (men med en værdi der er hvad pokker nu din housekeeping har efterladt i den).

mvh JakobA
Avatar billede jakoba Nybegynder
28. juni 2002 - 18:47 #2
prøv at udskifte din  while ( $k > 0 )  løkke med:

        while( $k > 0 ) {  # sålænge der KAN være et bogstav foran
            $c = substr($streng,$k,1);
            $k2 = $k - 1;
            $c2 = substr($streng,$k2,1);
           
            if (letter_pos($c) > letter_pos($c2)) {
                $sum = $sum + (letter2value($c) - letter2value($c2));
                $k = $k - 2;
            } else {
                $sum = $sum + letter2value($c);
                $k = $k - 1;
            }
            print "sum: " . $sum . "\n"; ################################
        }
                if ( $k = 0 ) {  # der er eet bogstav tilbage
            $c = substr($streng,$k,1);
            $sum = $sum + letter2value($c);
                }

mvh JakobA
Avatar billede jakoba Nybegynder
28. juni 2002 - 19:05 #3
Ups,  =  ->  ==  i  "if ($k = 0) ..."

men i det hele taget for meget.

        while($k >= 0) {
            $c = substr($streng,$k,1);
            $sum = $sum + letter2value($c);
            $k = $k-1;
                        if ( $k >= 0 ) {
                $c2 = substr($streng,$k,1);
                if (letter_pos($c) > letter_pos($c2)) {
                    $sum = $sum - letter2value($c2));
                    $k = $k -1;
                                }
            }
#### debug linie ####
            print "sofar: substr($streng,$k+1,$len) ." sum: " .$sum ."\n";
        }
# assert $k == -1;
Avatar billede billeschou Nybegynder
28. juni 2002 - 19:06 #4
det med my $k = 5; og
$k = 5;
er en smutter... godt set ;)
Avatar billede jakoba Nybegynder
28. juni 2002 - 19:08 #5
og igen:      "sofar: substr(    ->  "sofar: " .substr(          #indsat  " .
Avatar billede billeschou Nybegynder
28. juni 2002 - 19:09 #6
vil man ikke komme til at evaluere det samme tegn flere gange med din omskrivning?
Avatar billede jakoba Nybegynder
28. juni 2002 - 19:36 #7
Jo det vil man.
Til gengæld ridikerer man ikke at 'springe over' et mindre foran større par som man gør hvis man altid sige $k=$k-2
    MCMX
loop 1 kikker på X og M  og summer begge da M > X
loop 2 kikker på C og M  og summer begge sa M > C
MCMX bliver så  2110.

Det kan ikke ske hvis vi nøjes med at dekrementere $k med een når bogstavet foran er større.

mvh JakobA
Avatar billede billeschou Nybegynder
28. juni 2002 - 19:54 #8
god pointe... og din kode har rettet nogle af de problemer der var... lækkert! :)
Til gengæld har jeg opdaget andre fejl ved eksperimentere med inddata - men jeg kæmper videre :)

Du har da ærligt fortjent pointene... ville du være interesseret i sourcekoden hvis jeg får konstrueret en fejlfri algoritme?
Avatar billede jakoba Nybegynder
28. juni 2002 - 20:07 #9
Helt klart. men næsten endnu mere i at blive ved med at arbejde med koden da jeg trænger til at lære perl :-))

mvh JakobA
Avatar billede billeschou Nybegynder
28. juni 2002 - 20:22 #10
det eneste problem jeg mangler at håndtere nu, er et romertal hvor alle bogstaver er ens. Ellers er jeg vist nået igennem
Avatar billede billeschou Nybegynder
28. juni 2002 - 21:06 #11
http://www.billeschou.net/rom2arab2.txt - værsgo at teste den :)
Avatar billede jakoba Nybegynder
28. juni 2002 - 21:35 #12
vil nedenstående ikke tillade et romertal som "DDDDDDDDD" ?
        $k = check_numerals3($streng);
        $l = allsame($streng);
        if (($k != 1) && ($l != 1))
        {
            die "fejl!";
        }

PS: jeg har ikke perl, så jeg kan ikke teste; kun logikke.

mvh JakobA
Avatar billede billeschou Nybegynder
28. juni 2002 - 21:59 #13
jo du har helt ret... men jeg har jo kun implementeret de regler der var i det oprindelige spørgsmål. Faldt over denne side - http://search.cpan.org/doc/TELS/Math-Roman-1.05/lib/Math/Roman.pm - der er helt klart noget at arbejde videre med. Til gengæld kan man ikke skrive 90 som LXL - så han er lidt galt på den
Avatar billede jakoba Nybegynder
28. juni 2002 - 22:43 #14
Hmm...

mon ikke man bør skelne imellem 2 slags regler
    ting der er FORBUDT.
og ting der blot må frarådes.

et romertal der kan misforstås bør være forbudt.
      XXM  kan fortolkes både som 1000 og som 980.
      ILCXM  kan fortolkes på utallige måder
så det er ikke acceptable romertal. de skal afvises.

et romertal der er kluntet men eentydigt bør frarådes:
      DCD  kan kun betyde 900
      MIM  kan kun betyde 1999
så det bør forstås, evt med en advarsel.

arabertal -> romertal konverteringen skal 100% overholde begge typer regler.

vil det ikke være det mest brugervenligt? lidt i stil med "HTML 4.01 transitional"
romertal -> arabertal konverteren kunne så evt have en switch parameter der fik den til at afvise blot en 'bør frarådes' regel er overtrådt. ( "HTML 4.01 strict" :-))

mvh JakobA
Avatar billede jakoba Nybegynder
28. juni 2002 - 22:55 #15
det var forresten et prægtigt sted der http://search.cpan.org/ takker.
Avatar billede billeschou Nybegynder
28. juni 2002 - 23:15 #16
men både XXM og ILXCM er ugyldige i henhold til de fastsatte regler.
XXM dels fordi der står to ens mindre numeraler foran et større og dels fordi M er mere end 10 gange så stort som X.
ILCXM er ugyldigt fordi eksempelvis LC er en ugyldig token.

DCD er ulovligt fordi D står umiddelbart til venstre for C og ikke er mindst 10 gange større end C.
MIM er ugyldigt fordi IM er en ugyldig token (da M er mere end 10 gange større end I).

Men det var vist et sidespring... :)
Mon ikke der findes et bevis for at der er et 1-1 forhold mellem romertal og arabertal. Altså at hvert arabertal kan skrives som et og kun et romertal og omvendt (vel at mærke hvis det skal overholde reglerne selvfølgelig)
Avatar billede billeschou Nybegynder
28. juni 2002 - 23:17 #17
og ja... cpan er et rigtig godt sted at lede efter information/inspiration. Derudover er der selvfølgelig http://www.perl.com :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester