My Best Exapunks Solutions

Date: 2023-06-21 | create | ctech | exapunks |

I've been playing a lot of Exapunks recently and been enjoying it. I love the complex simplicity of Zachtronics games and this one is no exception - allowing you to program in an assembly-like language.

Some of these get pretty hard and require a certain insight to accomplish them but that makes solving them so much more satisfying.

In this post I'll be holding my solutions to all puzzles in Exapunks. Hopefully it helps you get unstuck or shares some new ways of solving things.

A few caveats:

  • This is a best effort, work in progress so not all solutions may be up yet
  • No guarantee that these are "optimal" though I'll try to share my best solutions anyway

Exapunks Puzzle Solutions

Zebros Copies

Zebros Copies Exapunks Solution

For this challenge, I decided to create 3 exas with their own job:

  • DateReader - Navigates to Clock and reads / messages the date
  • PayWriter - Navigates to the payment log (201) and listens for messages to write out the fake payment
  • DebtReader - Navigates to the customer database to find, read, and void the debt to clear

datereader

NOTE DATEREADER
LINK 800
LINK 801
COPY #DATE M
HALT

paywriter

NOTE PAYWRITER
LINK 800
GRAB 201
SEEK 9999
COPY M F ; DATE
MODE
COPY M F ; USERID
COPY M F ; DOLLARS
COPY M F ; CENTS
DROP
HALT

debtreader

NOTE DEBTREADER
GRAB 300
COPY F X
DROP
LINK 800
GRAB 200
MARK SCANLOOP
TEST F = X
FJMP SCANLOOP
COPY X M ; USERID
COPY F M ; DOLLARS
COPY F M ; CENTS
SEEK -2
COPY 0 F
COPY 0 F
HALT

SFCTA Highway Sign #4902

SFCTA Highway Sign 4902 - Exapunks Solution

For this solution, I split the process into two exas:

  • Messagereader - Picks up the input file data and messages it out via M
  • Signwriter - Keeps track of the rows / cols (3 rows of 9 cols) and writes out (row, col, char) to the sign's #data

Highlights:

  • Keeping track of rows, cols - this is actually kinda hard using only a few registers. I decided to basically keep track of the number of grids we've used in total and then working back from there to determine the row / col we must be at.
    • Row = RowColCount / 9
    • Col = RowColCount - (9 * Row)

messagereader

NOTE MESSAGEREADER
GRAB 300
MARK READMESSAGE
COPY F M
TEST EOF
FJMP READMESSAGE
HALT

signwriter

NOTE SIGNWRITER
LINK 800

NOTE FILEWRITE
NOTE ROW, COL, CHAR
MARK FILEWRITE
DIVI X 9 T ; T = ROW
COPY T #DATA
MULI 9 T T
SUBI X T T ; T = COL
COPY T #DATA
COPY M #DATA
ADDI X 1 X
TEST X = 27
FJMP FILEWRITE

HALT

Unknown Network 1

Unknown Network 1 - Exapunks Solution

For this solution, we just use 1 exa that recursively spawns itself for a "tree-like" search:

  • Searcher - For 4 levels (depth of tree), spawns a new exa to search right (801) and itself searches left (800). At 4 levels we are at a "leaf" where the target exa and file might live so we kill and grab the file (this kills off all incorrect exas due to no file error). Finally we return with the file.

Highlights:

  • Kill - It took me awhile to realize this was a function. It's in the booklet but no hints lead you there.
  • REPL - This is actually a really cool function and I'm betting we'll do some more complicated recursive stuff w it in the future.
  • GRAB and Errors - It's interesting that here we actually use errors to help us destroy our unnecessary exas. I bet this will be a common tactic throughout the game.

searcher

NOTE SEARCHER
LINK 800

NOTE SEARCH
MARK SEARCH
ADDI X 1 X
TEST X = 4
TJMP KILLANDFETCH
REPL SEARCHR

MARK SEARCHL
LINK 800
JUMP SEARCH

MARK SEARCHR
LINK 801
JUMP SEARCH

MARK KILLANDFETCH
KILL
GRAB 276
LINK -1
LINK -1
LINK -1
LINK -1

UC Berkeley

UC Berkeley - Exapunks Solution

For this solution, we use two exas:

  • FileFinder - Finds and reads the target file and section of files
  • HostSendWrite - This is a helper bot that both sends data to support FileFinder but also receives the target data to write out to our host

Highlights:

  • Syncing messages between FileFinder and HostSendWrite - Ideally we'd be able to peek() messages in M in a non-destructive manner but I haven't found a way to do that. This means we need to basically set up comms between the two exas so they know how much data they're agreeing to process.

FileFinder

NOTE FILEFINDER
GRAB 300
COPY F X
DROP

NOTE FINDHOST
MARK FINDHOST
LINK 800
HOST T
TEST T = X
FJMP FINDHOST

NOTE HOSTFOUND-GETMETA
NOTE META: NAME,OFF,LEN
GRAB 200
COPY M X
MARK FINDENTRY
TEST F = X
FJMP FINDENTRY

NOTE ENTRYFOUND-SETLOOP
COPY F T ; OFFSET
COPY F X ; LEN

NOTE SETTOOFFSET
SEEK -9999
SEEK T

COPY X M

MARK READDATA
COPY F M
SUBI X 1 X
TEST X = 0
FJMP READDATA

DROP
HALT

HostSendWrite

NOTE HOSTSENDWRITE
NOOP
NOOP
NOOP

NOTE SENDTARGETENTRY
GRAB 300
SEEK 1 ; TO TARGETNAME
COPY F X
COPY X M
DROP

NOTE WRITEENTRIES
MAKE

COPY M X

MARK WRITEDATA
COPY M F
SUBI X 1 X
TEST X = 0
FJMP WRITEDATA

HALT

Workhouse

Workhouse - Exapunks Solution

For this solution, we use two Exas:

  • FindUserDB - Finds the target username, then searches the user db to figure out which file contains its data, then pushes that to M
  • OverwriteUserDB - Receives the target file, sums the transaction value, then writes out new transactions in max(75) increments until its written out the sum

FindUserDB

NOTE FINDUSERDB
GRAB 300
COPY F X
DROP

LINK 800
GRAB 199
MARK FINDUSERDB
TEST F = X
FJMP FINDUSERDB

NOTE USERFILE TO M
SEEK 1
COPY F M

DROP
HALT

OverwriteUserDb

NOTE OVERWRITEUSERDB
LINK 800
LINK 799

COPY M X
GRAB X

COPY 0 X
SEEK 2

MARK SUMALL
ADDI X F X
TEST EOF
FJMP SUMALL

SEEK -9999
SEEK 2

MARK WRITEALL
TEST X > 75
TJMP WRITE75
JUMP WRITEREST

MARK WRITE75
COPY 75 F
SUBI X 75 X
JUMP WRITEALL

MARK WRITEREST
COPY X F

MARK END
DROP
HALT

Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.