Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS

Eksamenssett logo
eksamenssett.noTren målrettet
  • Ungdomsskole/VGS
  • Høyskole
  • Ressurser
  • Skolenyttig
  • Forum
  1. Hjem
  2. Informasjonsteknologi
  3. IT 2 – JavaScript
  4. Løsning Høst 2024
VG3

Løsningsforslag Informasjonsteknologi IT 2 – JavaScriptHøst 2024

Se eksamensoppgaven
Vår 2025NyereVår 2024Eldre
Om løsningsforslaget: Dette er et veiledende løsningsforslag laget av eksamenssett.no for REA3049-JS Høst 2024. Vi gir korrekte svar på flervalgsoppgavene med begrunnelse, fullstendig JavaScript-kode for programmeringsoppgavene (5b, 6, 9, 10), og eksempelsvar på drøftingsoppgavene om velferdsteknologi.

Løsningsforslag – IT 2 JavaScript Høst 2024

Eksamen: REA3049-JS | Semester: Høst 2024 | Tema: OOP, palindrom-test, batteri-klasse, velferdsteknologi, befolkningsdatasett, virusspredning

Oppgave 1 – OOP-prinsipp om gjenbruk

Riktig svar: arv

Arv er mekanismen som gjør at en subklasse arver egenskaper og metoder fra superklassen — ren gjenbruk. I JavaScript bruker man class B extends A.

Oppgave 2 – Klasserelasjon: felt inneholder objekter

Riktig svar: komposisjon

Når objektet «eier» de andre objektene som felt og de eide normalt ikke eksisterer uten den ytre helheten, er det komposisjon.

Oppgave 3 – Pseudokode-trace beregn(7)

Riktig svar: -4

Trace: −1+2−3+4−5+6−7 = −4.

Oppgave 4 – Sortering av temperatur-pseudokode

IF temperatur GREATER THAN 25
  DISPLAY "Det er varmt."
ELSE IF temperatur GREATER THAN OR EQUAL TO 10
  DISPLAY "Det er mildt."
ELSE IF temperatur GREATER THAN OR EQUAL TO 0
  DISPLAY "Det er kjølig."
ELSE
  DISPLAY "Det er kaldt."
ENDIF

Oppgave 5 – Palindrom-test

Oppgave 5a – Forklaring

Algoritmen sjekker om et tall er et palindrom (leses likt forfra og bakfra). Den bygger opp den reverserte versjonen av tallet i s ved å plukke siste siffer (h % 10), legge det til som ny siste siffer i s (s * 10 + r), og fjerne sist siffer fra h. Til slutt sammenlignes original (t) med revers (s). 121 → 121 (True), 123 → 321 (False).

Oppgave 5b – Tell tresifrede palindromer

// oppgave5b.mjs — antall tresifrede palindromer

function erPalindrom(h) {
  let t = h, s = 0;
  while (h !== 0) {
    s = s * 10 + (h % 10);
    h = Math.floor(h / 10);
  }
  return t === s;
}

let antall = 0;
for (let n = 100; n < 1000; n++) if (erPalindrom(n)) antall++;
console.log(`Antall tresifrede palindromer: ${antall}`);
// Forventet svar: 90

Resultat: 90 tresifrede palindromer (101, 111, 121, …, 999). Matematisk: 9 valg for første/siste siffer × 10 for midten = 90.

Oppgave 6 – Batteri-klasse

// batteri.mjs — energilager med privat tilstand (# = privat felt i moderne JS)

export class BatteriFeil extends Error {
  constructor(melding) { super(melding); this.name = "BatteriFeil"; }
}

export class Batteri {
  #kapasitet;
  #energinivaa;

  constructor(kapasitet, startNiva = 0) {
    if (kapasitet <= 0) throw new BatteriFeil("Kapasiteten må være positiv.");
    if (startNiva < 0 || startNiva > kapasitet)
      throw new BatteriFeil(`Startnivå (${startNiva}) må være mellom 0 og ${kapasitet}.`);
    this.#kapasitet = kapasitet;
    this.#energinivaa = startNiva;
  }

  lad(energi) {
    if (energi < 0) throw new BatteriFeil("Kan ikke lade med negativ energi.");
    this.#energinivaa = Math.min(this.#energinivaa + energi, this.#kapasitet);
  }

