The Let's Play Archive

EXAPUNKS

by Carbon dioxide

Part 47: US Department of Defense

Part 47 - US Department of Defense

Today, we have a very special guest. But first, let's check the inbox.


=== Trash World Inbox ===

Last time, I finished Cybermyth Studios with a score of 536/246/16. The max allowed number of lines for the leaderboard was 150, so it didn't really count.

Quackles shows some better ways to tackle it.

Quackles posted:

I... owe CO2 an apology.

My fully-optimized design uses a completely different approach than his, and it almost feels like I'm bragging. If so, I'm sorry.

But anyway, here's what I got.
code:
GRAB 300
COPY F X
REPL COMPTROLLER
SEEK -1
COPY M F ;CENTS 1
COPY F X
REPL COMPTROLLER
SEEK -1
COPY M F ;DOLLARS 1
SEEK -2
ADDI M F X ;CENTS 2
;WE AVOID HAVING TO TEST
;FOR NEGATIVE CENTS
;BY ADDING 300 TO CENTS
;AND SUBTRACTING 3 FROM 
;DOLLARS (LATER)
ADDI X 300 X
DIVI X 100 T
SEEK -1
MODI X 100 F
ADDI M T T
ADDI T F T
;X HAS CENTS,
;T HAS DOLLARS

;NOW JUST WRITE THE
;VALUES AND WE'RE GOOD
;TO GO
LINK 800
MODE
COPY F X
REPL HACKTHEPAYABLE
LINK 804
SEEK -9999
COPY F X
WIPE
COPY #DATE M
COPY T M
COPY X M


MARK HACKTHEPAYABLE
LINK 801
GRAB 220
SEEK 9999
SEEK -2
COPY F T
SEEK 1
ADDI T 1 F
COPY X F
DROP
GRAB 221
SEEK 9999
ADDI T 1 F
COPY M F
SUBI M 3 F
COPY M F


MARK COMPTROLLER
LINK 800
REPL GETFIN
COPY 1 T
REPL GETFIN

;PAYMENTS ALWAYS
;FINISHES FIRST!

SUBI 0 M X ;DOLLARS1
SUBI 0 M T ;CENTS1
ADDI X M X ;2
ADDI T M T ;2
LINK -1
COPY T M ;CENTS
COPY X M ;DOLLARS


MARK GETFIN
ADDI T 801 T
LINK T
SWIZ T 0010 T
ADDI T 210 T
GRAB T
SEEK 1
MARK SEARCHFIN
TEST F = X
TJMP FOUNDFIN
SEEK 1
JUMP SEARCHFIN

MARK FOUNDFIN
SEEK -2
COPY F X
FILE T
ADDI T 1 T
DROP
GRAB T
REPL COUNTER
MARK LISTFIN
TEST EOF 
TJMP DONEZO
TEST F = X
SEEK 3
FJMP LISTFIN
SEEK -2
COPY F M
COPY F M
JUMP LISTFIN


MARK COUNTER
MAKE
COPY 0 F
COPY 0 F
MARK COUNTER2
COPY M T
FJMP FINISHEDCOUNT
SEEK -2
ADDI F T T
ADDI F M X
SEEK -2
COPY T F
COPY X F
JUMP COUNTER2

MARK FINISHEDCOUNT
LINK -1
SEEK -2
COPY F M
COPY F M
WIPE
HALT

MARK DONEZO
COPY 0 M
;GIVE UP
This is a big block of code, but it's really in five main 'chunks': the main EXA, the main EXA's file writing routine ("HACKTHEPAYABLE"), the EXA that gets the amounts paid and owed for a single person ("COMPTROLLER"), and the subsidiary processes spun off by the controller ("GETFIN") and ("COUNTER").

It works as follows:

First, the main EXA moves 'Ghast' into X, then REPLs to COMPTROLLER. The 'comptroller' EXA will search for the accounts receivable and payable, return to our host, and communicate them to the main EXA over M, in the order (Cents, Dollars). We use this order to let us use the file for extra storage later.

The comptroller EXA heads into the Cybermyth host, then REPLs twice to GETFIN. Some numeric wrangling with T lets us use GETFIN for both the payroll and payable hosts, despite having different link and file IDs. Each GETFIN EXA still has 'Ghast' in its X, so it starts by grabbing the IDs file, searching for 'Ghast', and replacing its X with the numeric ID, instead. Then, it drops the IDs file, grabs the accounts file (using FILE and some addition to get the next file ID), and REPLs off into COUNTER. There's enough space in the host since we're grabbing a file.

