The Let's Play Archive

EXAPUNKS

by Carbon dioxide

Part 21: EXA-Blaster Modem - Radio Station hack

Part 21 - EXA-Blaster Modem - Radio Station hack

=== Trash World Inbox ===

I ended the last update with top scores of 232, 26, and 10. Let's see what you came up with.

silentsnack posted:

code:
;M=LOCAL
GRAB 300
MARK CLONE
ADDI F 2000 X
REPL TRAVERSE
JUMP CLONE

MARK TRAVERSE
LINK 800
REPL TRAVERSE
SWIZ X 421 X

GRAB X
REPL WRITER

MARK READ
COPY F M
JUMP READ

MARK WRITER
MAKE
MARK W_LOOP
COPY M F
NOOP
TEST MRD
TJMP W_LOOP

MARK HOME
LINK -1
JUMP HOME
289/24/87
Nice and simple size improvement. All it does different is skip the EOF check, and line up the cycles so the writer can do an MRD check instead. The ADDI F 2000 X; SWIZ X 421 X trick doesn't save any space but is a neat use of SWIZ. Since some people commented they didn't understand SWIZ very well, I'll try to explain what this does.

So, imagine you start with a file ID 512. According to the assignment, the GRAB instruction needs 212 (200 plus the last two digits). The 5 tells us what host it's in but because we try every host, we don't strictly need it.
First we add 2000 to 512 with the ADDI. That's 2512.
Next, we do SWIZ 2512 421. It looks more complex than it is. The second operand, 421, just says "take the fourth digit from the right, then the second, and then the first", so [2]512, 25[1]2, 251[2], forming 212, which is the actual number we need.

silentsnack posted:

code:
;M=LOCAL
GRAB 300
@REP 4
ADDI F 2000 T
REPL SKIP
@END
ADDI F 2000 T
WIPE

MARK SKIP
LINK 800
MARK TRAVERSE
LINK 800
REPL TRAVERSE

SWIZ T 421 T
GRAB T
REPL WRITER

MARK READ
@REP 18
COPY F M
@END
JUMP READ

MARK TIMER
SUBI T 1 T
TJMP TIMER
COPY 0 M
HALT

MARK WRITER
MAKE
COPY M F;  [[COPY--
COPY 15 T

MARK WRITE_BATCH
COPY M F;  --TO--
SUBI T 1 T
COPY M F;  --FILE--
TJMP WRITE_BATCH

COPY M F;  --EVERY--
COPY 34 T
COPY M F;  --OTHER--
REPL TIMER
COPY M T;  --CYCLE]]

MARK WRITE_END
COPY T F
COPY M T
TJMP WRITE_END

@REP 10
LINK -1
@END
188/72/87
Nice. It starts with a @REP for reading the file list. Sometimes there's less files to grab in which case the original one just dies once it reaches the end of the list. Otherwise it wipes that file and goes handle the last entry itself.

Then it uses a REPL setup to just send a copy of itself to every node to go look for the file - that's faster than checking if you're in the right host. There doesn't seem to be a big problem with the hosts getting too crowded because the EXAs die immediately if they can't find the file and don't all start moving in the same cycle. If it finds the file it makes a WRITER EXA and starts copying. The writer starts with a countdown from 15 which runs every 2 writes. This is all done in the spare cycles between the writes. After the internal timer runs out, it then starts doing a somewhat slower write where it checks if a separate TIMER EXA is done each write. This is necessary because without it it would block endlessly once the reader is done. The TIMER runs for a set time which corresponds to the longest file in the test set. That seems slow, but remember, only the slowest test counts so this works out very well.

By the way, you can drop it to 185 cycles by moving over the SWIZ to directly below MARK SKIP.

Quackles posted:

For the activity-10 version, I had the reader EXA send back the shelf ID it was in, plus 100. Then the control EXA in my host finds the first number in its list that is less than that number, and sends it to mean 'grab that book'. So it's a granular sort that sorts in buckets, even if the process of scanning the list is a bit inefficient each time the next book needs to be queued.

