Ekstraopgaver til Løbeseddel 2: løkker og procedurer

for Databasebaseret Webpublicering, forår 2001

af Niels Hallenberg sidst rettet 5. februar, 2001


Dette ekstrasæt til løbeseddel 2 indeholder små opgaver i henholdsvis while- og for- løkker samt procedurer i Tcl. Du lærer først om for-løkker i næste uge, så i første omgang kan du løse opgaverne med while. I næste uge kan du løse opgaverne med for-løkker. Løkke-opgaverne er oprindeligt lavet af Ken Friis Larsen til kurset Grundlæggende Programmering (Java) ved IT-C.

Skriv hver opgave i en fil, den første fil navngivet while0.tcl (eller for0.tcl), og indlæs dem i Tcl-fortolkeren med kommandoen source.


Syntaks for while-løkker

En while-løkke består af to dele: en løkkebetingelse og en løkkekrop:
  while {betingelse} {
     krop
  }
Det er normalt, at while-løkker også indeholder en optælling i løkkekroppen samt en initialisering inden while-løkken:
  initialisering
  while {betingelse} {
     krop
     optælling
  }
While-løkken ovenfor kan læses som:
Start med at udføre initialisering; hvis betingelse evaluerer til true (i Tcl er det tallet 1), udfør da krop efterfulgt af optælling. Fortsæt med at udføre krop efterfulgt af optælling, så længe betingelse evaluerer til true.
Her er et eksempel på en while-løkke:
  int x = 3;
  set i 1;
  while {$i <= 20} {
    incr x 5;
    incr i;
  }
while-løkkens krop (tildelingen incr x 5) udføres tyve gange. Det vil sige, x antager værdierne: 3, 8, 13, 18, 23, ... , 103, mens i antager værdierne: 1, 2, 3, 4, 5, ... , 20.

Syntaks for for-løkker

En for-løkke består af fire dele: en initialisering, en løkkebetingelse, en optælling, samt en løkkekrop:
  for {init} {betingelse} {optælling} {
     krop
  }
En for-løkke kan læses som:
Start med at udføre init; hvis betingelse evaluerer til true, udfør da krop efterfulgt af optælling. Fortsæt med at udføre krop efterfulgt af optælling, så længe betingelse evaluerer til true.
Her er et eksempel på en for-løkke:
  int x = 3;
  for {set i 1} {$i <= 20} {incr i} {
     incr x 5;
  }
for-løkkens krop (tildelingen incr x 5) udføres tyve gange. Det vil sige, x antager værdierne: 3, 8, 13, 18, 23, ... , 103, mens i antager værdierne: 1, 2, 3, 4, 5, ... , 20. Bemærk at variablen i, der erklæres i initialiseringen, kun har virkefelt (scope) i for-løkken.


Opgave for0.tcl

Lav et program der udskriver følgende:
  *
  *
  *
  *
  *

Opgave for1.tcl

Lav et program der udskriver følgende:
  *****

Bemærk at efter de fem stjerner er et linieskift.

Opgave for2.tcl

Lav et program der udskriver følgende:
  1 2 3 4 5

Opgave for3.tcl

Lav et program der udskriver følgende:
  1 3 5 7 9

Opgave for4.tcl

Lav et program der udskriver følgende:
  5 4 3 2 1

Opgave for5.tcl

Lav et program der udskriver følgende:
  0 5 10 15 20 25

Opgave for6.tcl

Lav et program der udskriver følgende:
  *****
  *****
  *****
  *****
  *****
Lav to løsninger: En hvor du kun bruger en for-løkke, og en hvor du bruger en for-løkke inden i en anden for-løkke.

Opgave for7.tcl

Lav et program der udskriver følgende:
  *
  **
  ***
  ****
  *****

Opgave for8.tcl

Lav et program der udskriver følgende:
  *****
  ****
  ***
  **
  *

Opgave for9.tcl

Lav et program der udskriver følgende:
  abc
  abcabc
  abcabcabc
  abcabcabcabc
  abcabcabcabcabc

Opgave for10.tcl

Lav et program der udskriver følgende:
  1
  12
  123
  1234
  12345

Opgave for11.tcl

Lav et program der udskriver følgende:
  1
  22
  333
  4444
  55555

Opgave for12.tcl

Lav et program der udskriver følgende:
  1
  23
  456
  78910
  1112131415

Opgave for13.tcl

Lav et program der udskriver følgende:
  *++++
  **+++
  ***++
  ****+
  *****