From here, the GETFIN EXA simply scans through the file and sends any dollar/cents values it finds with a matching ID out over M, then 0 once it's done. It then halts. COUNTER adds up the dollars and cents values it gets to a file; once it receives a 0 for a dollar value, it leaves the subhost and reports to the comptroller.

The payments file always takes less time to process than the payroll file! Cybermyth, you cheapskates. Because of this, we can assume that the first COUNTER EXA has the amount paid, while the second has the amount owed. We get the values over M, subtract the first EXA's values from our registers, and add the second EXA's values. Then we report back to the main EXA.

The main EXA stores the values to the file in place of 'Ghast' and 'Moss'. It repeats the comptroller process with 'Moss', and adds the second comptroller's values.

We have a little bit of rectification to do at this point. It's possible we could have a value for the 'cents' that is over 100, or even negative! To fix these, we add 300 to the cents value to counter out any negative amount. Then we add the modulo 100 of the cents to the dollars value, and leave the rest of the cents as is. (We'll subtract 3 from the dollars value later.)

At this point, the final part of the code kicks in.

The main EXA splits into two. One ('HACKTHEPAYABLE') moves into the payments subhost and patches the accounts file (the main EXA moves into the host with #DATE and helpfully sends 'TRASH WORLD CLEANING' over global M). Then, with the new ID, it moves to the bottom of the payments file, takes the dollars value (minus $3) and cents value from the main EXA over M, and writes to the file. Finished!


458/109/15. I'm pretty sure handling Ghast's and Moss's data separately drastically decomplicates things. It might also be possible to speed this up further by having separate routines for the payable and payroll sections, since the payroll section follows a pattern (so just find the first payment, then find the number of payments by jumping forward 15 places in the file and checking for EOF, then perform multiplication). I might try making that variant when I have some spare time.
First of all, this only works if you start the EXA in LOCAL mode. Secondly, very nice optimization. I guess I was overthinking things a bit. Also I have no idea why you'd need to apologize, I always welcome cool improvements.

Next Quackles implemented the faster variant.

Quackles posted:

code:
GRAB 300
COPY F X
REPL COMPTROLLER
SEEK -1
COPY M F ;CENTS 1
COPY F X
REPL COMPTROLLER
SEEK -1
COPY M F ;DOLLARS 1
SEEK -2
ADDI M F X ;CENTS 2
	;WE AVOID HAVING TO TEST FOR NEGATIVE CENTS
	;BY ADDING 300 TO CENTS AND SUBTRACTING 3 FROM DOLLARS (LATER)
ADDI X 300 X
DIVI X 100 T
SEEK -1
MODI X 100 F
ADDI M T T
ADDI T F T
	;X HAS CENTS,
	;T HAS DOLLARS

	;NOW JUST WRITE THE
	;VALUES AND WE'RE GOOD TO GO
LINK 800
MODE
COPY F X
REPL HACKTHEPAYABLE
LINK 804
SEEK -9999
COPY F X
WIPE
COPY #DATE M
COPY T M
COPY X M


MARK HACKTHEPAYABLE
LINK 801
GRAB 220
SEEK 9999
SEEK -2
COPY F T
SEEK 1
ADDI T 1 F
COPY X F
DROP
GRAB 221
SEEK 9999
ADDI T 1 F
COPY M F
SUBI M 3 F
COPY M F


MARK COMPTROLLER
LINK 800
REPL GETDUE
REPL GETFIN

ADDI 0 M X ;DOLLARS1
MODE ;SYNC GUARDS
ADDI 0 M T ;CENTS1
MODE

ADDI X M X ;2
MODE
ADDI T M T ;2
MODE
LINK -1

COPY T M ;CENTS
COPY X M ;DOLLARS


MARK GETDUE
LINK 802
GRAB 230
SEEK 1
MARK SEARCHDUE
TEST F = X
TJMP FOUNDDUE
SEEK 1
JUMP SEARCHDUE

MARK FOUNDDUE
SEEK -2
COPY F X
DROP
GRAB 231
REPL COUNTER

MARK LISTDUE
TEST F = X
SEEK 3
FJMP LISTDUE
SEEK -2
COPY F M
COPY F M
COPY 1 X
SEEK 16
MARK DUECOUNT
TEST EOF
ADDI X 1 X
SEEK 20
FJMP DUECOUNT
COPY 0 M
SUBI X 1 M


MARK GETFIN
LINK 801
GRAB 220
SEEK 1
MARK SEARCHFIN
TEST F = X
TJMP FOUNDFIN
SEEK 1
JUMP SEARCHFIN

MARK FOUNDFIN
SEEK -2
COPY F X
DROP
GRAB 221
REPL COUNTER
MARK LISTFIN
TEST EOF 
TJMP DONEZO
TEST F = X
SEEK 3
FJMP LISTFIN
SEEK -2
COPY F M
COPY F M
JUMP LISTFIN


MARK DONEZO 
COPY 0 M
COPY -1 M
;GIVE UP

MARK COUNTER
MAKE
COPY 0 F
COPY 0 F
MARK COUNTER2
COPY M T
FJMP FINISHEDCOUNT
SEEK -2
ADDI F T T
ADDI F M X
SEEK -2
COPY T F
COPY X F
JUMP COUNTER2

MARK FINISHEDCOUNT
COPY M X
LINK -1
SEEK -2
MULI F X M
MODE ;SYNC GUARD
MULI F X M
WIPE
This code is similar to the last one, except the code that scans the payroll and payable has been split off into separate blocks. The payable code ('GETFIN') is more or less as-is compared to the previous version, but the payroll code ('GETDUE') finds the first instance of the amount paid in the list, then jumps forward 20 entries to check if there was another payment scheduled. The payroll EXA then repeats this to count up the number of expected payments, then sends a zero, and that number, to the counter EXA.

Both the GETFIN and GETDUE EXAs use the same counter code, which has been modified slightly. Now, after receiving the 'finish up' zero, the counter EXA will read one more value over M, and multiply the totals by that value. This lets us not have to worry about the order the EXAs return when reporting our results to the comptroller. We can simply add the values together, as the amount CyberMyth paid us can be multiplied by -1 to mimic a subtraction.

The comptroller and counter do use 'mode guards' to handle the edge case where both counters return to the main CyberMyth host at about the same time. Once the first value is read from a counter, the second value will be read using the global mode instead of the local mode. This prevents the second counter from kramering in and getting the order of the values mixed up.

Aside from that, everything is pretty much the same.


354/140/15. It can theoretically get better cycles-wise, but this is as good as it gets for me.
Clear explanation, I have nothing to add.


=== US Department of Defense ===



Alright, is everyone ready to go hack the Department of Defense?


OST: Leave No Trace

The assignment:
- Find the unredacted version of the PROJECT OGRE report (file 300), make a copy of it, and bring the copy back to your host. The target file will be behind one or more locks, which each require a three-digit code.
- Since this task takes place inside a network run by the military it includes additional security features not found in other networks. You may not have more than one EXA in the network at a time, and you may not use the M register to communicate between an EXA in the network and an EXA in your host.


Camouflage colours or not, I found your network. And finally some real security. Honestly, all networks so far were wide open.

Anyway, I did some experiments to see what that second point of the assignment is about. M communication between the home host and the remote network is simply blocked, as if the networks are disconnected. If you bring in two EXAs to the military network, that grid of squares in the background starts flashing red and the "Leave no trace" goal is immediately failed. The same thing happens if you mess with the hardware registers on the helipad.

Those three files that are immediately accessible are heavily censored, so I'll need to crack that #LOCK.

The assignment says nothing about how to figure out the lock's combination, so let's just bruteforce it by trying all possible combinations.
code:
LINK 800

COPY 1000 T

MARK LOOP
SUBI T 1 T
COPY T #LOCK
TJMP LOOP

NOOP
Hmm, at some point it opens the link to that secured host but as soon as my EXA tries another code it closes again. Do I have to check whether the link is open after every try? But I can't use REPLs because that would mean 2 EXAs in the military network. I could spawn 1000 EXAs from some main EXA in my home host but that would be very slow and give a very high activity.

I think I will need a little help with this one...

----

This is the LockPickingLawyer and what I have for you today is a US Department of Defense Digital Combination Lock, model 1998-D. This lock was sent to me by my friend hydroponix. It is supposedly used by the Department of Defense to secure their digital information, and they consider it military grade.

There is a glaring weakness in this digital lock, though, and I will demonstrate it to you. Let me zoom in a little bit so you can see what is going on.



The combination for this lock has a six in the third position. I just tried to open it with 996 and you can see the correct digit sticks. This means we can open the lock with only a short loop.



I simply move all three digits to 999, save any correct digits to the EXA's X register, then repeat for 888 and so on. The code for this lock is 436, and I found this in only 39 cycles.

And there we have it. For any type of lock, there's a tool to pick it. In this case it's an EXA. The mechanism of this lock is similar to that of the Master Lock 878 Combination Lock, and just like that one, this digital lock can be decoded both easily and rapidly. In any case, that's all I have for you today. If you have any questions or comments about this, please put them below. If you liked this explanation and would like to see more like it, please subscribe to my channel, and as always, have a nice day. Thank you.


I hope the real LPL doesn't mind me doing this. After all, imitation is the sincerest form of flattery. Go check out his channel, it's interesting.

----

Thank you so much, LockPickingLawyer. Opening the link to the next host reveals a bunch more files, and another #LOCK to get access to the innermost files. I'll quickly open that as well by repeating the lock picking loop (or LPL for short) in that host.
code:
LINK 800

COPY 999 T

MARK LPL
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL

COPY X #LOCK

LINK 800
COPY 0 X

COPY 999 T

MARK LPL2
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL2

COPY X #LOCK
That gives me access to the full network.



The photo archive in the corner now shows... them filming something in the desert? Looks like an astronaut and someone dressed in a cheap alien costume.

The files here have some very interesting information. There's a few different files in the different test cases, so let me transcribe all of them for you.

The first three are uncensored versions of the censored files from the start.

Project Ogre
(1945-1953) Obtain special footage for the director depicting a hypothetical scenario involving a technologically advanced craft of non-earth origin with the purpose of scenario planning should such a situation occur. Footage was deemed unrealistic and not used. Result: FAILURE

Project Ptero
(1981-1990) Infer and test experimental new wing designs based on information from recovered DNA samples. Resulting wing shapes were not conducive to maintaining altitude. Result: FAILURE

Project Quir
(1960-1968) Investigate gravity shielding effects produced by condensed matter and superconducting materials. Analysis of tidal forces detected reduction of gravitational force of close to 1%. Future projects to focus on increasing power. Result: SUCCESS.


The rest of the files describe some other projects.

Project Orbus
(1994-) Develop additional capability and platforms for directed-energy weapons using chemically-based phase-conjugate mirrors. In all cases the mirrors overheated and experienced unplanned combustion. Result: FAILURE


I wonder if this is a kind of a vague reference to the boss missions in the Zachtronics game SpaceChem.

Project Ember
(1994-) Create general artificial intelligence using a baseline emulated reasoning approach. Of 4 initial seed programs, 1 developed knowledge acquisition, language comprehension, and exhibited signs of metacognition. Result: SUCCESS


Oh, hey. Ember was created by the military?

Project Virgil
(1983-1987) Explore use of chimpanzees as pilots for small reconnaissance aircraft to reduce radar cross-section and human casualties. Of 9 tests, 7 completed take-off but 0 returned to base. Result: FAILURE

Project Icarus
(1972-1978) Test advanced new methods to synthesize wing and fuselage material with carbon nanofibers to enable greater speed and maneuverability. Of the 21 tested methods, 20 created unusable materials and 1 resulted in a small incident. Result: FAILURE

Project Phosphor
(1979-1987) Project to develop and test technology related to inertial guidance, warhead separation, and ablative heat shielding of re-entry vehicles. Of 18 launches, 9 reached space and 3 returned to earth intact. Result: SUCCESS



That's all of them. But I need a copy of Project Ogre for myself. Let's find it first.
code:
GRAB 300
LINK 800

COPY 999 T

MARK LPL
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL

COPY X #LOCK

LINK 800
COPY 0 X

COPY 999 T

MARK LPL2
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL2

COPY X #LOCK

COPY F X
WIPE

; FIND

@REP 4
LINK 80@{1,1}
GRAB 200
TEST F = X
TJMP FOUND
DROP
LINK -1

@END

LINK 800
LINK 801
GRAB 200
TEST F = X
TJMP FOUND
DROP
LINK -1
LINK 802
GRAB 200

MARK FOUND
The EXA first grabs the encrypted version of Project Ogre from my home host, so it can extract the name later. Then it uses the lock picking loop (LPL) twice to pick both locks. After that, it doesn't need X anymore to hold lock information so it can take the project name from the file and put that in X.

Since the encrypted Project Ogre file started in my home host, I can safely WIPE without failing the "Leave no trace" goal. Then, the @REP makes the EXA go to each side host (801 to 804), check the file, and if it's wrong, continue to the next one. After @END, it continues to the deepest part of the network and searches for the file there as well. There's no test for the very last host, because if it's none of the others, that has to be the one.

I could maybe use a loop or two here, but I'm using my registers already. Maybe an optimization for later.

Now that the EXA has the file in hand... I have to copy it without M and without a second EXA. The files all have the little lock icon meaning I cannot move them either.

There's another issue: if I create another file in one of the side hosts, I don't have space to drop it and swap between the files. My copy has to be created in a central host, so my EXA has to link back and forth.

That means I need to either remember or bruteforce the following stuff:
- How far I am into copying the file.
- What host the correct file is in so I can link back to it to get more data.
- And of course the data to copy itself.


I started by expanding my file finding logic to save the LINK value to T. I need to do it there, because once I'm in the FOUND mark I don't know where I came from and can't save it anymore.
code:
; FIND

@REP 4
LINK 80@{1,1}
GRAB 200
TEST F = X
FJMP SKIP@{1,1}
COPY 80@{1,1} T
JUMP FOUND
MARK SKIP@{1,1}
DROP
LINK -1

@END

LINK 800
LINK 801
GRAB 200
TEST F = X
FJMP SKIP
COPY 801 T
JUMP FOUND
MARK SKIP
DROP
LINK -1
LINK 802
COPY 802 T
GRAB 200

MARK FOUND
Next, the actual copy logic.
code:
MARK FOUND
DROP
LINK -1

MAKE
COPY T F
COPY 0 X

MARK COPY
DROP
LINK T

GRAB 200
SEEK X
COPY F X
COPY F T
DROP

LINK -1
GRAB 400
SEEK 9999
COPY X F
COPY T F

SEEK -9999
COPY -1 X

MARK COUNT
SEEK 1
ADDI X 1 X
TEST EOF
FJMP COUNT

SEEK -9999
COPY F T
JUMP COPY
The first thing I do after finding the file is jump back and create a target file to copy the data to (file 400). I store the LINK ID in there to free up the registers. In the MARK COPY loop, I go to the source file, read two entries to X and T, drop it, go back to the target file, and write them there. Then I count the length of the file (minus one for the link ID sitting at the start) and put that in X so I can SEEK to that position in the source file. That count takes time, but it's a simple solution.

I read the link ID from the file, and go back to copy the next two values.

Once the whole file is copied, the EXA will crash because it'll try to read past the end of the file. This doesn't have to be a problem, I could have another EXA that waits at home for all this time using a simple wait loop and comes fetch this file when it's done. That's a bit complicated though, because the file can be both in the middle host and the far host, and if it can't find the file it will crash, so I would have to send two separate EXAs and... no thanks.

Let's instead just write a way for this EXA to know when it's done so it doesn't crash.

This turns out to be very easy. The file always has 44 words, so all I have to do is hardcode that in a TEST. The end becomes:
code:
MARK COUNT
SEEK 1
ADDI X 1 X
TEST EOF
FJMP COUNT

SEEK -9999
TEST X = 44
TJMP DONE
COPY F T
JUMP COPY

MARK DONE
VOID F
LINK -1
LINK -1
LINK -1
If the EXA copied 44 entries, void the value holding the LINK ID. Handling the fact that the EXA might be in different hosts is also easy, just add one more LINK -1 and if it's closer to home that will crash the EXA in the home host, make it drop the file there.



Large variety in the scores here. My code runs at 2654/105/62. The top percentiles are 531, 60 and 46.

Let's look at some improvements. Before I start, here's all the code so far.
code:
GRAB 300
LINK 800

COPY 999 T

MARK LPL
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL

COPY X #LOCK

LINK 800
COPY 0 X

COPY 999 T

MARK LPL2
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL2

COPY X #LOCK

COPY F X
WIPE

; FIND

@REP 4
LINK 80@{1,1}
GRAB 200
TEST F = X
FJMP SKIP@{1,1}
COPY 80@{1,1} T
JUMP FOUND
MARK SKIP@{1,1}
DROP
LINK -1

@END

LINK 800
LINK 801
GRAB 200
TEST F = X
FJMP SKIP
COPY 801 T
JUMP FOUND
MARK SKIP
DROP
LINK -1
LINK 802
COPY 802 T
GRAB 200

MARK FOUND
DROP
LINK -1

MAKE
COPY T F
COPY 0 X

MARK COPY
DROP
LINK T

GRAB 200
SEEK X
COPY F X
COPY F T
DROP

LINK -1
GRAB 400
SEEK 9999
COPY X F
COPY T F

SEEK -9999
COPY -1 X

MARK COUNT
SEEK 1
ADDI X 1 X
TEST EOF
FJMP COUNT

SEEK -9999
TEST X = 44
TJMP DONE
COPY F T
JUMP COPY

MARK DONE
VOID F
LINK -1
LINK -1
LINK -1
The first thing I can change is removing the COUNT loop. If I just keep a counter and increase it by 2 every time I copy two values, that's much faster. I didn't do that right away because I didn't have any registers free... but I can just use another value at the start of the file instead.
code:
;XA CONT'd

MAKE
COPY 0 X
COPY 0 F
COPY T F

MARK COPY
DROP
LINK T

GRAB 200
SEEK X
COPY F X
COPY F T
DROP

LINK -1
GRAB 400
SEEK 9999
COPY X F
COPY T F

SEEK -9999
ADDI F 2 X
SEEK -1
TEST X = 44
TJMP DONE
COPY X F
COPY F T
JUMP COPY

MARK DONE
VOID F
VOID F
LINK -1
LINK -1
LINK -1
565/103/62, much better speed.


To reduce the size, I can roll up the file search loops. But how? I already need X and T and I can't use M. The answer is to prepare a file that can handle the loops.

After the LPL:
code:
COPY F X
WIPE

MAKE
COPY 804 F
COPY 803 F
MARK NEXT
COPY 802 F
COPY 801 F
SEEK -9999

MARK SEARCH
COPY F T
DROP

LINK T
GRAB 200
TEST F = X
TJMP FOUND
DROP
LINK -1
GRAB 400
VOID F
TEST EOF
FJMP SEARCH

LINK 800
JUMP NEXT
The loop works by VOIDing a value from the file once I've tried it. I don't need the weird workaround to find the host ID anymore inside the loop. That'll just be the first value of file 400. So the MARK FOUND now GRABs that file, copies that value to T, WIPEs it and creates a fresh file to copy the data to. 611/79/62.

If you move the LPL loops into a separate EXA you can combine the two loops into one, the EXA will just die when it tries to write to a non-existent third #LOCK. However, that means the copying EXA has to wait at home until the LPL EXA is done, and the extra lines for the wait loop are the same amount as the lines saved by doing this, so the score is the same.


I have one more idea for a speed optimization.

Copying is slow, with only one EXA and while having to LINK between hosts. But I don't need to copy everything, significant chunks of the file are already in the censored copy. Let's make use of that.



After OBTAIN, the word SPECIAL is missing. After DEPICTING, things get more complicated. Between DEPICTING and TECHNOLOGICALLY, there are three censored keywords in this file, but 5 words in the original file. And it doesn't get any better after that. Dealing with these different file lengths is very complicated and it makes you run out of space for lines of code very fast.

But we can just take that first chunk before the lengths start to differ.

In this optimization, XA's only purpose is the LPL.
code:
;XA

LINK 800

COPY 999 T

MARK LPL
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL

COPY X #LOCK

LINK 800
COPY 0 X

COPY 999 T

MARK LPL2
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL2

COPY X #LOCK
Meanwhile, in the safety of my home host, XB grabs the file and copies only the first 10 values (until DEPICTING) using M.
code:
;XB

GRAB 300
COPY 10 T
MARK LP
SUBI T 1 T
COPY F M
TJMP LP
XC starts with putting a couple zeroes in an empty file (for the counter and the LINK ID later on), then copies the data from M.
code:
;XC

MAKE
COPY 0 F
COPY 0 F

COPY 10 T

MARK LP
COPY M F
SUBI T 1 T
TJMP LP

SEEK -9999
SEEK 2
COPY F X

COPY 16 T

MARK WAIT
SUBI T 1 T
TJMP WAIT

LINK 800
LINK 800

DROP
It needs to wait a bit until LPL is done, but by that time it has the PROJECT OGRE keyword in X and can start searching. As you can see, the file is now DROPped instead of WIPEd.


The FIND code is almost the same as in my 565 cycles solution. The only difference is that if it needs to go search in the deepest host, it will take the file along.
code:
;XC at the end of the FIND code

SEEK 1

MARK FOUND
SEEK 3
COPY F X
DROP
LINK -1

GRAB 400
COPY 10 F
COPY T F
SEEK 4
COPY X F
COPY 10 X

MARK COPY
After FOUND, the EXA has the LINK ID in T, and X isn't needed anymore. So it uses that first visit to immediately copy the word SPECIAL. The extra SEEK 1 at the top was added to the fallthrough case where the very last host is the one holding the file. The TEST in all other cases also pushes the file cursor forward one step.

After grabbing the file containing the partially copied censored file, the EXA writes 10 to the copy counter (because the first 10 values are already in there), and then it caches the LINK ID in the file. Finally, it copies SPECIAL to the right position, and starts the general copy loop by putting the 10 count value into X. The copy loop stayed unchanged from before. The complete code is in the appendix at the bottom.

472/131/54. A cycles and activity improvement. And the cycles are better than the top percentile. My best lines of code solution was 79 as I showed above. Not bad.


Some final remarks: I did actually try to use all uncensored words in the censored file. But the code to move them forward and then only grab the necessary words from the uncensored file just didn't fit. A solution like that requires a SEEK F using the counter value at the start of the file. Interestingly enough, that instruction actually moves the cursor forward F + 1 places, because the act of reading from F also moves the cursor forward one.

I think the only way to get the top percentile activity of 46 is to actually use code like that. It's a reduction of 8 more activity, and each activity roughly corresponds to copying one value (you copy 2 per round but a round requires 2 LINKs). There are 9 more values in the uncensored file (and with some trickery you could reuse the words THE and A because they both occur twice in the file), so theoretically you could save slightly more than 8 activity, but this might not be possible without going over the max size limit.

Well, if anyone in the thread has any ideas, I'd like to hear. Let's finish this update.



Finishing hydroponix' task makes 4 more tasks appear in the list. Next time, =plastered.


=== Appendix ===

code:
;XA

LINK 800

COPY 999 T

MARK LPL
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL

COPY X #LOCK

LINK 800
COPY 0 X

COPY 999 T

MARK LPL2
COPY T #LOCK
ADDI X #LOCK X
SUBI T 111 T
TJMP LPL2

COPY X #LOCK

;XB

GRAB 300
COPY 10 T
MARK LP
SUBI T 1 T
COPY F M
TJMP LP

;XC

MAKE
COPY 0 F
COPY 0 F

COPY 10 T

MARK LP
COPY M F
SUBI T 1 T
TJMP LP

SEEK -9999
SEEK 2
COPY F X

COPY 16 T

MARK WAIT
SUBI T 1 T
TJMP WAIT

LINK 800
LINK 800

DROP

; FIND

@REP 4
LINK 80@{1,1}
GRAB 200
TEST F = X
FJMP SKIP@{1,1}
COPY 80@{1,1} T
JUMP FOUND
MARK SKIP@{1,1}
DROP
LINK -1

@END

GRAB 400
LINK 800
DROP
LINK 801
GRAB 200
TEST F = X
FJMP SKIP
COPY 801 T
JUMP FOUND
MARK SKIP
DROP
LINK -1
LINK 802
COPY 802 T
GRAB 200
SEEK 1

MARK FOUND
SEEK 3
COPY F X
DROP
LINK -1

GRAB 400
COPY 10 F
COPY T F
SEEK 4
COPY X F
COPY 10 X

MARK COPY
DROP
LINK T

GRAB 200
SEEK X
COPY F X
COPY F T
DROP

LINK -1
GRAB 400
SEEK 9999
COPY X F
COPY T F

SEEK -9999
ADDI F 2 X
SEEK -1
TEST X = 44
TJMP DONE
COPY X F
COPY F T
JUMP COPY

MARK DONE
VOID F
VOID F
LINK -1
LINK -1
LINK -1