Jouw vlucht naar de belangrijkste hub van de luchtvaartmaatschappij bereikt zonder incidenten kruishoogte. Net op het moment dat je overweegt om in de menukaart te zoeken naar één van die drankjes met een klein parapluutje, wordt je op de schouder geklopt door het kind dat naast je zit.
Haar draagbare spelcomputer1 wil niet opstarten! Ze vraagt of je er eens wil naar kijken.
Je merkt al snel dat het probleem te herleiden is tot een vreemde oneindige lus in de opstartcode (de invoer van deze opgave) van het apparaat. Je zou het moeten kunnen oplossen, maar eerst moet je de code afzonderlijke kunnen uitvoeren.
Je zet de opstartcode in een tekstbestand. Elke instructie staat op een afzonderlijke regel en bestaat uit een bewerking (acc
, jmp
of nop
) en een argument (een getal voorafgegaan door een teken zoals +4
of -20
).
acc
verhoogt of verlaagt één enkele globale variabele die de accumulator genoemd wordt met de waarde die als argument wordt meegegeven. Zo verhoogt acc +7
bijvoorbeeld de accumulator met 7. De accumulator begint bij 0
. Na een acc
-instructie wordt vervolgens de instructie direct eronder uitgevoerd.jmp
springt naar een nieuwe instructie relatief ten opzichte van zichzelf. De volgende uit te voeren instructie wordt gevonden door het argument te gebruiken als een offset van de jmp
-instructie. Zo zou jmp +2
bijvoorbeeld de volgende instructie overslaan, terwijl jmp +1
zou doorgaan naar de instructie er direct onder, en jmp -20
zou ervoor zorgen dat de instructie 20 regels hoger als volgende wordt uitgevoerd.nop
staat voor No OPeration — ze doet niets. De instructie direct eronder wordt vervolgens uitgevoerd.Stel dat we bijvoorbeeld het volgende programma hebben:
nop +0
acc +1
jmp +4
acc +3
jmp -3
acc -99
acc +1
jmp -4
acc +6
De instructies worden in deze volgorde uitgevoerd:
nop +0 | 1
acc +1 | 2, 8(!)
jmp +4 | 3
acc +3 | 6
jmp -3 | 7
acc -99 |
acc +1 | 4
jmp -4 | 5
acc +6 |
Eerste doet de nop +0
niets. Vervolgens wordt de accumulator verhoogd van 0 naar 1 (acc +1
) en jmp +4
stelt de volgende instructie in op de andere acc +1
aan de onderkant. Nadat ze de accumulator verhoogd heeft van 1 naar 2, wordt jmp -4
uitgevoerd en wordt de volgende instructie ingesteld op de enige acc +3
. Ze stelt de accumulator in op 5 en jmp -3
zorgt ervoor dat het programma teruggaat naar de eerste acc +1
.
Dit is een oneindige lus: met deze reeks sprongen blijft het programma voor altijd lopen. Zodra een programma een instructie een tweede keer probeert uit te voeren, weet je dat het nooit zal eindigen.
Onmiddellijk *voor** het programma een instructie een tweede keer zou uitvoeren, is de waarde van de accumulator gelijk aan 5
.
Voer jouw kopie van de opstartcode uit. Wat is de waarde van de accumulator onmiddellijk voor het programma een instructie een tweede keer zou uitvoeren? Hiervoor ga je als volgt te werk: ,
inspect
waaraan de padnaam (char*
) moet doorgegeven worden van een tekstbestand met de opstartcode van een spelcomputer. De functie moet de waarde (int
) teruggeven die de accumulator heeft onmiddellijk voor het programma een instructie een tweede keer zou uitvoeren.In deze interactieve sessie gaan we ervan uit dat het tekstbestand code.txt
2 zich in de huidige directory bevindt.
> inspect("code.txt")
5