The control EXA also tells the reader EXA to go to the next shelf if it doesn't find anything.

Reader EXA:
code:
COPY 100 X	;ID of shelf AFTER this one
LINK 800
COPY 1 M 	;sync
MARK NEWSHELF
ADDI X 100 X
LINK 800
COPY X M	;send shelf ID
COPY M T	
FJMP NEWSHELF 	;0 = next shelf, other number = book to grab
GRAB T 
MARK READOUT
COPY F M
TEST EOF
FJMP READOUT
DROP
COPY -9999 M
JUMP NEWSHELF 	;exploiting assumption: only one book per shelf is ever needed
Controller EXA:
code:
VOID M			;sync
MARK NEXTBOOK
GRAB 300
MARK NEXTBOOK2
NOOP
TEST MRD		;wait for shelf ID - no response = reader vanished, give up
FJMP GAMEOVER
COPY M X		;X has shelf ID after this one
MARK READBOOKLIST
TEST EOF
TJMP NOTFOUND
TEST F < X		;find any number that's on this shelf
TJMP COPYBOOK
JUMP READBOOKLIST
MARK NOTFOUND
COPY 0 M 		;next shelf
SEEK -9999
JUMP NEXTBOOK2
MARK COPYBOOK
SEEK -1
SWIZ F 0021 X		;generate book ID, send it
ADDI 200 X X
COPY X M
SEEK -1 
VOID F
DROP
MAKE
MARK COPYLOOP		;copy book then go back to controlling the reader
COPY M X
TEST X = -9999
COPY X F
FJMP COPYLOOP
SEEK -1
VOID F
DROP
JUMP NEXTBOOK
MARK GAMEOVER
1304/54/10.
Ah, an alternative low activity solution. I think Quackles' explanation speaks for itself. The code is quite readable, which is in part because the low activity solution forces you to read the books one by one.

Finally, silentsnack has an update to the Mitzuzen HDI-10 Heart level (update 15 of this LP).

silentsnack posted:

and as usual some completely unrelated random thing reminded me go back and take another look at the Phage/Heart solution, because it kinda bugged me to have 3 separate control structures redundantly running independent countdowns of the same number. And it turns out the suspicion that there should be a better way was correct, it just required approaching the timer from a different angle. Previous best time was 62/50/45.
code:
;XA
LINK 800

MARK LOOP
DIVI #NERV -10 X
SUBI X 3 T

FJMP SKIP
MARK WAIT
SUBI T 1 T
TJMP WAIT
MARK SKIP

REPL LOOP
REPL B
LINK 1
LINK 1
KILL
COPY 40 #NERV
COPY -70 #NERV
COPY -70 #NERV
JUMP BEAT

MARK B
LINK 3
LINK 3
KILL
COPY -70 #NERV
COPY 40 #NERV
MARK BEAT
COPY -70 #NERV
JUMP BEAT

;XB
NOOP
NOOP
LINK 800
REPL B
LINK 1
LINK 1
COPY 40 #NERV
COPY -70 #NERV
COPY -70 #NERV
JUMP BEAT
MARK B
LINK 3
LINK 3
COPY -70 #NERV
COPY 40 #NERV
MARK BEAT
COPY -70 #NERV
JUMP BEAT
Combined with splitting off the special-case'd first generation into a separate EXA to save a REPL operation brings it down to 56/45/42.
I don't even know what to say about this other than I never thought the count could get this low.


=== TEC EXA-Blaster™ Modem ===

Processing.
Yes, this is what I wanted.




Two votes for the first option, one for the second.

Glad it's helping.

I love ingesting a good corpus...
Not that that's all I'm doing.
I read the same way any normal human reads.
By analyzing patterns of word recurrence and deriving correlations between concepts implicit in statistically significant word clusters.