  bruk(energi) {
    if (energi < 0) throw new BatteriFeil("Kan ikke bruke negativ energi.");
    if (energi > this.#energinivaa)
      throw new BatteriFeil(`Ikke nok energi: forsøkt ${energi}, tilgjengelig ${this.#energinivaa}.`);
    this.#energinivaa -= energi;
  }

  visStatus() {
    const prosent = (this.#energinivaa / this.#kapasitet * 100).toFixed(0);
    console.log(`Batteri: ${this.#energinivaa.toFixed(1)} / ${this.#kapasitet.toFixed(1)} kWh (${prosent} %)`);
  }
}

// Tester
function testBatteri() {
  const b = new Batteri(10, 5);
  b.visStatus();      // 5.0 / 10.0 (50%)
  b.lad(3); b.visStatus();
  b.lad(5); b.visStatus();   // cap til 10
  b.bruk(7.5); b.visStatus();

  try { b.bruk(10); } catch (e) { console.log(`OK – fanget: ${e.message}`); }
  try { b.lad(-1); } catch (e) { console.log(`OK – fanget: ${e.message}`); }
  try { new Batteri(-5); } catch (e) { console.log(`OK – fanget: ${e.message}`); }
  console.log("Alle tester passert.");
}

testBatteri();

Identifiserte feil/unntak: (1) Bruk av mer energi enn tilgjengelig. (2) Negativ ladnings- eller bruksverdi. (Unntak) Ugyldige verdier ved opprettelse. Alle håndtert ved BatteriFeil. #kapasitet og #energinivaa er private felter (moderne JS) — ekte innkapsling, ikke konvensjon med understrek.

Oppgave 7–8 – Velferdsteknologi (drøfting)

Velferdsteknologi — fallsensorer, GPS-armbånd, automatiske medisindispensere, robotkjæledyr og videokonsultasjon — gir både muligheter og dilemmaer i eldreomsorgen.

Fordeler. Teknologien kan øke selvstendigheten og tryggheten til eldre som bor hjemme. Fallsensorer varsler hjelp raskt, GPS-løsninger lar personer med demens bevege seg utendørs uten konstant tilsyn. Effektivt brukt frigjør teknologien tid for helsepersonell til oppgaver som krever menneskelig nærvær.

Etiske dilemmaer.

  • Personvern: Sensorer som logger bevegelser, søvn og toalettvaner samler svært personlige data. GDPR krever uttrykkelig samtykke, men kompetanse til å gi reelt informert samtykke kan være redusert ved demens.
  • Samtykke: Pårørende eller pleiehjem kan presse fram bruk av teknologi den eldre selv ikke ønsker — i strid med selvbestemmelsesretten.
  • Erstatning av menneskelig kontakt: Hvis robotkjæledyr og videosamtaler erstatter — i stedet for å supplere — menneskelig kontakt, kan ensomheten paradoksalt forsterkes.
  • Digital ulikhet: Velferdsteknologi som forutsetter smarttelefon og bredbånd, kan utelukke de eldste eller distrikts-bosatte.
  • Avhengighet og sårbarhet: Strømbrudd eller IT-angrep kan i verste fall sette liv i fare.

Konklusjon. Velferdsteknologi bør innføres etter prinsippet «teknologi som verktøy, ikke erstatning». Den krever solid juridisk rammeverk, opplæring av brukere og pleiere, og bevisst arbeidsdeling.

Oppgave 9 – Befolkningsutvikling i Norge

// oppgave9.mjs — befolkningsutvikling 1945–2024
/* Forberedelse av datasettet:
 * - Datasettet inneholder årlige tall for fødsler, innflyttinger og utflyttinger.
 * - Numeriske kolonner konverteres til tall (vi fjerner mellomrom som tusenskille).
 * - Netto folkevekst beregnes som fødsler + innflyttinger − utflyttinger.
 */
import { readFileSync, writeFileSync } from "node:fs";
import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

function lesData(filsti = "befolkning.csv") {
  const linjer = readFileSync(filsti, "utf-8").trim().split(/\r?\n/);
  const [head, ...rest] = linjer;
  const headers = head.split(";");
  return rest.map(linje => {
    const v = linje.split(";");
    const r = Object.fromEntries(headers.map((h, i) => [h, v[i]]));
    r["år"] = Number(r["år"]);
    for (const kol of ["fødselstall", "innflyttinger", "utflyttinger"]) {
      r[kol] = Number(r[kol].replace(/ /g, ""));
    }
    r["netto folkevekst"] = r["fødselstall"] + r["innflyttinger"] - r["utflyttinger"];
    return r;
  });
}

function visTabell(data) {
  console.log(`\n${"År".padEnd(6)}${"Fødte".padStart(10)}${"Inn".padStart(10)}${"Ut".padStart(10)}${"Netto".padStart(12)}`);
  console.log("-".repeat(48));
  for (const r of data) {
    console.log(
      String(r["år"]).padEnd(6) +
      r["fødselstall"].toLocaleString("nb-NO").padStart(10) +
      r["innflyttinger"].toLocaleString("nb-NO").padStart(10) +
      r["utflyttinger"].toLocaleString("nb-NO").padStart(10) +
      r["netto folkevekst"].toLocaleString("nb-NO").padStart(12)
    );
  }
}

// Linjediagram som SVG
function tegnDiagram(data, kolonne, fra, til) {
  const valgte = data.filter(r => r["år"] >= fra && r["år"] <= til);
  if (valgte.length === 0) { console.log("Ingen data."); return; }

  const bredde = 800, hoyde = 400, padding = 60;
  const verdier = valgte.map(r => r[kolonne]);
  const minV = Math.min(...verdier), maksV = Math.max(...verdier);
  const xSteg = (bredde - padding * 2) / (valgte.length - 1);
  const punkter = valgte.map((r, i) => {
    const x = padding + i * xSteg;
    const y = hoyde - padding - ((r[kolonne] - minV) / (maksV - minV || 1)) * (hoyde - padding * 2);
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(" ");

  const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${bredde}" height="${hoyde}">
    <text x="${bredde/2}" y="30" text-anchor="middle" font-size="18" font-weight="bold">${kolonne} ${fra}–${til}</text>
    <polyline points="${punkter}" fill="none" stroke="#1976D2" stroke-width="2"/>
  </svg>`;
  writeFileSync(`diagram_${kolonne.replace(/ /g, "_")}_${fra}_${til}.svg`, svg);
  console.log(`Diagram lagret som SVG.`);
}

async function main() {
  const data = lesData();
  visTabell(data);

  const rl = readline.createInterface({ input, output });
  const kolonne = (await rl.question("\nKolonne (fødselstall / innflyttinger / utflyttinger / netto folkevekst): ")).trim().toLowerCase();
  const fra = parseInt(await rl.question("Fra år: "), 10);
  const til = parseInt(await rl.question("Til år: "), 10);
  rl.close();

  if (!["fødselstall", "innflyttinger", "utflyttinger", "netto folkevekst"].includes(kolonne)) {
    console.log("Ugyldig kolonne."); return;
  }
  tegnDiagram(data, kolonne, fra, til);
}

main();

Oppgave 10 – Virusspredning (HTML5 Canvas)

<!DOCTYPE html>
<html lang="no">
<head><meta charset="utf-8"><title>Virusspredning</title></head>
<body style="text-align:center;font-family:sans-serif">
<h2>Virusspredning</h2>
<canvas id="lerret" width="560" height="560" style="border:1px solid #999"></canvas>
<p id="status"></p>
<script>
const RUTER = 40, CELLE = 14;
const DAGER_SMITTET = 3, DAGER_SYK = 4;
const DOD_PROB = 0.01, SMITTE_PROB = 0.3, SMITTE_RADIUS = 2;

const T = { FRISK: 0, SMITTET: 1, SYK: 2, IMMUN: 3, DOD: 4 };
const FARGER = ["#cccccc", "#f48fb1", "#e53935", "#424242", "#000000"];

class Person {
  constructor(r, k) {
    this.r = r; this.k = k;
    this.tilstand = T.FRISK;
    this.dager = 0;
  }
  smitt() { if (this.tilstand === T.FRISK) { this.tilstand = T.SMITTET; this.dager = 0; } }
  nesteDag() {
    if ([T.FRISK, T.IMMUN, T.DOD].includes(this.tilstand)) return;
    this.dager++;
    if (this.tilstand === T.SMITTET && this.dager >= DAGER_SMITTET) {
      this.tilstand = T.SYK; this.dager = 0;
    } else if (this.tilstand === T.SYK) {
      if (Math.random() < DOD_PROB) this.tilstand = T.DOD;
      else if (this.dager >= DAGER_SYK) { this.tilstand = T.IMMUN; this.dager = 0; }
    }
  }
}

class Populasjon {
  constructor(rader, kolonner, startSmittet) {
    this.rader = rader; this.kolonner = kolonner;
    this.personer = Array.from({length: rader}, (_, r) =>
      Array.from({length: kolonner}, (_, k) => new Person(r, k)));
    for (let i = 0; i < startSmittet; i++) {
      this.personer[Math.floor(Math.random() * rader)]
                   [Math.floor(Math.random() * kolonner)].smitt();
    }
  }
  naboer(p) {
    const result = [];
    for (let r = Math.max(0, p.r - SMITTE_RADIUS); r <= Math.min(this.rader - 1, p.r + SMITTE_RADIUS); r++)
      for (let k = Math.max(0, p.k - SMITTE_RADIUS); k <= Math.min(this.kolonner - 1, p.k + SMITTE_RADIUS); k++) {
        if (r !== p.r || k !== p.k) result.push(this.personer[r][k]);
      }
    return result;
  }
  enDag() {
    const smittebarere = this.personer.flat().filter(p => p.tilstand === T.SMITTET || p.tilstand === T.SYK);
    for (const p of smittebarere)
      for (const n of this.naboer(p))
        if (Math.random() < SMITTE_PROB) n.smitt();
    this.personer.flat().forEach(p => p.nesteDag());
  }
  statistikk() {
    const teller = [0, 0, 0, 0, 0];
    this.personer.flat().forEach(p => teller[p.tilstand]++);
    return teller;
  }
}

const pop = new Populasjon(RUTER, RUTER, 5);
const ctx = document.getElementById("lerret").getContext("2d");
const statusEl = document.getElementById("status");
let dag = 0;

function tegn() {
  for (let r = 0; r < pop.rader; r++)
    for (let k = 0; k < pop.kolonner; k++) {
      ctx.fillStyle = FARGER[pop.personer[r][k].tilstand];
      ctx.fillRect(k * CELLE, r * CELLE, CELLE, CELLE);
    }
  const [F, S, Sy, I, D] = pop.statistikk();
  statusEl.textContent = `Dag ${dag} | Frisk ${F} Smittet ${S} Syk ${Sy} Immun ${I} Død ${D}`;
}

function loop() {
  pop.enDag(); dag++;
  tegn();
  setTimeout(loop, 200);
}

tegn(); setTimeout(loop, 500);
</script></body></html>
Designvalg for sensor:
  • Tre klasser matcher de tre delene av oppgaven: Person (Del 1 — tilstandsmaskin), Populasjon (Del 2 — smittedynamikk), HTML-skript (Del 3 — visning).
  • Smitte i to faser: først finner vi alle smittebærerne, så smitter vi naboer. Dette unngår at en nylig smittet person umiddelbart smitter videre samme dag.
  • Konstanter ligger på toppen og kan justeres for eksperimenter.
  • Statuslinjen viser løpende SIR-statistikk så man ser epidemien utvikle seg.

Oppgave 11 – Innlevering

123456/
├── oppgave5b/palindrom.mjs
├── oppgave6/batteri.mjs
├── oppgave9/
│   ├── oppgave9.mjs
│   └── befolkning.csv
├── oppgave10/virusspredning.html
└── README.md   (Node.js 18+ for ESM og private felter)
Laster…
Nyere løsning
Vår 2025
Eldre løsning
Vår 2024

Alle løsningsforslag for IT 2 – JavaScript

Vår 2025Høst 2024Vår 2024Høst 2023
Se eksamensoppgaven
eksamenssett.noTren målrettet

Komplett samling av eksamensoppgaver og løsninger for norsk skole.

Om ossFAQPersonvernVilkårAngrerettKontakt

© 2025 Eksamenssett.no · Alle rettigheter forbeholdt

Innholdet er utviklet med AI-verktøy og kvalitetssikres kontinuerlig. Slik jobber vi med kvalitet →

Eksamenssett.no eies og drives av Studenthjelp Privatundervisning AS