Opgave for14.tcl

Lav et program der udskriver følgende:
  ++++*
  +++**
  ++***
  +****
  *****

Opgave for15.tcl

Lav et program der udskriver følgende:
      *
     **
    ***
   ****
  *****

Opgaver i procedurer

Opgaverne nedenfor øver anvendelsen af procedurer, dvs proc i Tcl.

Opgave proc0.tcl

Lav en procedure succ, som tager et argument i og returnerer i + 1. Vi antager, at i er et tal.

Hint: Du kan f.eks. anvende kommandoen expr til at beregne i + 1.

% source proc0.tcl
% succ 12
13

Opgave proc1.tcl

Lav en procedure splice, som tager to argumenter, og returnerer sammensætningen af dem separeret med et mellemrum.

Hint: Du behøver ikke at anvende kommandoen append til at sammensætte de to argumenter. Brug i stedet $-notationen.

% source proc1.tcl
% splice "Hans" "Jensen"
Hans Jensen

Opgave proc2.tcl

Skriv en procedure er_du_rig som tager et argument x, og returnerer strengen Du har søreme mange penge, hvis x er større end 1324345; ellers returneres strengen Du må vist spare lidt mere sammen, hvis du skal have et hus.

% source proc2.tcl
% er_du_rig 233043
Du må vist spare lidt mere sammen, hvis du skal have et hus
% er_du_rig 358485743
Du har søreme mange penge

Opgave proc3.tcl

Skriv en procedure email_link, som tager en email som argument og returnerer et email link, f.eks.
% source proc3.tcl
% email_link nh@it-c.dk
<a href="mailto:nh@it-c.dk">nh@it-c.dk</a>

Løsninger

Vi angiver kun løsninger der anvender for-løkker. Du kan selv omskrive for-løkkerne til while-løkker.

for0.tcl
  for {set i 1} {$i <= 5} {incr i} {
    puts "*";
  }
for1.tcl
  set res "";
  for {set i 1} {$i <= 5} {incr i} {
    append res "*";
  }
  puts $res;
for2.tcl
  set res "";
  for {set i 1} {$i <= 5} {incr i} {
    append res $i " ";
  }
  puts $res;
for3.tcl
  set res "";
  for {set i 1} {$i <= 10} {incr i 2} {
    append res $i " ";
  }
  puts $res;
for4.tcl
  set res "";
  for {set i 5} {$i >= 1} {incr i -1} {
    append res $i " ";
  }
  puts $res;
for5.tcl
  set res ""
  for {set i 0} {$i <= 5} {incr i} {
    append res [expr 5*$i] " ";
  }
  puts $res;
for6.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= 5} {incr j} {
      append res "*";
    }
    puts $res;
  }

Du må selv finde den løsning, som kun benytter en for-løkke.

for7.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      append res "*";
    }
    puts $res;
  }
for8.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 5} {$j >= $i} {incr j -1} {
      append res "*";
    }
    puts $res;
  }
for9.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      append res "abc";
    }
    puts $res;
  }
for10.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      append res $j;
    }
    puts $res;
  }
for11.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      append res $i;
    }
    puts $res;
  }
for12.tcl
  set count 0;
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      incr count;
      append res $count;
    }
    puts $res;
  }
for13.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 1} {$j <= $i} {incr j} {
      append res "*";
    }
    for {set j [expr $i+1]} {$j <= 5} {incr j} {
      append res "+";
    }
    puts $res;
  }
for14.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 5} {$j > $i} {incr j -1} {
      append res "+";
    }
    for {set j $i} {$j >= 1} {incr j -1} {
      append res "*";
    }
    puts $res;
  }
for15.tcl
  for {set i 1} {$i <= 5} {incr i} {
    set res "";
    for {set j 5} {$j > $i} {incr j -1} {
      append res " ";
    }
    for {set j $i} {$j >= 1} {incr j -1} {
      append res "*";
    }
    puts $res;
  }
proc0.tcl
  proc succ { i } {
    return [expr $i + 1]
  }
proc1.tcl
  proc splice {s1 s2} {
    return "$s1 $s2"
  }
proc2.tcl
  proc er_du_rig {x} {
    if {$x > 1324345} {
      return "Du har søreme mange penge"
    } else {
      return "Du må vist spare lidt mere sammen, hvis du skal have et hus"
    }
  }
proc3.tcl
  proc email_link {e} {
    return "<a href=\"mailto:$e\">$e</a>"
  }


nh@it.edu