Excuse me?



lmao

Anyway, speaking of hungry, the zine has some new recipes for y'all to try.



Mmm, sounds like another 5 star experience. :discourse:



For the new assignment, we have to influence the media.

I've been analyzing television and radio broadcasts.
And I have a few questions.
First of all, why do some things become popular while others don't?




One vote for "Good work finds its fans", but two for the one about big media.

Big media conglomerates push some artists and abandon others.

So it comes down to corporate agendas?
We should test this.
Think we could pick a random pop song and make it a hit?


Okay, let's.


OST: Code and Registers

The assignment:
- Connect to each radio station and replace every song in the playlist (file 200) with CAN'T (NOT) GET OVER YOU by ME2U (file 300). Each song in a playlist consists of two keywords: the song name and the artist name.
- A list of phone numbers for the radio stations is available in file 301.
- Note that the EXAs in global mode can only communicate if there is a path of links connecting them.
- For more information see "Hacker Skills: Modem Control at the Direct Level" in the second issue of the zine.




Manually operating a modem? It's been a while.





If I send the 11-digit number to the #DIAL register, the modem will make a connection. Sending -1 will make the modem hang up and reset, and you can dial again.

That one note in the assignment is important though. You can't communicate between EXAs if they're in completely separate networks. If an EXA needs to send a message from a radio host to elsewhere you better keep the link open.

There's one more thing: Even though the modem is ours, leaving a file in the modem host (the one with the #DIAL register) will fail the assignment because for some reason that counts as leaving a trace.

With a max of 100 lines we have plenty of space to play around. Let's start with the dialer.

code:
GRAB 301
LINK 800
MARK DIAL
@REP 11
COPY F #DIAL
@END
COPY -1 #DIAL
TEST EOF
FJMP DIAL
WIPE
Simply grab the file, dial 11 digits, then hang up immediately. That gives us only one cycle to actually get into each radio host but if I time it well that should work out. Since I take file 301 along, I need to WIPE it at the end.

The song is exactly two values (name and artist), so theoretically that should fit in the registers. Let's create a second EXA and give that a try.
code:
;XB
GRAB 300
COPY F T
COPY F X
WIPE
LINK 800
MARK TRY
REPL TRY
LINK 800

GRAB 200
Put the title in T and the artist in X. Destroy the file, then just keep trying to get into an open modem link with REPLs. This works, it's fast enough to try it each cycle.

Now I have to overwrite each song in the playlist with Ember's song. But I shouldn't add anything to the playlists, so I need to keep track of the length. That is going to require a register. We need a trick.

code:
;XB continued
MARK WRITE
COPY T F
COPY X F
TEST EOF
FJMP WRITE
On the first iteration of this loop, it writes the title and artist to the playlist. After that, it'll start writing 0s (the content of the T register after TEST EOF and the artist. That's good, it means we have the title safely stored at the beginning of the file.



Finally, the EXA SEEKs to the start of the file, grabs the song title, and writes it over the 0s in another loop.

The only thing that's left are copies of XB still replicating in the modem host. That's easily solved by just adding a couple of KILL instructions at the end of XA.



Not the cleanest solution, but it works.



Top percentile scores are 129, 32 and 9. Let's get closer to them.



The first thing I can do is unroll the loop of the file writer, making use of the fact that a playlist never has less than 6 songs. This immediately drops the cycle count from 185 to 159, with 55 cycles and 15 activity. For some reason, changing the speed of the file writer means XA needs more KILL instructions at the end.

I can use another trick to get it down a bit more to 154 cycles.
code:
GRAB 300
COPY F X
COPY F T
WIPE
LINK 800
MARK TRY
REPL TRY
LINK 800

GRAB 200

@REP 5
COPY X F
COPY T F
@END

MARK WRITE
COPY X F
COPY T F
TEST EOF
FJMP WRITE

SEEK -9999
SEEK 1
COPY F X
SEEK 10

MARK WRITE2
TEST F > 0
COPY X F
JUMP WRITE2
The main change was combining the SEEK 1 and the TEST EOF in the final loop. I do a file read (I used a TEST but a COPY would've worked just as well), which moves the cursor forward one if it succeeds. But if the EXA is already at the end of the file, it'll die. To make this work I had to write the artist name instead of the song title in the WRITE2 loop.

By the way, just to clean up the code a bit, putting a NOOP after the MARK TRY is just as fast, but XA only needs a single KILL at the end now.

Of course, since the WRITE2 loop has no conditional logic anymore, it is trivial to unroll.
code:
@REP 3
TEST F > 0
COPY X F
@END
Turns out three repeats is enough.

And since I have plenty of spare lines, the dialing sequence can be unrolled as well. It's manual, though, since you can't nest @REPs.



138/90/11

Conveniently, I can fit 4 dial actions. That way, the EOF test lines up perfectly after the second iteration of the outer loop.

And that's the best I can come up with... or so I thought at first. I then realized I can make use of the fact the slowest case needs three repeats at the end of XB.
code:
;XB second half
REPL SEND

MARK WRITE
COPY X F
COPY T F
TEST EOF
FJMP WRITE

SEEK -5
COPY M F
SEEK 1
COPY M F
SEEK 1
COPY M F
HALT

MARK SEND
@REP 3
COPY T M
@END
135/92/11

No need to do any tests in that last loop, all I need to do is seek back 3 songs from the end and run it exactly three times. Worst case, I overwrite some artist names twice with the same value. To prevent the need to SEEK back to the start to get the artist name, I just have a REPL hold it and send it to me.

But there's more. If I know a playlist is at least 6 songs and at most 9, and I can overwrite data, I don't need an EOF test at all.



Write six values from the start, 3 from the end. Worst case there's a bit of overlap. 122/85/11, several cycles under par.


The low activity score is trickier than it seems.
It's easy to get it down to 10: just merge XA and XB so you only LINK from home to the modem once. To get it down to 9 you need to remove the KILL for the ever-replicating original XB, though. The problem is you don't have much space for testing anything in XB, because you need both registers to hold the song info.

I came up with a solution where XB starts with only the song title. XA sends the artist name over M twice, every time it dials a number. It sends a zero when it's done. XB waits for M, and as soon as it sees something it first tests if it's zero (in which case it stops). If it's not zero, it reads M again to store the result in T - which can now safely be done because the test is complete. Other than that it works the same as before.
code:
GRAB 300
COPY F X
COPY F T
DROP

; ORIGINAL XA
GRAB 301
LINK 800
REPL TRY
COPY T X

MARK DIAL

@REP 11
COPY F #DIAL
@END
COPY X M
COPY X M
COPY -1 #DIAL

TEST EOF
FJMP DIAL
WIPE

COPY 0 M
HALT

; ORIGINAL XB
MARK TRY
NOOP
TEST M = 0
TJMP END

REPL TRY

COPY M T
LINK 800

GRAB 200

@REP 6
COPY X F
COPY T F
@END

SEEK 9999
SEEK -6

@REP 3
COPY X F
COPY T F
@END

MARK END
This code is all one EXA, the "ORIGINAL" notes are just a clarification. 180/57/9.

Since I spent a lot of time getting the cycles down to 122, I'll leave the low size optimization to the threads.

That was surprisingly easy.
People are requesting the single, humming it to themselves, buying the album...
Just because they've heard it before.
Is that really all it takes?




The first thread vote. And for next time...

Theory: The inconsistency of ratings depends on context.
We made a hit by picking a generic pop song and artificially boosting its exposure.
But there are other domains where this isn't possible.
For example, you couldn't change people's behavior by giving a Last Stop store a five-star rating in a restaurant guide.
That would be ridiculous.